public override int ThreeDSecurePayment(Payment payment, Uri postBackURL, string languageCode = "", string languageDialectCode = "")
        {
            int    ret = 10;
            string url = "";

            try
            {
                if (postBackURL == null)
                {
                    url = Tools.ConfigValue("SystemURL");
                }
                else
                {
                    url = postBackURL.GetLeftPart(UriPartial.Authority);
                }
                if (!url.EndsWith("/"))
                {
                    url = url + "/";
                }

                if (payment.TokenizerCode == Tools.BureauCode(Constants.PaymentProvider.TokenEx))
                {
                    xmlSent = "{{{" + Tools.URLString(payment.CardToken) + "}}}";
                }
                else
                {
                    xmlSent = Tools.URLString(payment.CardNumber);
                }

                d3Form  = "";
                xmlSent = "entityId=" + Tools.URLString(payment.ProviderUserID)
                          + "&amount=" + Tools.URLString(payment.PaymentAmountDecimal)
                          + "&currency=" + Tools.URLString(payment.CurrencyCode)
                          + "&card.number=" + xmlSent
                          + "&card.holder=" + Tools.URLString(payment.CardName)
                          + "&card.expiryMonth=" + Tools.URLString(payment.CardExpiryMM)
                          + "&card.expiryYear=" + Tools.URLString(payment.CardExpiryYYYY)
                          + "&card.cvv=" + Tools.URLString(payment.CardCVV)
                          + "&merchantTransactionId=" + Tools.URLString(payment.MerchantReference)
                          + "&descriptor=" + Tools.URLString(payment.PaymentDescription)
                          + "&shopperResultUrl=" + Tools.URLString(url + "RegisterThreeD.aspx"
                                                                   + "?ProviderCode=" + Tools.BureauCode(Constants.PaymentProvider.Peach)
                                                                   + "&TransRef=" + Tools.XMLSafe(payment.MerchantReference));
//				        + "&paymentType=DB"
//				        + "&shopperResultUrl="      + Tools.URLString(Tools.ConfigValue("SystemURL")+"/RegisterThreeD.aspx?TransRef="+Tools.XMLSafe(payment.MerchantReference));

                Tools.LogInfo("ThreeDSecurePayment/10", "Post=" + xmlSent + ", Key=" + payment.ProviderKey, 10, this);

                ret    = PostHTML((byte)Constants.TransactionType.ThreeDSecurePayment, payment);
                payRef = Tools.JSONValue(strResult, "id");

                if (ret > 0)
                {
                    Tools.LogInfo("ThreeDSecurePayment/20", "strResult=" + strResult, 222, this);
                }

/*
 * //	TESTING
 *                              ret = 0;
 *                              strResult = @"{
 |id|:|8ac7a4a173bdef630173be24d9710ad9|,
 |paymentBrand|:|VISA|,
 |amount|:|12.50|,
 |currency|:|EUR|,
 |result|:{
 |code|:|000.200.000|,
 |description|:|transaction pending|
 *                                                                      },
 |card|:{
 |bin|:|471110|,
 |last4Digits|:|0000|,
 |holder|:|John Smith|,
 |expiryMonth|:|12|,
 |expiryYear|:|2021|
 *                                                                      },
 |threeDSecure|:{
 |eci|:|06|
 *                                                                      },
 |redirect|:{
 |url|:|https://test.ppipe.net/connectors/demo/simulator.link?ndcid=8a8294174e735d0c014e78cf26461790_32b958682e7942e5a045c5b08bbd03ce&REMOTEADDRESS=10.71.36.33|,
 |parameters|:[
 *                                                                              {
 |name|:|PaReq|,
 |value|:|IT8ubu+5z4YupUCOEHKsbiPep8UzIAcPKJEjpwGlzD8#NDcxMTEwMDAwMDAwMDAwMCMxMi41MCBFVVIj|
 *                                                                              },
 *                                                                              {
 |name|:|TermUrl|,
 |value|:|https://test.ppipe.net/connectors/asyncresponse_simulator;jsessionid=12885DB09A3E49DB8B6214E20A7246D7.uat01-vm-con02?asyncsource=THREEDSECURE&ndcid=8a8294174e735d0c014e78cf26461790_32b958682e7942e5a045c5b08bbd03ce|
 *                                                                              },
 *                                                                              {
 |name|:|connector|,
 |value|:|THREEDSECURE|
 *                                                                              },
 *                                                                              {
 |name|:|MD|,
 |value|:|8ac7a4a173bdef630173be24d9710ad9|
 *                                                                              }
 *                                                                              ]
 *                                                                      },
 |buildNumber|:|982467e36fd8bc9e74f536ba375c5d0be4fe48eb@2020-07-30 03:42:32 +0000|,
 |timestamp|:|2020-08-05 10:22:32+0000|,
 |ndc|:|8a8294174e735d0c014e78cf26461790_32b958682e7942e5a045c5b08bbd03ce|
 *                                                                      }";
 *                              strResult = strResult.Replace("|","\"");
 * //	TESTING
 */

                short k = 1;
                string[,] d3Parms = new string[100, 3];
                string d3Parm = Tools.JSONValue(strResult, "parameters", "", k);
                string d3URL  = Tools.JSONValue(strResult, "url");

                while (d3Parm.Length > 0 && k < 100)
                {
                    d3Parms[k, 1] = Tools.JSONValue(d3Parm, "name");
                    d3Parms[k, 2] = Tools.JSONValue(d3Parm, "value");
                    d3Form        = d3Form + "<input type='hidden' name='" + d3Parms[k, 1] + "' value='" + d3Parms[k, 2] + "' />";
                    k++;
                    d3Parm = Tools.JSONValue(strResult, "parameters", "", k);
                }

                if (d3Form.Length > 0)
                {
                    //	Ver 1
                    //	d3Form = "<form name='frm3D' action='" + d3URL + "' class='paymentWidgets'>"
                    //	       + d3Form
                    //	       + "</form>"
                    //	       + "<script type='text/javascript'>"
                    //	       + "document.frm3D.submit();"
                    //	       + "</script>";
                    //	Ver 2
                    d3Form = "<html><body onload='document.forms[\"frm3D\"].submit()'>"
                             + "<form name='frm3D' method='POST' action='" + d3URL + "'>"
                             + d3Form
                             + "</form></body></html>";
                    string sql = "exec sp_WP_PaymentRegister3DSecA @ContractCode=" + Tools.DBString(payment.MerchantReference)
                                 + ",@ReferenceNumber=" + Tools.DBString(payRef)
                                 + ",@Status='77'";                                              // Means payment pending
                    if (languageCode.Length > 0)
                    {
                        sql = sql + ",@LanguageCode=" + Tools.DBString(languageCode);
                    }
                    if (languageDialectCode.Length > 0)
                    {
                        sql = sql + ",@LanguageDialectCode=" + Tools.DBString(languageDialectCode);
                    }
                    using (MiscList mList = new MiscList())
                        mList.ExecQuery(sql, 0, "", false, true);
                    Tools.LogInfo("ThreeDSecurePayment/50", "PayRef=" + payRef + "; SQL=" + sql + "; " + d3Form, 10, this);
                    return(0);
                }
                Tools.LogInfo("ThreeDSecurePayment/60", "ResultCode=" + ResultCode + ", payRef=" + payRef, 221, this);
            }
            catch (Exception ex)
            {
                Tools.LogException("ThreeDSecurePayment/90", "Ret=" + ret.ToString() + ", XML Sent=" + xmlSent, ex, this);
            }
            return(ret);
        }
        public override int ThreeDSecurePayment(Payment payment, Uri postBackURL, string languageCode = "", string languageDialectCode = "")
        {
            int    ret = 10;
            string url = "";

            err = "";

            try
            {
                StripeConfiguration.ApiKey = payment.ProviderPassword;                 // Secret key

                if (postBackURL == null)
                {
                    url = Tools.ConfigValue("SystemURL");
                }
                else
                {
                    url = postBackURL.GetLeftPart(UriPartial.Authority);
                }
                if (!url.EndsWith("/"))
                {
                    url = url + "/";
                }
                d3Form = "";
                ret    = 20;
                url    = url + "RegisterThreeD.aspx?ProviderCode=" + bureauCode
                         + "&TransRef=" + Tools.XMLSafe(payment.MerchantReference);

                ret = 50;
                var paymentMethodOptions = new PaymentMethodCreateOptions
                {
                    Type = "card",
                    Card = new PaymentMethodCardOptions
                    {
                        Number   = payment.CardNumber,
                        ExpMonth = payment.CardExpiryMonth,
                        ExpYear  = payment.CardExpiryYear,
                        Cvc      = payment.CardCVV
                    }
                };
                ret = 60;
                var paymentMethodService = new PaymentMethodService();
                var paymentMethod        = paymentMethodService.Create(paymentMethodOptions);
                err = err + ", paymentMethodId=" + Tools.NullToString(paymentMethod.Id);

                ret = 70;
                var customerOptions = new CustomerCreateOptions
                {
                    Name          = payment.CardName,                     // (payment.FirstName + " " + payment.LastName).Trim(),
                    Email         = payment.EMail,
                    Phone         = payment.PhoneCell,
                    PaymentMethod = paymentMethod.Id
                };
                ret = 80;
                var customerService = new CustomerService();
                var customer        = customerService.Create(customerOptions);
                err = err + ", customerId=" + Tools.NullToString(customer.Id);

//				if ( payment.PaymentDescription.Length < 1 )
//					payment.PaymentDescription = "CareAssist";
//				else if ( payment.PaymentDescription.Length > 22 )
//					payment.PaymentDescription = payment.PaymentDescription.Substring(0,22);

//	Stripe needs a minimum payment of 50 US cents
                var paymentIntentOptions = new PaymentIntentCreateOptions
                {
                    Amount              = 050,                         // payment.PaymentAmount,
                    Currency            = "usd",                       // payment.CurrencyCode.ToLower(), // Must be "usd" not "USD"
                    StatementDescriptor = payment.PaymentDescriptionLeft(22),
                    Customer            = customer.Id,
                    PaymentMethod       = paymentMethod.Id,
                    Description         = payment.MerchantReference,
                    ConfirmationMethod  = "manual"
                };
                ret = 40;
                var paymentIntentService = new PaymentIntentService();
                var paymentIntent        = paymentIntentService.Create(paymentIntentOptions);
                err = err + ", paymentIntentId=" + Tools.NullToString(paymentIntent.Id);

                ret = 50;
                var confirmOptions = new PaymentIntentConfirmOptions
                {
                    PaymentMethod = paymentMethod.Id,
                    ReturnUrl     = url
                };
                ret = 60;
                var paymentConfirm = paymentIntentService.Confirm(paymentIntent.Id, confirmOptions);
                payRef = paymentConfirm.Id;
                err    = err + ", paymentConfirmId=" + Tools.NullToString(payRef);

                ret        = 70;
                strResult  = paymentConfirm.StripeResponse.Content;
                d3Form     = Tools.JSONValue(strResult, "url", "next_action");
                d3Form     = Tools.JSONRaw(d3Form);
                resultMsg  = Tools.JSONValue(strResult, "status");
                ret        = 80;
                resultCode = paymentConfirm.StripeResponse.ToString();
                int k = resultCode.ToUpper().IndexOf(" STATUS=");
                err = err + ", StripeResponse=" + Tools.NullToString(resultCode);
                ret = 90;

                Tools.LogInfo("ThreeDSecurePayment/60", "strResult=" + strResult, 221, this);

                string sql = "exec sp_WP_PaymentRegister3DSecA @ContractCode=" + Tools.DBString(payment.MerchantReference)
                             + ",@ReferenceNumber=" + Tools.DBString(payRef)
                             + ",@Status='77'";                                               // Means payment pending
                if (languageCode.Length > 0)
                {
                    sql = sql + ",@LanguageCode=" + Tools.DBString(languageCode);
                }
                if (languageDialectCode.Length > 0)
                {
                    sql = sql + ",@LanguageDialectCode=" + Tools.DBString(languageDialectCode);
                }
                using (MiscList mList = new MiscList())
                    mList.ExecQuery(sql, 0, "", false, true);

                Tools.LogInfo("ThreeDSecurePayment/80", "PayRef=" + payRef + "; SQL=" + sql + "; " + d3Form, 10, this);
                return(0);
            }
            catch (Exception ex)
            {
                Tools.LogException("ThreeDSecurePayment/99", "Ret=" + ret.ToString(), ex, this);
            }
            return(ret);
        }
        public override int ThreeDSecurePayment(Payment payment, Uri postBackURL, string languageCode = "", string languageDialectCode = "")
        {
            int    ret = 10;
            string url = "";

            d3Form = "";

            try
            {
                if (postBackURL == null)
                {
                    url = Tools.ConfigValue("SystemURL");
                }
                else
                {
                    url = postBackURL.GetLeftPart(UriPartial.Authority);
                }
                if (!url.EndsWith("/"))
                {
                    url = url + "/";
                }
                url = url + "RegisterThreeD.aspx?ProviderCode=" + bureauCode
                      + "&amp;TransRef=" + Tools.XMLSafe(payment.MerchantReference);
//				          +                    "&amp;PayUReference="+Tools.XMLSafe(payment.TransactionID);

                if (payment.TokenizerCode == Tools.BureauCode(Constants.PaymentProvider.TokenEx))
                {
                    xmlSent = "{{{" + Tools.URLString(payment.CardToken) + "}}}";
                }
                else
                {
                    xmlSent = Tools.URLString(payment.CardNumber);
                }

//	2021/11/11 NOT Added
//				        + "<Customfield>"
//				        +   "<key>processingType</key>"
//				        +   "<value>REAL_TIME_RECURRING</value>"
//				        + "</Customfield>"
//	2021/11/11 Added
//				        + "<AdditionalInformation>"
//				        +   "<storePaymentMethod>true</storePaymentMethod>"
//				        +   "<supportedPaymentMethods>CREDITCARD_TOKEN</supportedPaymentMethods>"
//	2021/11/11 Removed
//				        +   "<supportedPaymentMethods>CREDITCARD</supportedPaymentMethods>"

                xmlSent = "<Safekey>" + payment.ProviderKey + "</Safekey>"
                          + "<TransactionType>RESERVE</TransactionType>"
                          + "<AdditionalInformation>"
                          + "<storePaymentMethod>true</storePaymentMethod>"
                          + "<supportedPaymentMethods>CREDITCARD_TOKEN</supportedPaymentMethods>"
                          + "<secure3d>true</secure3d>"
                          + "<returnUrl>" + url + "</returnUrl>"
                          + "<cancelUrl>" + url + "</cancelUrl>"
                          + "<notificationUrl>" + url + "</notificationUrl>"
                          + "<merchantReference>" + payment.MerchantReference + "</merchantReference>"
                          + "</AdditionalInformation>"
                          + "<Customer>"
                          + "<merchantUserId>" + payment.ContractCode + "</merchantUserId>"
                          + "<countryCode>" + payment.CountryCode() + "</countryCode>"
                          + "<email>" + payment.EMail + "</email>"
                          + "<firstName>" + payment.FirstName + "</firstName>"
                          + "<lastName>" + payment.LastName + "</lastName>"
                          + "<mobile>" + payment.PhoneCell + "</mobile>"
                          + "<regionalId>" + payment.RegionalId + "</regionalId>"
                          + "</Customer>"
                          + "<Basket>"
                          + "<amountInCents>" + payment.PaymentAmount.ToString() + "</amountInCents>"
                          + "<currencyCode>" + payment.CurrencyCode + "</currencyCode>"
                          + "<description>" + payment.PaymentDescription + "</description>"
                          + "</Basket>"
                          + "<Creditcard>"
                          + "<nameOnCard>" + payment.CardName + "</nameOnCard>"
                          + "<amountInCents>" + payment.PaymentAmount.ToString() + "</amountInCents>"
                          + "<cardNumber>" + payment.CardNumber + "</cardNumber>"
                          + "<cardExpiry>" + payment.CardExpiryMM + payment.CardExpiryYYYY + "</cardExpiry>"
                          + "<cvv>" + payment.CardCVV + "</cvv>"
                          + "</Creditcard>";

                ret    = SendXML(payment.ProviderURL, payment.ProviderUserID, payment.ProviderPassword);
                payRef = Tools.XMLNode(xmlResult, "payUReference");
                d3Form = Tools.XMLNode(xmlResult, "url", "", "", "redirect");

                if (ret == 0 && payRef.Length > 0 && d3Form.Length > 0)
                {
                    string sql = "exec sp_WP_PaymentRegister3DSecA @ContractCode=" + Tools.DBString(payment.MerchantReference)
                                 + ",@ReferenceNumber=" + Tools.DBString(payRef)
                                 + ",@Status='77'";                                              // Means payment pending
                    if (languageCode.Length > 0)
                    {
                        sql = sql + ",@LanguageCode=" + Tools.DBString(languageCode);
                    }
                    if (languageDialectCode.Length > 0)
                    {
                        sql = sql + ",@LanguageDialectCode=" + Tools.DBString(languageDialectCode);
                    }
                    using (MiscList mList = new MiscList())
                        mList.ExecQuery(sql, 0, "", false, true);
                    Tools.LogInfo("ThreeDSecurePayment/50", "PayRef=" + payRef + "; SQL=" + sql + "; " + d3Form, 10, this);
                    return(0);
                }
                else if (ret == 0 && payRef.Length == 0)
                {
                    ret = 73;
                }
                else if (ret == 0 && d3Form.Length == 0)
                {
                    ret = 74;
                }

//				Tools.LogInfo("ThreeDSecurePayment/60","ResultCode="+ResultCode + ", payRef=" + payRef,221,this);
            }
            catch (Exception ex)
            {
                Tools.LogException("ThreeDSecurePayment/90", "Ret=" + ret.ToString() + ", XML Sent=" + xmlSent, ex, this);
            }
            return(ret);
        }
        public override int ThreeDSecurePayment(Payment payment, Uri postBackURL, string languageCode = "", string languageDialectCode = "")
        {
            int    ret       = 10;
            string urlReturn = "";

            try
            {
//				Tools.LogInfo("ThreeDSecurePayment/10","Merchant Ref=" + payment.MerchantReference,10,this);

                if (postBackURL == null)
                {
                    urlReturn = Tools.ConfigValue("SystemURL");
                }
                else
                {
                    urlReturn = postBackURL.GetLeftPart(UriPartial.Authority);
                }
                if (!urlReturn.EndsWith("/"))
                {
                    urlReturn = urlReturn + "/";
                }
                ret       = 20;
                urlReturn = urlReturn + "RegisterThreeD.aspx?ProviderCode=" + bureauCode
                            + "&TransRef=" + Tools.XMLSafe(payment.MerchantReference)
                            + "&OrderCode=" + Tools.XMLSafe(payment.TransactionID)
                            + "&SessionID=" + Tools.XMLSafe(payment.SessionID);

                string descr = payment.PaymentDescription;
                if (descr.Length < 1)
                {
                    descr = "Initial 3d Secure payment";
                }

                ret     = 40;
                xmlSent = "<order orderCode='" + payment.TransactionID + "'>"
                          + "<description>" + payment.PaymentDescription + "</description>"
                          + "<amount currencyCode='" + payment.CurrencyCode + "'"
                          + " exponent='2'"
                          + " value='" + payment.PaymentAmount.ToString() + "' />"
                          + "<orderContent />"
                          + "<paymentDetails>"
                          + "<CARD-SSL>"
                          + "<cardNumber>" + payment.CardNumber + "</cardNumber>"
                          + "<expiryDate>"
                          + "<date month='" + payment.CardExpiryMM + "' year='" + payment.CardExpiryYYYY + "' />"
                          + "</expiryDate>"
                          + "<cardHolderName>3D</cardHolderName>"                     // + payment.CardName + "</cardHolderName>"
                          + "<cvc>" + payment.CardCVV + "</cvc>"
                          + CardAddress(payment)
                          + "</CARD-SSL>"
                          + "<session shopperIPAddress='" + payment.MandateIPAddress + "'"
                          + " id='" + payment.SessionID + "' />"                                         // Session id must be unique for each order
                          + "</paymentDetails>"
                          + "<shopper>"
                          + "<shopperEmailAddress>" + payment.EMail + "</shopperEmailAddress>"
                          + "<browser>"
                          + "<acceptHeader>text/html</acceptHeader>"
                          + "<userAgentHeader>" + payment.MandateBrowser + "</userAgentHeader>"
                          + "</browser>"
                          + "</shopper>"
                          + "<additional3DSData dfReferenceId=\"" + payment.SessionID + "\" />"
                          + "</order>";

//				        +   "<dynamicInteractionType type='ECOMMERCE' />"
//				        +   "<dynamic3DS overrideAdvice='do3DS' />"

                ret = 60;
                ret = CallWebService(payment, (byte)Constants.TransactionType.ThreeDSecurePayment);

/* Sample
 * <reply>
 *    <orderStatus orderCode="ExampleOrder1"> <!--The orderCode you supplied in the order-->
 *       <requestInfo>
 *          <request3DSecure> <!--PaRequest must be supplied as-is. Do not truncate-->
 *             <paRequest>eJxVUsFuwjAM/ZWK80aSUgpFJogNpHEo2hjTzlVr0Uq0KUkYsK+fUwpl72Q/2y/Jc2B2LvfeD2pTqGraE33e82YStrlGXHxietQoIUZjkh16RUYdQTge8DAII3846kl4n2/wIKFVkCTQ94HdUhrVaZ5UVkKSHl5Wayk6AGs5KFGvFo8lh+eu71qHOjHmpHQmhT8IhuFoDOxOQZWUKL+V3md1cvEWWCqTqxpYw0OqjpXVFzn0aeiWwFHvZW5tPWGsUtqqylilEZjjgXV3fz+6yJDOuchk/DsX8XZ3Wi+WPP6YP2IKzHVAlliUPhchHwnf4+FkGEz8CFjDQ1K6C8jl18YTT5yTD1cCanfO/JoIV3gkgJahsUovMnIvv2eA51pVSB1k/D2GDE0qLRrrkT2o6WxHAOve8vrmtpJasjYgDAg+4baapuDEC7JKRDxs1F0CzI2ydvWs/R4U/fs2f8B1wXg=</paRequest>
 *             <issuerURL><![CDATA[https://secure-test.worldpay.com/jsp/test/shopper/ThreeDResponseSimulator.jsp]]></issuerURL>
 *          </request3DSecure>
 *       </requestInfo>
 *       <echoData>1374244409987691395</echoData> <!--For compatibility with older integrations - can be ignored-->
 *    </orderStatus>
 * </reply>
 */
                if (ret == 0 && payRef.Length > 0 && otherRef.Length > 0 && d3Form.Length > 0)
                {
                    d3Form = "<html><body onload='document.forms[\"frm3D\"].submit()'>"
                             + "<form name='frm3D' method='POST' action='" + d3Form + "'>"
                             + "<input type='hidden' name='PaReq' value='" + payRef + "' />"
                             + "<input type='hidden' name='TermUrl' value='" + urlReturn + "' />"
                             + "<input type='hidden' name='MD' value='" + otherRef + "' />"
                             + "</form></body></html>";
                    string sql = "exec sp_WP_PaymentRegister3DSecA @ContractCode=" + Tools.DBString(payment.MerchantReference)
                                 + ",@ReferenceNumber=" + Tools.DBString(payRef)
                                 + ",@Status='77'";                                              // Means payment pending
                    if (languageCode.Length > 0)
                    {
                        sql = sql + ",@LanguageCode=" + Tools.DBString(languageCode);
                    }
                    if (languageDialectCode.Length > 0)
                    {
                        sql = sql + ",@LanguageDialectCode=" + Tools.DBString(languageDialectCode);
                    }
                    using (MiscList mList = new MiscList())
                        mList.ExecQuery(sql, 0, "", false, true);
                    Tools.LogInfo("ThreeDSecurePayment/50", "PayReq=" + payRef + "; Cookie=" + otherRef + "; SQL=" + sql + "; " + d3Form, logPriority, this);
                    return(0);
                }
            }
            catch (Exception ex)
            {
                Tools.LogInfo("ThreeDSecurePayment/98", "Ret=" + ret.ToString() + ", XML Sent=" + xmlSent, 255, this);
                Tools.LogException("ThreeDSecurePayment/99", "Ret=" + ret.ToString() + ", XML Sent=" + xmlSent, ex, this);
            }
            return(ret);
        }