Exemplo n.º 1
0
        // cancel subscription
        public async Task <IdResponseModel> CancelSubscription(string subscriptionId, int userId)
        {
            var user = await EnsureCustomerCreatedAsync(userId);

            SetStripeApiKey();

            var service = new SubscriptionService();

            Subscription subscription = null;

            try
            {
                subscription = await service.GetAsync(subscriptionId);

                if (subscription.CustomerId != user.Profile.StripeCustomerId)
                {
                    throw new CustomException(HttpStatusCode.BadRequest, "subscriptionId", "Invalid subscription id");
                }

                subscription = await service.CancelAsync(subscriptionId, null);
            }
            catch (StripeException ex)
            {
                throw new CustomException(HttpStatusCode.BadRequest, ex.StripeError?.Parameter, ex.StripeError?.Message);
            }

            return(new IdResponseModel
            {
                Id = subscription?.Id
            });
        }
Exemplo n.º 2
0
        public async Task CancelSubscription(int userId)
        {
            StripeConfiguration.ApiKey = _stripe.ApiKey;
            string stripeSubKey = "";
            string procName     = "[dbo].[Subscriptions_SelectStripeId_byUserId]";

            _data.ExecuteCmd(procName, paramCol =>
            {
                paramCol.AddWithValue("@userId", userId);
            }, (reader, set) => {
                stripeSubKey = reader.GetSafeString(0);
            });

            var service = new SubscriptionService();

            try
            {
                await service.CancelAsync(stripeSubKey, null);

                procName = "[dbo].[Subscriptions_Update_ActiveStatus_SetInactive]";

                _data.ExecuteNonQuery(procName, paramCol =>
                {
                    paramCol.AddWithValue("@userId", userId);
                });
            }
            catch
            {
                throw new Exception("Unable to Cancel Stripe Subscription.");
            }
        }
