public RefundResponse Refund(RefundRequest request)
        {
            var refundService = new StripeRefundService();
            var result        = _refundResponseCreator.CreateResponse(refundService.Create(request.ChargeId, _refundRequestCreator.CreateRequest(request)));

            return(result);
        }
Exemplo n.º 2
0
        static void GetChargeRefunds(StripeRefundService refundService, TraceWriter log)
        {
            string lastObjectId = GetLastObjectID();
            StripeList <StripeRefund> refundItems = null;

            //DateTime greaterEqualCreated = DateTime.UtcNow.AddHours(-48);
            //var lesserThanCreatedFilter = GetMinCreatedTime();
            log.Info($"LastObjectId: {lastObjectId}");

            var listOptions = new StripeRefundListOptions()
            {
                Limit         = 100,
                StartingAfter = lastObjectId,
            };

            DateTime?lastRefundCreated = null;

            do
            {
                refundItems = refundService.List(listOptions);
                foreach (var r in refundItems.Data)
                {
                    //log.Info(r.ToString());
                    var Refunds = StripeRefundToStripeTransaction(r);
                    UpsertStripeRefunds(Refunds, log);
                }
                lastObjectId              = refundItems.Data.LastOrDefault()?.Id;
                lastRefundCreated         = refundItems.Data.LastOrDefault()?.Created;
                listOptions.StartingAfter = lastObjectId;
                log.Info($"Refund last ObjectId: {lastObjectId}. Created: {lastRefundCreated} ");
            } while (refundItems.HasMore);
        }
Exemplo n.º 3
0
        public StripeProcessor(ISettingService settingService,
                               ICurrencyService currencyService, ICustomerService customerService,
                               CurrencySettings currencySettings, IWebHelper webHelper,
                               IOrderTotalCalculationService orderTotalCalculationService,
                               IOrderService orderService,
                               StripePaymentSettings stripePaymentSettings,
                               ILocalizationService localizationService,
                               ILogger logger)
        {
            _stripePaymentSettings        = stripePaymentSettings;
            _settingService               = settingService;
            _currencyService              = currencyService;
            _customerService              = customerService;
            _currencySettings             = currencySettings;
            _webHelper                    = webHelper;
            _orderTotalCalculationService = orderTotalCalculationService;
            _orderService                 = orderService;
            _localizationService          = localizationService;
            _logger = logger;

            if (!stripePaymentSettings.IsValid())
            {
                return;
            }

            StripeConfiguration.SetApiKey(stripePaymentSettings.SecretApiKey);
            _chargeService = new StripeChargeService();
            _tokenService  = new StripeTokenService();
            _refundService = new StripeRefundService();

            ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
        }
        static void GetRefundsForLast24Hours(StripeChargeService chargeService, TraceWriter log)
        {
            StripeRefundService refundService = new StripeRefundService();

            refundService.ExpandBalanceTransaction = true;
            refundService.ExpandCharge             = true;

            StripeRefundListOptions refundListOptions = new StripeRefundListOptions()
            {
                Limit = 50
            };

            DateTime greaterEqualCreated = DateTime.UtcNow.AddHours(-24);

            IEnumerable <StripeRefund> refunds;
            string   lastObjectId      = null;
            DateTime?lastRefundCreated = null;

            do
            {
                refunds = refundService.List(refundListOptions);
                foreach (var r in refunds)
                {
                    //var c = chargeService.Get(r.ChargeId);
                    //var trans = StripeChargeToStripeTransaction(c);

                    var trans = StripeRefundToStripeTransaction(r);
                    UpsertStripeTransaction(trans, log);
                }
                lastObjectId      = refunds.LastOrDefault()?.Id;
                lastRefundCreated = refunds.LastOrDefault()?.Created;
                refundListOptions.StartingAfter = lastObjectId;
                log.Info($"Refund last ObjectId: {lastObjectId}. Created: {lastRefundCreated} ");
            } while (refunds.Count() == 10 && lastRefundCreated.HasValue && lastRefundCreated.Value >= greaterEqualCreated);
        }
