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
            }));
        }
예제 #2
0
        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 }));
        }