Exemplo n.º 1
0
        public async Task <PaymentGatewayResult <IPaymentSubscription> > CreateSubscriptionAsync(string planId, string customerId, ChargeType type, string?coupon)
        {
            try
            {
                var options = new SubscriptionCreateOptions
                {
                    CustomerId = customerId,
                    Items      = new List <SubscriptionItemOption> {
                        new SubscriptionItemOption {
                            PlanId = planId
                        }
                    },
                    CollectionMethod = _chargeTypes[(int)type],
                    CouponId         = coupon
                };
                if ((int)type == 1)
                {
                    options.DaysUntilDue = _appSettings.Stripe.InvoiceDueDays;
                }

                var subscription = await _subscriptionService.CreateAsync(options);

                return(PaymentGatewayResult <IPaymentSubscription> .Success(_mapper.Map <IPaymentSubscription>(subscription)));
            }
            catch (StripeException e)
            {
                return(PaymentGatewayResult <IPaymentSubscription> .Failed(e));
            }
        }
Exemplo n.º 2
0
    public async Task <ActionResult <Subscription> > CreateCustomerAsync([FromBody] CustomerCreateRequest request)
    {
        var customerService = new CustomerService(this.client);

        var customer = await customerService.CreateAsync(new CustomerCreateOptions
        {
            Email           = request.Email,
            PaymentMethod   = request.PaymentMethod,
            InvoiceSettings = new CustomerInvoiceSettingsOptions
            {
                DefaultPaymentMethod = request.PaymentMethod,
            }
        });

        var subscriptionService = new SubscriptionService(this.client);

        var subscription = await subscriptionService.CreateAsync(new SubscriptionCreateOptions
        {
            Items = new List <SubscriptionItemOptions>
            {
                new SubscriptionItemOptions {
                    Plan = this.options.Value.SubscriptionPlanId,
                },
            },
            Customer = customer.Id,
            Expand   = new List <string> {
                "latest_invoice.payment_intent",
            }
        });

        return(subscription);
    }
Exemplo n.º 3
0
        public async Task <IActionResult> SubscribeAsync([FromBody] SubscribeRequest 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  prevsub     = context.Subscriptions.FirstOrDefault(sub => sub.CustomerEmail == email);
                bool newCustomer = (prevsub == null);

                var subscriptions = new SubscriptionService();

                var customerID = user.CustomerID;

                SubscriptionCreateOptions mysub = new SubscriptionCreateOptions();
                mysub.CustomerId    = customerID;
                mysub.Items         = new List <SubscriptionItemOption>();
                mysub.TrialFromPlan = newCustomer;
                mysub.TaxPercent    = 20m;

                mysub.Items.Add(new SubscriptionItemOption {
                    PlanId = req.planId, Quantity = 1
                });
                var subscription = await subscriptions.CreateAsync(mysub);

                await context.SaveChangesAsync();

                return(Ok());
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        public async Task StartCommunitySubscription(Community community, BillingRecord billing, User contact)
        {
            var plan = plans.GetPlan(billing.PlanId) !;

            if (plan.Stripe is StripePlan stripePlan)
            {
                try
                {
                    var customer = new CustomerCreateOptions()
                    {
                        Name  = community.Name,
                        Email = contact.Email.PlainText
                    };
                    var stripeCustomer = await Customers.CreateAsync(customer, RequestOptions);

                    var subscription = new SubscriptionCreateOptions()
                    {
                        Customer = stripeCustomer.Id,
                        Items    = new List <SubscriptionItemOptions>()
                        {
                            new SubscriptionItemOptions()
                            {
                                Price = stripePlan.PriceId
                            }
                        }
                    };

                    if (billing.TrialEnd > DateTime.Now)
                    {
                        subscription.TrialEnd = billing.TrialEnd;
                    }
                    var stripeSubscription = await Subscriptions.CreateAsync(subscription, RequestOptions);

                    if (billing.Stripe == null)
                    {
                        billing.Stripe = new StripeBillingRecord();
                    }
                    billing.Stripe.CustomerId         = stripeCustomer.Id;
                    billing.Stripe.SubscriptionId     = stripeSubscription.Id;
                    billing.Stripe.SubscriptionItemId = stripeSubscription.Items.Data[0].Id;
                }
                catch (StripeException e)
                {
                    logger.LogError(e, "Failed to create stripe subscription");
                    throw;
                }
            }
            else
            {
                throw new ArgumentException("StripePaymentProcessor requires a StripePlan");
            }
        }
Exemplo n.º 5
0
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,
            ILogger log, ExecutionContext context)
        {
            var config = new ConfigurationBuilder().SetBasePath(context.FunctionAppDirectory)
                         .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                         .AddEnvironmentVariables()
                         .Build();

            var authenticationService = new AuthenticationService(config["tenantId"], config["clientId"], config["clientSecret"]);
            var subscriptionService   = new SubscriptionService(authenticationService, config["graphEndpoint"], config["notificationEndpoint"]);

            var subscription = await subscriptionService.CreateAsync("created", config["resource"], DateTime.Now.AddMinutes(4230));

            return(new OkObjectResult(subscription));
        }
