Beispiel #1
0
        private List <SessionLineItemOptions> CreateRecharge(int userId, decimal Amount)
        {
            List <SessionLineItemOptions>              Items       = new List <SessionLineItemOptions>();
            SessionLineItemOptions                     ItemOptions = new SessionLineItemOptions();
            SessionLineItemPriceDataOptions            priceData   = new SessionLineItemPriceDataOptions();
            SessionLineItemPriceDataProductDataOptions prdData     = new SessionLineItemPriceDataProductDataOptions();

            prdData.Name   = "Customer Recharge Wallet | " + userId;
            prdData.Images = new List <string>()
            {
                "https://valhallaplanet.art/img/Logo.png"
            };
            prdData.Description = "Valhallaplanet User Wallet Recharge";

            priceData.ProductData       = prdData;
            priceData.Currency          = "eur";
            priceData.UnitAmountDecimal = Amount * 100;


            ItemOptions.Quantity  = 1;
            ItemOptions.PriceData = priceData;

            Items.Add(ItemOptions);

            return(Items);
        }
Beispiel #2
0
        public void Purchase()
        {
            if (Session["payment_amt"] != null)
            {
                try
                {
                    List <SessionLineItemOptions> cartList = new List <SessionLineItemOptions>();
                    using (fashionUtilityApplication.Logic.ShoppingCartActions usersShoppingCart = new fashionUtilityApplication.Logic.ShoppingCartActions())
                    {
                        List <CartItem> myOrderList = usersShoppingCart.GetCartItems();

                        // Add OrderDetail information to the DB for each product purchased.
                        for (int i = 0; i < myOrderList.Count; i++)
                        {
                            long convertValue = 100;
                            var  item         = new SessionLineItemOptions();
                            item.Name        = myOrderList[i].Product.ProductName;
                            item.Amount      = (long)myOrderList[i].Product.UnitPrice * convertValue;
                            item.Currency    = "cad";
                            item.Quantity    = myOrderList[i].Quantity;
                            item.Description = myOrderList[i].Product.Description;
                            cartList.Add(item);
                        }
                    }

                    string amt = Session["payment_amt"].ToString();
                    StripeConfiguration.ApiKey = System.Configuration.ConfigurationManager.AppSettings["stripeSecretKeyTest"];
                    var options = new SessionCreateOptions
                    {
                        SuccessUrl = "https://fashionutilityapplication.azurewebsites.net/Checkout/CheckoutComplete.aspx",
                        CancelUrl  = "https://fashionutilityapplication.azurewebsites.net/Checkout/CheckoutCancel.aspx",

                        PaymentMethodTypes = new List <string> {
                            "card",
                        },
                        LineItems = cartList
                    };

                    var     service = new SessionService();
                    Session session = service.Create(options);
                    sessionId        = session.Id;
                    Session["token"] = sessionId;
                    Session["userCheckoutCompleted"] = "true";
                }
                catch (Exception e)
                {
                    Response.Redirect("CheckoutError.aspx?");
                }
            }
            else
            {
                Response.Redirect("CheckoutError.aspx?ErrorCode=AmtMissing");
            }
        }
Beispiel #3
0
        private List <SessionLineItemOptions> AddProducts(BasketModel basket, decimal wallet, Barayand.DAL.Interfaces.IWalletHistoryRepository _walletrepository, int user)
        {
            List <SessionLineItemOptions> Items = new List <SessionLineItemOptions>();

            var     shippingCost = (basket.CartItems.Count > 0) ? basket.ShippingCost / basket.TotalQuantity() : basket.ShippingCost;
            decimal WALLET       = wallet;
            decimal USEDWALLET   = 0;

            foreach (var item in basket.CartItems)
            {
                SessionLineItemOptions                     ItemOptions = new SessionLineItemOptions();
                SessionLineItemPriceDataOptions            priceData   = new SessionLineItemPriceDataOptions();
                SessionLineItemPriceDataProductDataOptions prdData     = new SessionLineItemPriceDataProductDataOptions();

                prdData.Name   = item.Product.P_Code + "|" + item.Product.P_Title;
                prdData.Images = new List <string>()
                {
                    Barayand.Common.Services.UtilesService.MediaUrls("ProductMainImage") + item.Product.P_Image
                };
                //prdData.Description = (!string.IsNullOrEmpty(item.Product.P_Description)) ? Regex.Replace(item.Product.P_Description, "<.*?>", String.Empty) : "Valhallaplanet Product";

                //priceData.ProductData = prdData;
                //priceData.Currency = "eur";
                //priceData.UnitAmountDecimal = item.Product.FinalPrice(basket.SumDiscount(), shippingCost) * 100;
                //decimal TotalUnit = item.Product.FinalPrice(basket.SumDiscount(), shippingCost);
                if (WALLET > 0)
                {
                    //if (TotalUnit <= WALLET)
                    //{
                    //    priceData.UnitAmountDecimal = 0;
                    //    USEDWALLET +=  TotalUnit;
                    //    WALLET = WALLET - TotalUnit;
                    //}
                    //else
                    //{
                    //    USEDWALLET += WALLET;
                    //    priceData.UnitAmountDecimal = ((priceData.UnitAmountDecimal / 100) - WALLET) * 100;
                    //}
                }

                ItemOptions.Quantity  = item.Quantity;
                ItemOptions.PriceData = priceData;

                Items.Add(ItemOptions);
            }
            if (USEDWALLET > 0)
            {
                _walletrepository.DecreaseWallet(user, USEDWALLET);
            }
            return(Items);
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            HttpCookie cookie = Request.Cookies["user_id"];//getting the user_id

            Process_Executor exec = new Process_Executor();

            if (cookie != null)
            {
                List <CART_INFO_SUMMARY> items = exec.get_cart_summary(cookie.Value);


                List <SessionLineItemOptions> transactions = new List <SessionLineItemOptions>();

                foreach (CART_INFO_SUMMARY transaction_summary in items)
                {
                    SessionLineItemOptions item_list = new SessionLineItemOptions
                    {
                        Name        = transaction_summary.get_product_name(),
                        Description = transaction_summary.get_prod_desc(),
                        Amount      = Convert.ToInt64(decimal.Round(transaction_summary.get_sub_total()).ToString()),
                        Currency    = transaction_summary.get_currecy(),
                        Quantity    = Convert.ToInt64(transaction_summary.get_quantity().ToString()),
                    };

                    transactions.Add(item_list);
                }

                StripeConfiguration.ApiKey = "sk_test_4eC39HqLyjWDarjtT1zdp7dc";

                var options = new SessionCreateOptions
                {
                    //todo: change routes to a success or failure page (both woudld be nice )
                    //test card numbers cn=an be found at https://stripe.com/docs/testing#cards
                    //also if error occurs remove above link

                    SuccessUrl         = "https://localhost:44324/CART_DATA/INSERT_HISTORY.aspx",
                    CancelUrl          = "https://localhost:44324/Default.aspx",
                    PaymentMethodTypes = new List <string> {
                        "card",
                    },

                    //line items stores the items that are being checkout to be sent to stripe server
                    LineItems = transactions,
                    Mode      = "payment",
                };

                var     service = new SessionService();
                Session session = service.Create(options);
                sessionId = session.Id;
            }
        }