Exemplo n.º 5
0
        public async Task CancelAndRecoverChargesAsync(ISubscriber subscriber)
        {
            if (!string.IsNullOrWhiteSpace(subscriber.GatewaySubscriptionId))
            {
                var subscriptionService = new StripeSubscriptionService();
                await subscriptionService.CancelAsync(subscriber.GatewaySubscriptionId, false);
            }

            if (string.IsNullOrWhiteSpace(subscriber.GatewayCustomerId))
            {
                return;
            }

            var chargeService = new StripeChargeService();
            var charges       = await chargeService.ListAsync(new StripeChargeListOptions
            {
                CustomerId = subscriber.GatewayCustomerId
            });

            if (charges?.Data != null)
            {
                var refundService = new StripeRefundService();
                foreach (var charge in charges.Data.Where(c => !c.Refunded))
                {
                    await refundService.CreateAsync(charge.Id);
                }
            }

            var customerService = new StripeCustomerService();
            await customerService.DeleteAsync(subscriber.GatewayCustomerId);
        }
 public static string RefundToUser(string chargeId, bool isFullRefund, int specificAmount)
 {
     try
     {
         string stripekey = ConfigurationManager.AppSettings["AdminStripeApiKey"];
         StripeConfiguration.SetApiKey(stripekey);
         StripeRefundCreateOptions refundOptions;
         if (isFullRefund == true)
         {
             refundOptions = new StripeRefundCreateOptions()
             {
                 Reason = StripeRefundReasons.RequestedByCustomer,
                 //RefundApplicationFee = true
             };
         }
         else
         {
             refundOptions = new StripeRefundCreateOptions()
             {
                 Reason = StripeRefundReasons.RequestedByCustomer,
                 //RefundApplicationFee = true,
                 Amount = specificAmount * 100
             };
         }
         var          refundService = new StripeRefundService();
         StripeRefund refund        = refundService.Create(chargeId, refundOptions);
         return(refund.Id);
     }
     catch (Exception ex)
     {
         Common.ExcepLog(ex);
         return(null);
     }
 }
Exemplo n.º 7
0
        public async Task <StripeRefund> RefundChargeAsync(string chargeId, StripeRefundCreateOptions options, string apiKey)
        {
            var refundService = new StripeRefundService(apiKey);
            var refund        = refundService.Create(chargeId, options);

            return(refund);
        }
Exemplo n.º 8
0
        public void Refund(string paymentId, int amount)
        {
            var chargeService = new StripeRefundService();

            new StripeRefundCreateOptions().Amount = amount;
            chargeService.Create(paymentId);
        }
        private StripeRefund CreateStripeRefund(long Amount, string ChargeID)
        {
            var refundOptions = new StripeRefundCreateOptions()
            {
                Amount = (int)Amount,
                Reason = StripeRefundReasons.Unknown
            };

            var refundService = new StripeRefundService();

            return(refundService.Create(ChargeID, refundOptions));
        }
        private StripeRefund CallStripeRefund(string stripeChargeId, double diffPrice)
        {
            var refundService = new StripeRefundService();

            StripeRefund refund = refundService.Create(stripeChargeId, new StripeRefundCreateOptions()
            {
                Amount = Convert.ToInt32(diffPrice * 100),
                Reason = StripeRefundReasons.RequestedByCustomer
            });

            return(refund);
        }
Exemplo n.º 11
0
 public static StripeRefund RefundCharge(string chargeId)
 {
     try
     {
         var          refundService = new StripeRefundService();
         StripeRefund refund        = refundService.Create(chargeId);
         return(refund);
     }
     catch (Exception ex)
     {
         var exp = ex.Message.ToString();
         return(null);
     }
 }
Exemplo n.º 12
0
        public static StripeRefund RefundCharge(string token, int amount)
        {
            // Set your secret key: remember to change this to your live secret key in production
            // See your keys here: https://dashboard.stripe.com/account/apikeys
            StripeConfiguration.SetApiKey(MasterStrings.StripeSecretKey);

            var refundOptions = new StripeRefundCreateOptions()
            {
                Amount = amount,
                Reason = "requested_by_customer"
            };
            var          refundService = new StripeRefundService();
            StripeRefund refund        = refundService.Create(token, refundOptions);

            return(refund);
        }
Exemplo n.º 13
0
        public static void Run([TimerTrigger("0 0 7 * * *")] TimerInfo myTimer, TraceWriter log)
        {
            if (myTimer.IsPastDue)
            {
                log.Info("Timer is running late!");
            }

            log.Info($"C# Timer trigger function executed at: {DateTime.Now}");

            StripeRefundService refundService = new StripeRefundService();

            refundService.ExpandBalanceTransaction        = true;
            refundService.ExpandFailureBalanceTransaction = true;
            refundService.ExpandCharge = true;
            StripeConfiguration.SetApiKey(ConfigurationManager.AppSettings["StripeApiKey"]);

            GetChargeRefunds48hrs(refundService, log);
            //GetChargeRefunds(refundService, log);
        }
