Beispiel #1
0
        public IActionResult s2sHandler()
        {
            string errorCode = "", errorDesc = "";

            string strRequest = Request.QueryString.ToString().Replace("?", "");
            Dictionary <string, string> values;

            var processor = _paymentPluginManager.LoadPluginBySystemName("Payments.GestPay") as GestPayPaymentProcessor;

            if (processor == null ||
                !_paymentPluginManager.IsPluginActive(processor))
            {
                throw new NopException("GestPay module cannot be loaded");
            }

            processor.GetResponseDetails(strRequest, out values);
            if (values != null && values.Count > 0)
            {
                if (values.Count == 4)
                {
                    return(RedirectToRoute("Plugin.Payments.GestPay.AcceptPaymenyByLink", new { a = values["a"], status = values["Status"], paymentId = values["paymentID"], paymentToken = values["paymentToken"] }));
                }

                var    shopLogin = values["a"];
                var    encString = values["b"];
                string shopTransactionId = "", authorizationCode = "", bankTransactionId = "";
                string transactionResult = "", buyerName = "", buyerEmail = "", riskified = "", authorizationcode = "", threeDSAuthenticationLevel = "";

                var acceptedThreeDSAuthLevels = new List <string> {
                    "1H", "1F", "2F", "2C", "2E"
                };
                var checkAmount = decimal.Zero;

                var sb = new StringBuilder();
                sb.AppendLine("GestPay s2s:");

                if (processor.IsShopLoginChecked(shopLogin) && encString != null)
                {
                    var endpoint   = _gestPayPaymentSettings.UseSandbox ? WSCryptDecryptSoapClient.EndpointConfiguration.WSCryptDecryptSoap12Test : WSCryptDecryptSoapClient.EndpointConfiguration.WSCryptDecryptSoap12;
                    var objDecrypt = new WSCryptDecryptSoapClient(endpoint);

                    string xmlResponse = objDecrypt.DecryptAsync(shopLogin, encString, _gestPayPaymentSettings.ApiKey).Result.OuterXml;

                    XmlDocument XMLReturn = new XmlDocument();
                    XMLReturn.LoadXml(xmlResponse.ToLower());

                    //_logger.Information(xmlResponse.ToLower());

                    //Id transazione inviato
                    errorCode = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/errorcode")?.InnerText;
                    errorDesc = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/errordescription")?.InnerText;
                    //authorizationCode = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/authorizationcode")?.InnerText;
                    shopTransactionId = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/shoptransactionid")?.InnerText;

                    //_____ Messaggio OK _____//
                    if (errorCode == "0")
                    {
                        //Codice autorizzazione
                        authorizationCode = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/authorizationcode")?.InnerText;
                        //Codice transazione
                        bankTransactionId = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/banktransactionid")?.InnerText;
                        //Ammontare della transazione
                        var amount = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/amount")?.InnerText;
                        //Risultato transazione
                        transactionResult = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/transactionresult")?.InnerText;
                        //Nome dell'utente
                        buyerName = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/buyer/buyername")?.InnerText;
                        //Email utilizzata nella transazione
                        buyerEmail = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/buyer/buyeremail")?.InnerText;

                        //__________ ?validare il totale? __________//
                        riskified = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/riskresponsedescription")?.InnerText;

                        //  3DS authentication level (1H,1F,2F,2C,2E)
                        threeDSAuthenticationLevel = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/threeds/authenticationresult/authenticationlevel")?.InnerText?.ToUpper();

                        try
                        {
                            checkAmount = decimal.Parse(amount, new CultureInfo("en-US"));
                        }
                        catch (Exception exc)
                        {
                            _logger.Error("GestPay s2s. Error getting Amount", exc);
                        }
                        sb.AppendLine("GestPay success.");
                    }
                    else
                    {
                        sb.AppendLine("GestPay failed.");
                        _logger.Error("GestPay S2S. Transaction not found", new NopException(sb.ToString()));
                    }
                }

                //________ Inizio composizione messaggio dal server _________//
                foreach (var kvp in values)
                {
                    sb.AppendLine(kvp.Key + ": " + kvp.Value);
                }

                //Recupero lo stato del pagamento
                var newPaymentStatus = GestPayHelper.GetPaymentStatus(transactionResult, "");
                sb.AppendLine("New payment status: " + newPaymentStatus);
                sb.AppendLine("Riskified = " + riskified);
                sb.AppendLine("3DS Level = " + threeDSAuthenticationLevel);

                //Cerco di recuperare l'ordine
                var orderNumberGuid = Guid.Empty;
                try
                {
                    orderNumberGuid = new Guid(shopTransactionId);
                }
                catch { }

                var order = _orderService.GetOrderByGuid(orderNumberGuid);
                //_________ aggiorno lo stato dell'ordine _________//
                if (order != null)
                {
                    switch (newPaymentStatus)
                    {
                    case PaymentStatus.Pending:
                    {
                    }
                    break;

                    case PaymentStatus.Authorized:
                    {
                        if (_orderProcessingService.CanMarkOrderAsAuthorized(order))
                        {
                            _orderProcessingService.MarkAsAuthorized(order);
                        }
                    }
                    break;

                    case PaymentStatus.Paid:
                    {
                        if (_orderProcessingService.CanMarkOrderAsPaid(order))
                        {
                            order.AuthorizationTransactionId   = bankTransactionId;
                            order.AuthorizationTransactionCode = authorizationCode;
                            _orderService.UpdateOrder(order);

                            if (!_gestPayPaymentSettings.EnableGuaranteedPayment || acceptedThreeDSAuthLevels.Contains(threeDSAuthenticationLevel))
                            {
                                _orderProcessingService.MarkOrderAsPaid(order);
                            }
                        }
                    }
                    break;

                    case PaymentStatus.Refunded:
                    {
                        if (_orderProcessingService.CanRefundOffline(order))
                        {
                            _orderProcessingService.RefundOffline(order);
                        }
                    }
                    break;

                    case PaymentStatus.Voided:
                    {
                        /*_ Visto che non si può impostare il pagamento ad Annullato
                         * _orderProcessingService.CanVoidOffline allora cancello l'ordine.
                         * C'è da decidere se avvisare o meno l'utente _*/
                        if (_orderProcessingService.CanCancelOrder(order))
                        {
                            _orderProcessingService.CancelOrder(order, true);
                        }
                    }
                    break;
                    }

                    //__________________ salvo i valori restituiti __________________//
                    sb.AppendLine("GestPay response:");
                    //Codice Errore
                    sb.AppendLine("ErrorCode: " + errorCode);
                    //Descrizione Errore
                    sb.AppendLine("ErrorDesc: " + errorDesc);
                    sb.AppendLine("TrxResult: " + transactionResult);
                    sb.AppendLine("BankTrxID: " + bankTransactionId);
                    sb.AppendLine("AuthCode: " + authorizationCode);
                    sb.AppendLine("Amount: " + checkAmount);
                    if (!Math.Round(checkAmount, 2).Equals(Math.Round(order.OrderTotal, 2)))
                    {
                        //__________ ?validare il totale? __________//
                        sb.AppendLine(String.Format("Amount difference: {0}-{1}", Math.Round(checkAmount, 2), Math.Round(order.OrderTotal, 2)));
                    }
                    sb.AppendLine("BuyerName: " + buyerName);
                    sb.AppendLine("BuyerEmail: " + buyerEmail);

                    //Inserisco la nota sull'ordine
                    var orderNote = new OrderNote
                    {
                        OrderId           = order.Id,
                        Note              = sb.ToString(),
                        DisplayToCustomer = false,
                        CreatedOnUtc      = DateTime.UtcNow
                    };
                    _orderService.InsertOrderNote(orderNote);
                }
                else
                {
                    _logger.Error("GestPay S2S. Order is not found", new NopException(sb.ToString()));
                }
            }
            else
            {
                _logger.Error("GestPay S2S failed.", new NopException(strRequest));
            }

            //_________ Imposto il risultato __________//
            var s2SResponse = "KO";

            if (errorCode == "0")
            {
                s2SResponse = "OK";
            }
            //nothing should be rendered to visitor
            return(Content(String.Format("<html>{0}</html>", s2SResponse)));
        }
