// 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 }); }
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."); } }
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); }
public async Task CancelSubscription(string subscriptionId) { var options = new SubscriptionCancelOptions { }; await _subscriptionService.CancelAsync(subscriptionId, options); }
public async Task CancelSubscription(string subscriptionId) { var subscriptionService = new SubscriptionService(); await subscriptionService.CancelAsync(subscriptionId, new SubscriptionCancelOptions() { InvoiceNow = true }); }
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(); }
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"); }
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; } } }
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)); } }
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); }
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); } }
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; } }
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(); } }