示例#1
0
        public async Task <List <SubscriptionPlan> > GetAll()
        {
            var products = await productService.ListAsync();

            var plans = new List <SubscriptionPlan>();

            for (int i = 0; i < products.Count(); i++)
            {
                var product = products.ElementAt(i);

                // Check to see if we've given it an ID yet.
                if (!product.Metadata.ContainsKey("Id"))
                {
                    var updateOpts = new ProductUpdateOptions();
                    updateOpts.Metadata       = new Dictionary <string, string>();
                    updateOpts.Metadata["Id"] = Guid.NewGuid().ToString();

                    product = await productService.UpdateAsync(product.Id, updateOpts);
                }

                var plan = new SubscriptionPlan(
                    Guid.Parse(product.Metadata["Id"]),
                    product.Name,
                    product.Description,
                    BillingReference.Product(product.Id),
                    await GetPrices(product.Id)
                    );

                plans.Add(plan);
            }

            return(plans);
        }
示例#2
0
        public async Task <BillingReference> CreateSession(Customer customer, string priceBillingId)
        {
            var opts = new SessionCreateOptions {
                PaymentMethodTypes = new List <string> {
                    "card"
                },
                Customer        = customer.BillingReference.BillingId,
                SetupIntentData = new SessionSetupIntentDataOptions()
                {
                    Metadata = new Dictionary <string, string> {
                        { "customer_id", customer.BillingReference.BillingId },
                    }
                },
                Mode       = "setup",
                SuccessUrl = config.SuccessUrl,
                CancelUrl  = config.CancelUrl
            };

            if (customer.Subscription != null)
            {
                opts.SetupIntentData.Metadata.Add("subscription_id", customer.Subscription.BillingReference.BillingId);
            }

            var session = await sessionService.CreateAsync(opts);

            return(BillingReference.CheckoutSession(session.Id));
        }
示例#3
0
        public async Task <Domain.Scheduling.Billing.Customer> CreateTrialCustomer(User user, SubscriptionPlan trialPlan)
        {
            var customerId = Guid.NewGuid();

            var custCreateOpts = new Stripe.CustomerCreateOptions {
                Email    = user.Email,
                Metadata = new Dictionary <string, string>(new[] {
                    KeyValuePair.Create("Id", customerId.ToString()),
                    KeyValuePair.Create("UserId", user.Id.ToString()),
                })
            };

            var customer = await customerService.CreateAsync(custCreateOpts);

            var price = trialPlan.Prices.Find(p => p.BillingReference.BillingId == config.DefaultPrice) !;
            var subId = Guid.NewGuid();

            var subCreateOpts = new Stripe.SubscriptionCreateOptions {
                Customer = customer.Id,
                Items    = new List <Stripe.SubscriptionItemOptions> {
                    new Stripe.SubscriptionItemOptions {
                        Price = price.BillingReference.BillingId
                    }
                },
                TrialPeriodDays = config.TrialPeriod,
                Metadata        = new Dictionary <string, string>(new[] {
                    KeyValuePair.Create("Id", subId.ToString()),
                    KeyValuePair.Create("PlanId", trialPlan.Id.ToString()),
                    KeyValuePair.Create("PriceBillingId", price.BillingReference.BillingId)
                })
            };

            var subscription = await subscriptionService.CreateAsync(subCreateOpts);

            return(new Domain.Scheduling.Billing.Customer(
                       customerId,
                       user.Id,
                       BillingReference.Customer(customer.Id),
                       new Domain.Scheduling.Billing.Subscription(
                           subId,
                           Domain.Scheduling.Billing.Subscription.ParseStatus(subscription.Status),
                           new Domain.Scheduling.Billing.Period(
                               subscription.TrialStart ?? throw new NullReferenceException(),
                               subscription.TrialEnd ?? throw new NullReferenceException()
                               ),
                           new Domain.Scheduling.Billing.Period(
                               subscription.CurrentPeriodStart,
                               subscription.CurrentPeriodEnd
                               ),
                           subscription.CancelAtPeriodEnd,
                           new SubscriptionPlanReference(
                               trialPlan.Id,
                               price.BillingReference.BillingId
                               ),
                           BillingReference.Subscription(subscription.Id)
                           )
                       ));
        }
