public override CallbackResult ProcessCallback(OrderReadOnly order, HttpRequestBase request, OpayoSettings settings)
        {
            var callbackRequestModel = CallbackRequestModel.FromRequest(request);
            var client = new OpayoServerClient(
                logger,
                new OpayoServerClientConfig {
                ProviderAlias = Alias,
                ContinueUrl   = paymentProviderUriResolver.GetContinueUrl(Alias, order.GenerateOrderReference(), hashProvider),
                CancelUrl     = paymentProviderUriResolver.GetCancelUrl(Alias, order.GenerateOrderReference(), hashProvider),
                ErrorUrl      = GetErrorUrl(order, settings)
            });

            return(client.HandleCallback(order, callbackRequestModel, settings));
        }
        public override OrderReference GetOrderReference(HttpRequestBase request, SquareSettings settings)
        {
            var accessToken = settings.SandboxMode ? settings.SandboxAccessToken : settings.LiveAccessToken;
            var environment = settings.SandboxMode ? SquareSdk.Environment.Sandbox : SquareSdk.Environment.Production;

            var client = new SquareSdk.SquareClient.Builder()
                         .Environment(environment)
                         .AccessToken(accessToken)
                         .Build();

            var orderApi = client.OrdersApi;

            SquareSdk.Models.Order squareOrder = null;

            var squareEvent = GetSquareWebhookEvent(request, settings);

            if (squareEvent != null && squareEvent.IsValid)
            {
                try
                {
                    var referenceId = "";

                    var orderId = GetOrderId(squareEvent);
                    if (!string.IsNullOrWhiteSpace(orderId))
                    {
                        var result = orderApi.BatchRetrieveOrders(
                            new BatchRetrieveOrdersRequest(new List <string>()
                        {
                            orderId
                        }));

                        squareOrder = result.Orders.FirstOrDefault();
                        referenceId = squareOrder.ReferenceId;

                        if (!string.IsNullOrWhiteSpace(referenceId) && Guid.TryParse(referenceId, out var vendrOrderId))
                        {
                            OrderReadOnly vendrOrder = Vendr.Services.OrderService.GetOrder(vendrOrderId);
                            return(vendrOrder.GenerateOrderReference());
                        }
                    }
                }
                catch (Exception ex)
                {
                    Vendr.Log.Error <SquareCheckoutOnetimePaymentProvider>(ex, "Square - GetOrderReference");
                }
            }

            return(base.GetOrderReference(request, settings));
        }
예제 #3
0
        public override PaymentFormResult GenerateForm(OrderReadOnly order, string continueUrl, string cancelUrl, string callbackUrl, PayPalCheckoutOneTimeSettings settings)
        {
            // Get currency information
            var currency = Vendr.Services.CurrencyService.GetCurrency(order.CurrencyId);

            // Create the order
            var clientConfig = GetPayPalClientConfig(settings);
            var client       = new PayPalClient(clientConfig);
            var payPalOrder  = client.CreateOrder(new PayPalCreateOrderRequest
            {
                Intent = settings.Capture
                    ? PayPalOrder.Intents.CAPTURE
                    : PayPalOrder.Intents.AUTHORIZE,
                PurchaseUnits = new[] {
                    new PayPalPurchaseUnitRequest {
                        CustomId = order.GenerateOrderReference(),
                        Amount   = new PayPalAmount {
                            CurrencyCode = currency.Code,
                            Value        = order.TotalPrice.Value.WithTax.ToString("0.00", CultureInfo.InvariantCulture)
                        }
                    }
                },
                AplicationContext = new PayPalOrderApplicationContext
                {
                    BrandName  = settings.BrandName,
                    UserAction = "PAY_NOW",
                    ReturnUrl  = continueUrl,
                    CancelUrl  = cancelUrl
                }
            });

            // Setup the payment form to redirect to approval link
            var approveLink       = payPalOrder.Links.FirstOrDefault(x => x.Rel == "approve");
            var approveLinkMethod = (FormMethod)Enum.Parse(typeof(FormMethod), approveLink.Method, true);

            return(new PaymentFormResult()
            {
                Form = new PaymentForm(approveLink.Href, approveLinkMethod)
            });
        }
