public async Task <PaymentGatewayResult <IPaymentSubscription> > UpdateSubscriptionAsync(string planId, ChargeType type,
                                                                                                 string subscriptionId, string?coupon)
        {
            try
            {
                var subscription = await _subscriptionService.GetAsync(subscriptionId);

                if (subscription == null)
                {
                    throw new StripeException("Subscription Not Found")
                          {
                              HttpStatusCode = HttpStatusCode.NotFound
                          }
                }
                ;
                var opt = new SubscriptionUpdateOptions
                {
                    CancelAtPeriodEnd = false,
                    Items             = new List <SubscriptionItemUpdateOption> {
                        new SubscriptionItemUpdateOption {
                            Id     = subscription.Items.Data.FirstOrDefault()?.Id,
                            PlanId = planId
                        },
                    },
                    CouponId         = coupon,
                    Prorate          = true,
                    ProrationDate    = DateTime.UtcNow,
                    CollectionMethod = _chargeTypes[(int)type],
                };
                if (type == ChargeType.Manual)
                {
                    opt.DaysUntilDue = _appSettings.Stripe.InvoiceDueDays;
                }

                subscription = await _subscriptionService.UpdateAsync(subscription.Id, opt);

                return(PaymentGatewayResult <IPaymentSubscription> .Success(_mapper.Map <IPaymentSubscription>(subscription)));
            }
            catch (StripeException e)
            {
                return(PaymentGatewayResult <IPaymentSubscription> .Failed(e));
            }
        }
        public async Task <PaymentGatewayResult <IPaymentCoupon> > DeleteCouponAsync(string id)
        {
            try
            {
                var coupon = await _couponService.GetAsync(id);

                if (coupon == null)
                {
                    throw new Exception("Coupon not found");
                }
                coupon = await _couponService.DeleteAsync(id);

                return(PaymentGatewayResult <IPaymentCoupon> .Success(_mapper.Map <IPaymentCoupon>(coupon)));
            }
            catch (StripeException e)
            {
                return(PaymentGatewayResult <IPaymentCoupon> .Failed(e));
            }
        }
        public async Task <PaymentGatewayResult <IPaymentInvoice> > GetLatestInvoiceBySubscription(string subscriptionId, string customerId)
        {
            try
            {
                var prorationDate = DateTimeOffset.UtcNow;
                var options       = new InvoiceListOptions
                {
                    CustomerId     = customerId,
                    SubscriptionId = subscriptionId,
                };
                var invoices = await _invoiceService.ListAsync(options);

                var inv = invoices.Data.OrderByDescending(x => x.Created);
                return(PaymentGatewayResult <IPaymentInvoice> .Success(
                           _mapper.Map <IPaymentInvoice>(inv.FirstOrDefault())));
            }
            catch (StripeException e)
            {
                return(PaymentGatewayResult <IPaymentInvoice> .Failed(e));
            }
        }
        public async Task <PaymentGatewayResult <IPaymentCoupon> > GetCouponByIdAsync(string id)
        {
            try
            {
                var coupon = await _couponService.GetAsync(id);

                if (coupon.PercentOff != null)
                {
                    if (coupon.Duration == "once")
                    {
                        if (coupon.DurationInMonths == 1)
                        {
                            coupon.Object = coupon.PercentOff + "% off " + coupon.Duration + " for " + coupon.DurationInMonths + " month";
                        }
                        else
                        {
                            coupon.Object = coupon.PercentOff + "% off " + coupon.Duration + " for " + coupon.DurationInMonths + " months";
                        }
                    }
                    else if (coupon.Duration == "forever")
                    {
                        coupon.Object = coupon.PercentOff + "% off " + coupon.Duration;
                    }

                    else if (coupon.Duration == "repeating")
                    {
                        if (coupon.DurationInMonths == 1)
                        {
                            coupon.Object = coupon.PercentOff + "% off every Year for 1 month";
                        }
                        else
                        {
                            coupon.Object = coupon.PercentOff + "% off every Year for " + coupon.DurationInMonths + " months";
                        }
                    }
                }

                if (coupon.AmountOff != null)
                {
                    coupon.AmountOff = coupon.AmountOff / 100;
                    if (coupon.Duration == "once")
                    {
                        coupon.Object = "$" + coupon.AmountOff + " off once";
                    }

                    else if (coupon.Duration == "forever")
                    {
                        coupon.Object = "$" + coupon.AmountOff + " off " + coupon.Duration;
                    }

                    else if (coupon.Duration == "repeating")
                    {
                        if (coupon.DurationInMonths == 1)
                        {
                            coupon.Object = coupon.Currency.ToUpper() + coupon.AmountOff + " off every Year for 1 month";
                        }
                        else
                        {
                            coupon.Object = "$" + coupon.AmountOff + " off every Year for " + coupon.DurationInMonths + " months";
                        }
                    }
                }
                return(PaymentGatewayResult <IPaymentCoupon> .Success(_mapper.Map <IPaymentCoupon>(coupon)));
            }
            catch (StripeException e)
            {
                return(PaymentGatewayResult <IPaymentCoupon> .Failed(e));
            }
        }
        public async Task <PaymentGatewayResult <IPaymentCoupon> > CreateCouponAsync(CreateCouponViewModel model)
        {
            try
            {
                var options = new CouponCreateOptions();

                if (model.Duration != "repeating")
                {
                    model.DurationInMonths = null;
                }

                model.Currency       = "usd";
                model.MaxRedemptions = model.MaxRedemptions > 0 ? model.MaxRedemptions : null;
                model.PercentOff     = model.PercentOff > 0 ? model.PercentOff : null;
                model.AmountOff      = model.AmountOff > 0 ? model.AmountOff * 100 : null;

                options = _mapper.Map <CouponCreateOptions>(model);

                var coupon = await _couponService.CreateAsync(options);

                if (coupon.PercentOff != null)
                {
                    if (coupon.Duration == "once")
                    {
                        coupon.Object = coupon.PercentOff + "% off " + coupon.Duration;
                    }
                    else if (coupon.Duration == "forever")
                    {
                        coupon.Object = coupon.PercentOff + "% off " + coupon.Duration;
                    }

                    else if (coupon.Duration == "repeating")
                    {
                        if (coupon.DurationInMonths == 1)
                        {
                            coupon.Object = coupon.PercentOff + "% off every Year for 1 month";
                        }
                        else
                        {
                            coupon.Object = coupon.PercentOff + "% off every Year for " + coupon.DurationInMonths + " months";
                        }
                    }
                }

                if (coupon.AmountOff != null)
                {
                    if (coupon.Duration == "once")
                    {
                        coupon.Object = "$" + coupon.AmountOff + " off once";
                    }

                    else if (coupon.Duration == "forever")
                    {
                        coupon.Object = "$" + coupon.AmountOff + " off " + coupon.Duration;
                    }

                    else if (coupon.Duration == "repeating")
                    {
                        if (coupon.DurationInMonths == 1)
                        {
                            coupon.Object = coupon.Currency.ToUpper() + coupon.AmountOff + " off every Year for 1 month";
                        }
                        else
                        {
                            coupon.Object = "$" + coupon.AmountOff + " off every Year for " + coupon.DurationInMonths + " months";
                        }
                    }
                }
                return(PaymentGatewayResult <IPaymentCoupon> .Success(_mapper.Map <IPaymentCoupon>(coupon)));
            }
            catch (StripeException e)
            {
                return(PaymentGatewayResult <IPaymentCoupon> .Failed(e));
            }
        }
        public async Task <PaymentGatewayResult <List <IPaymentCoupon> > > GetAllCouponsAsync()
        {
            try
            {
                var options = new CouponListOptions
                {
                    Limit = 100,
                };
                var coupons = await _couponService.ListAsync(options);

                foreach (var item in coupons.Data)
                {
                    if (item.PercentOff != null)
                    {
                        if (item.Duration == "once")
                        {
                            item.Object = item.PercentOff + "% off " + item.Duration;
                        }
                        else if (item.Duration == "forever")
                        {
                            item.Object = item.PercentOff + "% off " + item.Duration;
                        }

                        else if (item.Duration == "repeating")
                        {
                            if (item.DurationInMonths == 1)
                            {
                                item.Object = item.PercentOff + "% off every Year for 1 month";
                            }
                            else
                            {
                                item.Object = item.PercentOff + "% off every Year for " + item.DurationInMonths + " months";
                            }
                        }
                    }

                    if (item.AmountOff != null)
                    {
                        item.AmountOff = item.AmountOff / 100;
                        if (item.Duration == "once")
                        {
                            item.Object = "$" + item.AmountOff + " off once";
                        }

                        else if (item.Duration == "forever")
                        {
                            item.Object = "$" + item.AmountOff + " off " + item.Duration;
                        }

                        else if (item.Duration == "repeating")
                        {
                            if (item.DurationInMonths == 1)
                            {
                                item.Object = "$" + item.AmountOff + " off every Year for 1 month";
                            }
                            else
                            {
                                item.Object = "$" + item.AmountOff + " off every Year for " + item.DurationInMonths + " months";
                            }
                        }
                    }
                }
                return(PaymentGatewayResult <List <IPaymentCoupon> > .Success(_mapper.Map <List <IPaymentCoupon> >(coupons)));
            }
            catch (StripeException e)
            {
                return(PaymentGatewayResult <List <IPaymentCoupon> > .Failed(e));
            }
        }