Beispiel #5
0
        public Session GetSession(OrdersVM ordersVM)
        {
            int?subTotal = 0;

            // Set your secret key. Remember to switch to your live secret key in production!
            // See your keys here: https://dashboard.stripe.com/account/apikeys
            //testkey
            //  StripeConfiguration.ApiKey = "sk_test_51Gzi07G3ZOAC0jt8niPlnlVoIWVWr7mNHGOFGXKwDPh4bFwDGSySN1miCyhS6yl2pqBfLbrPYUBZI61UAYtgtxkg00norJ7l27";
            //activekey
            StripeConfiguration.ApiKey = "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";


            var options   = new SessionCreateOptions();
            var lineItems = new List <SessionLineItemOptions>();

            options.PaymentMethodTypes = new List <string>
            {
                "card",
            };
            options.Mode       = "payment";
            options.SuccessUrl = "https://traincel.azurewebsites.net/order/success";
            options.CancelUrl  = "https://traincel.azurewebsites.net/order/failure";
            options.LineItems  = new List <SessionLineItemOptions>();
            ordersVM.OrderItems.ForEach((item) =>
            {
                var price          = _webinarPurchasedOptionsDetailsRepo.GetWebinarPrice(item.WebinarId, item.PurchaseOptionId);
                string priceString = String.Concat(item.Price.ToString(), "00");
                price = Convert.ToInt32(priceString);

                var lineItem = new SessionLineItemOptions
                {
                    PriceData = new SessionLineItemPriceDataOptions
                    {
                        Currency    = "usd",
                        ProductData = new SessionLineItemPriceDataProductDataOptions
                        {
                            Name = item.Webinar.WebinarName,
                        },

                        UnitAmountDecimal = price
                    },
                    Quantity = 1,
                };
                options.LineItems.Add(lineItem);
            });
            var     service = new SessionService();
            Session session = service.Create(options);

            return(session);
        }
        public static async Task <IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "checkoutSession")] HttpRequest req,
            [Queue("orders", Connection = "StorageConnectionString")] IAsyncCollector <Order> orderQueue,
            ILogger log)
        {
            try
            {
                log.LogInformation("C# HTTP trigger function processed the checkoutSession request.");

                StripeConfiguration.ApiKey = Environment.GetEnvironmentVariable("stripe_api_key");

                string       requestBody  = await new StreamReader(req.Body).ReadToEndAsync();
                CheckoutBody checkoutBody = JsonConvert.DeserializeObject <CheckoutBody>(requestBody);

                SessionLineItemOptions product = new SessionLineItemOptions
                {
                    Price    = checkoutBody.productId,
                    Quantity = 1,
                };

                string localUri = Environment.GetEnvironmentVariable("local_uri");

                SessionCreateOptions options = new SessionCreateOptions
                {
                    PaymentMethodTypes = new List <string> {
                        "card",
                    },
                    LineItems = new List <SessionLineItemOptions> {
                        product
                    },
                    Mode       = "payment",
                    SuccessUrl = localUri + "/checkout/success?session_id={CHECKOUT_SESSION_ID}",
                    CancelUrl  = localUri + "/checkout/cancel",
                };

                SessionService service = new SessionService();
                Session        session = service.Create(options);

                return(new OkObjectResult(new { id = session.Id }));
            }
            catch (Exception ex)
            {
                return(new BadRequestObjectResult(ex));
            }
        }