Exemplo n.º 14
0
 public RefundService
     (IWorkContext workContext,
     ILogger logger,
     StripeConnectPaymentSettings stripeConnectPaymentSettings,
     IWebHelper webHelper,
     HttpClient httpClient,
     ICustomerEntityService customerEntityService,
     IChargeService chargeService,
     IOrderChargeEntityService chargeEntityService)
 {
     _workContext = workContext;
     _logger      = logger;
     _stripeConnectPaymentSettings = stripeConnectPaymentSettings;
     _webHelper             = webHelper;
     _httpClient            = httpClient;
     _customerEntityService = customerEntityService;
     _chargeService         = chargeService;
     _chargeEntityService   = chargeEntityService;
     _stripeRefundService   = new StripeRefundService(_stripeConnectPaymentSettings.SecretKey);
 }
Exemplo n.º 15
0
        public static List <Transaction> GetDonorBoxTransactions(string apiKey, DateTime startDate, DateTime endDate)
        {
            StripeConfiguration.SetApiKey(apiKey);
            var transactions = new List <Transaction>();

            var balanceClient = new StripeBalanceService();
            var parameters    = new StripeBalanceTransactionListOptions();

            var chargeClient = new StripeChargeService();
            var refundClient = new StripeRefundService();

            parameters.Created = new StripeDateFilter
            {
                GreaterThanOrEqual = startDate,
                LessThanOrEqual    = endDate
            };

            parameters.Limit = 100;

            foreach (var balanceTransaction in balanceClient.List(parameters).Where(t => t.Type != "payout"))
            {
                StripeCharge charge = null;

                if (balanceTransaction.Type == "charge" || balanceTransaction.Type == "payment")
                {
                    charge = chargeClient.Get(balanceTransaction.SourceId);
                }
                else if (balanceTransaction.Type == "refund")
                {
                    var chargeId = refundClient.Get(balanceTransaction.SourceId).ChargeId;
                    charge = chargeClient.Get(chargeId);
                }

                if (charge?.Status == "succeeded")
                {
                    transactions.Add(StripeMapping.MapToTransaction(balanceTransaction, charge));
                }
            }

            return(transactions);
        }
Exemplo n.º 16
0
        public StripeRefundServiceTest()
        {
            this.service = new StripeRefundService();

            this.createOptions = new StripeRefundCreateOptions()
            {
                Amount = 123,
            };

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

            this.listOptions = new StripeRefundListOptions()
            {
                Limit = 1,
            };
        }
Exemplo n.º 17
0
        private void CreateRefund(Transaction t)
        {
            StripeConfiguration.SetApiKey(Settings.StripeApiKey);

            var refundService = new StripeRefundService();

            var refundOptions = new StripeRefundCreateOptions();

            refundOptions.Amount = (int)(t.Amount * 100);

            var refund = refundService.Create(t.PreviousTransactionNumber, refundOptions);

            if (refund.Id.Length > 0)
            {
                t.Result.Succeeded       = true;
                t.Result.ReferenceNumber = refund.Id;
            }
            else
            {
                t.Result.Succeeded               = false;
                t.Result.ResponseCode            = "FAIL";
                t.Result.ResponseCodeDescription = "Stripe Failure";
            }
        }
