/// <summary> /// Creates the customer asynchronous. /// </summary> /// <param name="user">The user.</param> /// <param name="planId">The plan identifier.</param> /// <param name="trialEnd">The trial end.</param> /// <param name="cardToken">The card token.</param> /// <returns></returns> public async Task<object> CreateCustomerAsync(SaasEcomUser user, string planId = null, DateTime? trialEnd = null, string cardToken = null) { var customer = new StripeCustomerCreateOptions { AccountBalance = 0, Email = user.Email }; if (!string.IsNullOrEmpty(cardToken)) { customer.Card = new StripeCreditCardOptions { TokenId = cardToken }; } if (!string.IsNullOrEmpty(planId)) { customer.PlanId = planId; customer.TrialEnd = trialEnd; } var stripeUser = await Task.Run(() => _customerService.Create(customer)); return stripeUser; }
/// <summary> /// Subscribes the user to a Stripe plan. If the user doesn't exist in Stripe, is created /// </summary> /// <param name="user">Application User</param> /// <param name="planId">Plan Id to subscribe the user to</param> /// <param name="taxPercent">The tax percent.</param> /// <param name="creditCard">The credit card.</param> /// <returns> /// Subscription /// </returns> public async Task<Subscription> SubscribeUserAsync (SaasEcomUser user, string planId, decimal taxPercent = 0, CreditCard creditCard = null) { Subscription subscription; // If the user isn't created in Stripe if (string.IsNullOrEmpty(user.StripeCustomerId)) { // Save the subscription in the DB subscription = await _subscriptionDataService.SubscribeUserAsync(user, planId, trialPeriodInDays: null, taxPercent: taxPercent); // Create a new customer in Stripe and subscribe him to the plan var cardToken = creditCard == null ? null : creditCard.StripeToken; var stripeUser = (StripeCustomer) await _customerProvider.CreateCustomerAsync(user, planId, null, cardToken); user.StripeCustomerId = stripeUser.Id; // Add stripe user Id to the user // Save Stripe Subscription Id in the DB subscription.StripeId = GetStripeSubscriptionIdForNewCustomer(stripeUser); await _subscriptionDataService.UpdateSubscriptionAsync(subscription); } else // Create new subscription in Stripe and DB { subscription = await this.SubscribeUserAsync(user, planId, creditCard, 0, taxPercent: taxPercent); } // Update tax percent on stripe if (taxPercent > 0) { await this.UpdateSubscriptionTax(user, subscription.StripeId, taxPercent); } return subscription; }
/// <summary> /// Adds the credit card asynchronous. /// </summary> /// <param name="user">The user.</param> /// <param name="card">The card.</param> /// <returns></returns> public async Task AddAsync(SaasEcomUser user, CreditCard card) { // Save to Stripe var stripeCustomerId = user.StripeCustomerId; AddCardToStripe(card, stripeCustomerId); // Save to storage card.SaasEcomUserId = user.Id; await _cardDataService.AddAsync(card); }
/// <summary> /// Subscribes the user. /// </summary> /// <param name="user">The user.</param> /// <param name="planId">The plan identifier.</param> /// <param name="trialEnds">The trial ends.</param> /// <param name="taxPercent">The tax percent.</param> public string SubscribeUser(SaasEcomUser user, string planId, DateTime? trialEnds, decimal taxPercent = 0) { var result = this._subscriptionService.Create(user.StripeCustomerId, planId, new StripeSubscriptionUpdateOptions { PlanId = planId, TaxPercent = taxPercent, TrialEnd = trialEnds }); return result.Id; }
/// <summary> /// Subscribes the user. /// </summary> /// <param name="user">The user.</param> /// <param name="planId">The plan identifier.</param> /// <param name="trialInDays">The trial in days.</param> /// <param name="taxPercent">The tax percent.</param> public string SubscribeUser(SaasEcomUser user, string planId, int trialInDays = 0, decimal taxPercent = 0) { var result = this._subscriptionService.Create(user.StripeCustomerId, planId, new StripeSubscriptionUpdateOptions { PlanId = planId, TaxPercent = taxPercent, TrialEnd = DateTime.UtcNow.AddDays(trialInDays) }); return result.Id; }
/// <summary> /// Updates the customer. /// </summary> /// <param name="user">The user.</param> /// <param name="card">The card.</param> /// <returns></returns> public object UpdateCustomer(SaasEcomUser user, CreditCard card) { var customer = new StripeCustomerUpdateOptions { Email = user.Email, // Card Details SourceToken = card.StripeToken }; return _customerService.Update(user.StripeCustomerId, customer); }
/// <summary> /// Updates the credit card asynchronous. /// </summary> /// <param name="user">The user.</param> /// <param name="creditcard">The creditcard.</param> /// <returns></returns> public async Task UpdateAsync(SaasEcomUser user, CreditCard creditcard) { // Remove current card from stripe var currentCard = await _cardDataService.FindAsync(user.Id, creditcard.Id, true); var stripeCustomerId = user.StripeCustomerId; _cardService.Delete(stripeCustomerId, currentCard.StripeId); this.AddCardToStripe(creditcard, stripeCustomerId); // Update card in the DB creditcard.SaasEcomUserId = user.Id; await _cardDataService.UpdateAsync(user.Id, creditcard); }
/// <summary> /// Subscribes the user, with a billing cycle that goes from the 1st of the month asynchronous. /// Creates the user in Stripe if doesn't exist already. /// Saves de Subscription data in the database if the subscription suceeds. /// </summary> /// <param name="user">The user.</param> /// <param name="planId">The plan identifier.</param> /// <param name="card">The card.</param> /// <param name="taxPercent">The tax percent.</param> /// <returns></returns> public async Task SubscribeUserNaturalMonthAsync(SaasEcomUser user, string planId, CreditCard card, decimal taxPercent = 0) { if (string.IsNullOrEmpty(user.StripeCustomerId)) { // Create a new customer in Stripe and save card var stripeUser = (StripeCustomer)await _customerProvider.CreateCustomerAsync(user, cardToken: card.StripeToken); user.StripeCustomerId = stripeUser.Id; card.SaasEcomUserId = user.Id; await _cardDataService.AddAsync(card); } else if (card != null && !string.IsNullOrEmpty(card.StripeToken)) { // Update the default card for the user var customer = (StripeCustomer)_customerProvider.UpdateCustomer(user, card); card.SaasEcomUserId = user.Id; card.StripeId = customer.DefaultSourceId; await _cardDataService.AddOrUpdateDefaultCardAsync(user.Id, card); } var stripeSubscription = (StripeSubscription)_subscriptionProvider.SubscribeUserNaturalMonth(user, planId, GetStartNextMonth(), taxPercent); await _subscriptionDataService.SubscribeUserAsync(user, planId, (int?)null, taxPercent, stripeSubscription.Id); }
/// <summary> /// Cancel subscription from Stripe /// </summary> /// <param name="subscriptionId">Stripe subscription Id</param> /// <param name="user">Application user</param> /// <param name="cancelAtPeriodEnd">Cancel immediately or when the paid period ends (default immediately)</param> /// <param name="reasonToCancel">The reason to cancel.</param> /// <returns>The Date when the subscription ends (it can be future if cancelAtPeriodEnd is true)</returns> public async Task<DateTime?> EndSubscriptionAsync(int subscriptionId, SaasEcomUser user, bool cancelAtPeriodEnd = false, string reasonToCancel = null) { DateTime? subscriptionEnd = null; try { var subscription = await _subscriptionDataService.UserActiveSubscriptionAsync(user.Id); if (subscription != null && subscription.Id == subscriptionId) { subscriptionEnd = _subscriptionProvider.EndSubscription(user.StripeCustomerId, subscription.StripeId, cancelAtPeriodEnd); await _subscriptionDataService.EndSubscriptionAsync(subscriptionId, subscriptionEnd.Value, reasonToCancel); } } catch (Exception) { // TODO: Log subscriptionEnd = null; } return subscriptionEnd; }
/// <summary> /// Updates the subscription tax. /// </summary> /// <param name="user">The user.</param> /// <param name="subscriptionId">The subscription stripe identifier.</param> /// <param name="taxPercent">The tax percent.</param> /// <returns>boolean</returns> public async Task<bool> UpdateSubscriptionTax(SaasEcomUser user, string subscriptionId, decimal taxPercent) { // DB await _subscriptionDataService.UpdateSubscriptionTax(subscriptionId, taxPercent); // Stripe return _subscriptionProvider.UpdateSubscriptionTax(user.StripeCustomerId, subscriptionId, taxPercent); }
/// <summary> /// Subscribe an existing user to a plan. /// </summary> /// <param name="user">Application User</param> /// <param name="planId">Stripe plan Id</param> /// <param name="creditCard">Credit card to pay this subscription.</param> /// <param name="trialInDays">The trial in days.</param> /// <param name="taxPercent">The tax percent.</param> /// <returns></returns> private async Task<Subscription> SubscribeUserAsync(SaasEcomUser user, string planId, CreditCard creditCard, int trialInDays = 0, decimal taxPercent = 0) { // Save payment details if (creditCard != null) { if (creditCard.Id == 0) { await _cardProvider.AddAsync(user, creditCard); } else { await _cardProvider.UpdateAsync(user, creditCard); } } // Save subscription details var subscriptionId = _subscriptionProvider.SubscribeUser (user, planId, trialInDays: trialInDays, taxPercent: taxPercent); // Stripe var subscription = await this._subscriptionDataService.SubscribeUserAsync(user, planId, trialInDays, taxPercent, subscriptionId); // DB return subscription; }
/// <summary> /// Deletes the customer. /// </summary> /// <param name="user">The user.</param> /// <returns></returns> /// <exception cref="System.NotImplementedException"></exception> public void DeleteCustomer(SaasEcomUser user) { _customerService.Delete(user.StripeCustomerId); }
/// <summary> /// Subscribes the user natural month. /// </summary> /// <param name="user">The user.</param> /// <param name="planId">The plan identifier.</param> /// <param name="billingAnchorCycle">The billing anchor cycle.</param> /// <param name="taxPercent">The tax percent.</param> /// <returns></returns> public object SubscribeUserNaturalMonth(SaasEcomUser user, string planId, DateTime? billingAnchorCycle, decimal taxPercent) { StripeSubscription stripeSubscription = _subscriptionService.Create (user.StripeCustomerId, planId, new StripeSubscriptionCreateOptions { BillingCycleAnchor = billingAnchorCycle, TaxPercent = taxPercent }); return stripeSubscription; }