public IHttpActionResult ChangePlan(string id, string planId, string stripeToken = null, string last4 = null, string couponId = null) { if (String.IsNullOrEmpty(id) || !CanAccessOrganization(id)) { return(NotFound()); } if (!Settings.Current.EnableBilling) { return(Ok(ChangePlanResult.FailWithMessage("Plans cannot be changed while billing is disabled."))); } Organization organization = _repository.GetById(id); if (organization == null) { return(Ok(ChangePlanResult.FailWithMessage("Invalid OrganizationId."))); } BillingPlan plan = BillingManager.GetBillingPlan(planId); if (plan == null) { return(Ok(ChangePlanResult.FailWithMessage("Invalid PlanId."))); } if (String.Equals(organization.PlanId, plan.Id) && String.Equals(BillingManager.FreePlan.Id, plan.Id)) { return(Ok(ChangePlanResult.SuccessWithMessage("Your plan was not changed as you were already on the free plan."))); } // Only see if they can downgrade a plan if the plans are different. string message; if (!String.Equals(organization.PlanId, plan.Id) && !_billingManager.CanDownGrade(organization, plan, ExceptionlessUser, out message)) { return(Ok(ChangePlanResult.FailWithMessage(message))); } var customerService = new StripeCustomerService(); var subscriptionService = new StripeSubscriptionService(); try { // If they are on a paid plan and then downgrade to a free plan then cancel their stripe subscription. if (!String.Equals(organization.PlanId, BillingManager.FreePlan.Id) && String.Equals(plan.Id, BillingManager.FreePlan.Id)) { if (!String.IsNullOrEmpty(organization.StripeCustomerId)) { var subs = subscriptionService.List(organization.StripeCustomerId).Where(s => !s.CanceledAt.HasValue); foreach (var sub in subs) { subscriptionService.Cancel(organization.StripeCustomerId, sub.Id); } } organization.BillingStatus = BillingStatus.Trialing; organization.RemoveSuspension(); } else if (String.IsNullOrEmpty(organization.StripeCustomerId)) { if (String.IsNullOrEmpty(stripeToken)) { return(Ok(ChangePlanResult.FailWithMessage("Billing information was not set."))); } organization.SubscribeDate = DateTime.Now; var createCustomer = new StripeCustomerCreateOptions { Card = new StripeCreditCardOptions { TokenId = stripeToken }, PlanId = planId, Description = organization.Name, Email = ExceptionlessUser.EmailAddress }; if (!String.IsNullOrWhiteSpace(couponId)) { createCustomer.CouponId = couponId; } StripeCustomer customer = customerService.Create(createCustomer); organization.BillingStatus = BillingStatus.Active; organization.RemoveSuspension(); organization.StripeCustomerId = customer.Id; if (customer.StripeCardList.StripeCards.Count > 0) { organization.CardLast4 = customer.StripeCardList.StripeCards[0].Last4; } } else { var update = new StripeSubscriptionUpdateOptions { PlanId = planId }; var create = new StripeSubscriptionCreateOptions(); bool cardUpdated = false; if (!String.IsNullOrEmpty(stripeToken)) { update.Card = new StripeCreditCardOptions { TokenId = stripeToken }; create.Card = new StripeCreditCardOptions { TokenId = stripeToken }; cardUpdated = true; } var subscription = subscriptionService.List(organization.StripeCustomerId).FirstOrDefault(s => !s.CanceledAt.HasValue); if (subscription != null) { subscriptionService.Update(organization.StripeCustomerId, subscription.Id, update); } else { subscriptionService.Create(organization.StripeCustomerId, planId, create); } customerService.Update(organization.StripeCustomerId, new StripeCustomerUpdateOptions { Email = ExceptionlessUser.EmailAddress }); if (cardUpdated) { organization.CardLast4 = last4; } organization.BillingStatus = BillingStatus.Active; organization.RemoveSuspension(); } BillingManager.ApplyBillingPlan(organization, plan, ExceptionlessUser); _repository.Save(organization); _messagePublisher.Publish(new PlanChanged { OrganizationId = organization.Id }); } catch (Exception e) { Log.Error().Exception(e).Message("An error occurred while trying to update your billing plan: " + e.Message).Critical().Property("User", ExceptionlessUser).ContextProperty("HttpActionContext", ActionContext).Write(); return(Ok(ChangePlanResult.FailWithMessage(e.Message))); } return(Ok(new ChangePlanResult { Success = true })); }
public IHttpActionResult ChangePlan(string id, string planId, string stripeToken = null, string last4 = null) { if (String.IsNullOrEmpty(id) || !CanAccessOrganization(id)) { throw new ArgumentException("Invalid organization id.", "id"); // TODO: These should probably throw http Response exceptions. } if (!Settings.Current.EnableBilling) { return(Ok(new { Success = false, Message = "Plans cannot be changed while billing is disabled." })); } Organization organization = _repository.GetById(id); if (organization == null) { return(Ok(new { Success = false, Message = "Invalid OrganizationId." })); } BillingPlan plan = _billingManager.GetBillingPlan(planId); if (plan == null) { return(Ok(new { Success = false, Message = "Invalid PlanId." })); } if (String.Equals(organization.PlanId, plan.Id) && String.Equals(BillingManager.FreePlan.Id, plan.Id)) { return(Ok(new { Success = true, Message = "Your plan was not changed as you were already on the free plan." })); } // Only see if they can downgrade a plan if the plans are different. string message; if (!String.Equals(organization.PlanId, plan.Id) && !_billingManager.CanDownGrade(organization, plan, ExceptionlessUser, out message)) { return(Ok(new { Success = false, Message = message })); } var customerService = new StripeCustomerService(); var subscriptionService = new StripeSubscriptionService(); try { // If they are on a paid plan and then downgrade to a free plan then cancel their stripe subscription. if (!String.Equals(organization.PlanId, BillingManager.FreePlan.Id) && String.Equals(plan.Id, BillingManager.FreePlan.Id)) { if (!String.IsNullOrEmpty(organization.StripeCustomerId)) { var subs = subscriptionService.List(organization.StripeCustomerId).Where(s => !s.CanceledAt.HasValue); foreach (var sub in subs) { subscriptionService.Cancel(organization.StripeCustomerId, sub.Id); } } organization.BillingStatus = BillingStatus.Trialing; organization.RemoveSuspension(); } else if (String.IsNullOrEmpty(organization.StripeCustomerId)) { if (String.IsNullOrEmpty(stripeToken)) { return(Ok(new { Success = false, Message = "Billing information was not set." })); } organization.SubscribeDate = DateTime.Now; StripeCustomer customer = customerService.Create(new StripeCustomerCreateOptions { TokenId = stripeToken, PlanId = planId, Description = organization.Name }); organization.BillingStatus = BillingStatus.Active; organization.RemoveSuspension(); organization.StripeCustomerId = customer.Id; if (customer.StripeCardList.StripeCards.Count > 0) { organization.CardLast4 = customer.StripeCardList.StripeCards[0].Last4; } } else { var update = new StripeSubscriptionUpdateOptions { PlanId = planId }; var create = new StripeSubscriptionCreateOptions(); bool cardUpdated = false; if (!String.IsNullOrEmpty(stripeToken)) { update.TokenId = stripeToken; create.TokenId = stripeToken; cardUpdated = true; } var subscription = subscriptionService.List(organization.StripeCustomerId).FirstOrDefault(s => !s.CanceledAt.HasValue); if (subscription != null) { subscriptionService.Update(organization.StripeCustomerId, subscription.Id, update); } else { subscriptionService.Create(organization.StripeCustomerId, planId, create); } if (cardUpdated) { organization.CardLast4 = last4; } organization.BillingStatus = BillingStatus.Active; organization.RemoveSuspension(); } _billingManager.ApplyBillingPlan(organization, plan, ExceptionlessUser); _repository.Save(organization); } catch (Exception e) { Log.Error().Exception(e).Message("An error occurred while trying to update your billing plan: " + e.Message).Report(r => r.MarkAsCritical()).Write(); return(Ok(new { Success = false, Message = e.Message })); } return(Ok(new { Success = true })); }