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));
        }
        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)
            });
        }
        public override CallbackResult ProcessCallback(OrderReadOnly order, HttpRequestBase request, SquareSettings settings)
        {
            var accessToken = settings.SandboxMode ? settings.SandboxAccessToken : settings.LiveAccessToken;
            var environment = settings.SandboxMode ? SquareSdk.Environment.Sandbox : SquareSdk.Environment.Production;

            var squareEvent = GetSquareWebhookEvent(request, settings);

            if (squareEvent != null && squareEvent.IsValid)
            {
                try
                {
                    var client = new SquareSdk.SquareClient.Builder()
                                 .Environment(environment)
                                 .AccessToken(accessToken)
                                 .Build();

                    var orderApi = client.OrdersApi;

                    var orderId = GetOrderId(squareEvent);

                    var paymentStatus = PaymentStatus.PendingExternalSystem;
                    SquareSdk.Models.Order squareOrder = null;

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

                        squareOrder = result.Orders.FirstOrDefault();
                    }

                    if (squareOrder != null)
                    {
                        var orderStatus = squareOrder.State ?? "";

                        switch (orderStatus.ToUpper())
                        {
                        case "COMPLETED":
                        case "AUTHORIZED":
                            paymentStatus = PaymentStatus.Authorized;
                            break;

                        case "CANCELED":
                            paymentStatus = PaymentStatus.Cancelled;
                            break;
                        }
                    }

                    var callbackResult = CallbackResult.Ok(new TransactionInfo
                    {
                        AmountAuthorized = order.TransactionAmount.Value.WithTax,
                        TransactionFee   = 0m,
                        TransactionId    = squareOrder.Id,
                        PaymentStatus    = paymentStatus
                    });

                    return(callbackResult);
                }
                catch (Exception ex)
                {
                    Vendr.Log.Error <SquareCheckoutOnetimePaymentProvider>(ex, "Square - ProcessCallback");
                }
            }

            return(CallbackResult.BadRequest());
        }