2021-11-14 05:28:24 +01:00
|
|
|
|
using Microsoft.AspNetCore.Http;
|
|
|
|
|
using Stripe;
|
2021-08-12 03:44:15 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2021-11-14 05:28:24 +01:00
|
|
|
|
using System.IO;
|
2021-08-12 03:44:15 +02:00
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
2021-11-14 05:28:24 +01:00
|
|
|
|
using System.Web;
|
2021-08-15 09:38:48 +02:00
|
|
|
|
using Teknik.BillingCore.Models;
|
2021-08-12 03:44:15 +02:00
|
|
|
|
using Teknik.Configuration;
|
|
|
|
|
|
|
|
|
|
namespace Teknik.BillingCore
|
|
|
|
|
{
|
|
|
|
|
public class StripeService : BillingService
|
|
|
|
|
{
|
|
|
|
|
public StripeService(BillingConfig config) : base(config)
|
2021-08-15 09:38:48 +02:00
|
|
|
|
{
|
|
|
|
|
StripeConfiguration.ApiKey = config.StripeSecretApiKey;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-20 01:59:31 +01:00
|
|
|
|
public override List<Models.Customer> GetCustomers()
|
|
|
|
|
{
|
|
|
|
|
var customers = new List<Models.Customer>();
|
|
|
|
|
var service = new CustomerService();
|
|
|
|
|
var foundCustomers = service.List();
|
|
|
|
|
if (foundCustomers != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var customer in foundCustomers)
|
|
|
|
|
{
|
|
|
|
|
customers.Add(ConvertCustomer(customer));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return customers;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override Models.Customer GetCustomer(string email)
|
2021-08-15 09:38:48 +02:00
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
if (!string.IsNullOrEmpty(email))
|
|
|
|
|
{
|
|
|
|
|
var service = new CustomerService();
|
|
|
|
|
var foundCustomer = service.Get(email);
|
|
|
|
|
if (foundCustomer != null)
|
2021-11-20 01:59:31 +01:00
|
|
|
|
return ConvertCustomer(foundCustomer);
|
2021-11-14 05:28:24 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
2021-08-15 09:38:48 +02:00
|
|
|
|
}
|
2021-08-12 03:44:15 +02:00
|
|
|
|
|
2022-08-15 04:43:45 +02:00
|
|
|
|
public override string GetCustomerProfileUrl(string email)
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(email))
|
|
|
|
|
{
|
|
|
|
|
var service = new CustomerService();
|
|
|
|
|
var foundCustomer = service.Get(email);
|
|
|
|
|
if (foundCustomer != null)
|
|
|
|
|
return $"https://dashboard.stripe.com/customers/{foundCustomer.Id}";
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-14 05:28:24 +01:00
|
|
|
|
public override string CreateCustomer(string username, string email)
|
2021-08-12 03:44:15 +02:00
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
if (string.IsNullOrEmpty(username))
|
|
|
|
|
throw new ArgumentNullException("username");
|
|
|
|
|
|
2021-08-12 03:44:15 +02:00
|
|
|
|
var options = new CustomerCreateOptions
|
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
Name = username,
|
2021-08-12 03:44:15 +02:00
|
|
|
|
Email = email,
|
2021-11-14 05:28:24 +01:00
|
|
|
|
Description = $"Customer for account {username}"
|
2021-08-12 03:44:15 +02:00
|
|
|
|
};
|
|
|
|
|
var service = new CustomerService();
|
|
|
|
|
var customer = service.Create(options);
|
2021-11-14 05:28:24 +01:00
|
|
|
|
return customer.Id;
|
2021-08-12 03:44:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-15 09:38:48 +02:00
|
|
|
|
public override List<Models.Product> GetProductList()
|
2021-08-12 03:44:15 +02:00
|
|
|
|
{
|
2021-08-15 09:38:48 +02:00
|
|
|
|
var productList = new List<Models.Product>();
|
|
|
|
|
var productService = new ProductService();
|
|
|
|
|
|
|
|
|
|
var options = new ProductListOptions
|
|
|
|
|
{
|
|
|
|
|
Active = true
|
|
|
|
|
};
|
|
|
|
|
var products = productService.List(options);
|
|
|
|
|
foreach (var product in products)
|
|
|
|
|
{
|
|
|
|
|
productList.Add(ConvertProduct(product));
|
|
|
|
|
}
|
|
|
|
|
return productList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override Models.Product GetProduct(string productId)
|
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
if (!string.IsNullOrEmpty(productId))
|
|
|
|
|
{
|
|
|
|
|
var productService = new ProductService();
|
|
|
|
|
Stripe.Product product = productService.Get(productId);
|
|
|
|
|
if (product != null)
|
|
|
|
|
return ConvertProduct(product);
|
|
|
|
|
}
|
2021-08-15 09:38:48 +02:00
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override List<Models.Price> GetPriceList(string productId)
|
|
|
|
|
{
|
|
|
|
|
var foundPrices = new List<Models.Price>();
|
2021-11-14 05:28:24 +01:00
|
|
|
|
if (!string.IsNullOrEmpty(productId))
|
2021-08-15 09:38:48 +02:00
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
var options = new PriceListOptions
|
|
|
|
|
{
|
|
|
|
|
Active = true,
|
|
|
|
|
Product = productId
|
|
|
|
|
};
|
|
|
|
|
options.AddExpand("data.product");
|
2021-08-15 09:38:48 +02:00
|
|
|
|
|
2021-11-14 05:28:24 +01:00
|
|
|
|
var priceService = new PriceService();
|
|
|
|
|
var priceList = priceService.List(options);
|
|
|
|
|
if (priceList != null)
|
2021-08-15 09:38:48 +02:00
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
foreach (var price in priceList)
|
|
|
|
|
{
|
|
|
|
|
foundPrices.Add(ConvertPrice(price));
|
|
|
|
|
}
|
2021-08-15 09:38:48 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
2021-11-14 05:28:24 +01:00
|
|
|
|
|
2021-08-15 09:38:48 +02:00
|
|
|
|
return foundPrices;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override Models.Price GetPrice(string priceId)
|
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
if (!string.IsNullOrEmpty(priceId))
|
|
|
|
|
{
|
|
|
|
|
var options = new PriceGetOptions();
|
|
|
|
|
var priceService = new PriceService();
|
|
|
|
|
var price = priceService.Get(priceId, options);
|
|
|
|
|
if (price != null)
|
|
|
|
|
return ConvertPrice(price);
|
|
|
|
|
}
|
2021-08-15 09:38:48 +02:00
|
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override List<Models.Subscription> GetSubscriptionList(string customerId)
|
|
|
|
|
{
|
|
|
|
|
var subscriptionList = new List<Models.Subscription>();
|
|
|
|
|
|
|
|
|
|
if (!string.IsNullOrEmpty(customerId))
|
|
|
|
|
{
|
|
|
|
|
var options = new SubscriptionListOptions
|
|
|
|
|
{
|
|
|
|
|
Customer = customerId
|
|
|
|
|
};
|
|
|
|
|
var subService = new SubscriptionService();
|
|
|
|
|
var subs = subService.List(options);
|
|
|
|
|
if (subs != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var sub in subs)
|
|
|
|
|
{
|
|
|
|
|
subscriptionList.Add(ConvertSubscription(sub));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return subscriptionList;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override Models.Subscription GetSubscription(string subscriptionId)
|
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
if (!string.IsNullOrEmpty(subscriptionId))
|
|
|
|
|
{
|
|
|
|
|
var subService = new SubscriptionService();
|
|
|
|
|
var sub = subService.Get(subscriptionId);
|
|
|
|
|
if (sub != null)
|
|
|
|
|
return ConvertSubscription(sub);
|
|
|
|
|
}
|
2021-08-15 09:38:48 +02:00
|
|
|
|
|
|
|
|
|
return null;
|
2021-08-12 03:44:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
2021-11-14 05:28:24 +01:00
|
|
|
|
public override Models.Subscription CreateSubscription(string customerId, string priceId)
|
2021-08-12 03:44:15 +02:00
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
if (!string.IsNullOrEmpty(customerId) &&
|
|
|
|
|
!string.IsNullOrEmpty(priceId))
|
2021-08-12 03:44:15 +02:00
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
// Create the subscription. Note we're expanding the Subscription's
|
|
|
|
|
// latest invoice and that invoice's payment_intent
|
|
|
|
|
// so we can pass it to the front end to confirm the payment
|
|
|
|
|
var subscriptionOptions = new SubscriptionCreateOptions
|
2021-08-12 03:44:15 +02:00
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
Customer = customerId,
|
|
|
|
|
Items = new List<SubscriptionItemOptions>
|
2021-08-12 03:44:15 +02:00
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
new SubscriptionItemOptions
|
|
|
|
|
{
|
|
|
|
|
Price = priceId,
|
|
|
|
|
},
|
2021-08-12 03:44:15 +02:00
|
|
|
|
},
|
2021-11-14 05:28:24 +01:00
|
|
|
|
PaymentBehavior = "default_incomplete",
|
|
|
|
|
CancelAtPeriodEnd = false
|
|
|
|
|
};
|
|
|
|
|
subscriptionOptions.AddExpand("latest_invoice.payment_intent");
|
|
|
|
|
var subscriptionService = new SubscriptionService();
|
|
|
|
|
var subscription = subscriptionService.Create(subscriptionOptions);
|
|
|
|
|
|
|
|
|
|
return ConvertSubscription(subscription);
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override Models.Subscription EditSubscriptionPrice(string subscriptionId, string priceId)
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(subscriptionId))
|
|
|
|
|
{
|
|
|
|
|
var subscriptionService = new SubscriptionService();
|
|
|
|
|
var subscription = subscriptionService.Get(subscriptionId);
|
|
|
|
|
if (subscription != null)
|
|
|
|
|
{
|
|
|
|
|
var subscriptionOptions = new SubscriptionUpdateOptions()
|
|
|
|
|
{
|
|
|
|
|
Items = new List<SubscriptionItemOptions>
|
|
|
|
|
{
|
|
|
|
|
new SubscriptionItemOptions
|
|
|
|
|
{
|
|
|
|
|
Id = subscription.Items.Data[0].Id,
|
|
|
|
|
Price = priceId,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
CancelAtPeriodEnd = false,
|
|
|
|
|
ProrationBehavior = "create_prorations"
|
|
|
|
|
};
|
|
|
|
|
subscriptionOptions.AddExpand("latest_invoice.payment_intent");
|
|
|
|
|
var result = subscriptionService.Update(subscriptionId, subscriptionOptions);
|
|
|
|
|
if (result != null)
|
|
|
|
|
return ConvertSubscription(result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-29 07:26:20 +01:00
|
|
|
|
public override Models.Subscription RenewSubscription(string subscriptionId)
|
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(subscriptionId))
|
|
|
|
|
{
|
|
|
|
|
var subscriptionService = new SubscriptionService();
|
|
|
|
|
var subscription = subscriptionService.Get(subscriptionId);
|
|
|
|
|
if (subscription != null)
|
|
|
|
|
{
|
|
|
|
|
var subscriptionOptions = new SubscriptionUpdateOptions()
|
|
|
|
|
{
|
|
|
|
|
CancelAtPeriodEnd = false
|
|
|
|
|
};
|
|
|
|
|
subscriptionOptions.AddExpand("latest_invoice.payment_intent");
|
|
|
|
|
var result = subscriptionService.Update(subscriptionId, subscriptionOptions);
|
|
|
|
|
if (result != null)
|
|
|
|
|
return ConvertSubscription(result);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-29 05:57:15 +01:00
|
|
|
|
public override bool CancelSubscription(string subscriptionId, bool atEndOfperiod)
|
2021-11-14 05:28:24 +01:00
|
|
|
|
{
|
|
|
|
|
if (!string.IsNullOrEmpty(subscriptionId))
|
|
|
|
|
{
|
2021-11-29 05:57:15 +01:00
|
|
|
|
if (atEndOfperiod)
|
2021-11-14 05:28:24 +01:00
|
|
|
|
{
|
2021-11-29 05:57:15 +01:00
|
|
|
|
var cancelOptions = new SubscriptionUpdateOptions()
|
|
|
|
|
{
|
|
|
|
|
CancelAtPeriodEnd = true
|
|
|
|
|
};
|
|
|
|
|
var subscriptionService = new SubscriptionService();
|
|
|
|
|
var subscription = subscriptionService.Update(subscriptionId, cancelOptions);
|
|
|
|
|
return subscription.CancelAtPeriodEnd;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
var cancelOptions = new SubscriptionCancelOptions()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
InvoiceNow = true
|
|
|
|
|
};
|
|
|
|
|
var subscriptionService = new SubscriptionService();
|
|
|
|
|
var subscription = subscriptionService.Cancel(subscriptionId, cancelOptions);
|
|
|
|
|
return subscription.Status == "canceled";
|
|
|
|
|
}
|
2021-11-14 05:28:24 +01:00
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override CheckoutSession CreateCheckoutSession(string customerId, string priceId, string successUrl, string cancelUrl)
|
|
|
|
|
{
|
|
|
|
|
// Modify Success URL to include session ID variable
|
|
|
|
|
var uriBuilder = new UriBuilder(successUrl);
|
|
|
|
|
var paramValues = HttpUtility.ParseQueryString(uriBuilder.Query);
|
|
|
|
|
paramValues.Add("session_id", "{CHECKOUT_SESSION_ID}");
|
|
|
|
|
uriBuilder.Query = paramValues.ToString();
|
|
|
|
|
successUrl = uriBuilder.Uri.ToString();
|
|
|
|
|
|
|
|
|
|
var checkoutService = new Stripe.Checkout.SessionService();
|
|
|
|
|
var sessionOptions = new Stripe.Checkout.SessionCreateOptions()
|
|
|
|
|
{
|
|
|
|
|
LineItems = new List<Stripe.Checkout.SessionLineItemOptions>()
|
|
|
|
|
{
|
|
|
|
|
new Stripe.Checkout.SessionLineItemOptions()
|
|
|
|
|
{
|
|
|
|
|
Price = priceId,
|
|
|
|
|
Quantity = 1
|
|
|
|
|
}
|
2021-08-12 03:44:15 +02:00
|
|
|
|
},
|
2021-11-14 05:28:24 +01:00
|
|
|
|
PaymentMethodTypes = new List<string>()
|
|
|
|
|
{
|
|
|
|
|
"card"
|
|
|
|
|
},
|
|
|
|
|
Mode = "subscription",
|
|
|
|
|
SuccessUrl = successUrl,
|
|
|
|
|
CancelUrl = cancelUrl,
|
|
|
|
|
Customer = customerId
|
2021-08-12 03:44:15 +02:00
|
|
|
|
};
|
2021-11-14 05:28:24 +01:00
|
|
|
|
sessionOptions.AddExpand("customer");
|
|
|
|
|
var session = checkoutService.Create(sessionOptions);
|
|
|
|
|
return ConvertCheckoutSession(session);
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-18 08:13:46 +01:00
|
|
|
|
public override CheckoutSession GetCheckoutSession(string sessionId)
|
|
|
|
|
{
|
|
|
|
|
var checkoutService = new Stripe.Checkout.SessionService();
|
|
|
|
|
var sessionOptions = new Stripe.Checkout.SessionGetOptions();
|
|
|
|
|
sessionOptions.AddExpand("customer");
|
|
|
|
|
var session = checkoutService.Get(sessionId, sessionOptions);
|
|
|
|
|
|
|
|
|
|
return ConvertCheckoutSession(session);
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-16 05:17:42 +01:00
|
|
|
|
public override async Task<Models.Event> ParseEvent(HttpRequest request, string apiKey)
|
2021-11-14 05:28:24 +01:00
|
|
|
|
{
|
|
|
|
|
var json = await new StreamReader(request.Body).ReadToEndAsync();
|
|
|
|
|
|
2021-08-12 03:44:15 +02:00
|
|
|
|
try
|
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
var stripeEvent = EventUtility.ConstructEvent(
|
|
|
|
|
json,
|
|
|
|
|
request.Headers["Stripe-Signature"],
|
2021-11-16 05:17:42 +01:00
|
|
|
|
apiKey
|
2021-11-14 05:28:24 +01:00
|
|
|
|
);
|
2021-08-12 03:44:15 +02:00
|
|
|
|
|
2021-11-14 05:28:24 +01:00
|
|
|
|
return ConvertEvent(stripeEvent);
|
2021-08-12 03:44:15 +02:00
|
|
|
|
}
|
2021-11-14 05:28:24 +01:00
|
|
|
|
catch (StripeException)
|
2021-08-12 03:44:15 +02:00
|
|
|
|
{
|
|
|
|
|
}
|
2021-11-14 05:28:24 +01:00
|
|
|
|
return null;
|
2021-08-12 03:44:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
2021-11-14 05:28:24 +01:00
|
|
|
|
public override CheckoutSession ProcessCheckoutCompletedEvent(Models.Event ev)
|
2021-08-12 03:44:15 +02:00
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
// Handle the checkout.session.completed event
|
|
|
|
|
var session = ev.Data as Stripe.Checkout.Session;
|
|
|
|
|
|
|
|
|
|
return ConvertCheckoutSession(session);
|
2021-08-12 03:44:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
2021-11-16 05:17:42 +01:00
|
|
|
|
public override Models.Subscription ProcessSubscriptionEvent(Models.Event ev)
|
2021-08-12 03:44:15 +02:00
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
// Handle the checkout.session.completed event
|
2021-11-16 05:17:42 +01:00
|
|
|
|
var subscription = ev.Data as Stripe.Subscription;
|
2021-11-14 05:28:24 +01:00
|
|
|
|
|
2021-11-16 05:17:42 +01:00
|
|
|
|
return ConvertSubscription(subscription);
|
2021-08-12 03:44:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
2021-11-20 01:14:27 +01:00
|
|
|
|
public override Models.Customer ProcessCustomerEvent(Models.Event ev)
|
|
|
|
|
{
|
|
|
|
|
// Handle the checkout.session.completed event
|
|
|
|
|
var customer = ev.Data as Stripe.Customer;
|
|
|
|
|
|
|
|
|
|
return ConvertCustomer(customer);
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-18 08:13:46 +01:00
|
|
|
|
public override PortalSession CreatePortalSession(string customerId, string returnUrl)
|
2021-08-12 03:44:15 +02:00
|
|
|
|
{
|
2021-11-18 08:13:46 +01:00
|
|
|
|
var portalService = new Stripe.BillingPortal.SessionService();
|
|
|
|
|
var sessionOptions = new Stripe.BillingPortal.SessionCreateOptions()
|
|
|
|
|
{
|
|
|
|
|
Customer = customerId,
|
|
|
|
|
ReturnUrl = returnUrl
|
|
|
|
|
};
|
|
|
|
|
var session = portalService.Create(sessionOptions);
|
|
|
|
|
return ConvertPortalSession(session);
|
2021-08-12 03:44:15 +02:00
|
|
|
|
}
|
|
|
|
|
|
2021-08-15 09:38:48 +02:00
|
|
|
|
private Models.Product ConvertProduct(Stripe.Product product)
|
2021-08-12 03:44:15 +02:00
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
if (product == null)
|
|
|
|
|
return null;
|
2021-08-15 09:38:48 +02:00
|
|
|
|
return new Models.Product()
|
|
|
|
|
{
|
|
|
|
|
ProductId = product.Id,
|
|
|
|
|
Name = product.Name,
|
|
|
|
|
Description = product.Description,
|
|
|
|
|
Prices = GetPriceList(product.Id)
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Models.Price ConvertPrice(Stripe.Price price)
|
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
if (price == null)
|
|
|
|
|
return null;
|
2021-08-15 09:38:48 +02:00
|
|
|
|
var interval = Interval.Once;
|
|
|
|
|
if (price.Type == "recurring")
|
|
|
|
|
{
|
|
|
|
|
switch (price.Recurring.Interval)
|
|
|
|
|
{
|
|
|
|
|
case "day":
|
|
|
|
|
interval = Interval.Day;
|
|
|
|
|
break;
|
|
|
|
|
case "week":
|
|
|
|
|
interval = Interval.Week;
|
|
|
|
|
break;
|
|
|
|
|
case "month":
|
|
|
|
|
interval = Interval.Month;
|
|
|
|
|
break;
|
|
|
|
|
case "year":
|
|
|
|
|
interval = Interval.Year;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
var convPrice = new Models.Price()
|
|
|
|
|
{
|
|
|
|
|
Id = price.Id,
|
|
|
|
|
ProductId = price.ProductId,
|
|
|
|
|
Name = price.Nickname,
|
|
|
|
|
Interval = interval,
|
|
|
|
|
Currency = price.Currency
|
|
|
|
|
};
|
|
|
|
|
if (price.UnitAmountDecimal != null)
|
|
|
|
|
convPrice.Amount = price.UnitAmountDecimal / 100;
|
|
|
|
|
if (price.Metadata.ContainsKey("storage"))
|
|
|
|
|
convPrice.Storage = long.Parse(price.Metadata["storage"]);
|
2021-11-14 05:28:24 +01:00
|
|
|
|
if (price.Metadata.ContainsKey("fileSize"))
|
|
|
|
|
convPrice.FileSize = long.Parse(price.Metadata["fileSize"]);
|
2021-08-15 09:38:48 +02:00
|
|
|
|
return convPrice;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Models.Subscription ConvertSubscription(Stripe.Subscription subscription)
|
|
|
|
|
{
|
2021-11-14 05:28:24 +01:00
|
|
|
|
if (subscription == null)
|
|
|
|
|
return null;
|
2021-08-15 09:38:48 +02:00
|
|
|
|
var status = SubscriptionStatus.Incomplete;
|
|
|
|
|
switch (subscription.Status)
|
|
|
|
|
{
|
|
|
|
|
case "active":
|
|
|
|
|
status = SubscriptionStatus.Active;
|
|
|
|
|
break;
|
|
|
|
|
case "past_due":
|
|
|
|
|
status = SubscriptionStatus.PastDue;
|
|
|
|
|
break;
|
|
|
|
|
case "unpaid":
|
|
|
|
|
status = SubscriptionStatus.Unpaid;
|
|
|
|
|
break;
|
|
|
|
|
case "canceled":
|
|
|
|
|
status = SubscriptionStatus.Canceled;
|
|
|
|
|
break;
|
|
|
|
|
case "incomplete":
|
|
|
|
|
status = SubscriptionStatus.Incomplete;
|
|
|
|
|
break;
|
|
|
|
|
case "incomplete_expired":
|
|
|
|
|
status = SubscriptionStatus.IncompleteExpired;
|
|
|
|
|
break;
|
|
|
|
|
case "trialing":
|
|
|
|
|
status = SubscriptionStatus.Trialing;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
var prices = new List<Models.Price>();
|
|
|
|
|
if (subscription.Items != null)
|
|
|
|
|
{
|
|
|
|
|
foreach (var item in subscription.Items)
|
|
|
|
|
{
|
|
|
|
|
prices.Add(ConvertPrice(item.Price));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return new Models.Subscription()
|
|
|
|
|
{
|
|
|
|
|
Id = subscription.Id,
|
|
|
|
|
CustomerId = subscription.CustomerId,
|
|
|
|
|
Status = status,
|
2021-11-29 07:26:20 +01:00
|
|
|
|
BillingPeriodEnd = subscription.CurrentPeriodEnd,
|
|
|
|
|
CancelAtBillingEnd = subscription.CancelAtPeriodEnd,
|
2021-11-14 05:28:24 +01:00
|
|
|
|
Prices = prices,
|
|
|
|
|
ClientSecret = subscription.LatestInvoice?.PaymentIntent?.ClientSecret
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private CheckoutSession ConvertCheckoutSession(Stripe.Checkout.Session session)
|
|
|
|
|
{
|
|
|
|
|
if (session == null)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
var paymentStatus = PaymentStatus.Unpaid;
|
|
|
|
|
switch (session.PaymentStatus)
|
|
|
|
|
{
|
|
|
|
|
case "paid":
|
|
|
|
|
paymentStatus = PaymentStatus.Paid;
|
|
|
|
|
break;
|
|
|
|
|
case "unpaid":
|
|
|
|
|
paymentStatus = PaymentStatus.Unpaid;
|
|
|
|
|
break;
|
|
|
|
|
case "no_payment_required":
|
|
|
|
|
paymentStatus = PaymentStatus.NoPaymentRequired;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new CheckoutSession()
|
|
|
|
|
{
|
|
|
|
|
PaymentIntentId = session.PaymentIntentId,
|
2021-11-16 05:17:42 +01:00
|
|
|
|
CustomerId = session.Customer?.Id ?? session.CustomerId,
|
2021-11-14 05:28:24 +01:00
|
|
|
|
SubscriptionId = session.SubscriptionId,
|
|
|
|
|
PaymentStatus = paymentStatus,
|
|
|
|
|
Url = session.Url
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-18 08:13:46 +01:00
|
|
|
|
private PortalSession ConvertPortalSession(Stripe.BillingPortal.Session session)
|
|
|
|
|
{
|
|
|
|
|
if (session == null)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
return new PortalSession()
|
|
|
|
|
{
|
|
|
|
|
Url = session.Url
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
2021-11-14 05:28:24 +01:00
|
|
|
|
private Models.Customer ConvertCustomer(Stripe.Customer customer)
|
|
|
|
|
{
|
|
|
|
|
var returnCust = new Models.Customer()
|
|
|
|
|
{
|
|
|
|
|
CustomerId = customer.Id
|
|
|
|
|
};
|
|
|
|
|
|
2021-11-20 01:14:27 +01:00
|
|
|
|
if (customer.Subscriptions != null &&
|
|
|
|
|
customer.Subscriptions.Any())
|
2021-11-14 05:28:24 +01:00
|
|
|
|
returnCust.Subscriptions = customer.Subscriptions.Select(s => ConvertSubscription(s)).ToList();
|
|
|
|
|
|
|
|
|
|
return returnCust;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Models.Event ConvertEvent(Stripe.Event ev)
|
|
|
|
|
{
|
|
|
|
|
if (ev == null)
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
|
|
var eventType = EventType.Unknown;
|
|
|
|
|
switch (ev.Type)
|
|
|
|
|
{
|
|
|
|
|
case Events.CheckoutSessionCompleted:
|
|
|
|
|
eventType = EventType.CheckoutComplete;
|
|
|
|
|
break;
|
|
|
|
|
case Events.CustomerSubscriptionDeleted:
|
|
|
|
|
eventType = EventType.SubscriptionDeleted;
|
|
|
|
|
break;
|
|
|
|
|
case Events.CustomerSubscriptionUpdated:
|
|
|
|
|
eventType = EventType.SubscriptionUpdated;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return new Models.Event()
|
|
|
|
|
{
|
|
|
|
|
EventType = eventType,
|
|
|
|
|
Data = ev.Data.Object
|
2021-08-15 09:38:48 +02:00
|
|
|
|
};
|
2021-08-12 03:44:15 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|