Beispiel #7
0
        private async Task <ActionResult> PayWithStripeCheckout(Sjop.Models.Order order)
        {
            // Read Stripe API key from config
            StripeConfiguration.ApiKey = _stripeSettings.SecretKey;

            // Add orderlines to Checkout session
            var lines = new List <SessionLineItemOptions>();

            foreach (var ol in order.OrderLines)
            {
                _logger.LogInformation($"linjepris: {ol.TotalPrice}");
                var newline = new SessionLineItemOptions
                {
                    Name        = ol.ProductName,
                    Description = ol.ProductDescription,
                    Amount      = Convert.ToInt64(ol.TotalPrice * 100),
                    Currency    = "nok",
                    Quantity    = ol.Quantity
                };
                lines.Add(newline);
            }
            var options = new SessionCreateOptions
            {
                ClientReferenceId  = order.Id.ToString(),
                CustomerEmail      = order.Customer.Email,
                Locale             = "nb",
                PaymentMethodTypes = new List <string> {
                    "card",
                },
                LineItems  = lines,
                SuccessUrl = _site.BaseUrl + "/PaymentSuccess?session_id={CHECKOUT_SESSION_ID}",
                CancelUrl  = _site.BaseUrl + "/PaymentFailed",
            };

            var     service = new SessionService();
            Session session = await service.CreateAsync(options);

            order.PaymentProviderSessionId = session.Id;
            _context.Update(order);
            await _context.SaveChangesAsync();

            return(Ok(session));
        }
Beispiel #8
0
        private async Task <ActionResult> PayWithStripeCheckout([FromBody] CustomerOrder order)
        {
            StripeConfiguration.ApiKey = StripeOptions.SecretKey;
            var lines = new List <SessionLineItemOptions>();

            foreach (var ol in order.orderItems)
            {
                var newline = new SessionLineItemOptions
                {
                    Name        = ol.Product.name,
                    Description = ol.Product.description,
                    Amount      = Convert.ToInt64(ol.total_payable),
                    Currency    = "usd",
                    Quantity    = ol.qty
                };
                lines.Add(newline);
            }
            var options = new SessionCreateOptions
            {
                ClientReferenceId  = order.order_id.ToString(),
                CustomerEmail      = order.customer.email,
                Locale             = "nb",
                PaymentMethodTypes = new List <string> {
                    "card",
                },
                LineItems  = lines,
                SuccessUrl = SiteBaseUrl + "/PaymentSuccess?session_id={CHECKOUT_SESSION_ID}",
                CancelUrl  = SiteBaseUrl + "/PaymentFailed",
            };

            var     service = new SessionService();
            Session session = await service.CreateAsync(options);

            order.PaymentProviderSessionId = session.Id;
            //_context.Update(order);
            //await _context.SaveChangesAsync();
            return(Ok(session));
        }