Beispiel #2
0
        public IActionResult EsitoGestPay(string esito = "check")
        {
            //___________ l'aggiornamento è già stato fatto via S2S ___________//
            //byte[] param = Request.BinaryRead(Request.ContentLength);
            //string strRequest = Encoding.ASCII.GetString(param);
            var strRequest = Request.QueryString.ToString().Replace("?", "");
            Dictionary <string, string> values;

            var processor = _paymentPluginManager.LoadPluginBySystemName("Payments.GestPay") as GestPayPaymentProcessor;

            if (processor == null ||
                !_paymentPluginManager.IsPluginActive(processor))
            {
                throw new NopException("GestPay module cannot be loaded");
            }

            processor.GetResponseDetails(strRequest, out values);
            if (values != null && values.Count > 0)
            {
                if (values.Count == 4)
                {
                    return(RedirectToRoute("Plugin.Payments.GestPay.AcceptPaymenyByLink", new { a = values["a"], status = values["Status"], paymentId = values["paymentID"], paymentToken = values["paymentToken"] }));
                }

                var shopLogin = values["a"];
                var encString = values["b"];

                if (processor.IsShopLoginChecked(shopLogin) && encString != null)
                {
                    var endpoint   = _gestPayPaymentSettings.UseSandbox ? WSCryptDecryptSoapClient.EndpointConfiguration.WSCryptDecryptSoap12Test : WSCryptDecryptSoapClient.EndpointConfiguration.WSCryptDecryptSoap12;
                    var objDecrypt = new WSCryptDecryptSoapClient(endpoint);

                    string xmlResponse = objDecrypt.DecryptAsync(shopLogin, encString, _gestPayPaymentSettings.ApiKey).Result.OuterXml;

                    XmlDocument XMLReturn = new XmlDocument();
                    XMLReturn.LoadXml(xmlResponse.ToLower());

                    //Id transazione inviato
                    string errorCode         = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/errorcode")?.InnerText;
                    string ErrorDesc         = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/errordescription")?.InnerText;
                    string shopTransactionId = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/shoptransactionid")?.InnerText;

                    //Recupero l'ordine
                    Guid orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(shopTransactionId);
                    }
                    catch { }
                    Order order = _orderService.GetOrderByGuid(orderNumberGuid);

                    if (errorCode == "0" && order != null)
                    {
                        //Codice autorizzazione
                        var authorizationCode = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/authorizationcode")?.InnerText;
                        //Codice transazione
                        var bankTransactionId = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/banktransactionid")?.InnerText;
                        //Ammontare della transazione
                        var amount = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/amount")?.InnerText;
                        //Risultato transazione
                        var transactionResult = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/transactionresult")?.InnerText;
                        //Nome dell'utente
                        var buyerName = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/buyer/buyername")?.InnerText;
                        //Email utilizzata nella transazione
                        var buyerEmail = XMLReturn.SelectSingleNode("/gestpaycryptdecrypt/buyer/buyeremail")?.InnerText;

                        //load settings for a chosen store scope
                        var storeScope             = _storeContext.ActiveStoreScopeConfiguration;
                        var gestPayPaymentSettings = _settingService.LoadSetting <GestPayPaymentSettings>(storeScope);

                        //__________ Ordine Completato __________//
                        return(RedirectToRoute("CheckoutCompleted", new { orderId = order.Id }));
                    }
                    else
                    {
                        //__________ ??Comunicarlo all'utente?? __________//
                        return(RedirectToAction("GeneralError", new { type = "1", errC = HttpUtility.UrlEncode(errorCode), errD = HttpUtility.UrlEncode(ErrorDesc) }));
                    }
                }
            }
            //________ Pagamento fallito e non posso recuperare i dati ________//
            //throw new NopException("GestPay cannot get transaction parameters.");
            return(RedirectToAction("GeneralError", new { type = "2" }));
        }
