public StripeInvoiceServiceTest()
        {
            this.service = new StripeInvoiceService();

            this.createOptions = new StripeInvoiceCreateOptions()
            {
                TaxPercent = 12.5m,
            };

            this.updateOptions = new StripeInvoiceUpdateOptions()
            {
                Metadata = new Dictionary <string, string>()
                {
                    { "key", "value" },
                },
            };

            this.listOptions = new StripeInvoiceListOptions()
            {
                Limit = 1,
            };

            this.listLineItemsOptions = new StripeInvoiceListLineItemsOptions()
            {
                Limit = 1,
            };

            this.upcomingOptions = new StripeUpcomingInvoiceOptions()
            {
                SubscriptionId = "sub_123",
            };
        }
        public IHttpActionResult GetInvoices(string id, string before = null, string after = null, int limit = 12)
        {
            if (String.IsNullOrWhiteSpace(id) || !CanAccessOrganization(id))
            {
                return(NotFound());
            }

            Organization organization = _repository.GetById(id, true);

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

            if (String.IsNullOrWhiteSpace(organization.StripeCustomerId))
            {
                return(Ok(new List <InvoiceGridModel>()));
            }

            var invoiceService = new StripeInvoiceService();
            var invoices       = invoiceService.List(new StripeInvoiceListOptions {
                CustomerId = organization.StripeCustomerId, Limit = limit + 1, EndingBefore = before, StartingAfter = after
            }).Select(Mapper.Map <InvoiceGridModel>).ToList();

            return(OkWithResourceLinks(invoices.Take(limit).ToList(), invoices.Count > limit, i => i.Id));
        }
Esempio n. 3
0
        private async Task PreviewUpcomingAndPayAsync(Organization org, Plan plan)
        {
            var invoiceService  = new StripeInvoiceService();
            var upcomingPreview = await invoiceService.UpcomingAsync(org.StripeCustomerId,
                                                                     new StripeUpcomingInvoiceOptions
            {
                SubscriptionId = org.StripeSubscriptionId
            });

            var prorationAmount = upcomingPreview.StripeInvoiceLineItems?.Data?
                                  .TakeWhile(i => i.Plan.Id == plan.StripeSeatPlanId && i.Proration).Sum(i => i.Amount);

            if (prorationAmount.GetValueOrDefault() >= 500)
            {
                try
                {
                    // Owes more than $5.00 on next invoice. Invoice them and pay now instead of waiting until next month.
                    var invoice = await invoiceService.CreateAsync(org.StripeCustomerId,
                                                                   new StripeInvoiceCreateOptions
                    {
                        SubscriptionId = org.StripeSubscriptionId
                    });

                    if (invoice.AmountDue > 0)
                    {
                        await invoiceService.PayAsync(invoice.Id);
                    }
                }
                catch (StripeException) { }
            }
        }
Esempio n. 4
0
        public async Task <InvoiceResult> CreateInvoiceAsync(InvoiceInfo info)
        {
            var customer = await GetOrCreateCustomer(info);

            var service = new StripeInvoiceItemService();

            foreach (var line in info.Lines.Where(l => l.Type == InvoiceLineType.Product))
            {
                await service.CreateAsync(new StripeInvoiceItemCreateOptions
                {
                    Amount      = (int)(line.Total ?? 0 * 100m), // inclusive of quantity & tax
                    Currency    = line.Currency,
                    CustomerId  = customer.Id,
                    Description = line.Description,
                });
            }

            var createInvoiceOptions = new StripeInvoiceCreateOptions
            {
                Billing      = StripeBilling.SendInvoice,
                DaysUntilDue = info.DueDate.HasValue
                    ? (info.DueDate.Value - SystemClock.Instance.Today()).Days
                    : 30,
                Description = string.Join(", ", info.Lines
                                          .Where(l => l.Type == InvoiceLineType.Text)
                                          .Select(l => l.Description))
            };
            var createInvoiceService = new StripeInvoiceService();
            var stripeInvoice        = await createInvoiceService.CreateAsync(customer.Id, createInvoiceOptions);

            return(new InvoiceResult(stripeInvoice.Id));
        }
Esempio n. 5
0
 // GET api/customer/5
 public HttpResponseMessage Get(string id, int organizationId)
 {
     OrganizationId = organizationId;
     try
     {
         if (UserIsAdminOfOrganization)
         {
             var subscription = subscriptionService.GetCustomerSubscription(id);
             if (subscription != null)
             {
                 var invoiceService = new StripeInvoiceService();
                 var invoice        = subscriptionService.GetUpcomingInvoice(id);
                 subscription.UpcomingInvoice = invoice;
             }
             return(Request.CreateResponse(HttpStatusCode.OK, subscription));
         }
     }
     catch (StripeException ex)
     {
         emailHelper.SendStripeError(ex);
     }
     catch (Exception e)
     {
         emailHelper.SendErrorEmail(e);
     }
     return(Request.CreateResponse(HttpStatusCode.InternalServerError));
 }
Esempio n. 6
0
 // GET api/invoice/5
 public HttpResponseMessage GetUpcoming(string id, bool upcoming, int organizationId)
 {
     this.OrganizationId = organizationId;
     try
     {
         if (this.UserIsAdminOfOrganization)
         {
             var           invoiceService = new StripeInvoiceService();
             StripeInvoice response;
             if (upcoming)
             {
                 var invoice = subscriptionService.GetUpcomingInvoice(id);
                 return(Request.CreateResponse(HttpStatusCode.OK, invoice));
             }
             else
             {
                 response = invoiceService.Get(id);
             }
             return(Request.CreateResponse(HttpStatusCode.OK, response));
         }
     }
     catch (StripeException ex)
     {
         emailHelper.SendStripeError(ex);
     }
     catch (Exception e)
     {
         emailHelper.SendErrorEmail(e);
     }
     return(Request.CreateResponse(HttpStatusCode.BadRequest));
 }