Beispiel #9
0
        public Session CreateSession(OrderReadOnly order, string continueUrl, string cancelUrl, StripeCheckoutSettings settings)
        {
            var secretKey = settings.TestMode ? settings.TestSecretKey : settings.LiveSecretKey;

            ConfigureStripe(secretKey);

            var currency       = Vendr.Services.CurrencyService.GetCurrency(order.CurrencyId);
            var billingCountry = order.PaymentInfo.CountryId.HasValue
                ? Vendr.Services.CountryService.GetCountry(order.PaymentInfo.CountryId.Value)
                : null;

            Customer customer;
            var      customerService = new CustomerService();

            // If we've created a customer already, keep using it but update it incase
            // any of the billing details have changed
            if (!string.IsNullOrWhiteSpace(order.Properties["stripeCustomerId"]))
            {
                var customerOptions = new CustomerUpdateOptions
                {
                    Name        = $"{order.CustomerInfo.FirstName} {order.CustomerInfo.LastName}",
                    Email       = order.CustomerInfo.Email,
                    Description = order.OrderNumber,
                    Address     = new AddressOptions
                    {
                        Line1 = !string.IsNullOrWhiteSpace(settings.BillingAddressLine1PropertyAlias)
                            ? order.Properties[settings.BillingAddressLine1PropertyAlias] : "",
                        Line2 = !string.IsNullOrWhiteSpace(settings.BillingAddressLine2PropertyAlias)
                            ? order.Properties[settings.BillingAddressLine2PropertyAlias] : "",
                        City = !string.IsNullOrWhiteSpace(settings.BillingAddressCityPropertyAlias)
                            ? order.Properties[settings.BillingAddressCityPropertyAlias] : "",
                        State = !string.IsNullOrWhiteSpace(settings.BillingAddressStatePropertyAlias)
                            ? order.Properties[settings.BillingAddressStatePropertyAlias] : "",
                        PostalCode = !string.IsNullOrWhiteSpace(settings.BillingAddressZipCodePropertyAlias)
                            ? order.Properties[settings.BillingAddressZipCodePropertyAlias] : "",
                        Country = billingCountry?.Code
                    }
                };

                // Pass billing country / zipcode as meta data as currently
                // this is the only way it can be validated via Radar
                // Block if ::customer:billingCountry:: != :card_country:
                customerOptions.Metadata = new Dictionary <string, string>
                {
                    { "billingCountry", customerOptions.Address.Country },
                    { "billingZipCode", customerOptions.Address.PostalCode }
                };

                customer = customerService.Update(order.Properties["stripeCustomerId"].Value, customerOptions);
            }
            else
            {
                var customerOptions = new CustomerCreateOptions
                {
                    Name        = $"{order.CustomerInfo.FirstName} {order.CustomerInfo.LastName}",
                    Email       = order.CustomerInfo.Email,
                    Description = order.OrderNumber,
                    Address     = new AddressOptions
                    {
                        Line1 = !string.IsNullOrWhiteSpace(settings.BillingAddressLine1PropertyAlias)
                        ? order.Properties[settings.BillingAddressLine1PropertyAlias] : "",
                        Line2 = !string.IsNullOrWhiteSpace(settings.BillingAddressLine2PropertyAlias)
                        ? order.Properties[settings.BillingAddressLine2PropertyAlias] : "",
                        City = !string.IsNullOrWhiteSpace(settings.BillingAddressCityPropertyAlias)
                        ? order.Properties[settings.BillingAddressCityPropertyAlias] : "",
                        State = !string.IsNullOrWhiteSpace(settings.BillingAddressStatePropertyAlias)
                        ? order.Properties[settings.BillingAddressStatePropertyAlias] : "",
                        PostalCode = !string.IsNullOrWhiteSpace(settings.BillingAddressZipCodePropertyAlias)
                        ? order.Properties[settings.BillingAddressZipCodePropertyAlias] : "",
                        Country = billingCountry?.Code
                    }
                };

                // Pass billing country / zipcode as meta data as currently
                // this is the only way it can be validated via Radar
                // Block if ::customer:billingCountry:: != :card_country:
                customerOptions.Metadata = new Dictionary <string, string>
                {
                    { "billingCountry", customerOptions.Address.Country },
                    { "billingZipCode", customerOptions.Address.PostalCode }
                };

                customer = customerService.Create(customerOptions);
            }

            var metaData = new Dictionary <string, string>
            {
                { "orderReference", order.GenerateOrderReference() },
                { "orderId", order.Id.ToString("D") },
                { "orderNumber", order.OrderNumber }
            };

            if (!string.IsNullOrWhiteSpace(settings.OrderProperties))
            {
                foreach (var alias in settings.OrderProperties.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                         .Select(x => x.Trim())
                         .Where(x => !string.IsNullOrWhiteSpace(x)))
                {
                    if (!string.IsNullOrWhiteSpace(order.Properties[alias]))
                    {
                        metaData.Add(alias, order.Properties[alias]);
                    }
                }
            }

            var  hasRecurringItems   = false;
            long recurringTotalPrice = 0;
            long orderTotalPrice     = AmountToMinorUnits(order.TransactionAmount.Value);

            var lineItems = new List <SessionLineItemOptions>();

            foreach (var orderLine in order.OrderLines.Where(IsRecurringOrderLine))
            {
                var orderLinePrice = AmountToMinorUnits(orderLine.TotalPrice.Value.WithTax);

                var lineItemOpts = new SessionLineItemOptions();

                if (orderLine.Properties.ContainsKey("stripePriceId") && !string.IsNullOrWhiteSpace(orderLine.Properties["stripePriceId"]))
                {
                    // NB: When using stripe prices there is an inherit risk that values may not
                    // actually be in sync and so the price displayed on the site might not match
                    // that in stripe and so this may cause inconsistant payments
                    lineItemOpts.Price = orderLine.Properties["stripePriceId"].Value;

                    // If we are using a stripe price, then assume the quantity of the line item means
                    // the quantity of the stripe price you want to buy.
                    lineItemOpts.Quantity = (long)orderLine.Quantity;
                }
                else
                {
                    // We don't have a stripe price defined on the order line
                    // so we'll create one on the fly using th order lines total
                    // value
                    var priceData = new SessionLineItemPriceDataOptions
                    {
                        Currency   = currency.Code,
                        UnitAmount = orderLinePrice,
                        Recurring  = new SessionLineItemPriceDataRecurringOptions
                        {
                            Interval      = orderLine.Properties["stripeRecurringInterval"].Value.ToLower(),
                            IntervalCount = long.TryParse(orderLine.Properties["stripeRecurringIntervalCount"], out var intervalCount) ? intervalCount : 1
                        }
                    };

                    if (orderLine.Properties.ContainsKey("stripeProductId") && !string.IsNullOrWhiteSpace(orderLine.Properties["stripeProductId"]))
                    {
                        priceData.Product = orderLine.Properties["stripeProductId"].Value;
                    }
                    else
                    {
                        priceData.ProductData = new SessionLineItemPriceDataProductDataOptions
                        {
                            Name     = orderLine.Name,
                            Metadata = new Dictionary <string, string>
                            {
                                { "ProductReference", orderLine.ProductReference }
                            }
                        };
                    }

                    lineItemOpts.PriceData = priceData;

                    // For dynamic subscriptions, regardless of line item quantity, treat the line
                    // as a single subscription item with one price being the line items total price
                    lineItemOpts.Quantity = 1;
                }

                lineItems.Add(lineItemOpts);

                recurringTotalPrice += orderLinePrice;
                hasRecurringItems    = true;
            }

            if (recurringTotalPrice < orderTotalPrice)
            {
                // If the total value of the order is not covered by the subscription items
                // then we add another line item for the remainder of the order value

                var lineItemOpts = new SessionLineItemOptions
                {
                    PriceData = new SessionLineItemPriceDataOptions
                    {
                        Currency    = currency.Code,
                        UnitAmount  = orderTotalPrice - recurringTotalPrice,
                        ProductData = new SessionLineItemPriceDataProductDataOptions
                        {
                            Name = hasRecurringItems
                                ? !string.IsNullOrWhiteSpace(settings.OneTimeItemsHeading) ? settings.OneTimeItemsHeading : "One time items"
                                : !string.IsNullOrWhiteSpace(settings.OrderHeading) ? settings.OrderHeading : "#" + order.OrderNumber,
                            Description = hasRecurringItems || string.IsNullOrWhiteSpace(settings.OrderHeading) ? null : "#" + order.OrderNumber,
                        }
                    },
                    Quantity = 1
                };

                lineItems.Add(lineItemOpts);
            }

            // Add image to the first item (only if it's not a product link)
            if (!string.IsNullOrWhiteSpace(settings.OrderImage) && lineItems.Count > 0 && lineItems[0].PriceData?.ProductData != null)
            {
                lineItems[0].PriceData.ProductData.Images = new[] { settings.OrderImage }.ToList();
            }

            var sessionOptions = new SessionCreateOptions
            {
                Customer           = customer.Id,
                PaymentMethodTypes = new List <string> {
                    "card",
                },
                LineItems = lineItems,
                Mode      = hasRecurringItems
                    ? "subscription"
                    : "payment",
                ClientReferenceId = order.GenerateOrderReference(),
                SuccessUrl        = continueUrl,
                CancelUrl         = cancelUrl,
            };

            if (hasRecurringItems)
            {
                sessionOptions.SubscriptionData = new SessionSubscriptionDataOptions
                {
                    Metadata = metaData
                };
            }
            else
            {
                sessionOptions.PaymentIntentData = new SessionPaymentIntentDataOptions
                {
                    CaptureMethod = settings.Capture ? "automatic" : "manual",
                    Metadata      = metaData
                };
            }

            if (settings.SendStripeReceipt)
            {
                sessionOptions.PaymentIntentData.ReceiptEmail = order.CustomerInfo.Email;
            }

            var sessionService = new SessionService();
            var session        = sessionService.Create(sessionOptions);

            return(session);
        }