예제 #4
0
 internal static string ReplacePlaceHolders(this string self, OrderReadOnly order)
 {
     return(self.Replace(OpayoConstants.PlaceHolders.OrderReference, order.GenerateOrderReference().OrderNumber)
            .Replace(OpayoConstants.PlaceHolders.OrderId, order.Id.ToString()));
 }
        public override PaymentFormResult GenerateForm(OrderReadOnly order, string continueUrl, string cancelUrl, string callbackUrl, StripeCheckoutOneTimeSettings settings)
        {
            var secretKey = settings.TestMode ? settings.TestSecretKey : settings.LiveSecretKey;
            var publicKey = settings.TestMode ? settings.TestPublicKey : settings.LivePublicKey;

            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;

            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.BillingAddressLine1PropertyAlias)
                        ? 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
                }
            };

            var customerService = new CustomerService();
            var customer        = customerService.Create(customerOptions);

            var sessionOptions = new SessionCreateOptions
            {
                Customer           = customer.Id,
                PaymentMethodTypes = new List <string> {
                    "card",
                },
                LineItems = new List <SessionLineItemOptions> {
                    new SessionLineItemOptions {
                        Name        = !string.IsNullOrWhiteSpace(settings.OrderHeading) ? settings.OrderHeading : "#" + order.OrderNumber,
                        Description = !string.IsNullOrWhiteSpace(settings.OrderHeading) ? "#" + order.OrderNumber : null,
                        Amount      = AmountToMinorUnits(order.TotalPrice.Value.WithTax),
                        Currency    = currency.Code,
                        Quantity    = 1
                    },
                },
                PaymentIntentData = new SessionPaymentIntentDataOptions
                {
                    CaptureMethod = settings.Capture ? "automatic" : "manual",
                    Metadata      = new Dictionary <string, string>
                    {
                        { "orderReference", order.GenerateOrderReference() },
                        // Pass billing country / zipecode as meta data as currently
                        // this is the only way it can be validated via Radar
                        // Block if ::orderBillingCountry:: != :card_country:
                        { "orderBillingCountry", billingCountry.Code?.ToUpper() },
                        { "orderBillingZipCode", customerOptions.Address.PostalCode }
                    }
                },
                Mode = "payment",
                ClientReferenceId = order.GenerateOrderReference(),
                SuccessUrl        = continueUrl,
                CancelUrl         = cancelUrl,
            };

            if (!string.IsNullOrWhiteSpace(settings.OrderImage))
            {
                sessionOptions.LineItems[0].Images = new[] { settings.OrderImage }.ToList();
            }

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

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

            return(new PaymentFormResult()
            {
                Form = new PaymentForm(continueUrl, FormMethod.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;
                        }
                    ")
            });
        }
예제 #6
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);
        }
        public override PaymentFormResult GenerateForm(OrderReadOnly order, string continueUrl, string cancelUrl, string callbackUrl, SquareSettings settings)
        {
            var currency     = Vendr.Services.CurrencyService.GetCurrency(order.CurrencyId);
            var currencyCode = currency.Code.ToUpperInvariant();

            // Ensure currency has valid ISO 4217 code
            if (!Iso4217.CurrencyCodes.ContainsKey(currencyCode))
            {
                throw new Exception("Currency must be a valid ISO 4217 currency code: " + currency.Name);
            }

            var accessToken = settings.SandboxMode ? settings.SandboxAccessToken : settings.LiveAccessToken;
            var environment = settings.SandboxMode ? SquareSdk.Environment.Sandbox : SquareSdk.Environment.Production;

            var client = new SquareSdk.SquareClient.Builder()
                         .Environment(environment)
                         .AccessToken(accessToken)
                         .Build();

            var checkoutApi = client.CheckoutApi;

            var bodyOrderOrderSource = new OrderSource.Builder()
                                       .Name("Vendr")
                                       .Build();

            var orderAmount = AmountToMinorUnits(order.TransactionAmount.Value);

            var bodyOrderOrderLineItems = new List <OrderLineItem>()
            {
                new OrderLineItem("1",
                                  order.Id.ToString(),
                                  order.OrderNumber,
                                  basePriceMoney: new Money(orderAmount, currencyCode))
            };

            var orderReference      = order.GenerateOrderReference();
            var shortOrderReference = $"{order.Id},{order.OrderNumber}";

            var bodyOrderOrder = new SquareSdk.Models.Order.Builder(settings.LocationId)
                                 .CustomerId(order.CustomerInfo.CustomerReference)
                                 .ReferenceId(order.Id.ToString())
                                 .Source(bodyOrderOrderSource)
                                 .LineItems(bodyOrderOrderLineItems)
                                 .Build();

            var bodyOrder = new CreateOrderRequest.Builder()
                            .Order(bodyOrderOrder)
                            .LocationId(settings.LocationId)
                            .IdempotencyKey(Guid.NewGuid().ToString())
                            .Build();

            var body = new CreateCheckoutRequest.Builder(
                Guid.NewGuid().ToString(), bodyOrder)
                       .RedirectUrl(continueUrl)
                       .Build();

            var result = checkoutApi.CreateCheckout(settings.LocationId, body);

            return(new PaymentFormResult()
            {
                Form = new PaymentForm(result.Checkout.CheckoutPageUrl, FormMethod.Get)
            });
        }