Beispiel #3
0
        public void PostProcessPayment(PostProcessPaymentRequest postProcessPaymentRequest)
        {
            /*
             * Dati transazione inviati verso GestPay
             * Alcuni dei parametri "importanti/principali" per creazione della stringa
             * "ShopLogin"         :VarChar (30) - Obbligatorio - Codice Esercente (Shop Login)
             * "Currency"          :Num (3) - Obbligatorio - Codice Identificativo della divisa per l'importo della transazione
             * "Amount"            :Num (9) - Obbligatorio - [ll separatore delle migliaia non deve essere inserito. I decimali (max 2 cifre) sono opzionali ed il separatore è il punto.]
             * "ShopTransactionID" :VarChar (50) - Obbligatorio - Identificativo attribuito alla transazione dall'esercente.
             * "BuyerName"         :VarChar (50) - Facoltativo - Nome e cognome dell'acquirente
             * "BuyerEmail"        :VarChar (50) - Facoltativo - Indirizzo e-mail dell'acquirente
             * "Language"          :Num (2) - Facoltativo - Codice che identifica la lingua utilizzata nella comunicazione con l'acquirente (vedi tabella Codici lingua).
             */
            var encryptedString  = "";
            var errorDescription = "";

            var nopBillingAddress = _addressService.GetAddressById(postProcessPaymentRequest.Order.BillingAddressId);

            var amount            = Math.Round(postProcessPaymentRequest.Order.OrderTotal, 2);
            var shopTransactionId = postProcessPaymentRequest.Order.OrderGuid.ToString();
            var buyerName         = String.Format(
                "{0} {1}",
                nopBillingAddress?.FirstName,
                nopBillingAddress?.LastName
                );

            var endpoint        = _gestPayPaymentSettings.UseSandbox ? EndpointConfiguration.WSCryptDecryptSoap12Test : EndpointConfiguration.WSCryptDecryptSoap12;
            var objCryptDecrypt = new WSCryptDecryptSoapClient(endpoint);

            var billingCountry       = _countryService.GetCountryById(Convert.ToInt32(nopBillingAddress.CountryId));
            var billingStateProvince = _stateProvinceService.GetStateProvinceByAddress(nopBillingAddress);

            Address       nopShippingAddress    = null;
            Country       shippingCountry       = null;
            StateProvince shippingStateProvince = null;

            if (postProcessPaymentRequest.Order.ShippingAddressId != null)
            {
                nopShippingAddress    = _addressService.GetAddressById((int)postProcessPaymentRequest.Order.ShippingAddressId);
                shippingCountry       = _countryService.GetCountryById((int)nopShippingAddress.CountryId);
                shippingStateProvince = _stateProvinceService.GetStateProvinceByAddress(nopShippingAddress);
            }

            XmlNode xmlResponse;
            EcommGestpayPaymentDetails paymentDetails = new EcommGestpayPaymentDetails();

            if (_gestPayPaymentSettings.EnableGuaranteedPayment)
            {
                FraudPrevention fraudPrevention = new FraudPrevention();
                fraudPrevention.BeaconSessionID  = _httpContextAccessor.HttpContext.Session.Id;
                fraudPrevention.SubmitForReview  = "1";
                fraudPrevention.OrderDateTime    = postProcessPaymentRequest.Order.CreatedOnUtc.ToString();
                fraudPrevention.Source           = "desktop_web";
                fraudPrevention.SubmissionReason = "rule_decision";
                fraudPrevention.VendorName       = _storeContext.CurrentStore.Name;
                paymentDetails.FraudPrevention   = fraudPrevention;

                //var logger = Nop.Core.Infrastructure.EngineContext.Current.Resolve<Nop.Services.Logging.ILogger>();
                //logger.Information("Gestpay BeaconId = " + _httpContextAccessor.HttpContext.Session.Id);

                var            customer       = _customerService.GetCustomerById(postProcessPaymentRequest.Order.CustomerId);
                CustomerDetail customerDetail = new CustomerDetail();
                customerDetail.PrimaryEmail       = nopBillingAddress?.Email;
                customerDetail.MerchantCustomerID = postProcessPaymentRequest.Order.CustomerId.ToString();
                customerDetail.FirstName          = nopBillingAddress?.FirstName;
                customerDetail.Lastname           = nopBillingAddress?.LastName;
                customerDetail.PrimaryPhone       = nopBillingAddress?.PhoneNumber;
                customerDetail.Company            = nopBillingAddress?.Company;
                customerDetail.CreatedAtDate      = customer?.CreatedOnUtc.ToString();
                customerDetail.VerifiedEmail      = "true";
                customerDetail.AccountType        = "normal";
                paymentDetails.CustomerDetail     = customerDetail;

                if (nopShippingAddress != null)
                {
                    ShippingAddress shippingAddress = new ShippingAddress();
                    shippingAddress.ProfileID      = postProcessPaymentRequest.Order.ShippingAddressId.ToString();
                    shippingAddress.FirstName      = nopShippingAddress.FirstName;
                    shippingAddress.Lastname       = nopShippingAddress.LastName;
                    shippingAddress.StreetName     = nopShippingAddress.Address1;
                    shippingAddress.Streetname2    = nopShippingAddress.Address2;
                    shippingAddress.City           = nopShippingAddress.City;
                    shippingAddress.ZipCode        = nopShippingAddress.ZipPostalCode;
                    shippingAddress.State          = shippingStateProvince?.Name;
                    shippingAddress.CountryCode    = shippingCountry?.TwoLetterIsoCode;
                    shippingAddress.Email          = nopShippingAddress.Email;
                    shippingAddress.PrimaryPhone   = nopShippingAddress.PhoneNumber;
                    shippingAddress.Company        = nopShippingAddress.Company;
                    shippingAddress.StateCode      = shippingStateProvince?.Abbreviation;
                    paymentDetails.ShippingAddress = shippingAddress;
                }

                BillingAddress billingAddress = new BillingAddress();
                billingAddress.ProfileID      = postProcessPaymentRequest.Order.BillingAddressId.ToString();
                billingAddress.FirstName      = nopBillingAddress?.FirstName;
                billingAddress.Lastname       = nopBillingAddress?.LastName;
                billingAddress.StreetName     = nopBillingAddress?.Address1;
                billingAddress.Streetname2    = nopBillingAddress?.Address2;
                billingAddress.City           = nopBillingAddress?.City;
                billingAddress.ZipCode        = nopBillingAddress?.ZipPostalCode;
                billingAddress.State          = billingStateProvince?.Name;
                billingAddress.CountryCode    = billingCountry?.TwoLetterIsoCode;
                billingAddress.Email          = nopBillingAddress?.Email;
                billingAddress.PrimaryPhone   = nopBillingAddress?.PhoneNumber;
                billingAddress.Company        = nopBillingAddress?.Company;
                billingAddress.StateCode      = billingStateProvince?.Abbreviation;
                paymentDetails.BillingAddress = billingAddress;

                var     orderItems        = _orderService.GetOrderItems(postProcessPaymentRequest.Order.Id);
                var     productDetails    = new List <ProductDetail>();
                decimal itemsTotalInclTax = 0;
                foreach (var item in orderItems)
                {
                    var product = _productService.GetProductById(item.ProductId);

                    if (product != null)
                    {
                        var productDetail = new ProductDetail();
                        productDetail.ProductCode = product.ManufacturerPartNumber;
                        productDetail.SKU         = product.Sku;
                        productDetail.Name        = product.Name;
                        productDetail.Description = product.ShortDescription;
                        productDetail.Quantity    = item.Quantity.ToString();
                        productDetail.Price       = item.PriceInclTax.ToString("0.00", CultureInfo.InvariantCulture);
                        productDetail.UnitPrice   = item.UnitPriceInclTax.ToString("0.00", CultureInfo.InvariantCulture);

                        if ((!product.IsGiftCard && product.IsShipEnabled) || (product.IsGiftCard && product.GiftCardType == Core.Domain.Catalog.GiftCardType.Physical))
                        {
                            productDetail.Type             = "physical";
                            productDetail.RequiresShipping = "true";
                        }
                        else
                        {
                            productDetail.Type             = "digital";
                            productDetail.RequiresShipping = "false";

                            if (product.IsGiftCard)
                            {
                                DigitalGiftCardDetails giftcardDetails = new DigitalGiftCardDetails();
                                var associatedGiftCards = _giftCardService.GetAllGiftCards(postProcessPaymentRequest.Order.Id);
                                foreach (var giftcard in associatedGiftCards)
                                {
                                    giftcardDetails.SenderName      = giftcard.SenderName;
                                    giftcardDetails.DisplayName     = giftcard.SenderName;
                                    giftcardDetails.GreetingMessage = giftcard.Message;

                                    Recipient recipient = new Recipient();
                                    recipient.Email           = giftcard.RecipientEmail;
                                    giftcardDetails.Recipient = recipient;

                                    break;
                                }
                                productDetail.DigitalGiftCardDetails = giftcardDetails;
                            }
                        }

                        productDetail.Vat       = item.PriceInclTax > 0 ? "22" : "0";
                        productDetail.Condition = "new";

                        var productManufacturers = _manufacturerService.GetProductManufacturersByProductId(product.Id);
                        productDetail.Brand = _manufacturerService.GetManufacturerById((int)productManufacturers.FirstOrDefault()?.ManufacturerId)?.Name;
                        //productDetail.DeliveryAt = "home";
                        productDetails.Add(productDetail);

                        itemsTotalInclTax += item.UnitPriceInclTax * item.Quantity;
                    }
                }
                paymentDetails.ProductDetails = productDetails.ToArray();

                IList <DiscountCode> discountCodes = new List <DiscountCode>();
                IList <ShippingLine> shippingLines = new List <ShippingLine>();

                //  Discount on Sub Total
                var subTotalDiscountCode = new DiscountCode();
                subTotalDiscountCode.Code   = "Order subtotal discount";
                subTotalDiscountCode.Amount = postProcessPaymentRequest.Order.OrderSubTotalDiscountInclTax.ToString("0.00", CultureInfo.InvariantCulture);
                discountCodes.Add(subTotalDiscountCode);

                //  Discount on Total
                var discountCode = new DiscountCode();
                discountCode.Code   = "Order total discount";
                discountCode.Amount = postProcessPaymentRequest.Order.OrderDiscount.ToString("0.00", CultureInfo.InvariantCulture);
                discountCodes.Add(discountCode);

                //  Shipping
                var shipping = new ShippingLine();
                shipping.Code  = postProcessPaymentRequest.Order.ShippingRateComputationMethodSystemName;
                shipping.Title = postProcessPaymentRequest.Order.ShippingRateComputationMethodSystemName;
                shipping.Price = postProcessPaymentRequest.Order.OrderShippingInclTax.ToString("0.00", CultureInfo.InvariantCulture);
                shippingLines.Add(shipping);

                //  Additional Charges / GiftWrap / GiftCard
                var extraAdjustment = postProcessPaymentRequest.Order.OrderTotal - (itemsTotalInclTax + postProcessPaymentRequest.Order.OrderShippingInclTax - postProcessPaymentRequest.Order.OrderDiscount - postProcessPaymentRequest.Order.OrderSubTotalDiscountInclTax);
                if (extraAdjustment > 0)
                {
                    var additionalShipping = new ShippingLine();
                    additionalShipping.Code  = "Additional Charge/Giftwrap";
                    additionalShipping.Title = "Additional Charge/Giftwrap";
                    additionalShipping.Price = extraAdjustment.ToString("0.00", CultureInfo.InvariantCulture);
                    shippingLines.Add(additionalShipping);
                }
                else
                {
                    var additionalDiscount = new DiscountCode();
                    additionalDiscount.Code   = "Giftcard/Additional Discount";
                    additionalDiscount.Amount = (extraAdjustment * -1).ToString("0.00", CultureInfo.InvariantCulture);      // * -1 converts into positive number
                    discountCodes.Add(additionalDiscount);
                }

                paymentDetails.DiscountCodes = discountCodes.ToArray();
                paymentDetails.ShippingLines = shippingLines.ToArray();
            }

            //  3DS
            var threeDSTransDetails = new ThreeDSEncryptTransDetails();

            threeDSTransDetails.type = "EC";
            threeDSTransDetails.authenticationAmount = amount.ToString("0.00", CultureInfo.InvariantCulture);

            var threeDSContainer = new EncryptThreeDsContainer();

            threeDSContainer.transTypeReq = "P";
            //threeDSContainer.exemption = "SKIP";  As asked by Gestpay Support

            BuyerDetails buyerDetails = new BuyerDetails();

            ThreeDSBillingAddress threeDSBillingAddress = new ThreeDSBillingAddress();

            threeDSBillingAddress.line1    = nopBillingAddress?.Address1;
            threeDSBillingAddress.line2    = nopBillingAddress?.Address2;
            threeDSBillingAddress.city     = nopBillingAddress?.City;
            threeDSBillingAddress.postCode = nopBillingAddress?.ZipPostalCode;
            threeDSBillingAddress.state    = billingStateProvince?.Name;
            threeDSBillingAddress.country  = billingCountry?.TwoLetterIsoCode;
            buyerDetails.billingAddress    = threeDSBillingAddress;

            if (nopShippingAddress != null)
            {
                ThreeDSShippingAddress threeDSShippingAddress = new ThreeDSShippingAddress();
                threeDSShippingAddress.line1    = nopShippingAddress?.Address1;
                threeDSShippingAddress.line2    = nopShippingAddress?.Address2;
                threeDSShippingAddress.city     = nopShippingAddress?.City;
                threeDSShippingAddress.postCode = nopShippingAddress?.ZipPostalCode;
                threeDSShippingAddress.state    = shippingStateProvince?.Name;
                threeDSShippingAddress.country  = shippingCountry?.TwoLetterIsoCode;
                buyerDetails.shippingAddress    = threeDSShippingAddress;
            }

            buyerDetails.addrMatch = "N";

            threeDSContainer.buyerDetails        = buyerDetails;
            threeDSTransDetails.threeDsContainer = threeDSContainer;

            xmlResponse = objCryptDecrypt.EncryptAsync(
                _gestPayPaymentSettings.ShopOperatorCode,
                _gestPayPaymentSettings.CurrencyUiCcode.ToString(),
                amount.ToString("0.00", CultureInfo.InvariantCulture),
                shopTransactionId,
                "", "", "", buyerName, nopBillingAddress.Email,
                _gestPayPaymentSettings.LanguageCode.ToString(), "",
                "Order Number = " + postProcessPaymentRequest.Order.CustomOrderNumber, "", "", "",
                null,
                null,
                null, "",
                null, null, null, null, null, null, "", null, "", "",
                paymentDetails, _gestPayPaymentSettings.ApiKey, threeDSTransDetails).Result.EncryptResult;

            XmlDocument xmlReturn = new XmlDocument();

            xmlReturn.LoadXml(xmlResponse.OuterXml);

            string errorCode = xmlReturn.SelectSingleNode("/GestPayCryptDecrypt/ErrorCode")?.InnerText;

            if (errorCode == "0")
            {
                encryptedString = xmlReturn.SelectSingleNode("/GestPayCryptDecrypt/CryptDecryptString")?.InnerText;
            }
            else
            {
                //Put error handle code HERE
                errorDescription = xmlReturn.SelectSingleNode("/GestPayCryptDecrypt/ErrorDescription")?.InnerText;
            }

            var builder = new StringBuilder();

            if (!String.IsNullOrEmpty(encryptedString))
            {
                builder.Append(GetGestPayUrl());
                builder.AppendFormat("?a={0}&b={1}", _gestPayPaymentSettings.ShopOperatorCode, encryptedString);
            }
            else
            {
                //Errore
                builder.Append(_webHelper.GetStoreLocation(false) + "Plugins/PaymentGestPay/Error");
                builder.AppendFormat("?type=0&errc={0}&errd={1}", HttpUtility.UrlEncode(errorCode), HttpUtility.UrlEncode(errorDescription));
            }
            _httpContextAccessor.HttpContext.Response.Redirect(builder.ToString());
        }