Beispiel #10
0
        public IActionResult Purchase()
        {
            // get all items in the user's cart
            Guid            userId    = GetUserId();
            List <CartItem> cartItems = _cartService.GetUsersCart(userId);

            if (cartItems.Count == 0)
            {
                return(BadRequest(new { err = "Your cart is empty" }));
            }

            // create a list of session line items to pass them to stripe
            var lineItems = new List <SessionLineItemOptions>();

            cartItems.ForEach(item =>
            {
                // get the product's price
                decimal productPrice = _productService.GetProductPrice(item.Product.ID);

                SessionLineItemOptions itemOptions = new SessionLineItemOptions
                {
                    PriceData = new SessionLineItemPriceDataOptions
                    {
                        // the unit amount is in cents, therefore, it needs to be multiplied by 100
                        UnitAmount = (int)(productPrice * 100),
                        // add the name of the item
                        ProductData = new SessionLineItemPriceDataProductDataOptions
                        {
                            Name = item.Product.Title
                        },
                        Currency = "USD"
                    },
                    Quantity = item.Quantity
                };

                lineItems.Add(itemOptions);
            });

            // create session options
            var options = new SessionCreateOptions
            {
                // attach user's id in metadata, so that the webhook can verify it later
                PaymentIntentData = new SessionPaymentIntentDataOptions
                {
                    Metadata = new Dictionary <string, string> {
                        { "userId", userId.ToString() }
                    }
                },
                PaymentMethodTypes = new List <string>
                {
                    "card",
                },
                LineItems = lineItems,
                Mode      = "payment",
                // take the user to the client app's homepage if the payment is successful
                SuccessUrl = $"{Request.Scheme}://{Request.Host}",
                // take the user back to the checkout page if the payment was cancelled
                CancelUrl = $"{Request.Scheme}://{Request.Host}/checkout"
            };

            var     service = new SessionService();
            Session session = service.Create(options);

            return(Ok(new { res = session.Id }));
        }