示例#4
0
 public VoidedDocumentsLine()
 {
     TotalAmount             = new PayableAmount();
     BillingPayments         = new List <BillingPayment>();
     AllowanceCharge         = new AllowanceCharge();
     TaxTotals               = new List <TaxTotal>();
     AccountingCustomerParty = new AccountingSupplierParty();
     BillingReference        = new BillingReference();
 }
示例#5
0
        async Task <List <SubscriptionPlanPrice> > GetPrices(string planBillingId)
        {
            var prices = await priceService.ListAsync(new PriceListOptions()
            {
                Product = planBillingId
            });

            return(prices.Select(p => new SubscriptionPlanPrice(
                                     p.UnitAmountDecimal ?? throw new InvalidOperationException($"No price amount specified for price {p.Id}"),
                                     p.Recurring.Interval,
                                     BillingReference.Price(p.Id)
                                     )
                                 ).ToList());
        }
示例#6
0
        Customer?Read(SqlMapper.GridReader reader)
        {
            var customer = reader.Read <CustomerRow, BillingReferenceRow, Customer>(
                (c, br) => new Customer(
                    c.Id,
                    c.UserId,
                    BillingReference.Customer(br.BillingId)
                    )
                ).FirstOrDefault();

            if (customer == null)
            {
                return(null);
            }

            customer.Subscription = reader.Read <SubscriptionRow, BillingReferenceRow, Subscription>(
                (s, br) => new Subscription(
                    s.Id,
                    Subscription.ParseStatus(s.Status),
                    new Period(
                        s.TrialStart,
                        s.TrialEnd
                        ),
                    new Period(
                        s.PeriodStart,
                        s.PeriodEnd
                        ),
                    s.CancellingAtPeriodEnd,
                    new SubscriptionPlanReference(s.PlanId, s.PriceBillingId),
                    BillingReference.Subscription(br.BillingId)
                    )
                ).FirstOrDefault();

            customer.PaymentMethods = reader.Read <PaymentMethodRow, BillingReferenceRow, PaymentMethod>(
                (pm, br) => new PaymentMethod(
                    pm.Id,
                    pm.Brand,
                    pm.Last4,
                    pm.IsDefault,
                    new ExpirationDate(pm.ExpirationMonth, pm.ExpirationYear),
                    BillingReference.PaymentMethod(br.BillingId)
                    )
                ).ToList();

            return(customer);
        }
示例#7
0
        public async Task <SubscriptionPlan?> FindByName(string name)
        {
            using (var conn = OpenConnection()) {
                using (var reader = await conn.QueryMultipleAsync(
                           @"select sp.*, br.* from subscription_plans sp
                    left join billing_references br on sp.billing_reference_id = br.id
                    where sp.name = @Name;
                    
                  select spp.*, br.* from subscription_plan_prices spp
                    left join billing_references br on spp.billing_reference_id = br.id
                    left join subscription_plan sp on spp.plan_id = sp.id
                    where sp.name = @Name",
                           new {
                    Name = name
                }
                           )) {
                    var sp = reader.Read <SubscriptionPlanRow, BillingReferenceRow, SubscriptionPlan>(
                        (sp, br) => new SubscriptionPlan(
                            sp.Id,
                            sp.Name,
                            sp.Description,
                            BillingReference.Product(br.BillingId),
                            roleId: sp.RoleId
                            )).SingleOrDefault();

                    if (sp == null)
                    {
                        return(null);
                    }

                    sp.Prices = reader.Read <SubscriptionPlanPriceRow, BillingReferenceRow, SubscriptionPlanPrice>(
                        (spp, br) => new SubscriptionPlanPrice(
                            spp.Price,
                            spp.Interval,
                            new BillingReference(
                                br.BillingId,
                                br.Type
                                )
                            )
                        ).ToList();

                    return(sp);
                }
            }
        }
