public IActionResult Register([FromBody] Registration registration) { _telemetryClient.TrackEvent("Registration:Requested"); var user = registration.User; var organization = registration.Organization; using (var transaction = _context.Database.BeginTransaction()) { try { // Ensure Email address is unique. var duplicate = _context.Users.Where(u => u.EmailAddress.ToLower().Equals(user.EmailAddress)); if (duplicate.Any()) { return(BadRequest("Email address is already taken.")); } // Generate an organization code if one is not provided. var code = organization.Code; while (string.IsNullOrEmpty(code)) { var generated = GetRandomNumber(); var found = _context.Organizations .Where(o => o.Code == generated); if (!found.Any()) { code = generated; } } organization.Code = code; // Generate a user pin if one is not provided. if (string.IsNullOrEmpty(user.Pin)) { user.Pin = GetRandomNumber(); } // Generates a password hash and salt. var service = new SecurityService(); user.PasswordSalt = service.GenerateHash(service.GenerateRandomString()); user.PasswordHash = service.GenerateHash(string.Format("{0} {1}", user.Password, user.PasswordSalt)); user.Password = null; // Formatting user.EmailAddress = user.EmailAddress.ToLower(); // Auto-generated. user.Role = "Administrator"; user.CreatedAt = DateTime.UtcNow; user.AllowedPhoneNumbers = "*"; user.TimeZone = "America/New_York"; user.IsActive = true; user.CanViewPunches = true; user.CanCreatePunches = true; user.CanModifyPunches = true; user.CanDeletePunches = true; user.CanSplitAndPopulatePunches = true; user.CanViewReports = true; user.CanViewLocks = true; user.CanCreateLocks = true; user.CanUndoLocks = true; user.CanViewTimecards = true; user.CanCreateTimecards = true; user.CanModifyTimecards = true; user.CanDeleteTimecards = true; user.CanViewUsers = true; user.CanCreateUsers = true; user.CanModifyUsers = true; user.CanDeleteUsers = true; user.CanViewInventoryItems = true; user.CanSyncInventoryItems = true; user.CanViewInventoryConsumptions = true; user.CanSyncInventoryConsumptions = true; user.CanDeleteInventoryConsumptions = true; user.CanViewRates = true; user.CanCreateRates = true; user.CanModifyRates = true; user.CanDeleteRates = true; user.CanViewOrganizationDetails = true; user.CanModifyOrganizationDetails = true; user.CanViewCustomers = true; user.CanCreateCustomers = true; user.CanModifyCustomers = true; user.CanDeleteCustomers = true; user.CanViewProjects = true; user.CanCreateProjects = true; user.CanModifyProjects = true; user.CanDeleteProjects = true; user.CanViewTasks = true; user.CanCreateTasks = true; user.CanModifyTasks = true; user.CanDeleteTasks = true; organization.CreatedAt = DateTime.UtcNow; organization.MinutesFormat = "minutes"; organization.StripeCustomerId = "UNSPECIFIED"; organization.StripeSubscriptionId = "UNSPECIFIED"; organization.ShowCustomerNumber = true; organization.ShowProjectNumber = true; organization.ShowTaskNumber = true; organization.SortCustomersByColumn = "Number"; organization.SortProjectsByColumn = "Number"; organization.SortTasksByColumn = "Number"; // Determine the actual Stripe Plan Id based on the PlanId. var stripePlanId = _configuration["StripePlanId1"]; // Default plan is the contractor plan switch (organization.PlanId) { case 1: stripePlanId = _configuration["StripePlanId1"]; break; case 2: stripePlanId = _configuration["StripePlanId2"]; break; case 3: stripePlanId = _configuration["StripePlanId3"]; break; case 4: stripePlanId = _configuration["StripePlanId4"]; break; } if (!string.IsNullOrEmpty(stripePlanId)) { try { _telemetryClient.TrackEvent("Registration:Subscribe"); // Create a Stripe customer object and save the customer id. var customerOptions = new CustomerCreateOptions { Email = user.EmailAddress }; var customers = new CustomerService(); Stripe.Customer customer = customers.Create(customerOptions); organization.StripeCustomerId = customer.Id; // Subscribe the customer to the price and save the subscription id. var subscriptionOptions = new SubscriptionCreateOptions { Customer = customer.Id, // ex. cus_IDjvN9UsoFp2mk Items = new List <SubscriptionItemOptions> { new SubscriptionItemOptions { Price = stripePlanId // ex. price_1Hd5PvLI44a19MHX9w5EGD4r } }, TrialFromPlan = true }; var subscriptions = new SubscriptionService(); Subscription subscription = subscriptions.Create(subscriptionOptions); organization.StripeSubscriptionId = subscription.Id; // Send Welcome Email. _telemetryClient.TrackEvent("Registration:Email"); var apiKey = _configuration["SendGridApiKey"]; var client = new SendGridClient(apiKey); var from = new EmailAddress("BRIZBEE <*****@*****.**>"); var to = new EmailAddress(user.EmailAddress); var msg = MailHelper.CreateSingleTemplateEmail(from, to, "d-8c48a9ad2ddd4d73b6e6c10307182f43", null); var response = client.SendEmailAsync(msg); } catch (Exception ex) { _telemetryClient.TrackException(ex); return(BadRequest(ex.Message)); } } // Save the organization and user. _context.Organizations.Add(organization); user.OrganizationId = organization.Id; _context.Users.Add(user); _context.SaveChanges(); _telemetryClient.TrackEvent("Registration:Succeeded"); transaction.Commit(); return(Created("auth/me", user)); } catch (DbUpdateException ex) { transaction.Rollback(); _telemetryClient.TrackException(ex); return(BadRequest(ex.Message)); } catch (Exception ex) { transaction.Rollback(); _telemetryClient.TrackException(ex); return(BadRequest(ex.Message)); } } }
public static Subscription CreateCustomer(string email, string payment_method) { // creating a customer with Stripe API information (https://stripe.com/docs/api/customers/create) // below options are sample data var options = new CustomerCreateOptions { Email = email, PaymentMethod = payment_method, InvoiceSettings = new CustomerInvoiceSettingsOptions { DefaultPaymentMethod = payment_method, }, }; //create the customer with above options var service = new CustomerService(); Customer customer; try { customer = service.Create(options); } catch (Exception ex) { throw ex; } // At this point, you may associate the ID of the Customer object with your // own internal representation of a customer, if you have one. string sample_internal_customerid = "1"; string StripeCustomerId = customer.Id; string AccountInfoEmail = customer.Email; //connect to the database string cs = WebConfigurationManager.ConnectionStrings["StripeDatabaseConnectionString"].ConnectionString; SqlConnection con = new SqlConnection(cs); //insert in db string sql = "INSERT INTO [CUSTOMERS](CustomerId, StripeCustomerId, AccountInfoEmail) VALUES('" + sample_internal_customerid + "', '" + StripeCustomerId + "', '" + AccountInfoEmail + "');"; con.Open(); SqlCommand cmd = new SqlCommand(sql, con); cmd.ExecuteNonQuery(); con.Close(); // find all plans (temporary) var planListOptions = new PlanListOptions { Limit = 3 }; var planListService = new PlanService(); var allPlans = planListService.List(planListOptions); string planId = allPlans.Select(x => x.Id).First(); // for now just retrieving the first plan available. A dropdown will allow selecting the plan // get plan by plan id var planService = new PlanService(); var plan = planService.Get(planId); // Subscribe the user to the subscription created var items = new List <SubscriptionItemOption> { new SubscriptionItemOption { Plan = plan.Id } }; var subscriptionOptions = new SubscriptionCreateOptions { Customer = customer.Id, Items = items }; var subscriptionService = new SubscriptionService(); Subscription subscription = subscriptionService.Create(subscriptionOptions); // return subscription object as JSON back to web method // return JsonConvert.SerializeObject(subscription); return(subscription); }
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 (!_stripeOptions.Value.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(_stripeOptions.Value.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 async Task <IActionResult> Post([FromRoute] Guid id, [FromQuery] string token) { if (id != Guid.Empty) { var subscriptionType = await Db.SubscriptionTypes.FirstOrDefaultAsync(x => x.SubscriptionTypeId == id); if (subscriptionType == null) { return(Error("Subscription type not found", code: 404)); } var subscription = await Db.Subscriptions.FirstOrDefaultAsync(x => x.UserId == UserId); if (subscription != null) { if (subscription.SubscriptionTypeId == subscriptionType.SubscriptionTypeId) { return(Error("You have already this subscription.")); } return(Success("We will add this feature.")); } else { subscription = new MVDSubscription { SubscriptionId = Guid.NewGuid(), SubscriptionTypeId = subscriptionType.SubscriptionTypeId, UserId = UserId, StartDate = DateTime.UtcNow, EndDate = subscriptionType.IsPaid ? DateTime.UtcNow.AddMonths(1) : DateTime.MinValue, PaymentPeriod = MVDPaymentPeriodTypes.Monthly }; await Db.AddAsync(subscription); var features = await Db.SubscriptionTypeFeatures.Where(x => x.SubscriptionTypeId == subscriptionType.SubscriptionTypeId).ToListAsync(); foreach (var feature in features) { await Db.AddAsync(new MVDSubscriptionFeature { SubscriptionFeatureId = Guid.NewGuid(), SubscriptionId = subscription.SubscriptionId, SubscriptionTypeId = subscriptionType.SubscriptionTypeId, SubscriptionTypeFeatureId = feature.SubscriptionTypeFeatureId, Description = feature.Description, Name = feature.Name, Value = feature.Value, Title = feature.Title, ValueUsed = string.Empty, ValueRemained = string.Empty }); } } if (subscriptionType.Price > 0) { try { var user = await Db.Users.FirstOrDefaultAsync(x => x.Id == UserId); var customerService = new CustomerService(); var customerResult = await customerService.CreateAsync(new CustomerCreateOptions { Email = user.Email, SourceToken = token }); var items = new List <SubscriptionItemOption> { new SubscriptionItemOption { PlanId = subscriptionType.Name } }; var subscriptionService = new SubscriptionService(); var subscriptionOptions = new SubscriptionCreateOptions { CustomerId = customerResult.Id, Items = items }; var subscriptionResult = await subscriptionService.CreateAsync(subscriptionOptions); if (subscriptionResult.Status == "active") { var payment = new MVDPayment { PaymentId = Guid.NewGuid(), Provider = "stripe", SubscriptionId = subscription.SubscriptionId, UserId = UserId, Token = subscriptionResult.LatestInvoiceId, Amount = subscriptionType.Price, Currency = "usd", Date = DateTime.UtcNow, Description = $"{subscriptionType.Title} {subscriptionType.Description}", }; await Db.AddAsync(payment); } else { return(Error("Payment not completed.", code: 400)); } } catch (Exception ex) { return(Error("Payment error. Please check your credit card and details.", internalMessage: ex.Message, code: 400)); } } if (await Db.SaveChangesAsync() > 0) { return(Success("Your subscription has been updated.")); } return(Error("There is nothing to save.")); } return(Error("You must send subscription id.")); }
public IActionResult Subscription(CustomerPaymentViewModel payment) { string email = HttpContext.Session.GetString("User"); ViewBag.isLoggedIn = 1; try { NewWebSubContext context = HttpContext.RequestServices.GetService(typeof(new_websub.NewWebSubContext)) as NewWebSubContext; string query = "select * from useraccounts u inner join address a on u.AddressId=a.addresskey where u.Email=@Email"; MySqlConnection conn = context.GetConnection(); conn.Open(); MySqlCommand cmd = new MySqlCommand(query, conn); MySqlParameter param = new MySqlParameter("@Email", email); param.MySqlDbType = MySqlDbType.VarChar; cmd.Parameters.Add(param); MySqlDataReader reader = cmd.ExecuteReader(); if (reader.Read()) { User user = new User(); user.Email = email; user.Id = reader["UserID"].ToString(); user.FullName = reader["UserName"].ToString(); user.StripeCustomerId = ""; user.AddressLine1 = reader["Address1"].ToString(); user.AddressLine2 = reader["Address2"].ToString(); user.City = reader["City"].ToString(); user.State = reader["State"].ToString(); user.Zip = reader["Zipcode"].ToString(); user.Country = reader["Country"].ToString(); user.HistoryView = true; StripeConfiguration.SetApiKey(_stripeSettings.Value.SecretKey); var tokenoptions = new TokenCreateOptions { Card = new CreditCardOptions { Number = payment.CardNumber, ExpYear = payment.ExpiryYear, ExpMonth = payment.ExpiryMonth, Cvc = payment.Cvc } }; var tokenservice = new TokenService(); Token stripeToken = tokenservice.Create(tokenoptions); payment.cardtoken = stripeToken.Id; CustomerCreateOptions customerCreateOptions = GetCustomerCreateOptions(payment, user); var cusservice = new CustomerService(); var customers = cusservice.Create(customerCreateOptions); Subscription subscription; var plservice = new PlanService(); try { var plplan = plservice.Get(payment.subsctype); var items = new List <SubscriptionItemOption> { new SubscriptionItemOption { PlanId = plplan.Id } }; var suboptions = new SubscriptionCreateOptions { CustomerId = customers.Id, Items = items }; var subservice = new SubscriptionService(); subscription = subservice.Create(suboptions); } catch { var options = new PlanCreateOptions { Product = new PlanProductCreateOptions { Id = payment.subsctype, Name = payment.subsctype }, Amount = payment.Amount, Currency = payment.Currency, Interval = payment.subsctype, Id = payment.subsctype }; var service = new PlanService(); Plan plan = service.Create(options); var items = new List <SubscriptionItemOption> { new SubscriptionItemOption { PlanId = plan.Id } }; var suboptions = new SubscriptionCreateOptions { CustomerId = customers.Id, Items = items }; var subservice = new SubscriptionService(); subscription = subservice.Create(suboptions); } reader.Close(); // insert into subscriptions table query = "insert into subscriptions(Email, CustomerId, SubscriptionId, Subscription_Started, Subscription_Ended) values(@Email," + "@CustomerId, @SubscriptionId, @Subscription_Started, @Subscription_Ended)"; MySqlCommand cmd1 = new MySqlCommand(query, conn); MySqlParameter param1 = new MySqlParameter("@Email", user.Email); param1.MySqlDbType = MySqlDbType.VarChar; cmd1.Parameters.Add(param1); param1 = new MySqlParameter("@CustomerId", subscription.CustomerId); param1.MySqlDbType = MySqlDbType.VarChar; cmd1.Parameters.Add(param1); param1 = new MySqlParameter("@SubscriptionId", subscription.Id); param1.MySqlDbType = MySqlDbType.VarChar; cmd1.Parameters.Add(param1); param1 = new MySqlParameter("@Subscription_Started", subscription.StartDate); param1.MySqlDbType = MySqlDbType.DateTime; cmd1.Parameters.Add(param1); param1 = new MySqlParameter("@Subscription_Ended", subscription.EndedAt); param1.MySqlDbType = MySqlDbType.DateTime; cmd1.Parameters.Add(param1); cmd1.ExecuteNonQuery(); HttpContext.Session.SetInt32("isLoggedIn", 1); payment.massage = "Payment created successfully"; //return View("Success"); // render Success.cshtml return(View(payment)); } else { return(RedirectToAction(nameof(Login))); } } catch (Exception ex) { MailMessage mail = new MailMessage(); mail.From = new MailAddress(_emailSettings.Value.PrimaryEmail); mail.Subject = "Subscription Fail"; mail.IsBodyHtml = true; mail.Body = ex.Message; mail.Sender = new MailAddress(_emailSettings.Value.PrimaryEmail); mail.To.Add(email); SmtpClient smtp = new SmtpClient(); smtp.Host = _emailSettings.Value.PrimaryDomain; //Or Your SMTP Server Address smtp.Port = _emailSettings.Value.PrimaryPort; smtp.UseDefaultCredentials = false; smtp.DeliveryMethod = SmtpDeliveryMethod.Network; smtp.Credentials = new System.Net.NetworkCredential(_emailSettings.Value.PrimaryEmail, _emailSettings.Value.PrimaryPassword); //Or your Smtp Email ID and Password smtp.EnableSsl = _emailSettings.Value.EnableSsl; smtp.Send(mail); payment.massage = ex.Message; return(View(payment)); } }
private string ProcessCaptureRequest(Order order, HttpRequest request, IDictionary <string, string> settings) { var apiKey = settings[settings["mode"] + "_secret_key"]; var billingMode = settings["billing_mode"]; ConfigureStripe(apiKey); ValidateBillingModeSetting(billingMode); var customerService = new CustomerService(); var subscriptionService = new SubscriptionService(); var invoiceService = new InvoiceService(); // Create the stripe customer var customer = customerService.Create(new CustomerCreateOptions { PaymentMethod = billingMode == "charge" ? request.Form["stripePaymentMethodId"] : null, Email = order.PaymentInformation.Email, Metadata = new Dictionary <string, string> { { "customerId", order.CustomerId } } }); // Create subscription for customer (will auto attempt payment) var subscriptionOptions = new SubscriptionCreateOptions { Customer = customer.Id, Items = order.OrderLines.Select(x => new SubscriptionItemOptions { Plan = !string.IsNullOrWhiteSpace(x.Properties["planId"]) ? x.Properties["planId"] : x.Sku, Quantity = (long)x.Quantity }).ToList(), TaxPercent = order.VatRate.Value * 100, Metadata = new Dictionary <string, string> { { "orderId", order.Id.ToString() }, { "cartNumber", order.CartNumber } }, Expand = new[] { "latest_invoice.payment_intent" }.ToList() }; if (billingMode == "charge") { subscriptionOptions.CollectionMethod = "charge_automatically"; subscriptionOptions.DefaultPaymentMethod = request.Form["stripePaymentMethodId"]; } else { subscriptionOptions.CollectionMethod = "send_invoice"; subscriptionOptions.DaysUntilDue = settings.ContainsKey("invoice_days_until_due") ? int.Parse("0" + settings["invoice_days_until_due"]) : 30; } foreach (var prop in order.Properties) { subscriptionOptions.Metadata.Add(prop.Alias, prop.Value); } var subscription = subscriptionService.Create(subscriptionOptions); var invoice = subscription.LatestInvoice; // Stash the stripe info in the order order.Properties.AddOrUpdate(new CustomProperty("stripeCustomerId", customer.Id) { ServerSideOnly = true }); order.Properties.AddOrUpdate(new CustomProperty("stripeSubscriptionId", subscription.Id) { ServerSideOnly = true }); order.Save(); if (subscription.Status == "active" || subscription.Status == "trialing") { return(JsonConvert.SerializeObject(new { success = true })); } else if (invoice.PaymentIntent.Status == "requires_action") { return(JsonConvert.SerializeObject(new { requires_action = true, payment_intent_client_secret = invoice.PaymentIntent.ClientSecret })); } return(JsonConvert.SerializeObject(new { error = "Invalid payment intent status" })); }
protected Models.PaymentIntent UpdatePaymentIntent(string sessionId) { StripeConfiguration.ApiKey = ConfigurationManager.AppSettings["Cashier:Stripe:Secret"]; var sessionService = new SessionService(); var session = sessionService.Get(sessionId); var setupIntentService = new SetupIntentService(); var setupIntent = setupIntentService.Get(session.SetupIntentId); var paymentIntent = PaymentService.GetPaymentIntentByTransactionRef(session.Metadata["TransactionRef"]); if (string.IsNullOrEmpty(setupIntent.PaymentMethodId)) { paymentIntent.PaymentStatus = PaymentStatus.Failed; PaymentService.UpdatePaymentStatus(paymentIntent.TransactionReference, session.PaymentIntentId, PaymentStatus.Failed); return(paymentIntent); } var ddPriceName = $"Direct Debit - {paymentIntent.DirectDebitFrequencyInterval} {Enum.GetName(typeof(PaymentFrequencyUnit), paymentIntent.DirectDebitFrequencyUnit)}{(paymentIntent.DirectDebitFrequencyInterval > 1 ? "s" : "")} - {paymentIntent.Amount}"; var productService = new ProductService(); var product = productService.List().FirstOrDefault(p => p.Description == "Direct Debit"); if (product == null) { product = productService.Create(new ProductCreateOptions { Name = ddPriceName, Type = "service" }); } var priceService = new PriceService(); var price = priceService.List().FirstOrDefault(p => p.Nickname == ddPriceName); if (price == null) { price = priceService.Create(new PriceCreateOptions { Nickname = ddPriceName, Product = product.Id, UnitAmount = (long)paymentIntent.Amount * 100, Currency = paymentIntent.Currency, Recurring = new PriceRecurringOptions { Interval = Enum.GetName(typeof(PaymentFrequencyUnit), paymentIntent.DirectDebitFrequencyUnit).ToLower(), IntervalCount = paymentIntent.DirectDebitFrequencyInterval, UsageType = "licensed" } }); } var customerService = new CustomerService(); var customer = customerService.List().FirstOrDefault(c => c.Name == paymentIntent.CustomerUniqueReference); if (customer == null) { customer = customerService.Create(new CustomerCreateOptions { Name = paymentIntent.CustomerUniqueReference, Description = paymentIntent.CustomerUniqueReference, PaymentMethod = setupIntent.PaymentMethodId, Email = paymentIntent.CustomerEmail, Address = new AddressOptions { Line1 = paymentIntent.CustomerAddressLines, City = paymentIntent.CustomerCity, Country = paymentIntent.CustomerCountry, PostalCode = paymentIntent.CustomerPostcode } }); } else { var paymentMethodService = new PaymentMethodService(); paymentMethodService.Attach(setupIntent.PaymentMethodId, new PaymentMethodAttachOptions { Customer = customer.Id }); } var subscriptionService = new SubscriptionService(); var subscriptionCreate = new SubscriptionCreateOptions { Customer = customer.Id, DefaultPaymentMethod = setupIntent.PaymentMethodId, BillingCycleAnchor = paymentIntent.DirectDebitStartDate, Items = new List <SubscriptionItemOptions> { new SubscriptionItemOptions { Price = price.Id } } }; if (paymentIntent.DirectDebitTrialDateEnd.HasValue) { //let the trial date specify the days that should not be charged subscriptionCreate.TrialEnd = paymentIntent.DirectDebitTrialDateEnd; } else { //otherwise let it start on the anchor date and disable proration subscriptionCreate.ProrationBehavior = "none"; } var subscription = subscriptionService.Create(subscriptionCreate); paymentIntent.PaymentStatus = PaymentStatus.Succeeded; PaymentService.UpdatePaymentStatus(paymentIntent.TransactionReference, subscription.Id, PaymentStatus.Succeeded); return(paymentIntent); }
public async Task PurchasePremiumAsync(User user, PaymentMethodType paymentMethodType, string paymentToken, short additionalStorageGb) { if (paymentMethodType != PaymentMethodType.Credit && string.IsNullOrWhiteSpace(paymentToken)) { throw new BadRequestException("Payment token is required."); } if (paymentMethodType == PaymentMethodType.Credit && (user.Gateway != GatewayType.Stripe || string.IsNullOrWhiteSpace(user.GatewayCustomerId))) { throw new BadRequestException("Your account does not have any credit available."); } if (paymentMethodType == PaymentMethodType.BankAccount) { throw new GatewayException("Bank account payment method is not supported at this time."); } var invoiceService = new InvoiceService(); var customerService = new CustomerService(); var createdStripeCustomer = false; string stripeCustomerId = null; Braintree.Transaction braintreeTransaction = null; Braintree.Customer braintreeCustomer = null; var stripePaymentMethod = paymentMethodType == PaymentMethodType.Card || paymentMethodType == PaymentMethodType.BankAccount || paymentMethodType == PaymentMethodType.Credit; if (user.Gateway == GatewayType.Stripe && !string.IsNullOrWhiteSpace(user.GatewayCustomerId)) { if (!string.IsNullOrWhiteSpace(paymentToken)) { try { await UpdatePaymentMethodAsync(user, paymentMethodType, paymentToken); } catch { stripeCustomerId = null; } } stripeCustomerId = user.GatewayCustomerId; createdStripeCustomer = false; } if (string.IsNullOrWhiteSpace(stripeCustomerId) && !string.IsNullOrWhiteSpace(paymentToken)) { string stipeCustomerSourceToken = null; var stripeCustomerMetadata = new Dictionary <string, string>(); if (stripePaymentMethod) { stipeCustomerSourceToken = paymentToken; } else if (paymentMethodType == PaymentMethodType.PayPal) { var randomSuffix = Utilities.CoreHelpers.RandomString(3, upper: false, numeric: false); var customerResult = await _btGateway.Customer.CreateAsync(new Braintree.CustomerRequest { PaymentMethodNonce = paymentToken, Email = user.Email, Id = user.BraintreeCustomerIdPrefix() + user.Id.ToString("N").ToLower() + randomSuffix, CustomFields = new Dictionary <string, string> { [user.BraintreeIdField()] = user.Id.ToString() } }); if (!customerResult.IsSuccess() || customerResult.Target.PaymentMethods.Length == 0) { throw new GatewayException("Failed to create PayPal customer record."); } braintreeCustomer = customerResult.Target; stripeCustomerMetadata.Add("btCustomerId", braintreeCustomer.Id); } else { throw new GatewayException("Payment method is not supported at this time."); } var customer = await customerService.CreateAsync(new CustomerCreateOptions { Description = user.Name, Email = user.Email, SourceToken = stipeCustomerSourceToken, Metadata = stripeCustomerMetadata }); stripeCustomerId = customer.Id; createdStripeCustomer = true; } var subCreateOptions = new SubscriptionCreateOptions { CustomerId = stripeCustomerId, Items = new List <SubscriptionItemOption>(), Metadata = new Dictionary <string, string> { [user.GatewayIdField()] = user.Id.ToString() } }; subCreateOptions.Items.Add(new SubscriptionItemOption { PlanId = PremiumPlanId, Quantity = 1, }); if (additionalStorageGb > 0) { subCreateOptions.Items.Add(new SubscriptionItemOption { PlanId = StoragePlanId, Quantity = additionalStorageGb }); } var subInvoiceMetadata = new Dictionary <string, string>(); Subscription subscription = null; try { if (!stripePaymentMethod) { var previewInvoice = await invoiceService.UpcomingAsync(new UpcomingInvoiceOptions { CustomerId = stripeCustomerId, SubscriptionItems = ToInvoiceSubscriptionItemOptions(subCreateOptions.Items) }); await customerService.UpdateAsync(stripeCustomerId, new CustomerUpdateOptions { AccountBalance = -1 * previewInvoice.AmountDue }); if (braintreeCustomer != null) { var btInvoiceAmount = (previewInvoice.AmountDue / 100M); var transactionResult = await _btGateway.Transaction.SaleAsync( new Braintree.TransactionRequest { Amount = btInvoiceAmount, CustomerId = braintreeCustomer.Id, Options = new Braintree.TransactionOptionsRequest { SubmitForSettlement = true, PayPal = new Braintree.TransactionOptionsPayPalRequest { CustomField = $"{user.BraintreeIdField()}:{user.Id}" } }, CustomFields = new Dictionary <string, string> { [user.BraintreeIdField()] = user.Id.ToString() } }); if (!transactionResult.IsSuccess()) { throw new GatewayException("Failed to charge PayPal customer."); } braintreeTransaction = transactionResult.Target; subInvoiceMetadata.Add("btTransactionId", braintreeTransaction.Id); subInvoiceMetadata.Add("btPayPalTransactionId", braintreeTransaction.PayPalDetails.AuthorizationId); } else { throw new GatewayException("No payment was able to be collected."); } } else if (paymentMethodType == PaymentMethodType.Credit) { var previewInvoice = await invoiceService.UpcomingAsync(new UpcomingInvoiceOptions { CustomerId = stripeCustomerId, SubscriptionItems = ToInvoiceSubscriptionItemOptions(subCreateOptions.Items) }); if (previewInvoice.AmountDue > 0) { throw new GatewayException("Your account does not have enough credit available."); } } var subscriptionService = new SubscriptionService(); subscription = await subscriptionService.CreateAsync(subCreateOptions); if (!stripePaymentMethod && subInvoiceMetadata.Any()) { var invoices = await invoiceService.ListAsync(new InvoiceListOptions { SubscriptionId = subscription.Id }); var invoice = invoices?.FirstOrDefault(); if (invoice == null) { throw new GatewayException("Invoice not found."); } await invoiceService.UpdateAsync(invoice.Id, new InvoiceUpdateOptions { Metadata = subInvoiceMetadata }); } } catch (Exception e) { if (createdStripeCustomer && !string.IsNullOrWhiteSpace(stripeCustomerId)) { await customerService.DeleteAsync(stripeCustomerId); } if (braintreeTransaction != null) { await _btGateway.Transaction.RefundAsync(braintreeTransaction.Id); } if (braintreeCustomer != null) { await _btGateway.Customer.DeleteAsync(braintreeCustomer.Id); } throw e; } user.Gateway = GatewayType.Stripe; user.GatewayCustomerId = stripeCustomerId; user.GatewaySubscriptionId = subscription.Id; user.Premium = true; user.PremiumExpirationDate = subscription.CurrentPeriodEnd; }
public async Task PurchaseOrganizationAsync(Organization org, PaymentMethodType paymentMethodType, string paymentToken, Models.StaticStore.Plan plan, short additionalStorageGb, short additionalSeats, bool premiumAccessAddon) { var invoiceService = new InvoiceService(); var customerService = new CustomerService(); Braintree.Customer braintreeCustomer = null; string stipeCustomerSourceToken = null; var stripeCustomerMetadata = new Dictionary <string, string>(); var stripePaymentMethod = paymentMethodType == PaymentMethodType.Card || paymentMethodType == PaymentMethodType.BankAccount; if (stripePaymentMethod) { stipeCustomerSourceToken = paymentToken; } else if (paymentMethodType == PaymentMethodType.PayPal) { var randomSuffix = Utilities.CoreHelpers.RandomString(3, upper: false, numeric: false); var customerResult = await _btGateway.Customer.CreateAsync(new Braintree.CustomerRequest { PaymentMethodNonce = paymentToken, Email = org.BillingEmail, Id = org.BraintreeCustomerIdPrefix() + org.Id.ToString("N").ToLower() + randomSuffix, CustomFields = new Dictionary <string, string> { [org.BraintreeIdField()] = org.Id.ToString() } }); if (!customerResult.IsSuccess() || customerResult.Target.PaymentMethods.Length == 0) { throw new GatewayException("Failed to create PayPal customer record."); } braintreeCustomer = customerResult.Target; stripeCustomerMetadata.Add("btCustomerId", braintreeCustomer.Id); } else { throw new GatewayException("Payment method is not supported at this time."); } var subCreateOptions = new SubscriptionCreateOptions { TrialPeriodDays = plan.TrialPeriodDays, Items = new List <SubscriptionItemOption>(), Metadata = new Dictionary <string, string> { [org.GatewayIdField()] = org.Id.ToString() } }; if (plan.StripePlanId != null) { subCreateOptions.Items.Add(new SubscriptionItemOption { PlanId = plan.StripePlanId, Quantity = 1 }); } if (additionalSeats > 0 && plan.StripeSeatPlanId != null) { subCreateOptions.Items.Add(new SubscriptionItemOption { PlanId = plan.StripeSeatPlanId, Quantity = additionalSeats }); } if (additionalStorageGb > 0) { subCreateOptions.Items.Add(new SubscriptionItemOption { PlanId = plan.StripeStoragePlanId, Quantity = additionalStorageGb }); } if (premiumAccessAddon && plan.StripePremiumAccessPlanId != null) { subCreateOptions.Items.Add(new SubscriptionItemOption { PlanId = plan.StripePremiumAccessPlanId, Quantity = 1 }); } Customer customer = null; Subscription subscription = null; try { customer = await customerService.CreateAsync(new CustomerCreateOptions { Description = org.BusinessName, Email = org.BillingEmail, SourceToken = stipeCustomerSourceToken, Metadata = stripeCustomerMetadata }); subCreateOptions.CustomerId = customer.Id; var subscriptionService = new SubscriptionService(); subscription = await subscriptionService.CreateAsync(subCreateOptions); } catch (Exception e) { if (customer != null) { await customerService.DeleteAsync(customer.Id); } if (braintreeCustomer != null) { await _btGateway.Customer.DeleteAsync(braintreeCustomer.Id); } throw e; } org.Gateway = GatewayType.Stripe; org.GatewayCustomerId = customer.Id; org.GatewaySubscriptionId = subscription.Id; org.ExpirationDate = subscription.CurrentPeriodEnd; }
public void Components_Create_Subscription_Multiple_Components() { // Arrange var product = Chargify.GetProductList().Values.FirstOrDefault(); Assert.IsNotNull(product, "Product couldn't be found"); var referenceId = Guid.NewGuid().ToString(); var newCustomer = new CustomerAttributes("Scott", "Pilgrim", "*****@*****.**", "Chargify", referenceId); var newPaymentInfo = GetTestPaymentMethod(newCustomer); // Find components that allow for a simple allocated_quantity = 1 to work for this simple test var components = Chargify.GetComponentsForProductFamily(product.ProductFamily.ID).Values.Where(c => c.Kind == ComponentType.Quantity_Based_Component || c.Kind == ComponentType.On_Off_Component); var componentsToUse = components.Take(2).ToList(); var options = new SubscriptionCreateOptions() { CustomerAttributes = newCustomer, CreditCardAttributes = newPaymentInfo, ProductHandle = product.Handle, Components = new System.Collections.Generic.List <ComponentDetails> { new ComponentDetails() { ComponentID = componentsToUse.First().ID, AllocatedQuantity = 1 }, new ComponentDetails() { ComponentID = componentsToUse.Last().ID, AllocatedQuantity = 1 } } }; // Act var newSubscription = Chargify.CreateSubscription(options); var subComponents = Chargify.GetComponentsForSubscription(newSubscription.SubscriptionID); var usedComponents = from c in subComponents where componentsToUse.Any(x => x.ID == c.Value.ComponentID) select c; // Assert Assert.IsInstanceOfType(newSubscription, typeof(Subscription)); Assert.IsNotNull(newSubscription); Assert.IsNotNull(newSubscription.Customer); Assert.IsNotNull(newSubscription.PaymentProfile); Assert.IsTrue(newSubscription.SubscriptionID > int.MinValue); Assert.IsTrue(newSubscription.Customer.ChargifyID > int.MinValue); Assert.IsTrue(newSubscription.Customer.FirstName == newCustomer.FirstName); Assert.IsTrue(newSubscription.Customer.LastName == newCustomer.LastName); Assert.IsTrue(newSubscription.Customer.Email == newCustomer.Email); Assert.IsTrue(newSubscription.Customer.Organization == newCustomer.Organization); Assert.IsTrue(newSubscription.Customer.SystemID == referenceId); Assert.IsTrue(newSubscription.PaymentProfile.FirstName == newPaymentInfo.FirstName); Assert.IsTrue(newSubscription.PaymentProfile.LastName == newPaymentInfo.LastName); Assert.IsTrue(newSubscription.PaymentProfile.ExpirationMonth == newPaymentInfo.ExpirationMonth); Assert.IsTrue(newSubscription.PaymentProfile.ExpirationYear == newPaymentInfo.ExpirationYear); Assert.IsTrue(newSubscription.PaymentProfile.BillingAddress == newPaymentInfo.BillingAddress); //Assert.IsTrue(newSubscription.PaymentProfile.BillingAddress2 == newPaymentInfo.BillingAddress2); Assert.IsTrue(newSubscription.PaymentProfile.BillingCity == newPaymentInfo.BillingCity); Assert.IsTrue(newSubscription.PaymentProfile.BillingCountry == newPaymentInfo.BillingCountry); Assert.IsTrue(newSubscription.PaymentProfile.BillingState == newPaymentInfo.BillingState); Assert.IsTrue(newSubscription.PaymentProfile.BillingZip == newPaymentInfo.BillingZip); Assert.IsTrue(usedComponents.Count() == componentsToUse.Count); foreach (var component in usedComponents) { Assert.IsTrue(componentsToUse.Any(x => x.ID == component.Key)); //Assert.AreEqual(decimal.Parse(componentsToUse[component.Key]), component.Value.AllocatedQuantity); } // Cleanup Assert.IsTrue(Chargify.DeleteSubscription(newSubscription.SubscriptionID, "Automatic cancel due to test")); }
public static TransactionResult CreateSubscription(TransactionRequest request, StripeSettings stripeSettings, ILogger logger) { var order = request.Order; InitStripe(stripeSettings); var parameters = request.Parameters; parameters.TryGetValue("cardNumber", out var cardNumber); parameters.TryGetValue("cardName", out var cardName); parameters.TryGetValue("expireMonth", out var expireMonthStr); parameters.TryGetValue("expireYear", out var expireYearStr); parameters.TryGetValue("cvv", out var cvv); var paymentMethodService = new PaymentMethodService(); var paymentMethod = paymentMethodService.Create(new PaymentMethodCreateOptions() { Card = new PaymentMethodCardCreateOptions() { Number = cardNumber.ToString(), ExpYear = long.Parse(expireYearStr.ToString()), ExpMonth = long.Parse(expireMonthStr.ToString()), Cvc = cvv.ToString() }, Type = "card" }); var address = DependencyResolver.Resolve <IDataSerializer>() .DeserializeAs <Address>(order.BillingAddressSerialized); InitStripe(stripeSettings, true); //do we have a saved stripe customer id? var customerId = GetCustomerId(order.User, paymentMethod, address); var subscriptionItems = new List <SubscriptionItemOptions>(); var productService = new ProductService(); var planService = new PlanService(); foreach (var orderItem in order.OrderItems) { var product = productService.Create(new ProductCreateOptions { Name = orderItem.Product.Name, Type = "service" }); var lineTotal = orderItem.Price * orderItem.Quantity + orderItem.Tax; GetFinalAmountDetails(lineTotal, order.CurrencyCode, address, out var currencyCode, out var finalAmount); var planOptions = new PlanCreateOptions() { Nickname = product.Name, Product = product.Id, Amount = (long)(finalAmount), Interval = GetInterval(orderItem.Product.SubscriptionCycle), IntervalCount = orderItem.Product.CycleCount == 0 ? 1 : orderItem.Product.CycleCount, Currency = currencyCode, UsageType = "licensed", TrialPeriodDays = orderItem.Product.TrialDays }; var plan = planService.Create(planOptions); subscriptionItems.Add(new SubscriptionItemOptions() { Plan = plan.Id, Quantity = orderItem.Quantity }); } //create a coupon if any var coupon = GetCoupon(order); var subscriptionOptions = new SubscriptionCreateOptions() { Customer = customerId, Items = subscriptionItems, Metadata = new Dictionary <string, string>() { { "orderGuid", order.Guid }, { "internalId", order.Id.ToString() }, { "isSubscription", bool.TrueString } }, Coupon = coupon?.Id, #if DEBUG TrialEnd = DateTime.UtcNow.AddMinutes(5) #endif }; subscriptionOptions.AddExpand("latest_invoice.payment_intent"); var subscriptionService = new SubscriptionService(); var subscription = subscriptionService.Create(subscriptionOptions); var processPaymentResult = new TransactionResult() { OrderGuid = order.Guid, }; if (subscription.Status == "active" || subscription.Status == "trialing") { processPaymentResult.NewStatus = PaymentStatus.Complete; processPaymentResult.TransactionCurrencyCode = order.CurrencyCode; processPaymentResult.IsSubscription = true; processPaymentResult.TransactionAmount = (subscription.Plan.AmountDecimal / 100) ?? order.OrderTotal; processPaymentResult.ResponseParameters = new Dictionary <string, object>() { { "subscriptionId", subscription.Id }, { "invoiceId", subscription.LatestInvoiceId }, { "feePercent", subscription.ApplicationFeePercent }, { "collectionMethod", subscription.CollectionMethod }, { "metaInfo", subscription.Metadata } }; processPaymentResult.Success = true; } else { processPaymentResult.Success = false; logger.Log <TransactionResult>(LogLevel.Warning, $"The subscription for Order#{order.Id} by stripe failed with status {subscription.Status}." + subscription.StripeResponse.Content); } return(processPaymentResult); }
public ActionResult <Subscription> CreateSubscription([FromBody] CreateSubscriptionRequest req) { if (!ModelState.IsValid) { return(this.FailWithMessage("invalid params")); } var newPrice = Environment.GetEnvironmentVariable(req.Price.ToUpper()); if (newPrice is null || newPrice == "") { return(this.FailWithMessage($"No price with the new price ID ({req.Price}) found in .env")); } // Attach payment method var options = new PaymentMethodAttachOptions { Customer = req.Customer, }; var service = new PaymentMethodService(); PaymentMethod paymentMethod; try { paymentMethod = service.Attach(req.PaymentMethod, options); } catch (Exception e) { return(this.FailWithMessage($"Failed to attach payment method {e}")); } // Update customer's default invoice payment method var customerOptions = new CustomerUpdateOptions { InvoiceSettings = new CustomerInvoiceSettingsOptions { DefaultPaymentMethod = paymentMethod.Id, }, }; var customerService = new CustomerService(); try { customerService.Update(req.Customer, customerOptions); } catch (StripeException e) { return(this.FailWithMessage($"Failed to attach payment method {e}")); } // Create subscription var subscriptionOptions = new SubscriptionCreateOptions { Customer = req.Customer, Items = new List <SubscriptionItemOptions> { new SubscriptionItemOptions { Price = Environment.GetEnvironmentVariable(req.Price), Quantity = req.Quantity, }, }, }; subscriptionOptions.AddExpand("latest_invoice.payment_intent"); var subscriptionService = new SubscriptionService(); try { return(subscriptionService.Create(subscriptionOptions)); } catch (StripeException e) { return(this.FailWithMessage($"Failed to attach payment method: {e}")); } }
public async Task <string> CreateACustomerSubcription(string customerId) { try { StripeConfiguration.ApiKey = this._configuration.GetSection("Stripe")["SecretKey"]; //================================================================== // Create Product Subcription var productoptions = new ProductCreateOptions { Name = "Quick Order Subcription", Active = true, Description = "Quick Order Admin System Subcription", Type = "service" }; var productservice = new ProductService(); var producttoken = await productservice.CreateAsync(productoptions); var priceoptions = new PriceCreateOptions { UnitAmount = 200, Currency = "usd", Recurring = new PriceRecurringOptions { Interval = "month", }, Product = producttoken.Id, }; var priceservice = new PriceService(); var priceservicetoken = await priceservice.CreateAsync(priceoptions); //======================================================================= End Create Product Subcription //=================================================================================== //Create Subcription to store var options = new SubscriptionCreateOptions { Customer = customerId, Items = new List <SubscriptionItemOptions> { new SubscriptionItemOptions { Price = priceservicetoken.Id, }, }, }; var service = new SubscriptionService(); Subscription subscription = await service.CreateAsync(options); if (!string.IsNullOrEmpty(subscription.Id)) { //var newSubcription = new Subcription() //{ // StripeCustomerId = customerId, // StripeSubCriptionID = subscription.Id //}; //_context.Subcriptions.Add(newSubcription); //try //{ //_context.SaveChanges(); //} //catch (Exception e) //{ // Console.WriteLine(e); //} return(subscription.Id); } else { return(string.Empty); } } catch (Exception e) { Console.WriteLine(e); return(string.Empty); } }
public ActionResult Subscribe(string email, string plan, string stripeToken) { CustomerModel cm = new CustomerModel(); var customerOptions = new CustomerCreateOptions { Email = email, Source = stripeToken, }; try { var customerService = new CustomerService(); var customer = customerService.Create(customerOptions); customer_id = customer.Id; // Previous code in action var planId = ""; if (plan == "basicPlan") { planId = "price_1Htq5ZHQbClkzxezJlLhffk6"; global_plan_id = "price_1Htq5ZHQbClkzxezJlLhffk6"; } else { planId = "price_1I2w4MHQbClkzxezSyy1Cd1j"; global_plan_id = "price_1I2w4MHQbClkzxezSyy1Cd1j"; } var subscriptionOptions = new SubscriptionCreateOptions { Customer = customer.Id, Items = new List <SubscriptionItemOptions> { new SubscriptionItemOptions { Plan = planId }, }, }; subscriptionOptions.AddExpand("latest_invoice.payment_intent"); var subscriptionService = new SubscriptionService(); var subscription = subscriptionService.Create(subscriptionOptions); ViewBag.stripeKey = "{PUBLIC KEY}; ViewBag.subscription = subscription.ToJson(); cm.customer_id = subscription.CustomerId; cm.email = email.ToString(); cm.subscription_status = subscription.Status; if (planId == " price_1Htq5ZHQbClkzxezJlLhffk6 ") { cm.basic = " True "; cm.premium = " False "; } else { cm.basic = " False "; cm.premium = " True "; } cm.SaveDetails(); return View(" SubscribeResult "); } catch(Exception e) { cm.customer_id = " not - valid "; cm.email = email.ToString(); cm.subscription_status = " not - valid "; cm.basic = null; cm.premium = null; cm.SaveDetails(); return View(" SubscribeFailed "); } }