public override int TokenPayment(Payment payment)
        {
            if (!EnabledFor3d(payment.TransactionType))
            {
                return(590);
            }

            int ret = 10;

            try
            {
                xmlSent = "version=" + Tools.URLString(providerVersion)
                          + "&ipaddress="
                          + "&merchant_account=" + Tools.URLString(payment.ProviderUserID)
                          + "&first_name=" + Tools.URLString(payment.FirstName)
                          + "&last_name=" + Tools.URLString(payment.LastName)
                          + "&address1=" + Tools.URLString(payment.Address1())
                          + "&city=" + Tools.URLString(payment.Address2())
                          + "&state=" + Tools.URLString(payment.State)                               // USA only, do NOT include in hash
                          + "&zip_code=" + Tools.URLString(payment.PostalCode())
                          + "&country=" + Tools.URLString(payment.CountryCode())
                          + "&phone=" + Tools.URLString(payment.PhoneCell)
                          + "&email=" + Tools.URLString(payment.EMail)
                          + "&merchant_order=" + Tools.URLString(payment.MerchantReference)
                          + "&merchant_product_desc=" + Tools.URLString(payment.PaymentDescription)
                          + "&amount=" + Tools.URLString(payment.PaymentAmount.ToString())
                          + "&currency=" + Tools.URLString(payment.CurrencyCode)
                          + "&merchant_card_number=" + Tools.URLString(payment.CardToken);

                //	Checksum (SHA1)
                ret = 20;
                string chk = Tools.URLString(payment.ProviderUserID)
                             + Tools.URLString(payment.FirstName)
                             + Tools.URLString(payment.LastName)
                             + Tools.URLString(payment.Address1())
                             + Tools.URLString(payment.Address2())
                             + Tools.URLString(payment.PostalCode())
                             + Tools.URLString(payment.CountryCode())
                             + Tools.URLString(payment.PhoneCell)
                             + Tools.URLString(payment.EMail)
                             + Tools.URLString(payment.MerchantReference)
                             + Tools.URLString(payment.PaymentDescription)
                             + Tools.URLString(payment.PaymentAmount.ToString())
                             + Tools.URLString(payment.CurrencyCode)
                             + Tools.URLString(payment.CardToken)
                             + Tools.URLString(payment.ProviderKey);

                ret     = 40;
                xmlSent = xmlSent + "&control=" + HashSHA1(chk);

                Tools.LogInfo("TransactionT24.TokenPayment/20", "Post=" + xmlSent + ", Key=" + payment.ProviderKey, 30);

                ret = PostHTML(payment.ProviderURL);
            }
            catch (Exception ex)
            {
                Tools.LogException("TransactionT24.TokenPayment/90", "Ret=" + ret.ToString() + ", XML Sent=" + xmlSent, ex);
            }
            return(ret);
        }
        private string CardAddress(Payment payment)
        {
            string addr = "";

            if (payment.Address1(0).Length > 0)
            {
                addr = addr + "<address1>" + payment.Address1(0) + "</address1>";
            }
            if (payment.Address2(0).Length > 0)
            {
                addr = addr + "<address2>" + payment.Address2(0) + "</address2>";
            }
            if (payment.Address3(0).Length > 0)
            {
                addr = addr + "<address3>" + payment.Address3(0) + "</address3>";
            }
            if (payment.PostalCode(0).Length > 0)
            {
                addr = addr + "<postalCode>" + payment.PostalCode(0) + "</postalCode>";
            }
            if (payment.State.Length > 0)
            {
                addr = addr + "<state>" + payment.State + "</state>";
            }
            if (payment.CountryCode(0).Length > 0)
            {
                addr = addr + "<countryCode>" + payment.CountryCode(0) + "</countryCode>";
            }
            if (addr.Length > 0)
            {
                addr = "<cardAddress><address>" + addr + "</address></cardAddress>";
            }

            return(addr);
        }
        public override int TokenPayment(Payment payment)
        {
            if (!EnabledFor3d(payment.TransactionType))
            {
                return(590);
            }

            int ret = 600;

            xmlSent = "";

//	Testing
//			payment.ProviderURL      = "https://staging.payu.co.za";
//			payment.ProviderUserID   = "800060";
//			payment.ProviderPassword = "******";
//			payment.ProviderKey      = "{FBEF85FC-F395-4DE2-B17F-F53098D8F978}";
//			payment.RegionalId       = "8212115010081";
//			payment.CurrencyCode     = "ZAR";
//	//		payment.CardToken        = "E13648542276F54C44C754843840821D";
//			payment.CardToken        = "74BF0BC8AE9987B423AA94A4BC894A2A"; // This token WORKS!
//	Testing

            try
            {
                xmlSent = "<Safekey>" + payment.ProviderKey + "</Safekey>"
                          + "<TransactionType>PAYMENT</TransactionType>"
                          + "<AuthenticationType>TOKEN</AuthenticationType>"
                          + "<Customfield>"
                          + "<key>processingType</key>"
                          + "<value>REAL_TIME_RECURRING</value>"
                          + "</Customfield>"
                          + "<AdditionalInformation>"
                          + "<merchantReference>" + payment.MerchantReference + "</merchantReference>"
                          + "<notificationUrl>" + Tools.ConfigValue("SystemURL") + "/Succeed.aspx?TransRef=" + Tools.XMLSafe(payment.MerchantReference) + "</notificationUrl>"
                          + "</AdditionalInformation>"
                          + "<Customer>"
                          + "<merchantUserId>" + payment.ContractCode + "</merchantUserId>"
                          + "<countryCode>" + payment.CountryCode() + "</countryCode>"
                          + "<regionalId>" + payment.RegionalId + "</regionalId>"
                          + "</Customer>"
                          + "<Basket>"
                          + "<amountInCents>" + payment.PaymentAmount.ToString() + "</amountInCents>"
                          + "<currencyCode>" + payment.CurrencyCode + "</currencyCode>"
                          + "<description>" + payment.PaymentDescription + "</description>"
                          + "</Basket>"
                          + "<Creditcard>"
                          + "<pmId>" + payment.CardToken + "</pmId>"
                          + "<amountInCents>" + payment.PaymentAmount.ToString() + "</amountInCents>"
                          + "</Creditcard>";

                ret    = SendXML(payment.ProviderURL, payment.ProviderUserID, payment.ProviderPassword);
                payRef = Tools.XMLNode(xmlResult, "payUReference");
            }
            catch (Exception ex)
            {
                Tools.LogInfo("TokenPayment/98", "Ret=" + ret.ToString() + ", XML Sent=" + xmlSent, 255, this);
                Tools.LogException("TokenPayment/99", "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 = "";

            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 GetToken(Payment payment)
        {
            int ret = 300;

            xmlSent = "";

//	Testing
            //		payment.ProviderURL      = "https://staging.payu.co.za";
//	//		payment.ProviderUserID   = "800060";
//	//		payment.ProviderPassword = "******";
//	//		payment.ProviderKey      = "{FBEF85FC-F395-4DE2-B17F-F53098D8F978}";
            //		payment.ProviderUserID   = "200208";
            //		payment.ProviderPassword = "******";
            //		payment.ProviderKey      = "{A580B3C7-3EF3-47F1-9B90-4047CE0EC54C}";
            //		payment.RegionalId       = "8212115010081";
            //		payment.CurrencyCode     = "USD";
            //		payment.CardNumber       = "4000015372250142"; // This card works!
            //		payment.CardExpiryMM     = "07";
            //		payment.CardExpiryYYYY   = "2025";
            //		payment.CardCVV          = "123";
//	Testing

            try
            {
                string tmp = Tools.ConfigValue("SystemURL")
                             + "/Succeed.aspx?TransRef="
                             + Tools.XMLSafe(payment.MerchantReference)
                             + "&#38;Mode=";
                xmlSent = "<Safekey>" + payment.ProviderKey + "</Safekey>"
                          + "<TransactionType>RESERVE</TransactionType>"
                          + "<Customfield>"
                          + "<key>processingType</key>"
                          + "<value>REAL_TIME_RECURRING</value>"
                          + "</Customfield>"
                          + "<AdditionalInformation>"
                          + "<storePaymentMethod>true</storePaymentMethod>"
                          + "<secure3d>false</secure3d>"
                          + "<showBudget>false</showBudget>"
                          + "<demoMode>false</demoMode>"
                          + "<redirectChannel>responsive</redirectChannel>"
                          + "<supportedPaymentMethods>CREDITCARD_TOKEN</supportedPaymentMethods>"
                          + "<returnUrl>" + tmp + "1</returnUrl>"
                          + "<cancelUrl>" + tmp + "2</cancelUrl>"
                          + "<notificationUrl>" + tmp + "3</notificationUrl>"
                          + "<merchantReference>" + payment.MerchantReference + "</merchantReference>"
                          + "</AdditionalInformation>"
                          + "<Customer>"
                          + "<merchantUserId>" + payment.ContractCode + "</merchantUserId>"                  // This must be unique per customer, it is NOT the payment provider user id
                          + "<countryCode>" + payment.CountryCode() + "</countryCode>"
                          + "<regionalId>" + payment.RegionalId + "</regionalId>"
                          + "<email>" + payment.EMail + "</email>"
                          + "<firstName>" + payment.FirstName + "</firstName>"
                          + "<lastName>" + payment.LastName + "</lastName>"
                          + "<mobile>" + payment.PhoneCell + "</mobile>"
                          + "</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, "setTransaction");
//				tmp      = Tools.XMLNode(xmlResult,"gatewayReference");
//				payToken = Tools.XMLNode(xmlResult,"pmId");
                payRef = Tools.XMLNode(xmlResult, "payUReference");

                if (ret != 0)
                {
                    return(ret);
                }

                if (payRef.Length < 1)                   // || payToken.Length < 1 )
                {
                    return(320);
                }

//	Now complete the transaction

                ret = 330;
                string         url      = payment.ProviderURL + "/rpp.do?PayUReference=" + Tools.HTMLSafe(payRef);
                HttpWebRequest wRequest = (HttpWebRequest)WebRequest.Create(url);
                ret = 350;
                HttpWebResponse wResponse = (HttpWebResponse)wRequest.GetResponse();
                ret = 370;
                using (StreamReader rdr = new StreamReader(wResponse.GetResponseStream()))
                    strResult = rdr.ReadToEnd().Trim();

//	Get the token (pmId)

                ret     = 390;
                xmlSent = "<Safekey>" + payment.ProviderKey + "</Safekey>"
                          + "<AdditionalInformation>"
                          + "<payUReference>" + payRef + "</payUReference>"
                          + "</AdditionalInformation>";
                ret      = SendXML(payment.ProviderURL, payment.ProviderUserID, payment.ProviderPassword, "getTransaction");
                payToken = Tools.XMLNode(xmlResult, "pmId");

                if (ret != 0)
                {
                    return(ret);
                }

                if (payToken.Length < 1)
                {
                    return(410);
                }

//	Now reverse the initial RESERVE transaction

                ret     = 430;
                xmlSent = "<Safekey>" + payment.ProviderKey + "</Safekey>"
                          + "<TransactionType>RESERVE_CANCEL</TransactionType>"
                          + "<AuthenticationType>TOKEN</AuthenticationType>"
                          + "<AdditionalInformation>"
                          + "<merchantReference>" + payment.MerchantReference + "</merchantReference>"
                          + "<payUReference>" + payRef + "</payUReference>"
                          + "</AdditionalInformation>"
                          + "<Basket>"
                          + "<amountInCents>" + payment.PaymentAmount.ToString() + "</amountInCents>"
                          + "<currencyCode>" + payment.CurrencyCode + "</currencyCode>"
                          + "</Basket>"
                          + "<Creditcard>"
                          + "<amountInCents>" + payment.PaymentAmount.ToString() + "</amountInCents>"
                          + "</Creditcard>";
                ret = SendXML(payment.ProviderURL, payment.ProviderUserID, payment.ProviderPassword);
            }
            catch (Exception ex)
            {
                Tools.LogInfo("GetToken/98", "Ret=" + ret.ToString() + ", XML Sent=" + xmlSent, 255, this);
                Tools.LogException("GetToken/99", "Ret=" + ret.ToString() + ", XML Sent=" + xmlSent, ex, this);
            }
            return(ret);
        }
        public override int GetToken(Payment payment)
        {
            int ret = 10;

            try
            {
                xmlSent = "version=" + Tools.URLString(providerVersion)
                          + "&ipaddress="
                          + "&merchant_account=" + Tools.URLString(payment.ProviderUserID)
                          + "&first_name=" + Tools.URLString(payment.FirstName)
                          + "&last_name=" + Tools.URLString(payment.LastName)
                          + "&address1=" + Tools.URLString(payment.Address1())
                          + "&city=" + Tools.URLString(payment.Address2())
                          + "&state=" + Tools.URLString(payment.State)                               // USA only, do not include in hash
                          + "&zip_code=" + Tools.URLString(payment.PostalCode())
                          + "&country=" + Tools.URLString(payment.CountryCode())
                          + "&phone=" + Tools.URLString(payment.PhoneCell)
                          + "&email=" + Tools.URLString(payment.EMail)
                          + "&merchant_order=" + Tools.URLString(payment.MerchantReference)
                          + "&merchant_product_desc=" + Tools.URLString(payment.PaymentDescription)
                          + "&amount=" + Tools.URLString(payment.PaymentAmount.ToString())
                          + "&currency=" + Tools.URLString(payment.CurrencyCode)
                          + "&credit_card_type=" + Tools.URLString(payment.CardType)
                          + "&credit_card_number=" + Tools.URLString(payment.CardNumber)
                          + "&expire_month=" + Tools.URLString(payment.CardExpiryMM)
                          + "&expire_year=" + Tools.URLString(payment.CardExpiryYY)
                          + "&cvv2=" + Tools.URLString(payment.CardCVV);

                //	Checksum (SHA1)
                ret = 20;
                string chk = Tools.URLString(payment.ProviderUserID)
                             + Tools.URLString(payment.FirstName)
                             + Tools.URLString(payment.LastName)
                             + Tools.URLString(payment.Address1())
                             + Tools.URLString(payment.Address2())
                             + Tools.URLString(payment.PostalCode())
                             + Tools.URLString(payment.CountryCode())
                             + Tools.URLString(payment.PhoneCell)
                             + Tools.URLString(payment.EMail)
                             + Tools.URLString(payment.MerchantReference)
                             + Tools.URLString(payment.PaymentDescription)
                             + Tools.URLString(payment.PaymentAmount.ToString())
                             + Tools.URLString(payment.CurrencyCode)
                             + Tools.URLString(payment.CardType)
                             + Tools.URLString(payment.CardNumber)
                             + Tools.URLString(payment.CardExpiryMM)
                             + Tools.URLString(payment.CardExpiryYY)
                             + Tools.URLString(payment.CardCVV)
                             + Tools.URLString(payment.ProviderKey);

//	Do NOT include "State" in the checksum (David Tin, 2017/08/29)
//							  + Tools.URLString(payment.State)

//				ret        = 30;
//				xmlSent    = xmlSent + "&address2=";
//				if ( payment.Address(2).Length > 0 && payment.Address(2) != payment.Address(255) )
//				{
//					xmlSent = xmlSent + Tools.URLString(payment.Address(2));
//					chk     = chk + payment.Address(2);
//				}

                ret     = 40;
                xmlSent = xmlSent + "&control=" + HashSHA1(chk);

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

                ret      = PostHTML(payment.ProviderURL);
                payToken = Tools.XMLNode(xmlResult, "merchant_card_number");
                payRef   = Tools.XMLNode(xmlResult, "transaction_id");

                Tools.LogInfo("TransactionT24.GetToken/20", "ResultCode=" + ResultCode + ", payRef=" + payRef + ", payToken=" + payToken, 10);

//	Removed at Deon Smith's request (2017/08/25)
//	This code is correct, complete and tested. Merely un-comment it
//
//				if ( ret == 0 ) // Do refund
//				{
//					Tools.LogInfo("TransactionT24.GetToken/30","(Refund) Transaction Id=" + payRef,177);
//					ret     = 50;
//					xmlSent =  "merchant_account=" + Tools.URLString(payment.ProviderUserID)
//					        + "&order_id="         + Tools.URLString(payRef)
//					        + "&amount="           + Tools.URLString(payment.PaymentAmount.ToString())
//					        + "&currency="         + Tools.URLString(payment.CurrencyCode)
//					        + "&version="          + Tools.URLString(providerVersion);
//					ret     = 60;
//					chk     = payment.ProviderUserID
//					        + payRef
//					        + payment.PaymentAmount.ToString()
//					        + payment.CurrencyCode
//					        + providerVersion
//					        + payment.ProviderKey;
//					ret     = 70;
//					xmlSent = xmlSent + "&control=" + HashSHA1(chk);
//					Tools.LogInfo("TransactionT24.GetToken/40","(Refund) POST="+xmlSent+", Key="+payment.ProviderKey,177);
//					ret     = PostHTML(BureauURL + "/Refund");
//				}
            }
            catch (Exception ex)
            {
                Tools.LogException("TransactionT24.GetToken/90", "Ret=" + ret.ToString() + ", XML Sent=" + xmlSent, ex);
            }
            return(ret);
        }
        //	Moved to Transaction.cs
        //	private string customerId;
        //	private string paymentMethodId;

        public override int GetToken(Payment payment)
        {
            int ret = 10;

            err             = "";
            payToken        = "";
            customerId      = "";
            paymentMethodId = "";
            strResult       = "";
            resultCode      = "991";
            resultMsg       = "Fail";

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

            try
            {
//	Testing
//				StripeConfiguration.ApiKey = "sk_test_51It78gGmZVKtO2iKBZF7DA5JisJzRqvibQdXSfBj9eQh4f5UDvgCShZIjznOWCxu8MtcJG5acVkDcd8K184gIegx001uXlHI5g";
//	Testing
                ret = 20;
                StripeConfiguration.ApiKey = payment.ProviderPassword;                 // Secret key

                ret = 30;
                var tokenOptions = new TokenCreateOptions
                {
                    Card = new TokenCardOptions
                    {
                        Number   = payment.CardNumber,
                        ExpMonth = payment.CardExpiryMonth,
                        ExpYear  = payment.CardExpiryYear,
                        Cvc      = payment.CardCVV
                    }
                };
                ret = 40;
                var tokenService = new TokenService();
                var token        = tokenService.Create(tokenOptions);
                payToken = token.Id;
                err      = err + ", tokenId=" + Tools.NullToString(payToken);

                ret = 50;
                var paymentMethodOptions = new PaymentMethodCreateOptions
                {
                    Type = "card",
                    Card = new PaymentMethodCardOptions
                    {
                        Token = token.Id
                    }
                };
                ret = 60;
                var paymentMethodService = new PaymentMethodService();
                var paymentMethod        = paymentMethodService.Create(paymentMethodOptions);
                paymentMethodId = paymentMethod.Id;
                err             = err + ", paymentMethodId=" + Tools.NullToString(paymentMethodId);

                ret = 70;
                string tmp             = (payment.FirstName + " " + payment.LastName).Trim();
                var    customerOptions = new CustomerCreateOptions
                {
                    Name          = payment.CardName,                     // (payment.FirstName + " " + payment.LastName).Trim(),
                    Email         = payment.EMail,
                    Phone         = payment.PhoneCell,
                    Description   = payment.MerchantReference + (tmp.Length > 0 ? " (" + tmp + ")" : ""),
                    PaymentMethod = paymentMethod.Id
                };
                ret = 75;
                if (payment.Address1(0).Length > 0 || payment.Address2(0).Length > 0 || payment.ProvinceCode.Length > 0 || payment.CountryCode(0).Length > 0)
                {
                    ret = 80;
                    customerOptions.Address = new AddressOptions()
                    {
                        Line1 = payment.Address1(0),
                        //	Line2      = payment.Address2(0),
                        City       = payment.Address2(0),
                        State      = payment.ProvinceCode,
                        PostalCode = payment.PostalCode(0)
                    };
                    ret = 85;
                    if (payment.CountryCode(0).Length == 2)
                    {
                        customerOptions.Address.Country = payment.CountryCode(0).ToUpper();
                    }
                }

                ret = 90;
                var customerService = new CustomerService();
                var customer        = customerService.Create(customerOptions);
//				customer.Currency   = payment.CurrencyCode.ToLower();
                customerId = customer.Id;
                err        = err + ", customerId=" + Tools.NullToString(customerId);

                ret       = 100;
                strResult = customer.StripeResponse.Content;
//				resultMsg           = Tools.JSONValue(strResult,"status");
                resultCode = customer.StripeResponse.ToString();
                int k = resultCode.ToUpper().IndexOf(" STATUS=");
                ret = 110;
                err = err + ", StripeResponse=" + Tools.NullToString(resultCode);

//	customer.StripeResponse.ToString() is as follows:
//	<Stripe.StripeResponse status=200 Request-Id=req_bI0B5glG6r6DNe Date=2021-05-28T09:35:23>

                if (k > 0)
                {
                    resultCode = resultCode.Substring(k + 8).Trim();
                    k          = resultCode.IndexOf(" ");
                    if (k > 0)
                    {
                        resultCode = resultCode.Substring(0, k);
                    }
                }
                else
                {
                    resultCode = "999";
                }

                ret = 120;
                err = err + ", strResult=" + Tools.NullToString(strResult)
                      + ", resultCode=" + Tools.NullToString(resultCode);
                customer             = null;
                customerService      = null;
                customerOptions      = null;
                paymentMethod        = null;
                paymentMethodService = null;
                paymentMethodOptions = null;
                token        = null;
                tokenService = null;
                tokenOptions = null;

                if (resultCode.StartsWith("2") && payToken.Length > 0 && paymentMethodId.Length > 0 && customerId.Length > 0)
                {
                    resultMsg = "Success";
                    ret       = 0;
                    //	Tools.LogInfo ("GetToken/189","Ret=0"                 + err,255,this);
                }
                else
                {
                    Tools.LogInfo("GetToken/197", "Ret=" + ret.ToString() + err, 231, this);
                }
            }
            catch (Exception ex)
            {
                err = "Ret=" + ret.ToString() + err;
                Tools.LogInfo("GetToken/198", err, 231, this);
                Tools.LogException("GetToken/199", err, ex, this);
            }
            return(ret);
        }
        public override int GetToken(Payment payment)
        {
            string url = Tools.ConfigValue("SystemURL") + "/Succeed.aspx?TransRef=" + Tools.XMLSafe(payment.MerchantReference);
            int    ret = 300;

            Tools.LogInfo("TransactionIkajo.GetToken/10", "Sale, Merchant Ref=" + payment.MerchantReference, 10);

            try
            {
                string md5Signature = HashMD5(Tools.XMLSafe(payment.CardExpiryMM + payment.CardExpiryYY)
                                              + Tools.XMLSafe(payment.CardNumber)
                                              + Tools.XMLSafe(payment.CardType)
                                              + Tools.XMLSafe(payment.CardCVV)
                                              + Tools.XMLSafe(payment.Address1())
                                              + Tools.XMLSafe(payment.Address2())
                                              + Tools.XMLSafe(payment.CountryCode())
                                              + Tools.XMLSafe(payment.EMail)
                                              + Tools.XMLSafe(payment.MandateIPAddress)
                                              + Tools.XMLSafe(payment.FirstName + " " + payment.LastName)
                                              + Tools.XMLSafe(payment.PhoneCell)
                                              + Tools.XMLSafe(payment.State)
                                              + Tools.XMLSafe(payment.PostalCode())
                                              + Tools.XMLSafe("YES")
                                              + Tools.XMLSafe(payment.ProviderUserID)
                                              + Tools.XMLSafe(payment.PaymentAmountDecimal)
                                              + Tools.XMLSafe(payment.CurrencyCode)
                                              + Tools.XMLSafe(payment.PaymentDescription)
                                              + Tools.XMLSafe(payment.MerchantReference)
                                              + Tools.XMLSafe(url)
                                              + Tools.XMLSafe(payment.ProviderPassword));

                if (saleReq == null)
                {
                    saleReq = new SaleRequest();
                }

                saleReq.cardExpiration       = Tools.XMLSafe(payment.CardExpiryMM + payment.CardExpiryYY);
                saleReq.cardNumber           = Tools.XMLSafe(payment.CardNumber);
                saleReq.cardType             = Tools.XMLSafe(payment.CardType);
                saleReq.cardVerificationCode = Tools.XMLSafe(payment.CardCVV);
                saleReq.customerAddress      = Tools.XMLSafe(payment.Address1());
                saleReq.customerCity         = Tools.XMLSafe(payment.Address2());
                saleReq.customerCountry      = Tools.XMLSafe(payment.CountryCode());
                saleReq.customerEmail        = Tools.XMLSafe(payment.EMail);
                saleReq.customerIP           = Tools.XMLSafe(payment.MandateIPAddress);
                saleReq.customerName         = Tools.XMLSafe(payment.FirstName + " " + payment.LastName);
                saleReq.customerPhoneNumber  = Tools.XMLSafe(payment.PhoneCell);
                saleReq.customerState        = Tools.XMLSafe(payment.State);
                saleReq.customerZipCode      = Tools.XMLSafe(payment.PostalCode());
                saleReq.initRecurring        = "YES";
                saleReq.merchantID           = Tools.XMLSafe(payment.ProviderUserID);
                saleReq.orderAmount          = Tools.XMLSafe(payment.PaymentAmountDecimal);
                saleReq.orderCurrency        = Tools.XMLSafe(payment.CurrencyCode);
                saleReq.orderDescription     = Tools.XMLSafe(payment.PaymentDescription);
                saleReq.orderReference       = Tools.XMLSafe(payment.MerchantReference);
                saleReq.returnUrl            = Tools.XMLSafe(url);
                saleReq.signature            = md5Signature;

                Tools.LogInfo("TransactionIkajo.GetToken/20", "", 10);

                if (ikajo == null)
                {
                    ikajo = new PtCardService();
                }

                PCIBusiness.IkajoService.SaleResult result = ikajo.sale(saleReq);
                string x = "[TokenResult] StatusCode=" + result.statusCode
                           + " | TransactionStatus=" + result.transactionStatus
                           + " | TransactionError=" + result.transactionError
                           + " | RecurringToken=" + result.recurringToken;

                Tools.LogInfo("TransactionIkajo.GetToken/30", x, 10);

                payToken   = result.recurringToken;
                payRef     = result.orderReference;
                resultCode = result.transactionStatus;
                resultMsg  = result.transactionError;

//				if ( ret != 0 )
//					Tools.LogInfo("TransactionIkajo.GetToken/50","ResultCode="+ResultCode + ", payToken=" + payToken,220);
            }
            catch (Exception ex)
            {
                Tools.LogInfo("TransactionIkajo.GetToken/98", "Ret=" + ret.ToString() + ", XML Sent=" + xmlSent, 255);
                Tools.LogException("TransactionIkajo.GetToken/99", "Ret=" + ret.ToString() + ", XML Sent=" + xmlSent, ex);
            }
            return(ret);
        }