Esempio n. 7
0
        public async Task <BillingInfo.BillingInvoice> GetUpcomingInvoiceAsync(ISubscriber subscriber)
        {
            if (!string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
            {
                var subscriptionService = new StripeSubscriptionService();
                var invoiceService      = new StripeInvoiceService();
                var sub = await subscriptionService.GetAsync(subscriber.GatewaySubscriptionId);

                if (sub != null)
                {
                    if (!sub.CanceledAt.HasValue && !string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
                    {
                        try
                        {
                            var upcomingInvoice = await invoiceService.UpcomingAsync(subscriber.GatewayCustomerId);

                            if (upcomingInvoice != null)
                            {
                                return(new BillingInfo.BillingInvoice(upcomingInvoice));
                            }
                        }
                        catch (StripeException) { }
                    }
                }
            }
            return(null);
        }
Esempio n. 8
0
        public async Task PreviewUpcomingInvoiceAndPayAsync(ISubscriber subscriber, string planId,
                                                            int prorateThreshold = 500)
        {
            var invoiceService  = new StripeInvoiceService();
            var upcomingPreview = await invoiceService.UpcomingAsync(subscriber.GatewayCustomerId,
                                                                     new StripeUpcomingInvoiceOptions
            {
                SubscriptionId = subscriber.GatewaySubscriptionId
            });

            var prorationAmount = upcomingPreview.StripeInvoiceLineItems?.Data?
                                  .TakeWhile(i => i.Plan.Id == planId && i.Proration).Sum(i => i.Amount);

            if (prorationAmount.GetValueOrDefault() >= prorateThreshold)
            {
                try
                {
                    // Owes more than prorateThreshold on next invoice.
                    // Invoice them and pay now instead of waiting until next month.
                    var invoice = await invoiceService.CreateAsync(subscriber.GatewayCustomerId,
                                                                   new StripeInvoiceCreateOptions
                    {
                        SubscriptionId = subscriber.GatewaySubscriptionId
                    });

                    if (invoice.AmountDue > 0)
                    {
                        await invoiceService.PayAsync(invoice.Id);
                    }
                }
                catch (StripeException) { }
            }
        }
        public IHttpActionResult GetInvoices(string id, string before = null, string after = null, int limit = 12)
        {
            var organization = GetModel(id);

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

            if (String.IsNullOrWhiteSpace(organization.StripeCustomerId))
            {
                return(Ok(new List <InvoiceGridModel>()));
            }

            if (!String.IsNullOrEmpty(before) && !before.StartsWith("in_"))
            {
                before = "in_" + before;
            }

            if (!String.IsNullOrEmpty(after) && !after.StartsWith("in_"))
            {
                after = "in_" + after;
            }

            var invoiceService = new StripeInvoiceService();
            var invoices       = invoiceService.List(new StripeInvoiceListOptions {
                CustomerId = organization.StripeCustomerId, Limit = limit + 1, EndingBefore = before, StartingAfter = after
            }).Select(Mapper.Map <InvoiceGridModel>).ToList();

            return(OkWithResourceLinks(invoices.Take(limit).ToList(), invoices.Count > limit, i => i.Id));
        }
Esempio n. 10
0
        public async Task <bool> CreateInvoiceAsync(Domain.Order order)
        {
            var customer = await getOrCreateCustomer(order);

            var service = new StripeInvoiceItemService();

            foreach (var line in order.OrderLines)
            {
                var createInvoiceLineOptions = new StripeInvoiceItemCreateOptions
                {
                    Amount      = (int)(line.LineTotal * 100m), // inclusive of quantity & tax
                    Currency    = "nok",                        // TODO: read this from config
                    CustomerId  = customer.Id,
                    Description = !string.IsNullOrWhiteSpace(line.ProductVariantName) ? $"{line.ProductName} ({line.ProductVariantName})" : line.ProductName,
                };
                var invoiceLineItem = await service.CreateAsync(createInvoiceLineOptions);
            }

            var eventInfo            = order.Registration.EventInfo;
            var createInvoiceOptions = new StripeInvoiceCreateOptions
            {
                Billing      = StripeBilling.SendInvoice,
                DaysUntilDue = eventInfo.DateStart.HasValue ? ((eventInfo.LastCancellationDate ?? eventInfo.LastRegistrationDate ?? eventInfo.DateStart) - DateTime.UtcNow).Value.Days : 30,
                Description  = $"Deltakelse for {order.Registration.ParticipantName} på {order.Registration.EventInfo.Title} "
            };
            var createInvoiceService = new StripeInvoiceService();
            await createInvoiceService.CreateAsync(customer.Id, createInvoiceOptions);

            return(true);
        }
        public creating_and_updating_invoices_with_manual_invoicing()
        {
            var customerService    = new StripeCustomerService(Cache.ApiKey);
            var invoiceItemService = new StripeInvoiceItemService(Cache.ApiKey);
            var invoiceService     = new StripeInvoiceService(Cache.ApiKey);

            var CustomerCreateOptions = new StripeCustomerCreateOptions
            {
                Email = "*****@*****.**",
            };
            var Customer = customerService.Create(CustomerCreateOptions);

            var InvoiceItemCreateOptions = new StripeInvoiceItemCreateOptions
            {
                Amount     = 1000,
                Currency   = "usd",
                CustomerId = Customer.Id
            };
            var InvoiceItem = invoiceItemService.Create(InvoiceItemCreateOptions);

            var InvoiceCreateOptions = new StripeInvoiceCreateOptions
            {
                Billing      = StripeBilling.SendInvoice,
                DaysUntilDue = 7,
            };

            InvoiceCreated = invoiceService.Create(Customer.Id, InvoiceCreateOptions);

            var InvoiceUpdateOptions = new StripeInvoiceUpdateOptions
            {
                Paid = true,
            };

            InvoiceUpdated = invoiceService.Update(InvoiceCreated.Id, InvoiceUpdateOptions);
        }
Esempio n. 12
0
        Invoice ISubscriptionService.GetUpcomingInvoice(string customerBillingId)
        {
            var           invoiceService = new StripeInvoiceService();
            StripeInvoice response       = null;

            try
            {
                response = invoiceService.Upcoming(customerBillingId);

                return(new Invoice
                {
                    AmountDueInCents = response.AmountDueInCents,
                    AttemptCount = response.AttemptCount,
                    Attempted = response.Attempted,
                    ChargeId = response.ChargeId,
                    Closed = response.Closed,
                    CustomerId = response.CustomerId,
                    Date = response.Date,
                    EndingBalanceInCents = response.EndingBalanceInCents,
                    Id = response.Id,
                    LiveMode = response.LiveMode,
                    NextPaymentAttempt = response.NextPaymentAttempt,
                    Paid = response.Paid,
                    PeriodEnd = response.PeriodEnd,
                    PeriodStart = response.PeriodStart,
                    StartingBalanceInCents = response.StartingBalanceInCents,
                    SubtotalInCents = response.SubtotalInCents,
                    TotalInCents = response.TotalInCents
                });
            }
            catch { }
            return(new Invoice());
        }
Esempio n. 13
0
        public static StripeInvoice GetInvoice(string Id)
        {
            var invoiceSevice = new StripeInvoiceService();

            try
            {
                return(invoiceSevice.Get(Id));
            }
            catch (Exception ex)
            {
                return(null);
            }
        }
Esempio n. 14
0
        public static StripePlan CreatePlan(StripePlanCreateOptions planOptions)
        {
            var invoiceSevice = new StripeInvoiceService();

            try
            {
                var        planService = new StripePlanService();
                StripePlan plan        = planService.Create(planOptions);
                return(plan);
            }
            catch (Exception ex)
            {
                return(null);
            }
        }
        public IEnumerable <StripeInvoice> ListInvoices(int companyId)
        {
            var subscription = GetSubscription(companyId);

            if (subscription.StripeCustomerId != null)
            {
                var invoiceService           = new StripeInvoiceService();
                var stripeInvoiceListOptions = new StripeInvoiceListOptions {
                    CustomerId = subscription.StripeCustomerId
                };

                return(invoiceService.List(stripeInvoiceListOptions));
            }
            return(new List <StripeInvoice>());
        }
Esempio n. 16
0
        public static async Task <string> RequiredInvoice(string subscriptionId)
        {
            StripeConfiguration.SetApiKey("sk_test_5nCTR2UZmnOPWgZASvirbYDy");

            StripeInvoiceService       invoiceService = new StripeInvoiceService();
            StripeList <StripeInvoice> invoiceItems   = await invoiceService.ListAsync(
                new StripeInvoiceListOptions()
            {
                SubscriptionId = subscriptionId
            }
                );

            StripeInvoice value = invoiceItems.First <StripeInvoice>();

            return(value.Id);
        }
Esempio n. 17
0
        public static async Task <string> UpdateInvoice(string invoiceId)
        {
            StripeConfiguration.SetApiKey("sk_test_5nCTR2UZmnOPWgZASvirbYDy");

            StripeInvoiceUpdateOptions invoiceOptions = new StripeInvoiceUpdateOptions()
            {
                Closed = false
            };

            StripeInvoiceService invoiceService = new StripeInvoiceService();
            //"in_1D18zxHWpLOEdy24Tgw0TzEq"
            //             |
            //             V
            StripeInvoice invoice = await invoiceService.UpdateAsync(invoiceId, invoiceOptions);

            return("OK");
        }
Esempio n. 18
0
        public static List <StripeInvoice> GetInvoices(string custId)
        {
            var invoiceSevice = new StripeInvoiceService();

            try
            {
                StripeList <StripeInvoice> invoiceItems = invoiceSevice.List(new StripeInvoiceListOptions()
                {
                    CustomerId = custId,
                    Limit      = 50
                });
                return(invoiceItems.ToList());
            }
            catch (Exception ex)
            {
                return(null);
            }
        }
Esempio n. 19
0
        public static List <StripePlan> GetTopPlan()
        {
            var invoiceSevice = new StripeInvoiceService();

            try
            {
                var planService = new StripePlanService();
                StripeList <StripePlan> planItems = planService.List(new StripeListOptions()
                {
                    Limit = 1,
                }
                                                                     );
                return(planItems.ToList());
            }
            catch (Exception ex)
            {
                return(null);
            }
        }
Esempio n. 20
0
        static void Main(string[] args)
        {
            // Set Stripe Api Key
            StripeConfiguration.SetApiKey(AppConfiguration.StripeApiKey);

            using (var subscriptionBookingRepository = new SubscriptionBookingRepository())
            {
                var subscriptionBookingList = subscriptionBookingRepository.SubscriptionBookingsList.ToList();

                var invoiceService = new StripeInvoiceService();
                var invoiceItems   = invoiceService.List(
                    new StripeInvoiceListOptions
                {
                    Limit = Int32.MaxValue
                }
                    ).ToList();

                invoiceItems.ForEach(invoice =>
                {
                    var subscription = subscriptionBookingList
                                       .FirstOrDefault(sb => sb.StripeSubscriptionId.Equals(invoice.SubscriptionId, StringComparison.OrdinalIgnoreCase));
                    if (subscription == null)
                    {
                        try
                        {
                            var subscriptionService = new StripeSubscriptionService();
                            var stripeSubscription  = subscriptionService.Cancel(invoice.SubscriptionId);
                            Console.WriteLine("Cancel - " + invoice.SubscriptionId);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Error - " + ex.Message);
                        }
                    }
                });

                Console.WriteLine("Done!!!");
                Console.ReadLine();
            }
        }
Esempio n. 21
0
        public async Task <IHttpActionResult> GetInvoicesAsync(string id, string before = null, string after = null, int limit = 12)
        {
            if (!Settings.Current.EnableBilling)
            {
                return(NotFound());
            }

            var organization = await GetModelAsync(id);

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

            if (String.IsNullOrWhiteSpace(organization.StripeCustomerId))
            {
                return(Ok(new List <InvoiceGridModel>()));
            }

            if (!String.IsNullOrEmpty(before) && !before.StartsWith("in_"))
            {
                before = "in_" + before;
            }

            if (!String.IsNullOrEmpty(after) && !after.StartsWith("in_"))
            {
                after = "in_" + after;
            }

            var invoiceService = new StripeInvoiceService(Settings.Current.StripeApiKey);
            var invoiceOptions = new StripeInvoiceListOptions {
                CustomerId = organization.StripeCustomerId, Limit = limit + 1, EndingBefore = before, StartingAfter = after
            };
            var invoices = (await MapCollectionAsync <InvoiceGridModel>(await invoiceService.ListAsync(invoiceOptions), true)).ToList();

            return(OkWithResourceLinks(invoices.Take(limit).ToList(), invoices.Count > limit, i => i.Id));
        }
Esempio n. 22
0
        public PagedResult <InvoiceGridModel> Payments(string id, int page = 1, int pageSize = 12)
        {
            if (String.IsNullOrWhiteSpace(id) || !User.CanAccessOrganization(id))
            {
                throw new HttpResponseException(BadRequestErrorResponseMessage());
            }

            int skip = (page - 1) * pageSize;

            if (skip < 0)
            {
                skip = 0;
            }

            if (pageSize < 1)
            {
                pageSize = 10;
            }

            Organization organization = _repository.GetByIdCached(id);

            if (organization == null || String.IsNullOrWhiteSpace(organization.StripeCustomerId))
            {
                return(new PagedResult <InvoiceGridModel>());
            }

            var invoiceService = new StripeInvoiceService();
            List <InvoiceGridModel> invoices = invoiceService.List(pageSize, skip, organization.StripeCustomerId).Select(Mapper.Map <InvoiceGridModel>).ToList();

            return(new PagedResult <InvoiceGridModel>(invoices)
            {
                Page = page,
                PageSize = pageSize,
                TotalCount = invoices.Count // TODO: Return the total count.
            });
        }
Esempio n. 23
0
        public ActionResult Payment(string id)
        {
            if (String.IsNullOrEmpty(id))
            {
                return(HttpNotFound());
            }

            if (!id.StartsWith("in_"))
            {
                id = "in_" + id;
            }

            var           invoiceService = new StripeInvoiceService();
            StripeInvoice invoice        = invoiceService.Get(id);

            if (invoice == null)
            {
                return(HttpNotFound());
            }

            Organization org = _repository.GetByStripeCustomerId(invoice.CustomerId);

            if (org == null)
            {
                return(HttpNotFound());
            }

            if (!CanAccessOrganization(org.Id))
            {
                return(HttpNotFound());
            }

            return(View(new InvoiceModel {
                Invoice = invoice, Organization = org
            }));
        }
Esempio n. 24
0
        public async Task <IHttpActionResult> GetInvoiceAsync(string id)
        {
            if (!Settings.Current.EnableBilling)
            {
                return(NotFound());
            }

            if (!id.StartsWith("in_"))
            {
                id = "in_" + id;
            }

            StripeInvoice stripeInvoice = null;

            try {
                var invoiceService = new StripeInvoiceService(Settings.Current.StripeApiKey);
                stripeInvoice = await invoiceService.GetAsync(id);
            } catch (Exception ex) {
                _logger.Error().Exception(ex).Message("An error occurred while getting the invoice: " + id).Identity(CurrentUser.EmailAddress).Property("User", CurrentUser).SetActionContext(ActionContext).Write();
            }

            if (String.IsNullOrEmpty(stripeInvoice?.CustomerId))
            {
                return(NotFound());
            }

            var organization = await _repository.GetByStripeCustomerIdAsync(stripeInvoice.CustomerId);

            if (organization == null || !CanAccessOrganization(organization.Id))
            {
                return(NotFound());
            }

            var invoice = new Invoice {
                Id               = stripeInvoice.Id.Substring(3),
                OrganizationId   = organization.Id,
                OrganizationName = organization.Name,
                Date             = stripeInvoice.Date.GetValueOrDefault(),
                Paid             = stripeInvoice.Paid,
                Total            = stripeInvoice.Total / 100.0
            };

            foreach (var line in stripeInvoice.StripeInvoiceLineItems.Data)
            {
                var item = new InvoiceLineItem {
                    Amount = line.Amount / 100.0
                };

                if (line.Plan != null)
                {
                    item.Description = $"Exceptionless - {line.Plan.Name} Plan ({(line.Plan.Amount / 100.0):c}/{line.Plan.Interval})";
                }
                else
                {
                    item.Description = line.Description;
                }

                item.Date = $"{(line.StripePeriod.Start ?? stripeInvoice.PeriodStart).ToShortDateString()} - {(line.StripePeriod.End ?? stripeInvoice.PeriodEnd).ToShortDateString()}";
                invoice.Items.Add(item);
            }

            var coupon = stripeInvoice.StripeDiscount?.StripeCoupon;

            if (coupon != null)
            {
                if (coupon.AmountOff.HasValue)
                {
                    double discountAmount = coupon.AmountOff.GetValueOrDefault() / 100.0;
                    string description    = $"{coupon.Id} ({discountAmount.ToString("C")} off)";
                    invoice.Items.Add(new InvoiceLineItem {
                        Description = description, Amount = discountAmount
                    });
                }
                else
                {
                    double discountAmount = (stripeInvoice.Subtotal / 100.0) * (coupon.PercentOff.GetValueOrDefault() / 100.0);
                    string description    = $"{coupon.Id} ({coupon.PercentOff.GetValueOrDefault()}% off)";
                    invoice.Items.Add(new InvoiceLineItem {
                        Description = description, Amount = discountAmount
                    });
                }
            }

            return(Ok(invoice));
        }
        public IHttpActionResult GetInvoice(string id)
        {
            if (!id.StartsWith("in_"))
            {
                id = "in_" + id;
            }

            var invoiceService = new StripeInvoiceService();
            var stripeInvoice  = invoiceService.Get(id);

            if (stripeInvoice == null || String.IsNullOrEmpty(stripeInvoice.CustomerId))
            {
                return(NotFound());
            }

            var organization = _repository.GetByStripeCustomerId(stripeInvoice.CustomerId);

            if (organization == null || !IsInOrganization(organization.Id))
            {
                return(NotFound());
            }

            var invoice = new Invoice {
                Id               = stripeInvoice.Id.Substring(4),
                OrganizationId   = organization.Id,
                OrganizationName = organization.Name,
                Date             = stripeInvoice.Date.GetValueOrDefault(),
                Paid             = stripeInvoice.Paid.GetValueOrDefault(),
                Total            = stripeInvoice.Total.GetValueOrDefault() / 100.0
            };

            foreach (var line in stripeInvoice.StripeInvoiceLines.StripeInvoiceItems)
            {
                var item = new InvoiceLineItem {
                    Amount = line.Amount.GetValueOrDefault() / 100.0
                };

                if (line.Plan != null)
                {
                    item.Description = String.Format("Exceptionless - {0} Plan ({1}/{2})", line.Plan.Name, (line.Plan.Amount / 100.0).ToString("c"), line.Plan.Interval);
                }
                else
                {
                    item.Description = line.Description;
                }

                if (line.Period.Start.GetValueOrDefault() == line.Period.End.GetValueOrDefault())
                {
                    item.Date = line.Period.Start.GetValueOrDefault().ToShortDateString();
                }
                else
                {
                    item.Date = String.Format("{0} - {1}", line.Period.Start.GetValueOrDefault().ToShortDateString(), line.Period.End.GetValueOrDefault().ToShortDateString());
                }

                invoice.Items.Add(item);
            }

            var coupon = stripeInvoice.StripeDiscount != null ? stripeInvoice.StripeDiscount.StripeCoupon : null;

            if (coupon != null)
            {
                double discountAmount = coupon.AmountOff ?? stripeInvoice.Subtotal.GetValueOrDefault() * (coupon.PercentOff.GetValueOrDefault() / 100.0);
                string description    = String.Format("{0} {1}", coupon.Id, coupon.PercentOff.HasValue ? String.Format("({0}% off)", coupon.PercentOff.Value) : String.Format("({0} off)", (coupon.AmountOff.GetValueOrDefault() / 100.0).ToString("C")));

                invoice.Items.Add(new InvoiceLineItem {
                    Description = description, Amount = discountAmount
                });
            }

            return(Ok(invoice));
        }
Esempio n. 26
0
        public async Task <OrganizationBilling> GetBillingAsync(Organization organization)
        {
            var orgBilling          = new OrganizationBilling();
            var customerService     = new StripeCustomerService();
            var subscriptionService = new StripeSubscriptionService();
            var chargeService       = new StripeChargeService();
            var invoiceService      = new StripeInvoiceService();

            if (!string.IsNullOrWhiteSpace(organization.StripeCustomerId))
            {
                var customer = await customerService.GetAsync(organization.StripeCustomerId);

                if (customer != null)
                {
                    if (!string.IsNullOrWhiteSpace(customer.DefaultSourceId) && customer.Sources?.Data != null)
                    {
                        if (customer.DefaultSourceId.StartsWith("card_"))
                        {
                            orgBilling.PaymentSource =
                                customer.Sources.Data.FirstOrDefault(s => s.Card?.Id == customer.DefaultSourceId);
                        }
                        else if (customer.DefaultSourceId.StartsWith("ba_"))
                        {
                            orgBilling.PaymentSource =
                                customer.Sources.Data.FirstOrDefault(s => s.BankAccount?.Id == customer.DefaultSourceId);
                        }
                    }

                    var charges = await chargeService.ListAsync(new StripeChargeListOptions
                    {
                        CustomerId = customer.Id,
                        Limit      = 20
                    });

                    orgBilling.Charges = charges?.Data?.OrderByDescending(c => c.Created);
                }
            }

            if (!string.IsNullOrWhiteSpace(organization.StripeSubscriptionId))
            {
                var sub = await subscriptionService.GetAsync(organization.StripeSubscriptionId);

                if (sub != null)
                {
                    orgBilling.Subscription = sub;
                }

                if (!sub.CanceledAt.HasValue && !string.IsNullOrWhiteSpace(organization.StripeCustomerId))
                {
                    try
                    {
                        var upcomingInvoice = await invoiceService.UpcomingAsync(organization.StripeCustomerId);

                        if (upcomingInvoice != null)
                        {
                            orgBilling.UpcomingInvoice = upcomingInvoice;
                        }
                    }
                    catch (StripeException) { }
                }
            }

            return(orgBilling);
        }
Esempio n. 27
0
        public async Task AdjustSeatsAsync(Guid organizationId, int seatAdjustment)
        {
            var organization = await _organizationRepository.GetByIdAsync(organizationId);

            if (organization == null)
            {
                throw new NotFoundException();
            }

            if (string.IsNullOrWhiteSpace(organization.StripeCustomerId))
            {
                throw new BadRequestException("No payment method found.");
            }

            if (string.IsNullOrWhiteSpace(organization.StripeSubscriptionId))
            {
                throw new BadRequestException("No subscription found.");
            }

            var plan = StaticStore.Plans.FirstOrDefault(p => p.Type == organization.PlanType);

            if (plan == null)
            {
                throw new BadRequestException("Existing plan not found.");
            }

            if (!plan.CanBuyAdditionalSeats)
            {
                throw new BadRequestException("Plan does not allow additional seats.");
            }

            var newSeatTotal = organization.Seats + seatAdjustment;

            if (plan.BaseSeats > newSeatTotal)
            {
                throw new BadRequestException($"Plan has a minimum of {plan.BaseSeats} seats.");
            }

            var additionalSeats = newSeatTotal - plan.BaseSeats;

            if (plan.MaxAdditionalSeats.HasValue && additionalSeats > plan.MaxAdditionalSeats.Value)
            {
                throw new BadRequestException($"Organization plan allows a maximum of " +
                                              $"{plan.MaxAdditionalSeats.Value} additional seats.");
            }

            if (!organization.Seats.HasValue || organization.Seats.Value > newSeatTotal)
            {
                var userCount = await _organizationUserRepository.GetCountByOrganizationIdAsync(organization.Id);

                if (userCount > newSeatTotal)
                {
                    throw new BadRequestException($"Your organization currently has {userCount} seats filled. Your new plan " +
                                                  $"only has ({newSeatTotal}) seats. Remove some users.");
                }
            }

            var invoiceService          = new StripeInvoiceService();
            var subscriptionItemService = new StripeSubscriptionItemService();
            var subscriptionService     = new StripeSubscriptionService();
            var sub = await subscriptionService.GetAsync(organization.StripeSubscriptionId);

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

            var seatItem = sub.Items?.Data?.FirstOrDefault(i => i.Plan.Id == plan.StripeSeatPlanId);

            if (seatItem == null)
            {
                await subscriptionItemService.CreateAsync(new StripeSubscriptionItemCreateOptions
                {
                    PlanId         = plan.StripeSeatPlanId,
                    Quantity       = additionalSeats,
                    Prorate        = true,
                    SubscriptionId = sub.Id
                });

                await PreviewUpcomingAndPayAsync(invoiceService, organization, plan);
            }
            else if (additionalSeats > 0)
            {
                await subscriptionItemService.UpdateAsync(seatItem.Id, new StripeSubscriptionItemUpdateOptions
                {
                    PlanId   = plan.StripeSeatPlanId,
                    Quantity = additionalSeats,
                    Prorate  = true
                });

                await PreviewUpcomingAndPayAsync(invoiceService, organization, plan);
            }
            else if (additionalSeats == 0)
            {
                await subscriptionItemService.DeleteAsync(seatItem.Id);
            }

            organization.Seats = (short?)newSeatTotal;
            await _organizationRepository.ReplaceAsync(organization);
        }
Esempio n. 28
0
        public async Task <BillingInfo> GetBillingAsync(ISubscriber subscriber)
        {
            var billingInfo         = new BillingInfo();
            var customerService     = new StripeCustomerService();
            var subscriptionService = new StripeSubscriptionService();
            var chargeService       = new StripeChargeService();
            var invoiceService      = new StripeInvoiceService();

            if (!string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
            {
                var customer = await customerService.GetAsync(subscriber.GatewayCustomerId);

                if (customer != null)
                {
                    if (!string.IsNullOrWhiteSpace(customer.DefaultSourceId) && customer.Sources?.Data != null)
                    {
                        if (customer.DefaultSourceId.StartsWith("card_"))
                        {
                            var source = customer.Sources.Data.FirstOrDefault(s => s.Card?.Id == customer.DefaultSourceId);
                            if (source != null)
                            {
                                billingInfo.PaymentSource = new BillingInfo.BillingSource(source);
                            }
                        }
                        else if (customer.DefaultSourceId.StartsWith("ba_"))
                        {
                            var source = customer.Sources.Data
                                         .FirstOrDefault(s => s.BankAccount?.Id == customer.DefaultSourceId);
                            if (source != null)
                            {
                                billingInfo.PaymentSource = new BillingInfo.BillingSource(source);
                            }
                        }
                    }

                    var charges = await chargeService.ListAsync(new StripeChargeListOptions
                    {
                        CustomerId = customer.Id,
                        Limit      = 20
                    });

                    billingInfo.Charges = charges?.Data?.OrderByDescending(c => c.Created)
                                          .Select(c => new BillingInfo.BillingCharge(c));
                }
            }

            if (!string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
            {
                var sub = await subscriptionService.GetAsync(subscriber.GatewaySubscriptionId);

                if (sub != null)
                {
                    billingInfo.Subscription = new BillingInfo.BillingSubscription(sub);
                }

                if (!sub.CanceledAt.HasValue && !string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
                {
                    try
                    {
                        var upcomingInvoice = await invoiceService.UpcomingAsync(subscriber.GatewayCustomerId);

                        if (upcomingInvoice != null)
                        {
                            billingInfo.UpcomingInvoice = new BillingInfo.BillingInvoice(upcomingInvoice);
                        }
                    }
                    catch (StripeException) { }
                }
            }

            return(billingInfo);
        }
        static void Main(string[] args)
        {
            // Set Stripe Api Key
            StripeConfiguration.SetApiKey(AppConfiguration.StripeApiKey);

            using (var subscriptionBookingRepository = new SubscriptionBookingRepository())
            {
                var subscriptionBookingList = subscriptionBookingRepository.SubscriptionBookingsList.ToList();

                // Each Subscription Bookings
                subscriptionBookingList.ForEach(subscriptionBookings =>
                {
                    var customerInfos = subscriptionBookingRepository.CustomerInfoList
                                        .FirstOrDefault(ci => ci.CustomerId == subscriptionBookings.CustomerId);

                    // Customer Infos
                    if (customerInfos != null)
                    {
                        var subscriptionService         = new StripeSubscriptionService();
                        StripeSubscription subscription = subscriptionService.Get(subscriptionBookings.StripeSubscriptionId);
                        DateTime?canceledDate           = subscription.CanceledAt;

                        var invoiceService = new StripeInvoiceService();

                        // All Invoices of Customer
                        var invoiceItems = invoiceService.List(new StripeInvoiceListOptions
                        {
                            CustomerId = customerInfos.StripeCustomerId
                        }
                                                               ).OrderBy(ic => ic.Date).ToList();

                        short cycleNumber = 0;
                        invoiceItems.ForEach(invoice =>
                        {
                            if (invoice.SubscriptionId.Equals(subscriptionBookings.StripeSubscriptionId, StringComparison.InvariantCulture))
                            {
                                cycleNumber++;
                                double totalCharge = (double)invoice.Total / 100;
                                if (!totalCharge.Equals(subscriptionBookings.TotalPrice))
                                {
                                    subscriptionBookings.Price = totalCharge;
                                }

                                DateTime?periodStart = invoice.PeriodStart;
                                DateTime?periodEnd   = invoice.PeriodEnd;
                                try
                                {
                                    if (periodStart.Value.Date == periodEnd.Value.Date)
                                    {
                                        periodEnd = periodEnd.Value.AddDays(30);
                                    }
                                    periodStart = invoice.StripeInvoiceLineItems.Data[0].StripePeriod.Start;
                                    periodEnd   = invoice.StripeInvoiceLineItems.Data[0].StripePeriod.End;
                                }
                                catch (Exception) { }
                                var subscriptionCycle = new SubscriptionCycles
                                {
                                    SubscriptionBookingId = subscriptionBookings.Id,
                                    StartDate             = periodStart,
                                    EndDate         = periodEnd,
                                    CancelDate      = subscriptionBookings.CancelDate,
                                    Status          = subscriptionBookings.Status,
                                    LastUpdatedDate = subscriptionBookings.LastUpdatedDate,
                                    LastUpdatedBy   = subscriptionBookings.LastUpdatedBy,
                                    Price           = totalCharge.Equals(0) && subscriptionBookings.PayByCredit > 0 ? subscriptionBookings.PayByCredit : totalCharge,
                                    MerchantPrice   = subscriptionBookings.MerchantPrice,
                                    PayByCredit     = subscriptionBookings.PayByCredit,
                                    TotalPrice      = totalCharge,
                                    Quantity        = subscriptionBookings.Quantity,
                                    StripeInvoiceId = invoice.Id,
                                    StripeChargeId  = invoice.ChargeId,
                                    StripeCouponId  = subscriptionBookings.StripeCouponId,
                                    CycleNumber     = cycleNumber
                                };

                                var param = new AddSubscriptionCycleParams
                                {
                                    CanceledDate             = canceledDate,
                                    SubscriptionCyclesObject = subscriptionCycle,
                                    SubscriptionInvoices     = new List <SubscriptionInvoices>()
                                };

                                SubscriptionInvoices subscriptionInvoice;

                                // Paid Charge
                                if (invoice.Paid)
                                {
                                    if (!string.IsNullOrEmpty(invoice.ChargeId))
                                    {
                                        var chargeService   = new StripeChargeService();
                                        StripeCharge charge = chargeService.Get(invoice.ChargeId);
                                        subscriptionInvoice = new SubscriptionInvoices
                                        {
                                            SubscriptionCyclesId = subscriptionCycle.Id,
                                            BookingStatus        = subscriptionCycle.Status,
                                            Quantity             = subscriptionBookings.Quantity,
                                            Price              = (double)charge.Amount / 100,
                                            MerchantPrice      = subscriptionBookings.MerchantPrice,
                                            PayByCredit        = subscriptionBookings.PayByCredit,
                                            TotalPrice         = (double)charge.Amount / 100,
                                            InvoiceStatus      = (int)Enums.InvoiceStatus.Charge,
                                            StripeChargeId     = charge.Id,
                                            ChargeAmount       = (double)charge.Amount / 100,
                                            StripeRefundId     = string.Empty,
                                            RefundAmount       = 0,
                                            RefundCreditAmount = 0,
                                            StripeCouponId     = subscriptionBookings.StripeCouponId,
                                            CreatedDate        = DateTime.UtcNow,
                                            CreatedBy          = 1
                                        };

                                        param.SubscriptionInvoices.Add(subscriptionInvoice);

                                        // Charge with Refunded
                                        if (charge.Refunded || charge.AmountRefunded > 0)
                                        {
                                            var refundList = charge.Refunds;
                                            for (int i = 0; i < refundList.Data.Count; i++)
                                            {
                                                var refundItem = charge.Refunds.Data[i];
                                                var subscriptionInvoiceRefunded = new SubscriptionInvoices
                                                {
                                                    SubscriptionCyclesId = subscriptionCycle.Id,
                                                    BookingStatus        = subscriptionCycle.Status,
                                                    Quantity             = subscriptionBookings.Quantity,
                                                    Price = (double)charge.Amount / 100 -
                                                            (double)refundItem.Amount / 100,
                                                    MerchantPrice = subscriptionBookings.MerchantPrice,
                                                    PayByCredit   = subscriptionBookings.PayByCredit,
                                                    TotalPrice    =
                                                        subscriptionBookings.MerchantPrice -
                                                        (double)refundItem.Amount / 100 -
                                                        subscriptionBookings.PayByCredit,
                                                    InvoiceStatus =
                                                        refundItem.Amount < charge.Amount
                                                            ? (int)Enums.InvoiceStatus.PartialRefund
                                                            : (int)Enums.InvoiceStatus.FullRefund,
                                                    StripeChargeId     = charge.Id,
                                                    ChargeAmount       = (double)charge.Amount / 100,
                                                    StripeRefundId     = refundItem.Id,
                                                    RefundAmount       = (double)refundItem.Amount / 100,
                                                    RefundCreditAmount = 0,
                                                    StripeCouponId     = subscriptionBookings.StripeCouponId,
                                                    CreatedDate        = DateTime.UtcNow,
                                                    CreatedBy          = 1
                                                };

                                                param.SubscriptionInvoices.Add(subscriptionInvoiceRefunded);

                                                param.SubscriptionCyclesObject.Price      = subscriptionInvoiceRefunded.Price;
                                                param.SubscriptionCyclesObject.TotalPrice = subscriptionInvoiceRefunded.TotalPrice;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        // Charge but have Coupon and use DayAxe Credit so Amount = 0
                                        subscriptionInvoice = new SubscriptionInvoices
                                        {
                                            SubscriptionCyclesId = subscriptionCycle.Id,
                                            BookingStatus        = subscriptionCycle.Status,
                                            Quantity             = subscriptionBookings.Quantity,
                                            Price              = 0,
                                            MerchantPrice      = subscriptionBookings.MerchantPrice,
                                            PayByCredit        = subscriptionBookings.PayByCredit,
                                            TotalPrice         = 0,
                                            InvoiceStatus      = (int)Enums.InvoiceStatus.Charge,
                                            StripeChargeId     = string.Empty,
                                            ChargeAmount       = 0,
                                            StripeRefundId     = string.Empty,
                                            RefundAmount       = 0,
                                            RefundCreditAmount = 0,
                                            StripeCouponId     = subscriptionBookings.StripeCouponId,
                                            CreatedDate        = DateTime.UtcNow,
                                            CreatedBy          = 1
                                        };

                                        param.SubscriptionInvoices.Add(subscriptionInvoice);
                                    }
                                }
                                else
                                {
                                    // Closed Charge
                                    subscriptionInvoice = new SubscriptionInvoices
                                    {
                                        SubscriptionCyclesId = subscriptionCycle.Id,
                                        BookingStatus        = subscriptionCycle.Status,
                                        Quantity             = subscriptionBookings.Quantity,
                                        Price              = totalCharge,
                                        MerchantPrice      = subscriptionBookings.MerchantPrice,
                                        PayByCredit        = subscriptionBookings.PayByCredit,
                                        TotalPrice         = totalCharge,
                                        InvoiceStatus      = (int)Enums.InvoiceStatus.Charge,
                                        StripeChargeId     = invoice.ChargeId,
                                        ChargeAmount       = totalCharge,
                                        StripeRefundId     = string.Empty,
                                        RefundAmount       = 0,
                                        RefundCreditAmount = 0,
                                        StripeCouponId     = subscriptionBookings.StripeCouponId,
                                        CreatedDate        = DateTime.UtcNow,
                                        CreatedBy          = 1
                                    };

                                    param.SubscriptionInvoices.Add(subscriptionInvoice);
                                }

                                subscriptionBookingRepository.AddSubscriptionCycle(param);

                                Console.WriteLine("Update - " + invoice.SubscriptionId);
                            }
                        });
                    }
                });

                Console.WriteLine("Done!!!");
                Console.ReadLine();
            }
        }
        public IHttpActionResult GetInvoice(string id)
        {
            if (!Settings.Current.EnableBilling)
            {
                return(NotFound());
            }

            if (!id.StartsWith("in_"))
            {
                id = "in_" + id;
            }

            StripeInvoice stripeInvoice = null;

            try {
                var invoiceService = new StripeInvoiceService();
                stripeInvoice = invoiceService.Get(id);
            } catch (Exception ex) {
                Log.Error().Exception(ex).Message("An error occurred while getting the invoice: " + id).Write();
            }

            if (stripeInvoice == null || String.IsNullOrEmpty(stripeInvoice.CustomerId))
            {
                return(NotFound());
            }

            var organization = _repository.GetByStripeCustomerId(stripeInvoice.CustomerId);

            if (organization == null || !IsInOrganization(organization.Id))
            {
                return(NotFound());
            }

            var invoice = new Invoice {
                Id               = stripeInvoice.Id.Substring(3),
                OrganizationId   = organization.Id,
                OrganizationName = organization.Name,
                Date             = stripeInvoice.Date.GetValueOrDefault(),
                Paid             = stripeInvoice.Paid,
                Total            = stripeInvoice.Total / 100.0
            };

            foreach (var line in stripeInvoice.StripeInvoiceLineItems.Data)
            {
                var item = new InvoiceLineItem {
                    Amount = line.Amount / 100.0
                };

                if (line.Plan != null)
                {
                    item.Description = String.Format("Exceptionless - {0} Plan ({1}/{2})", line.Plan.Name, (line.Plan.Amount / 100.0).ToString("c"), line.Plan.Interval);
                }
                else
                {
                    item.Description = line.Description;
                }

                if (stripeInvoice.PeriodStart == stripeInvoice.PeriodEnd)
                {
                    item.Date = stripeInvoice.PeriodStart.ToShortDateString();
                }
                else
                {
                    item.Date = String.Format("{0} - {1}", stripeInvoice.PeriodStart.ToShortDateString(), stripeInvoice.PeriodEnd.ToShortDateString());
                }

                invoice.Items.Add(item);
            }

            var coupon = stripeInvoice.StripeDiscount != null ? stripeInvoice.StripeDiscount.StripeCoupon : null;

            if (coupon != null)
            {
                double discountAmount = coupon.AmountOff ?? stripeInvoice.Subtotal * (coupon.PercentOff.GetValueOrDefault() / 100.0);
                string description    = String.Format("{0} {1}", coupon.Id, coupon.PercentOff.HasValue ? String.Format("({0}% off)", coupon.PercentOff.Value) : String.Format("({0} off)", (coupon.AmountOff.GetValueOrDefault() / 100.0).ToString("C")));

                invoice.Items.Add(new InvoiceLineItem {
                    Description = description, Amount = discountAmount
                });
            }

            return(Ok(invoice));
        }