Beispiel #11
0
        public SessionModel CreateCheckoutSession(OrderModel order)
        {
            _validator.ValidateOrder(order);
            bool          isExisting = order.Id is not null;
            PaymentEntity payment    = isExisting ? new PaymentEntity {
                Id = order.PaymentId
            } : null;

            if (!isExisting)
            {
                order.Status = Enums.OrderStatusType.Unpaid;
                order.Date   = DateTime.UtcNow;
                payment      = new PaymentEntity
                {
                    TransactionId = string.Empty
                };
                _paymentRepository.Insert(payment);
            }
            var dbOrder = _mapper.Map <OrderEntity>(order);

            if (!isExisting)
            {
                dbOrder.PaymentId = payment.Id;
                dbOrder.Total     = order.CurrentItems.Sum(item => item.Price);
                _orderRepository.Insert(dbOrder);
            }
            var items         = new List <SessionLineItemOptions>();
            var editionIds    = order.CurrentItems.Select(item => item.PrintingEditionId).ToList();
            var editionFilter = new PrintingEditionFilterModel {
                EditionIds = editionIds
            };
            var printingEditions = _printingEditionService.GetPrintingEditionsRange(editionFilter);
            var dbItems          = _mapper.Map <List <OrderItemEntity> >(order.CurrentItems);

            dbItems.ForEach(item => item.OrderId = dbOrder.Id);
            foreach (var item in dbItems)
            {
                var printingEdition = printingEditions.Where(edition => edition.Id == item.PrintingEditionId).FirstOrDefault();
                var lineItem        = new SessionLineItemOptions
                {
                    PriceData = new SessionLineItemPriceDataOptions
                    {
                        UnitAmountDecimal = printingEdition.Price * Constants.CENTMULTIPLIER,
                        Currency          = item.Currency.ToString(),
                        ProductData       = new SessionLineItemPriceDataProductDataOptions
                        {
                            Name        = printingEdition.Title,
                            Description = printingEdition.Description
                        }
                    },
                    Quantity = item.Amount
                };
                items.Add(lineItem);
            }
            if (!isExisting)
            {
                _itemRepository.InsertRange(dbItems);
            }
            string successUrl = new UriBuilder
            {
                Scheme = _urlConfig.Scheme,
                Port   = _urlConfig.Port,
                Host   = _urlConfig.Host,
                Path   = Constants.STRIPESUCCESSPATH
            }.ToString();
            string cancelUrl = new UriBuilder
            {
                Scheme = _urlConfig.Scheme,
                Port   = _urlConfig.Port,
                Host   = _urlConfig.Host,
                Path   = Constants.STRIPECANCELPATH
            }.ToString();
            var options = new SessionCreateOptions
            {
                PaymentMethodTypes = new List <string>
                {
                    Constants.DEFAULTPAYMENTMETHOD
                },
                LineItems  = items,
                Mode       = Constants.DEFAULTPAYMENTMODE,
                SuccessUrl = successUrl,
                CancelUrl  = cancelUrl
            };
            var     service = new SessionService();
            Session session = service.Create(options);

            payment.TransactionId = session.PaymentIntentId;
            _paymentRepository.Update(payment);
            return(new SessionModel
            {
                Id = session.Id,
                PaymentIntentId = session.PaymentIntentId
            });
        }
        public override async Task <PaymentFormResult> GenerateFormAsync(PaymentProviderContext <StripeCheckoutSettings> ctx)
        {
            var secretKey = ctx.Settings.TestMode ? ctx.Settings.TestSecretKey : ctx.Settings.LiveSecretKey;
            var publicKey = ctx.Settings.TestMode ? ctx.Settings.TestPublicKey : ctx.Settings.LivePublicKey;

            ConfigureStripe(secretKey);

            var currency       = Vendr.Services.CurrencyService.GetCurrency(ctx.Order.CurrencyId);
            var billingCountry = ctx.Order.PaymentInfo.CountryId.HasValue
                ? Vendr.Services.CountryService.GetCountry(ctx.Order.PaymentInfo.CountryId.Value)
                : null;

            Customer customer;
            var      customerService = new CustomerService();

            // If we've created a customer already, keep using it but update it incase
            // any of the billing details have changed
            if (!string.IsNullOrWhiteSpace(ctx.Order.Properties["stripeCustomerId"]))
            {
                var customerOptions = new CustomerUpdateOptions
                {
                    Name        = $"{ctx.Order.CustomerInfo.FirstName} {ctx.Order.CustomerInfo.LastName}",
                    Email       = ctx.Order.CustomerInfo.Email,
                    Description = ctx.Order.OrderNumber,
                    Address     = new AddressOptions
                    {
                        Line1 = !string.IsNullOrWhiteSpace(ctx.Settings.BillingAddressLine1PropertyAlias)
                            ? ctx.Order.Properties[ctx.Settings.BillingAddressLine1PropertyAlias] : "",
                        Line2 = !string.IsNullOrWhiteSpace(ctx.Settings.BillingAddressLine2PropertyAlias)
                            ? ctx.Order.Properties[ctx.Settings.BillingAddressLine2PropertyAlias] : "",
                        City = !string.IsNullOrWhiteSpace(ctx.Settings.BillingAddressCityPropertyAlias)
                            ? ctx.Order.Properties[ctx.Settings.BillingAddressCityPropertyAlias] : "",
                        State = !string.IsNullOrWhiteSpace(ctx.Settings.BillingAddressStatePropertyAlias)
                            ? ctx.Order.Properties[ctx.Settings.BillingAddressStatePropertyAlias] : "",
                        PostalCode = !string.IsNullOrWhiteSpace(ctx.Settings.BillingAddressZipCodePropertyAlias)
                            ? ctx.Order.Properties[ctx.Settings.BillingAddressZipCodePropertyAlias] : "",
                        Country = billingCountry?.Code
                    }
                };

                // Pass billing country / zipcode as meta data as currently
                // this is the only way it can be validated via Radar
                // Block if ::customer:billingCountry:: != :card_country:
                customerOptions.Metadata = new Dictionary <string, string>
                {
                    { "billingCountry", customerOptions.Address.Country },
                    { "billingZipCode", customerOptions.Address.PostalCode }
                };

                customer = customerService.Update(ctx.Order.Properties["stripeCustomerId"].Value, customerOptions);
            }
            else
            {
                var customerOptions = new CustomerCreateOptions
                {
                    Name        = $"{ctx.Order.CustomerInfo.FirstName} {ctx.Order.CustomerInfo.LastName}",
                    Email       = ctx.Order.CustomerInfo.Email,
                    Description = ctx.Order.OrderNumber,
                    Address     = new AddressOptions
                    {
                        Line1 = !string.IsNullOrWhiteSpace(ctx.Settings.BillingAddressLine1PropertyAlias)
                        ? ctx.Order.Properties[ctx.Settings.BillingAddressLine1PropertyAlias] : "",
                        Line2 = !string.IsNullOrWhiteSpace(ctx.Settings.BillingAddressLine2PropertyAlias)
                        ? ctx.Order.Properties[ctx.Settings.BillingAddressLine2PropertyAlias] : "",
                        City = !string.IsNullOrWhiteSpace(ctx.Settings.BillingAddressCityPropertyAlias)
                        ? ctx.Order.Properties[ctx.Settings.BillingAddressCityPropertyAlias] : "",
                        State = !string.IsNullOrWhiteSpace(ctx.Settings.BillingAddressStatePropertyAlias)
                        ? ctx.Order.Properties[ctx.Settings.BillingAddressStatePropertyAlias] : "",
                        PostalCode = !string.IsNullOrWhiteSpace(ctx.Settings.BillingAddressZipCodePropertyAlias)
                        ? ctx.Order.Properties[ctx.Settings.BillingAddressZipCodePropertyAlias] : "",
                        Country = billingCountry?.Code
                    }
                };

                // Pass billing country / zipcode as meta data as currently
                // this is the only way it can be validated via Radar
                // Block if ::customer:billingCountry:: != :card_country:
                customerOptions.Metadata = new Dictionary <string, string>
                {
                    { "billingCountry", customerOptions.Address.Country },
                    { "billingZipCode", customerOptions.Address.PostalCode }
                };

                customer = customerService.Create(customerOptions);
            }

            var metaData = new Dictionary <string, string>
            {
                { "ctx.OrderReference", ctx.Order.GenerateOrderReference() },
                { "ctx.OrderId", ctx.Order.Id.ToString("D") },
                { "ctx.OrderNumber", ctx.Order.OrderNumber }
            };

            if (!string.IsNullOrWhiteSpace(ctx.Settings.OrderProperties))
            {
                foreach (var alias in ctx.Settings.OrderProperties.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                         .Select(x => x.Trim())
                         .Where(x => !string.IsNullOrWhiteSpace(x)))
                {
                    if (!string.IsNullOrWhiteSpace(ctx.Order.Properties[alias]))
                    {
                        metaData.Add(alias, ctx.Order.Properties[alias]);
                    }
                }
            }

            var  hasRecurringItems   = false;
            long recurringTotalPrice = 0;
            long orderTotalPrice     = AmountToMinorUnits(ctx.Order.TransactionAmount.Value);

            var lineItems = new List <SessionLineItemOptions>();

            foreach (var orderLine in ctx.Order.OrderLines.Where(IsRecurringOrderLine))
            {
                var orderLineTaxRate = orderLine.TaxRate * 100;

                var lineItemOpts = new SessionLineItemOptions();

                if (orderLine.Properties.ContainsKey("stripePriceId") && !string.IsNullOrWhiteSpace(orderLine.Properties["stripePriceId"]))
                {
                    // NB: When using stripe prices there is an inherit risk that values may not
                    // actually be in sync and so the price displayed on the site might not match
                    // that in stripe and so this may cause inconsistant payments
                    lineItemOpts.Price = orderLine.Properties["stripePriceId"].Value;

                    // If we are using a stripe price, then assume the quantity of the line item means
                    // the quantity of the stripe price you want to buy.
                    lineItemOpts.Quantity = (long)orderLine.Quantity;

                    // Because we are in charge of what taxes apply, we need to setup a tax rate
                    // to ensure the price defined in stripe has the relevant taxes applied
                    var stripePricesIncludeTax = PropertyIsTrue(orderLine.Properties, "stripePriceIncludesTax");
                    var stripeTaxRate          = GetOrCreateStripeTaxRate(ctx, "Subscription Tax", orderLineTaxRate, stripePricesIncludeTax);
                    if (stripeTaxRate != null)
                    {
                        lineItemOpts.TaxRates = new List <string>(new[] { stripeTaxRate.Id });
                    }
                }
                else
                {
                    // We don't have a stripe price defined on the ctx.Order line
                    // so we'll create one on the fly using the ctx.Order lines total
                    // value
                    var priceData = new SessionLineItemPriceDataOptions
                    {
                        Currency   = currency.Code,
                        UnitAmount = AmountToMinorUnits(orderLine.TotalPrice.Value.WithoutTax / orderLine.Quantity), // Without tax as Stripe will apply the tax
                        Recurring  = new SessionLineItemPriceDataRecurringOptions
                        {
                            Interval      = orderLine.Properties["stripeRecurringInterval"].Value.ToLower(),
                            IntervalCount = long.TryParse(orderLine.Properties["stripeRecurringIntervalCount"], out var intervalCount) ? intervalCount : 1
                        }
                    };

                    if (orderLine.Properties.ContainsKey("stripeProductId") && !string.IsNullOrWhiteSpace(orderLine.Properties["stripeProductId"]))
                    {
                        priceData.Product = orderLine.Properties["stripeProductId"].Value;
                    }
                    else
                    {
                        priceData.ProductData = new SessionLineItemPriceDataProductDataOptions
                        {
                            Name     = orderLine.Name,
                            Metadata = new Dictionary <string, string>
                            {
                                { "ProductReference", orderLine.ProductReference }
                            }
                        };
                    }

                    lineItemOpts.PriceData = priceData;

                    // For dynamic subscriptions, regardless of line item quantity, treat the line
                    // as a single subscription item with one price being the line items total price
                    lineItemOpts.Quantity = (long)orderLine.Quantity;

                    // If we define the price, then create tax rates that are set to be inclusive
                    // as this means that we can pass prices inclusive of tax and Stripe works out
                    // the pre-tax price which would be less suseptable to rounding inconsistancies
                    var stripeTaxRate = GetOrCreateStripeTaxRate(ctx, "Subscription Tax", orderLineTaxRate, false);
                    if (stripeTaxRate != null)
                    {
                        lineItemOpts.TaxRates = new List <string>(new[] { stripeTaxRate.Id });
                    }
                }

                lineItems.Add(lineItemOpts);

                recurringTotalPrice += AmountToMinorUnits(orderLine.TotalPrice.Value.WithTax);
                hasRecurringItems    = true;
            }

            if (recurringTotalPrice < orderTotalPrice)
            {
                // If the total value of the ctx.Order is not covered by the subscription items
                // then we add another line item for the remainder of the ctx.Order value

                var lineItemOpts = new SessionLineItemOptions
                {
                    PriceData = new SessionLineItemPriceDataOptions
                    {
                        Currency    = currency.Code,
                        UnitAmount  = orderTotalPrice - recurringTotalPrice,
                        ProductData = new SessionLineItemPriceDataProductDataOptions
                        {
                            Name = hasRecurringItems
                                ? !string.IsNullOrWhiteSpace(ctx.Settings.OneTimeItemsHeading) ? ctx.Settings.OneTimeItemsHeading : "One time items (inc Tax)"
                                : !string.IsNullOrWhiteSpace(ctx.Settings.OrderHeading) ? ctx.Settings.OrderHeading : "#" + ctx.Order.OrderNumber,
                            Description = hasRecurringItems || !string.IsNullOrWhiteSpace(ctx.Settings.OrderHeading) ? "#" + ctx.Order.OrderNumber : null,
                        }
                    },
                    Quantity = 1
                };

                lineItems.Add(lineItemOpts);
            }

            // Add image to the first item (only if it's not a product link)
            if (!string.IsNullOrWhiteSpace(ctx.Settings.OrderImage) && lineItems.Count > 0 && lineItems[0].PriceData?.ProductData != null)
            {
                lineItems[0].PriceData.ProductData.Images = new[] { ctx.Settings.OrderImage }.ToList();
            }

            var sessionOptions = new SessionCreateOptions
            {
                Customer           = customer.Id,
                PaymentMethodTypes = !string.IsNullOrWhiteSpace(ctx.Settings.PaymentMethodTypes)
                    ? ctx.Settings.PaymentMethodTypes.Split(',')
                                     .Select(tag => tag.Trim())
                                     .Where(tag => !string.IsNullOrEmpty(tag))
                                     .ToList()
                    : new List <string> {
                    "card",
                },
                LineItems = lineItems,
                Mode      = hasRecurringItems
                    ? "subscription"
                    : "payment",
                ClientReferenceId = ctx.Order.GenerateOrderReference(),
                SuccessUrl        = ctx.Urls.ContinueUrl,
                CancelUrl         = ctx.Urls.CancelUrl
            };

            if (hasRecurringItems)
            {
                sessionOptions.SubscriptionData = new SessionSubscriptionDataOptions
                {
                    Metadata = metaData
                };
            }
            else
            {
                sessionOptions.PaymentIntentData = new SessionPaymentIntentDataOptions
                {
                    CaptureMethod = ctx.Settings.Capture ? "automatic" : "manual",
                    Metadata      = metaData
                };
            }

            if (ctx.Settings.SendStripeReceipt)
            {
                sessionOptions.PaymentIntentData.ReceiptEmail = ctx.Order.CustomerInfo.Email;
            }

            var sessionService = new SessionService();
            var session        = await sessionService.CreateAsync(sessionOptions);

            return(new PaymentFormResult()
            {
                MetaData = new Dictionary <string, string>
                {
                    { "stripeSessionId", session.Id },
                    { "stripeCustomerId", session.CustomerId }
                },
                Form = new PaymentForm(ctx.Urls.ContinueUrl, PaymentFormMethod.Post)
                       .WithAttribute("onsubmit", "return handleStripeCheckout(event)")
                       .WithJsFile("https://js.stripe.com/v3/")
                       .WithJs(@"
                        var stripe = Stripe('" + publicKey + @"');
                        window.handleStripeCheckout = function (e) {
                            e.preventDefault();
                            stripe.redirectToCheckout({
                                sessionId: '" + session.Id + @"'
                            }).then(function (result) {
                              // If `redirectToCheckout` fails due to a browser or network
                              // error, display the localized error message to your customer
                              // using `result.error.message`.
                            });
                            return false;
                        }
                    ")
            });
        }