Exemplo n.º 6
0
        public async Task <Subscription> Subscribe(string customerId, string paymentMethod, List <SubscribeItemOption> items)
        {
            var service = new SubscriptionService();
            var item    = await service.CreateAsync(new SubscriptionCreateOptions
            {
                Customer             = customerId,
                DefaultPaymentMethod = paymentMethod,
                Items = items.Select(x => new SubscriptionItemOptions
                {
                    Price    = x.PriceId,
                    Quantity = x.Quantity
                }).ToList(),
            });

            return(item);
        }
Exemplo n.º 7
0
        public async Task <Subscription> Subscribe(string customerId, string productId)
        {
            var service = new SubscriptionService();
            var prices  = await GetPrices(productId);

            var item = await service.CreateAsync(new SubscriptionCreateOptions
            {
                Customer = customerId,
                Items    = prices.Where(x => x.Type == "recurring").Select(x => new SubscriptionItemOptions
                {
                    Price = x.Id
                }).ToList(),
            });

            return(item);
        }
Exemplo n.º 8
0
        /*
         * Here we're initializing a stripe SEPA subscription on a source with sepa/iban data. This subscription should auto-charge.
         */
        public async Task InitializeSepaDirect(SepaDirectCheckout checkout, CancellationToken token)
        {
            logger.LogInformation("Initializing sepa direct");
            IEnumerable <ValidationResult> validationResults = ValidationHelper.Validate(checkout, serviceProvider);

            if (validationResults.Any())
            {
                throw new InvalidOperationException(string.Join(",", validationResults.Select(v => $"{string.Join(", ", v.MemberNames)}: {v.ErrorMessage}")));
            }

            ApplicationUser user = await userManager.FindByEmailAsync(checkout.Email).ConfigureAwait(false);

            Customer customer = await GetOrCreateCustomer(checkout.Name, checkout.Email, token).ConfigureAwait(false);

            Source source = await sourceService.AttachAsync(
                customer.Id,
                new SourceAttachOptions()
            {
                Source = checkout.SourceId
            },
                cancellationToken : token).ConfigureAwait(false);

            Plan plan = await CreateRecurringPlan(checkout.Amount, "eur", token).ConfigureAwait(false);

            Subscription subscription = await subscriptionService.CreateAsync(
                new SubscriptionCreateOptions()
            {
                DefaultSource = source.Id,
                Billing       = Billing.ChargeAutomatically,
                CustomerId    = customer.Id,
                Items         = new List <SubscriptionItemOption>()
                {
                    new SubscriptionItemOption()
                    {
                        PlanId   = plan.Id,
                        Quantity = 1
                    }
                }
            },
                cancellationToken : token).ConfigureAwait(false);

            context.DonationEventLog.Add(new DonationEventLog(userId: user?.Id, type: DonationEventType.Internal, eventData: subscription.ToJson()));
            await context.SaveChangesAsync(token).ConfigureAwait(false);

            logger.LogInformation("Done initializing sepa direct");
        }
        // GET: Test/Subscribe
        public async Task <ActionResult> Subscribe(int?id)
        {
            try
            {
                // I. Checks.
                string currentUserId = System.Web.HttpContext.Current.User.Identity.GetUserId();
                if (currentUserId == null)
                {
                    return(RedirectToAction("Login", "Account"));
                }
                // Check id.
                if (!int.TryParse(id.ToString(), out int intId))
                {
                    return(RedirectToAction("Index"));
                }

                // II. Add a new subscription to DB.
                if (ModelState.IsValid)
                {
                    SubscriptionDTO subscriptionDTO = new SubscriptionDTO
                    {
                        UserProfileId      = currentUserId,
                        CourseId           = intId,
                        SubscriptionPeriod = 1,
                        IsApproved         = false
                    };
                    OperationDetails operationDetails = await SubscriptionService.CreateAsync(subscriptionDTO, currentUserId);

                    if (operationDetails.Succedeed)
                    {
                        return(PartialView("Report", operationDetails));
                    }
                    else
                    {
                        ModelState.AddModelError(operationDetails.Property, operationDetails.Message);
                        return(PartialView("Report", operationDetails));
                    }
                }
                ViewBag.Message = "Non valid";
                return(PartialView());
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }
Exemplo n.º 10
0
        public async Task <StripeIdResponse> CreateSubscription(string customerId, string planId)
        {
            var subscriptionService = new SubscriptionService();
            var subscription        = await subscriptionService.CreateAsync(new SubscriptionCreateOptions
            {
                CustomerId = customerId,
                Items      = new List <SubscriptionItemOption>
                {
                    new SubscriptionItemOption
                    {
                        PlanId = planId
                    }
                }
            });

            return(new StripeIdResponse
            {
                Id = subscription.Id
            });
        }
Exemplo n.º 11
0
        /// <summary>
        /// Subscribes - new subscription
        /// </summary>
        /// <returns></returns>
        private async Task <Subscription> Subscribe(PaymentModel payment)
        {
            var subscriptions = new List <SubscriptionItemOptions>()
            {
                new SubscriptionItemOptions()
                {
                    Plan     = payment.PlanId,
                    Quantity = 1,
                }
            };

            var subscriptionService = new SubscriptionService();
            var subscriptionOptions = new SubscriptionCreateOptions()
            {
                Customer          = payment.CustomerId,
                CancelAtPeriodEnd = false,
                Items             = subscriptions,
            };

            return(await subscriptionService.CreateAsync(subscriptionOptions));
        }
Exemplo n.º 12
0
        public async Task <Subscription> SubscribeMemberToVendorshipPlan(string VendorshipPlanId,
                                                                         string CustomerId)
        {
            var items = new List <SubscriptionItemOptions>
            {
                new SubscriptionItemOptions {
                    Plan = VendorshipPlanId
                }
            };

            var options = new SubscriptionCreateOptions
            {
                Items    = items,
                Customer = CustomerId
            };

            var          service      = new SubscriptionService();
            Subscription subscription = await service.CreateAsync(options);

            return(subscription);
        }
Exemplo n.º 13
0
        public async Task Create_SupplyValidData_ReturnResponseDto()
        {
            #region Arrange
            var message = new CreateSubscriptionRequestDto {
                Email = "*****@*****.**", Details = new List <SubscriptionDetailDto> {
                    new SubscriptionDetailDto {
                        Catalogue = "catalogue", Key = "item", Operator = "=", Value = "BMW"
                    }
                }
            };
            _mockSubscriptionRepository.Setup(x => x.CreateAsync(It.IsAny <Subscription>())).ReturnsAsync(Guid.NewGuid().ToString());
            #endregion

            #region Act
            var result = await _subscriptionService.CreateAsync(message, It.IsAny <string>());

            #endregion

            #region Assert
            Assert.NotNull(result);
            Assert.NotNull(result.SubscriptionId);
            _mockCacheProvider.Verify(c => c.AddOrUpdateItem(It.IsAny <string>(), It.IsAny <object>()), Times.Once);
            #endregion
        }
Exemplo n.º 14
0
        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."));
        }
Exemplo n.º 15
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 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);
            }
        }
Exemplo n.º 17
0
        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;
        }
Exemplo n.º 18
0
        public async Task PurchasePremiumAsync(User user, PaymentMethodType paymentMethodType, string paymentToken,
                                               short additionalStorageGb)
        {
            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;

            if (paymentMethodType == PaymentMethodType.BankAccount)
            {
                throw new GatewayException("Bank account payment method is not supported at this time.");
            }

            if (user.Gateway == GatewayType.Stripe && !string.IsNullOrWhiteSpace(user.GatewayCustomerId))
            {
                try
                {
                    await UpdatePaymentMethodAsync(user, paymentMethodType, paymentToken);

                    stripeCustomerId      = user.GatewayCustomerId;
                    createdStripeCustomer = false;
                }
                catch (Exception)
                {
                    stripeCustomerId = null;
                }
            }

            if (string.IsNullOrWhiteSpace(stripeCustomerId))
            {
                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.");
                    }
                }

                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;
        }