Exemplo n.º 3
0
        public async Task CancelAndRecoverChargesAsync(ISubscriber subscriber)
        {
            if (!string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
            {
                var subscriptionService = new SubscriptionService();
                await subscriptionService.CancelAsync(subscriber.GatewaySubscriptionId,
                                                      new SubscriptionCancelOptions());
            }

            if (string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
            {
                return;
            }

            var customerService = new CustomerService();
            var customer        = await customerService.GetAsync(subscriber.GatewayCustomerId);

            if (customer == null)
            {
                return;
            }

            if (customer.Metadata.ContainsKey("btCustomerId"))
            {
                var transactionRequest = new Braintree.TransactionSearchRequest()
                                         .CustomerId.Is(customer.Metadata["btCustomerId"]);
                var transactions = _btGateway.Transaction.Search(transactionRequest);

                if ((transactions?.MaximumCount ?? 0) > 0)
                {
                    var txs = transactions.Cast <Braintree.Transaction>().Where(c => c.RefundedTransactionId == null);
                    foreach (var transaction in txs)
                    {
                        await _btGateway.Transaction.RefundAsync(transaction.Id);
                    }
                }

                await _btGateway.Customer.DeleteAsync(customer.Metadata["btCustomerId"]);
            }
            else
            {
                var chargeService = new ChargeService();
                var charges       = await chargeService.ListAsync(new ChargeListOptions
                {
                    CustomerId = subscriber.GatewayCustomerId
                });

                if (charges?.Data != null)
                {
                    var refundService = new RefundService();
                    foreach (var charge in charges.Data.Where(c => !c.Refunded))
                    {
                        await refundService.CreateAsync(new RefundCreateOptions { ChargeId = charge.Id });
                    }
                }
            }

            await customerService.DeleteAsync(subscriber.GatewayCustomerId);
        }
Exemplo n.º 4
0
        public async Task CancelSubscription(string subscriptionId)
        {
            var options = new SubscriptionCancelOptions
            {
            };

            await _subscriptionService.CancelAsync(subscriptionId, options);
        }
Exemplo n.º 5
0
 public async Task CancelSubscription(string subscriptionId)
 {
     var subscriptionService = new SubscriptionService();
     await subscriptionService.CancelAsync(subscriptionId,
                                           new SubscriptionCancelOptions()
     {
         InvoiceNow = true
     });
 }
Exemplo n.º 6
0
        public async Task <Subscription> SubscriptionCancel(string subscriptionId)
        {
            var service = new SubscriptionService();
            var item    = await service.CancelAsync(subscriptionId, new SubscriptionCancelOptions
            {
            });

            return(item);
        }
        public async Task CancelSubscription(string subscriptionId)
        {
            var subscriptionService = new SubscriptionService();
            await subscriptionService.CancelAsync(subscriptionId, null);

            var payment = await _subscriptionPaymentRepository.GetByGatewayAndPaymentIdAsync(
                SubscriptionPaymentGatewayType.Stripe,
                subscriptionId
                );

            payment.SetAsCancelled();
        }
Exemplo n.º 8
0
        public async Task <bool> CancelSubscription(string SubscriptionId)
        {
            SubscriptionCancelOptions opts =
                new SubscriptionCancelOptions()
            {
            };

            var subscriptionService = new SubscriptionService();
            var sub = await subscriptionService.CancelAsync(SubscriptionId, opts);

            return(sub.Status == "canceled");
        }
Exemplo n.º 9
0
        public async Task CancelSubscriptionAsync(ISubscriber subscriber, bool endOfPeriod = false)
        {
            if (subscriber == null)
            {
                throw new ArgumentNullException(nameof(subscriber));
            }

            if (string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
            {
                throw new GatewayException("No subscription.");
            }

            var subscriptionService = new SubscriptionService();
            var sub = await subscriptionService.GetAsync(subscriber.GatewaySubscriptionId);

            if (sub == null)
            {
                throw new GatewayException("Subscription was not found.");
            }

            if (sub.CanceledAt.HasValue || sub.Status == "canceled" || sub.Status == "unpaid")
            {
                // Already canceled
                return;
            }

            try
            {
                var canceledSub = endOfPeriod ?
                                  await subscriptionService.UpdateAsync(sub.Id,
                                                                        new SubscriptionUpdateOptions { CancelAtPeriodEnd = true }) :
                                  await subscriptionService.CancelAsync(sub.Id, new SubscriptionCancelOptions());

                if (!canceledSub.CanceledAt.HasValue)
                {
                    throw new GatewayException("Unable to cancel subscription.");
                }
            }
            catch (StripeException e)
            {
                if (e.Message != $"No such subscription: {subscriber.GatewaySubscriptionId}")
                {
                    throw e;
                }
            }
        }
Exemplo n.º 10
0
        public async Task <PaymentGatewayResult <IPaymentSubscription> > CancelSubscriptionAsync(string subscriptionId, bool?invoiceNow, bool?prorate)
        {
            try
            {
                var subscription = await _subscriptionService.CancelAsync(subscriptionId,
                                                                          new SubscriptionCancelOptions()
                {
                    InvoiceNow = invoiceNow,
                    Prorate    = prorate,
                });

                return(PaymentGatewayResult <IPaymentSubscription> .Success(_mapper.Map <IPaymentSubscription>(subscription)));
            }
            catch (StripeException e)
            {
                return(PaymentGatewayResult <IPaymentSubscription> .Failed(e));
            }
        }
Exemplo n.º 11
0
        public async Task CancelSubscription(string subscriptionId, ClaimsPrincipal userFor, CancellationToken token)
        {
            var user = await userManager.GetUserAsync(userFor).ConfigureAwait(false);

            Subscription subscription = await subscriptionService.GetAsync(subscriptionId, cancellationToken : token).ConfigureAwait(false);

            Customer customer = await customerService.GetAsync(subscription.CustomerId, cancellationToken : token).ConfigureAwait(false);

            if (!customer.Email.Equals(user.Email, StringComparison.OrdinalIgnoreCase))
            {
                throw new InvalidOperationException($"User {user.Email} doesn't match subscription e-mail {subscription.Customer.Email}");
            }

            subscription = await subscriptionService.CancelAsync(subscriptionId, new SubscriptionCancelOptions(), cancellationToken : token).ConfigureAwait(false);

            context.DonationEventLog.Add(new DonationEventLog(userId: user.Id, type: DonationEventType.Internal, eventData: subscription.ToJson()));
            await context.SaveChangesAsync(token).ConfigureAwait(false);
        }
Exemplo n.º 12
0
        public async Task CancelSubscriptionsAsync(Organization organization)
        {
            if (String.IsNullOrEmpty(organization.StripeCustomerId))
            {
                return;
            }

            var client = new StripeClient(_stripeOptions.StripeApiKey);
            var subscriptionService = new SubscriptionService(client);
            var subscriptions       = await subscriptionService.ListAsync(new SubscriptionListOptions { Customer = organization.StripeCustomerId }).AnyContext();

            foreach (var subscription in subscriptions.Where(s => !s.CanceledAt.HasValue))
            {
                _logger.LogInformation("Canceling stripe subscription ({SubscriptionId}) for {OrganizationName} ({organization})", subscription.Id, organization.Name, organization.Id);
                await subscriptionService.CancelAsync(subscription.Id, new SubscriptionCancelOptions()).AnyContext();

                _logger.LogInformation("Canceled stripe subscription ({SubscriptionId}) for {OrganizationName} ({organization})", subscription.Id, organization.Name, organization.Id);
            }
        }
Exemplo n.º 13
0
        public async Task <IActionResult> UnSubscribeAsync([FromBody] UnSubscribeRequest req)
        {
            try
            {
                AuthController.ValidateAndGetCurrentUserName(this.HttpContext.Request);
                var email = this.HttpContext.Request.Headers["From"];

                var user = await context.Users.FindAsync(email);

                if (user == null)
                {
                    return(NotFound());
                }

                for (int i = 0; i < 3; i++)
                {
                    if (string.IsNullOrEmpty(user.CustomerID))
                    {
                        await Task.Delay(2000);

                        user = await context.Users.FindAsync(email);
                    }
                }

                if (string.IsNullOrEmpty(user.CustomerID))
                {
                    return(NotFound());
                }

                var subscriptions = new SubscriptionService();

                await subscriptions.CancelAsync(req.subscriptionId, new SubscriptionCancelOptions());

                return(Ok());
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Exemplo n.º 14
0
        public async Task <ActionResult <ChangePlanResult> > ChangePlanAsync(string id, string planId, string stripeToken = null, string last4 = null, string couponId = null)
        {
            if (String.IsNullOrEmpty(id) || !CanAccessOrganization(id))
            {
                return(NotFound());
            }

            if (!_options.StripeOptions.EnableBilling)
            {
                return(Ok(ChangePlanResult.FailWithMessage("Plans cannot be changed while billing is disabled.")));
            }

            var organization = await GetModelAsync(id, false);

            if (organization == null)
            {
                return(Ok(ChangePlanResult.FailWithMessage("Invalid OrganizationId.")));
            }

            var plan = _billingManager.GetBillingPlan(planId);

            if (plan == null)
            {
                return(Ok(ChangePlanResult.FailWithMessage("Invalid PlanId.")));
            }

            if (String.Equals(organization.PlanId, plan.Id) && String.Equals(_plans.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.
            if (!String.Equals(organization.PlanId, plan.Id))
            {
                var result = await _billingManager.CanDownGradeAsync(organization, plan, CurrentUser);

                if (!result.Success)
                {
                    return(Ok(result));
                }
            }

            var client              = new StripeClient(_options.StripeOptions.StripeApiKey);
            var customerService     = new CustomerService(client);
            var subscriptionService = new SubscriptionService(client);

            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, _plans.FreePlan.Id) && String.Equals(plan.Id, _plans.FreePlan.Id))
                {
                    if (!String.IsNullOrEmpty(organization.StripeCustomerId))
                    {
                        var subs = await subscriptionService.ListAsync(new SubscriptionListOptions { Customer = organization.StripeCustomerId });

                        foreach (var sub in subs.Where(s => !s.CanceledAt.HasValue))
                        {
                            await subscriptionService.CancelAsync(sub.Id, new SubscriptionCancelOptions());
                        }
                    }

                    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 = SystemClock.UtcNow;

                    var createCustomer = new CustomerCreateOptions {
                        Source      = stripeToken,
                        Plan        = planId,
                        Description = organization.Name,
                        Email       = CurrentUser.EmailAddress
                    };

                    if (!String.IsNullOrWhiteSpace(couponId))
                    {
                        createCustomer.Coupon = couponId;
                    }

                    var customer = await customerService.CreateAsync(createCustomer);

                    organization.BillingStatus = BillingStatus.Active;
                    organization.RemoveSuspension();
                    organization.StripeCustomerId = customer.Id;
                    if (customer.Sources.Data.Count > 0)
                    {
                        organization.CardLast4 = (customer.Sources.Data.First() as Card)?.Last4;
                    }
                }
                else
                {
                    var update = new SubscriptionUpdateOptions {
                        Items = new List <SubscriptionItemOptions>()
                    };
                    var create = new SubscriptionCreateOptions {
                        Customer = organization.StripeCustomerId, Items = new List <SubscriptionItemOptions>()
                    };
                    bool cardUpdated = false;

                    var customerUpdateOptions = new CustomerUpdateOptions {
                        Description = organization.Name, Email = CurrentUser.EmailAddress
                    };
                    if (!String.IsNullOrEmpty(stripeToken))
                    {
                        customerUpdateOptions.Source = stripeToken;
                        cardUpdated = true;
                    }

                    await customerService.UpdateAsync(organization.StripeCustomerId, customerUpdateOptions);

                    var subscriptionList = await subscriptionService.ListAsync(new SubscriptionListOptions { Customer = organization.StripeCustomerId });

                    var subscription = subscriptionList.FirstOrDefault(s => !s.CanceledAt.HasValue);
                    if (subscription != null)
                    {
                        update.Items.Add(new SubscriptionItemOptions {
                            Id = subscription.Items.Data[0].Id, Plan = planId
                        });
                        await subscriptionService.UpdateAsync(subscription.Id, update);
                    }
                    else
                    {
                        create.Items.Add(new SubscriptionItemOptions {
                            Plan = planId
                        });
                        await subscriptionService.CreateAsync(create);
                    }

                    if (cardUpdated)
                    {
                        organization.CardLast4 = last4;
                    }

                    organization.BillingStatus = BillingStatus.Active;
                    organization.RemoveSuspension();
                }

                _billingManager.ApplyBillingPlan(organization, plan, CurrentUser);
                await _repository.SaveAsync(organization, o => o.Cache());

                await _messagePublisher.PublishAsync(new PlanChanged { OrganizationId = organization.Id });
            } catch (Exception ex) {
                using (_logger.BeginScope(new ExceptionlessState().Tag("Change Plan").Identity(CurrentUser.EmailAddress).Property("User", CurrentUser).SetHttpContext(HttpContext)))
                    _logger.LogCritical(ex, "An error occurred while trying to update your billing plan: {Message}", ex.Message);

                return(Ok(ChangePlanResult.FailWithMessage(ex.Message)));
            }

            return(Ok(new ChangePlanResult {
                Success = true
            }));
        }
        public override async Task HandleItemAsync(WorkItemContext context)
        {
            var wi = context.GetData <RemoveOrganizationWorkItem>();

            using (Log.BeginScope(new ExceptionlessState().Organization(wi.OrganizationId))) {
                Log.LogInformation("Received remove organization work item for: {organization}", wi.OrganizationId);

                await context.ReportProgressAsync(0, "Starting deletion...").AnyContext();

                var organization = await _organizationRepository.GetByIdAsync(wi.OrganizationId).AnyContext();

                if (organization == null)
                {
                    await context.ReportProgressAsync(100, "Organization deleted").AnyContext();

                    return;
                }

                await context.ReportProgressAsync(10, "Removing subscriptions").AnyContext();

                if (!String.IsNullOrEmpty(organization.StripeCustomerId))
                {
                    Log.LogInformation("Canceling stripe subscription for the organization {OrganizationName} with Id: {organization}.", organization.Name, organization.Id);

                    var client = new StripeClient(_stripeOptions.Value.StripeApiKey);
                    var subscriptionService = new SubscriptionService(client);
                    var subscriptions       = (await subscriptionService.ListAsync(new SubscriptionListOptions {
                        Customer = organization.StripeCustomerId
                    }).AnyContext()).Where(s => !s.CanceledAt.HasValue);
                    foreach (var subscription in subscriptions)
                    {
                        await subscriptionService.CancelAsync(subscription.Id, new SubscriptionCancelOptions()).AnyContext();
                    }
                }

                await context.ReportProgressAsync(20, "Removing users").AnyContext();

                var users = await _userRepository.GetByOrganizationIdAsync(organization.Id).AnyContext();

                foreach (var user in users.Documents)
                {
                    // delete the user if they are not associated to any other organizations and they are not the current user
                    if (user.OrganizationIds.All(oid => String.Equals(oid, organization.Id)) && !String.Equals(user.Id, wi.CurrentUserId))
                    {
                        Log.LogInformation("Removing user {user} as they do not belong to any other organizations.", user.Id);
                        await _userRepository.RemoveAsync(user.Id).AnyContext();
                    }
                    else
                    {
                        Log.LogInformation("Removing user {user} from organization {OrganizationName} with Id: {organization}", user.Id, organization.Name, organization.Id);
                        user.OrganizationIds.Remove(organization.Id);
                        await _userRepository.SaveAsync(user, o => o.Cache()).AnyContext();
                    }
                }

                await context.ReportProgressAsync(30, "Removing tokens").AnyContext();

                await _tokenRepository.RemoveAllByOrganizationIdAsync(organization.Id).AnyContext();

                await context.ReportProgressAsync(40, "Removing web hooks").AnyContext();

                await _webHookRepository.RemoveAllByOrganizationIdAsync(organization.Id).AnyContext();

                await context.ReportProgressAsync(50, "Removing projects").AnyContext();

                var projects = await _projectRepository.GetByOrganizationIdAsync(organization.Id).AnyContext();

                if (wi.IsGlobalAdmin && projects.Total > 0)
                {
                    int completed = 1;
                    foreach (var project in projects.Documents)
                    {
                        using (Log.BeginScope(new ExceptionlessState().Organization(wi.OrganizationId).Project(project.Id))) {
                            Log.LogInformation("Resetting all project data for project {ProjectName} with Id: {project}.", project.Name, project.Id);
                            await _eventRepository.RemoveAllByProjectIdAsync(organization.Id, project.Id).AnyContext();

                            await _stackRepository.RemoveAllByProjectIdAsync(organization.Id, project.Id).AnyContext();

                            await context.ReportProgressAsync(CalculateProgress(projects.Total, completed++, 51, 89), "Removing projects...").AnyContext();
                        }
                    }

                    Log.LogInformation("Deleting all projects for organization {OrganizationName} with Id: {organization}.", organization.Name, organization.Id);
                    await _projectRepository.RemoveAsync(projects.Documents).AnyContext();
                }

                Log.LogInformation("Deleting organization {OrganizationName} with Id: {organization}.", organization.Name, organization.Id);
                await context.ReportProgressAsync(90, "Removing organization").AnyContext();

                await _organizationRepository.RemoveAsync(organization.Id).AnyContext();

                await context.ReportProgressAsync(100, "Organization deleted").AnyContext();
            }
        }