Exemplo n.º 18
0
        public async Task <Tuple <Organization, OrganizationUser> > SignUpAsync(OrganizationSignup signup)
        {
            var plan = StaticStore.Plans.FirstOrDefault(p => p.Type == signup.Plan && !p.Disabled);

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

            var                customerService     = new StripeCustomerService();
            var                subscriptionService = new StripeSubscriptionService();
            StripeCustomer     customer            = null;
            StripeSubscription subscription        = null;

            if (!plan.CanBuyAdditionalSeats && signup.AdditionalSeats > 0)
            {
                throw new BadRequestException("Plan does not allow additional users.");
            }

            if (plan.CanBuyAdditionalSeats && plan.MaxAdditionalSeats.HasValue &&
                signup.AdditionalSeats > plan.MaxAdditionalSeats.Value)
            {
                throw new BadRequestException($"Selected plan allows a maximum of " +
                                              $"{plan.MaxAdditionalSeats.GetValueOrDefault(0)} additional users.");
            }

            if (plan.Type == PlanType.Free)
            {
                var ownerExistingOrgCount =
                    await _organizationUserRepository.GetCountByFreeOrganizationAdminUserAsync(signup.Owner.Id);

                if (ownerExistingOrgCount > 0)
                {
                    throw new BadRequestException("You can only be an admin of one free organization.");
                }
            }
            else
            {
                customer = await customerService.CreateAsync(new StripeCustomerCreateOptions
                {
                    Description = signup.BusinessName,
                    Email       = signup.BillingEmail,
                    SourceToken = signup.PaymentToken
                });

                var subCreateOptions = new StripeSubscriptionCreateOptions
                {
                    Items = new List <StripeSubscriptionItemOption>
                    {
                        new StripeSubscriptionItemOption
                        {
                            PlanId   = plan.StripePlanId,
                            Quantity = 1
                        }
                    }
                };

                if (signup.AdditionalSeats > 0)
                {
                    subCreateOptions.Items.Add(new StripeSubscriptionItemOption
                    {
                        PlanId   = plan.StripeSeatPlanId,
                        Quantity = signup.AdditionalSeats
                    });
                }

                try
                {
                    subscription = await subscriptionService.CreateAsync(customer.Id, subCreateOptions);
                }
                catch (StripeException)
                {
                    if (customer != null)
                    {
                        await customerService.DeleteAsync(customer.Id);
                    }

                    throw;
                }
            }

            var organization = new Organization
            {
                Name                 = signup.Name,
                BillingEmail         = signup.BillingEmail,
                BusinessName         = signup.BusinessName,
                PlanType             = plan.Type,
                Seats                = (short)(plan.BaseSeats + signup.AdditionalSeats),
                MaxSubvaults         = plan.MaxSubvaults,
                Plan                 = plan.Name,
                StripeCustomerId     = customer?.Id,
                StripeSubscriptionId = subscription?.Id,
                CreationDate         = DateTime.UtcNow,
                RevisionDate         = DateTime.UtcNow
            };

            try
            {
                await _organizationRepository.CreateAsync(organization);

                var orgUser = new OrganizationUser
                {
                    OrganizationId     = organization.Id,
                    UserId             = signup.Owner.Id,
                    Key                = signup.OwnerKey,
                    Type               = OrganizationUserType.Owner,
                    Status             = OrganizationUserStatusType.Confirmed,
                    AccessAllSubvaults = true,
                    CreationDate       = DateTime.UtcNow,
                    RevisionDate       = DateTime.UtcNow
                };

                await _organizationUserRepository.CreateAsync(orgUser);

                // push
                await _pushService.PushSyncOrgKeysAsync(signup.Owner.Id);

                return(new Tuple <Organization, OrganizationUser>(organization, orgUser));
            }
            catch
            {
                if (subscription != null)
                {
                    await subscriptionService.CancelAsync(subscription.Id, false);
                }

                if (customer != null)
                {
                    var chargeService = new StripeChargeService();
                    var charges       = await chargeService.ListAsync(new StripeChargeListOptions { CustomerId = customer.Id });

                    if (charges?.Data != null)
                    {
                        var refundService = new StripeRefundService();
                        foreach (var charge in charges.Data.Where(c => !c.Refunded))
                        {
                            await refundService.CreateAsync(charge.Id);
                        }
                    }

                    await customerService.DeleteAsync(customer.Id);
                }

                if (organization.Id != default(Guid))
                {
                    await _organizationRepository.DeleteAsync(organization);
                }

                throw;
            }
        }