示例#8
0
        public async Task <List <SubscriptionPlan> > FindAll()
        {
            using (var conn = OpenConnection()) {
                using (var reader = await conn.QueryMultipleAsync(
                           @"select sp.*, br.* from subscription_plans sp
                    join billing_references br on sp.billing_reference_id = br.id;

                  select spp.*, br2.* from subscription_plan_prices spp
                    join subscription_plans sp on spp.plan_id = sp.id
                    join billing_references br2 on sp.billing_reference_id = br2.id;
                ")
                       ) {
                    var plans = reader.Read <SubscriptionPlanRow, BillingReferenceRow, SubscriptionPlan>(
                        (sp, br) => new SubscriptionPlan(
                            sp.Id,
                            sp.Name,
                            sp.Description,
                            BillingReference.Product(br.BillingId),
                            roleId: sp.RoleId
                            )
                        );

                    var planDict = new Dictionary <Guid, SubscriptionPlan>(plans.Select(p => KeyValuePair.Create(p.Id, p)));

                    var prices = reader.Read <SubscriptionPlanPriceRow, BillingReferenceRow, SubscriptionPlanPrice>(
                        (spp, br) => {
                        var price = new SubscriptionPlanPrice(
                            spp.Price,
                            spp.Interval,
                            new BillingReference(
                                br.BillingId,
                                br.Type
                                )
                            );

                        planDict[spp.PlanId].Prices.Add(price);

                        return(price);
                    }
                        );

                    return(plans.ToList());
                }
            }
        }
示例#9
0
        public async Task <Domain.Scheduling.Billing.Customer> GetByBillingId(string billingId)
        {
            var stripeCustomer = await customerService.GetAsync(billingId);

            var customer = new Domain.Scheduling.Billing.Customer(
                Guid.Parse(stripeCustomer.Metadata["Id"]),
                Guid.Parse(stripeCustomer.Metadata["UserId"]),
                BillingReference.Customer(stripeCustomer.Id)
                );

            if (stripeCustomer.Subscriptions.Data.Count > 0)
            {
                var stripeSubscription = stripeCustomer.Subscriptions.Data[0];

                customer.Subscription = new Domain.Scheduling.Billing.Subscription(
                    Guid.Parse(stripeSubscription.Metadata["Id"]),
                    Domain.Scheduling.Billing.Subscription.ParseStatus(stripeSubscription.Status),
                    new Domain.Scheduling.Billing.Period(
                        stripeSubscription.TrialStart ?? throw new NullReferenceException(),
                        stripeSubscription.TrialEnd ?? throw new NullReferenceException()
                        ),
                    new Domain.Scheduling.Billing.Period(
                        stripeSubscription.CurrentPeriodStart,
                        stripeSubscription.CurrentPeriodEnd
                        ),
                    stripeSubscription.CancelAtPeriodEnd,
                    new SubscriptionPlanReference(
                        Guid.Parse(stripeSubscription.Metadata["PlanId"]),
                        stripeSubscription.Metadata["PriceBillingId"]
                        ),
                    BillingReference.Subscription(stripeSubscription.Id)
                    );
            }

            /*
             * Payment sources on customer from CustomerService.GetAsync() will always be empty.
             * Need to get them manually instead.
             */
            var paymentMethods = await paymentMethodService.ListAsync(new Stripe.PaymentMethodListOptions()
            {
                Customer = stripeCustomer.Id,
                Type     = "card"
            });

            for (int i = 0; i < paymentMethods.Data.Count; i++)
            {
                var paymentMethod = paymentMethods.Data[i];

                // Add our id to the card if this is the first time we've seen it.
                if (!paymentMethod.Metadata.ContainsKey("Id"))
                {
                    paymentMethod = await paymentMethodService.UpdateAsync(paymentMethod.Id, new PaymentMethodUpdateOptions()
                    {
                        Metadata = new Dictionary <string, string>(new[] {
                            KeyValuePair.Create("Id", Guid.NewGuid().ToString())
                        })
                    });
                }

                var card = paymentMethod.Card;

                customer.PaymentMethods.Add(new Domain.Scheduling.Billing.PaymentMethod(
                                                Guid.Parse(paymentMethod.Metadata["Id"]),
                                                card.Brand,
                                                card.Last4,
                                                // Stripe won't set default unless there is more than 1 payment method on a customer
                                                paymentMethods.Data.Count == 1 ? true : stripeCustomer.InvoiceSettings.DefaultPaymentMethodId == paymentMethod.Id,
                                                new ExpirationDate(card.ExpMonth.ToString(), card.ExpYear.ToString()),
                                                BillingReference.PaymentMethod(paymentMethod.Id)
                                                ));
            }

            return(customer);
        }
示例#10
0
        public async Task <SubscriptionPlan> FindDefault()
        {
            var p = await FindByBillingReference(BillingReference.Product(billingConfig.DefaultPlan));

            return(p ?? throw new EntityNotFoundException());
        }