Exemplo n.º 19
0
        public HttpResponseMessage ProcessTransaction(IncomingProcessTransaction model)
        {
            return(ErrorFactory.Handle(() =>
            {
                var userId = User?.Identity?.GetUserId();

                if (string.IsNullOrWhiteSpace(userId))
                {
                    throw new Exception();
                }

                var context = new PoolReservationEntities();

                using (var unitOfWork = new UnitOfWork(context))
                {
                    PrepareAndGetReservationForProcessing_Result reservation = null;

                    try
                    {
                        reservation = context.PrepareAndGetReservationForProcessing(model.ReservationId)?.FirstOrDefault();
                    }
                    catch (Exception)
                    {
                        context.ChangeProcessingStatusToPending(model.ReservationId);
                    }



                    if (reservation == null)
                    {
                        try
                        {
                            context.ChangeProcessingStatusToPending(model.ReservationId);
                        }
                        catch (Exception)
                        {
                        }

                        return JsonFactory.CreateJsonMessage(null, HttpStatusCode.NotFound, this.Request);
                    }

                    if (reservation.StatusId != Convert.ToInt32(ReservationGroupStatusEnum.PROCESSING))
                    {
                        try
                        {
                            context.ChangeProcessingStatusToPending(model.ReservationId);
                        }
                        catch (Exception)
                        {
                        }

                        return JsonFactory.CreateJsonMessage(new OutgoingMessage {
                            Action = "wrongStatus"
                        }, HttpStatusCode.NotFound, this.Request);
                    }

                    ReservationGroup reservationDBObject = null;


                    try
                    {
                        reservationDBObject = unitOfWork.Reservations.GetReservationWithItems(userId, model.ReservationId);

                        if (reservationDBObject == null)
                        {
                            return JsonFactory.CreateJsonMessage(null, HttpStatusCode.NotFound, this.Request);
                        }
                    }
                    catch (Exception)
                    {
                        context.ChangeProcessingStatusToPending(model.ReservationId);
                    }


                    if (reservationDBObject.StatusId != Convert.ToInt32(ReservationGroupStatusEnum.PROCESSING))
                    {
                        try
                        {
                            context.ChangeProcessingStatusToPending(model.ReservationId);
                        }
                        catch (Exception)
                        {
                        }

                        return JsonFactory.CreateJsonMessage(new OutgoingMessage {
                            Action = "wrongStatus"
                        }, HttpStatusCode.NotFound, this.Request);
                    }

                    ReservationTransaction resTransaction = null;
                    int stripeModifiedPriceInCents = 0;
                    try
                    {
                        decimal priceToCharge = 0M;

                        foreach (var item in reservationDBObject.ReserveItems)
                        {
                            if (item.IsDeleted == true)
                            {
                                continue;
                            }

                            priceToCharge += item.FinalPrice;
                        }



                        decimal stripeModifiedPrice = priceToCharge * 100.0M;

                        stripeModifiedPriceInCents = (int)Math.Round(stripeModifiedPrice); //Must Update Repo If Changed.  Rounds to the nearest penny.

                        if (stripeModifiedPriceInCents <= 50)
                        {
                            return JsonFactory.CreateJsonMessage(new OutgoingMessage {
                                Action = "noPriceToCharge"
                            }, HttpStatusCode.NotFound, this.Request);
                        }

                        resTransaction = unitOfWork.Reservations.AddStripeChargeToPendingReservation(userId, userId, model.ReservationId, model.StripeTokenId, priceToCharge);

                        unitOfWork.Complete();
                    }
                    catch (Exception e)
                    {
                        context.ChangeProcessingStatusToPending(model.ReservationId);
                    }



                    string chargeId = null;
                    try
                    {
                        if (resTransaction == null)
                        {
                            throw new Exception();
                        }

                        var myCharge = new StripeChargeCreateOptions();

                        // always set these properties
                        myCharge.Amount = stripeModifiedPriceInCents;
                        myCharge.Currency = "usd";

                        // set this if you want to
                        myCharge.Description = "JustMosey Reservation";

                        myCharge.SourceTokenOrExistingSourceId = model.StripeTokenId;

                        // (not required) set this to false if you don't want to capture the charge yet - requires you call capture later
                        myCharge.Capture = true;

                        var chargeService = new StripeChargeService();
                        StripeCharge stripeCharge = chargeService.Create(myCharge);

                        chargeId = stripeCharge.Id;

                        unitOfWork.Reservations.UpdateStripeSuccessfulChargeOnPendingReservation(userId, userId, resTransaction.Id, chargeId);

                        unitOfWork.Complete();
                    }
                    catch (Exception e)
                    {
                        try
                        {
                            var refundService = new StripeRefundService();

                            StripeRefund refund = refundService.Create(chargeId, new StripeRefundCreateOptions()
                            {
                                Amount = stripeModifiedPriceInCents,
                                Reason = StripeRefundReasons.Unknown
                            });
                        }
                        catch (Exception)
                        {
                        }

                        try
                        {
                            unitOfWork.Reservations.RefundStripeSuccessfulChargeOnPendingReservation(userId, userId, resTransaction.Id);
                            unitOfWork.Complete();
                        }
                        catch (Exception)
                        {
                        }

                        try
                        {
                        }
                        catch (Exception)
                        {
                            context.ChangeProcessingStatusToPending(model.ReservationId);
                        }

                        return JsonFactory.CreateJsonMessage(new OutgoingMessage {
                            Action = "unknownErrorAfterProcessing"
                        }, HttpStatusCode.InternalServerError, this.Request);
                    }

                    try
                    {
                        var updatedReservationDBObject = unitOfWork.Reservations.GetReservationWithItems(userId, model.ReservationId);

                        var outgoingRes = OutgoingReservationGroup.Parse(updatedReservationDBObject);

                        return JsonFactory.CreateJsonMessage(outgoingRes, HttpStatusCode.OK, this.Request);
                    }
                    catch (Exception)
                    {
                        return JsonFactory.CreateJsonMessage(null, HttpStatusCode.OK, this.Request);
                    }
                }
            }, this.Request));
        }
        public int Add(AddSubscriptionBookingParams param)
        {
            try
            {
                using (var transaction = new TransactionScope())
                {
                    var bookingCode = Helper.RandomString(Constant.BookingCodeLength);
                    while (IsBookingCodeExists(bookingCode))
                    {
                        bookingCode = Helper.RandomString(Constant.BookingCodeLength);
                    }
                    param.SubscriptionBookingsObject.BookingCode = bookingCode;

                    // Insert New Bookings
                    DayaxeDbContext.SubscriptionBookings.InsertOnSubmit(param.SubscriptionBookingsObject);
                    Commit();

                    if (param.SubscriptionBookingDiscounts != null && param.SubscriptionBookingDiscounts.Id > 0)
                    {
                        var subscriptionDiscount = new SubscriptionBookingDiscounts
                        {
                            DiscountId            = param.SubscriptionBookingDiscounts.Id,
                            SubscriptionBookingId = param.SubscriptionBookingsObject.Id,
                            SubscriptionId        = param.SubscriptionBookingsObject.SubscriptionId
                        };

                        DayaxeDbContext.SubscriptionBookingDiscounts.InsertOnSubmit(subscriptionDiscount);
                    }

                    // Insert to History for First Cycle
                    var cycle = new SubscriptionCycles
                    {
                        SubscriptionBookingId = param.SubscriptionBookingsObject.Id,
                        StartDate             = param.SubscriptionBookingsObject.StartDate,
                        EndDate         = param.SubscriptionBookingsObject.EndDate,
                        CancelDate      = param.SubscriptionBookingsObject.CancelDate,
                        LastUpdatedBy   = param.SubscriptionBookingsObject.LastUpdatedBy,
                        LastUpdatedDate = param.SubscriptionBookingsObject.LastUpdatedDate,
                        Status          = param.SubscriptionBookingsObject.Status,
                        Price           = param.ActualPrice,
                        MerchantPrice   = param.MerchantPrice,
                        PayByCredit     = param.PayByCredit,
                        TotalPrice      = param.TotalPrice,
                        Quantity        = param.SubscriptionBookingsObject.Quantity,
                        StripeChargeId  = string.Empty,
                        StripeCouponId  = param.SubscriptionBookingsObject.StripeCouponId,
                        StripeInvoiceId = string.Empty,
                        CycleNumber     = 1
                    };

                    DayaxeDbContext.SubscriptionCycles.InsertOnSubmit(cycle);

                    // Insert Discount for Current Customer active Subscription
                    var discount = new Discounts
                    {
                        DiscountName = string.Format("{0} - {1} {2}",
                                                     param.SubscriptionName,
                                                     param.FirstName,
                                                     param.LastName),
                        Code          = string.Format("SUP{0}", Helper.RandomString(8)),
                        StartDate     = param.SubscriptionBookingsObject.StartDate,
                        EndDate       = param.SubscriptionBookingsObject.EndDate,
                        CodeRequired  = true,
                        PercentOff    = 100,
                        PromoType     = (byte)Enums.PromoType.SubscriptionPromo,
                        MinAmount     = 0,
                        IsAllProducts = true,
                        MaxPurchases  = (byte)param.MaxPurchases
                    };
                    DayaxeDbContext.Discounts.InsertOnSubmit(discount);
                    Commit();

                    // Add Invoices
                    var subscriptionInvoice = new SubscriptionInvoices
                    {
                        SubscriptionCyclesId = cycle.Id,
                        BookingStatus        = cycle.Status,
                        Quantity             = cycle.Quantity,
                        Price              = cycle.Price,
                        MerchantPrice      = cycle.MerchantPrice,
                        PayByCredit        = cycle.PayByCredit,
                        TotalPrice         = cycle.TotalPrice,
                        InvoiceStatus      = (int)Enums.InvoiceStatus.Charge,
                        StripeChargeId     = cycle.StripeChargeId,
                        ChargeAmount       = cycle.Price,
                        StripeRefundId     = string.Empty,
                        RefundAmount       = 0,
                        RefundCreditAmount = 0,
                        StripeCouponId     = cycle.StripeCouponId,
                        CreatedDate        = DateTime.UtcNow,
                        CreatedBy          = 1
                    };
                    DayaxeDbContext.SubscriptionInvoices.InsertOnSubmit(subscriptionInvoice);

                    var discountUsed = new SubsciptionDiscountUseds
                    {
                        CustomerId            = param.SubscriptionBookingsObject.CustomerId,
                        DiscountId            = discount.Id,
                        SubscriptionBookingId = param.SubscriptionBookingsObject.Id
                    };
                    DayaxeDbContext.SubsciptionDiscountUseds.InsertOnSubmit(discountUsed);

                    var cusCredits = DayaxeDbContext.CustomerCredits
                                     .SingleOrDefault(cc => cc.CustomerId == param.CustomerCreditsObject.CustomerId);

                    // Add Logs when refund by Upgrade to Subscription
                    if (param.RefundCreditByUpgrade > 0)
                    {
                        var creditLogs = new CustomerCreditLogs
                        {
                            Amount                = param.RefundCreditByUpgrade,
                            ProductId             = 0,
                            BookingId             = 0,
                            SubscriptionId        = param.SubscriptionBookingsObject.SubscriptionId,
                            CreatedBy             = param.CustomerCreditsObject.CustomerId,
                            CreatedDate           = DateTime.UtcNow,
                            CreditType            = (byte)Enums.CreditType.PartialPuchaseRefund,
                            Description           = param.RefundCreditDescription,
                            CustomerId            = param.CustomerCreditsObject.CustomerId,
                            ReferralId            = param.CustomerCreditsObject.ReferralCustomerId,
                            SubscriptionBookingId = param.SubscriptionBookingsObject.Id,
                            Status                = true,
                            GiftCardId            = 0
                        };

                        DayaxeDbContext.CustomerCreditLogs.InsertOnSubmit(creditLogs);

                        if (cusCredits != null)
                        {
                            cusCredits.Amount += param.RefundCreditByUpgrade;
                        }
                    }

                    // Add Logs when pay by DayAxe Credit
                    if (param.PayByCredit > 0)
                    {
                        var creditLogs = new CustomerCreditLogs
                        {
                            Amount                = param.PayByCredit,
                            ProductId             = 0,
                            BookingId             = 0,
                            SubscriptionId        = param.SubscriptionBookingsObject.SubscriptionId,
                            CreatedBy             = param.CustomerCreditsObject.CustomerId,
                            CreatedDate           = DateTime.UtcNow,
                            CreditType            = (byte)Enums.CreditType.Charge,
                            Description           = param.Description,
                            CustomerId            = param.CustomerCreditsObject.CustomerId,
                            ReferralId            = param.CustomerCreditsObject.ReferralCustomerId,
                            SubscriptionBookingId = param.SubscriptionBookingsObject.Id,
                            Status                = true,
                            GiftCardId            = 0
                        };

                        DayaxeDbContext.CustomerCreditLogs.InsertOnSubmit(creditLogs);

                        if (cusCredits != null)
                        {
                            cusCredits.Amount -= param.PayByCredit;
                        }
                    }

                    // First Buy of referral
                    if (param.CustomerCreditsObject != null && param.CustomerCreditsObject.ReferralCustomerId > 0 && (
                            DayaxeDbContext.Bookings.Count(x => x.CustomerId == param.SubscriptionBookingsObject.CustomerId) == 1 ||
                            DayaxeDbContext.SubscriptionBookings.Count(x => x.CustomerId == param.SubscriptionBookingsObject.CustomerId) == 1))
                    {
                        var logs = DayaxeDbContext.CustomerCreditLogs
                                   .Where(ccl => ccl.CustomerId == param.CustomerCreditsObject.ReferralCustomerId &&
                                          ccl.ReferralId == param.SubscriptionBookingsObject.CustomerId &&
                                          !ccl.Status)
                                   .ToList();

                        if (logs.Any())
                        {
                            logs.ForEach(log =>
                            {
                                var cus = DayaxeDbContext.CustomerCredits
                                          .FirstOrDefault(cc => cc.CustomerId == log.CustomerId);
                                if (cus != null)
                                {
                                    cus.Amount += log.Amount;
                                }

                                log.Status = true;
                            });
                            Commit();
                        }
                    }

                    // Add to Customer Credit Log
                    var logsReferred = DayaxeDbContext.CustomerCreditLogs
                                       .Where(ccl => ccl.ReferralId == param.SubscriptionBookingsObject.CustomerId && !ccl.Status)
                                       .ToList();
                    if (logsReferred.Any())
                    {
                        logsReferred.ForEach(log =>
                        {
                            var cus = DayaxeDbContext.CustomerCredits
                                      .FirstOrDefault(cc => cc.CustomerId == log.CustomerId);
                            if (cus != null)
                            {
                                cus.Amount += log.Amount;
                            }

                            log.Status = true;
                        });
                    }

                    // Insert Schedule
                    var schedules = new Schedules
                    {
                        ScheduleSendType      = (int)Enums.ScheduleSendType.IsEmailConfirmSubscription,
                        Name                  = "Send Email confirm Subscription",
                        Status                = (int)Enums.ScheduleType.NotRun,
                        SubscriptionBookingId = param.SubscriptionBookingsObject.Id
                    };
                    DayaxeDbContext.Schedules.InsertOnSubmit(schedules);

                    // Maybe not use here because flow upgrade to subscription do not use this
                    if (param.BookingId > 0)
                    {
                        var bookings = DayaxeDbContext.Bookings.FirstOrDefault(b => b.BookingId == param.BookingId);
                        if (bookings != null)
                        {
                            var chargePrice = (int)((bookings.TotalPrice - bookings.HotelPrice) * 100);
                            try
                            {
                                bookings.TotalPrice -= bookings.HotelPrice;
                                bookings.PassStatus  = (int)Enums.BookingStatus.Active;

                                var discounts = new DiscountBookings
                                {
                                    DiscountId = discount.Id,
                                    ProductId  = bookings.ProductId,
                                    BookingId  = bookings.BookingId
                                };

                                DayaxeDbContext.DiscountBookings.InsertOnSubmit(discounts);
                                bookings.IsActiveSubscription = true;

                                string responseString;
                                if (chargePrice > 0)
                                {
                                    var          chargeService = new StripeChargeService();
                                    StripeCharge charge        = chargeService.Capture(bookings.StripeChargeId, chargePrice);
                                    responseString = charge.StripeResponse.ResponseJson;
                                }
                                else
                                {
                                    var refundOptions = new StripeRefundCreateOptions
                                    {
                                        Reason = StripeRefundReasons.RequestedByCustomer
                                    };
                                    var          refundService = new StripeRefundService();
                                    StripeRefund refund        = refundService.Create(bookings.StripeChargeId, refundOptions);
                                    responseString = refund.StripeResponse.ResponseJson;
                                }

                                var logs = new Logs
                                {
                                    LogKey         = "UpgradeSubscriptionCharge",
                                    UpdatedContent = string.Format("Params: {0} - Response: {1}",
                                                                   JsonConvert.SerializeObject(param, CustomSettings.SerializerSettings()),
                                                                   responseString),
                                    UpdatedBy   = param.SubscriptionBookingsObject.CustomerId,
                                    UpdatedDate = DateTime.UtcNow
                                };
                                AddLog(logs);
                            }
                            catch (Exception ex)
                            {
                                var logs = new Logs
                                {
                                    LogKey         = "UpgradeSubscriptionChargeError",
                                    UpdatedContent = string.Format("Params: {0} - {1} - {2} - {3}",
                                                                   JsonConvert.SerializeObject(param, CustomSettings.SerializerSettings()),
                                                                   ex.Message,
                                                                   ex.StackTrace,
                                                                   ex.Source),
                                    UpdatedBy   = param.SubscriptionBookingsObject.CustomerId,
                                    UpdatedDate = DateTime.UtcNow
                                };
                                AddLog(logs);
                            }
                        }
                    }

                    Commit();

                    transaction.Complete();
                }
            }
            catch (Exception ex)
            {
                var logs = new Logs
                {
                    LogKey         = "AddBookingError",
                    UpdatedContent = string.Format("{0} - {1} - {2} - {3}", param.SubscriptionBookingsObject.CustomerId, ex.Message, ex.StackTrace, ex.Source),
                    UpdatedBy      = param.SubscriptionBookingsObject.CustomerId,
                    UpdatedDate    = DateTime.UtcNow
                };
                AddLog(logs);

                throw new Exception(ex.Message, ex);
            }

            return(param.SubscriptionBookingsObject.Id);
        }