//To avoid using Reflection
 public static IDictionary <string, string> GetPropertiesDictionary(this CreditVouchersPostToAggregatorFormModel model)
 {
     return(new Dictionary <string, string>
     {
         { "Action", model.Action },
         { "AmountToPay", model.AmountToPay.ToString("####") },
         { "AmountCurrency", model.AmountCurrency },
         { "PaymentType", model.PaymentType },
         { "API_UserName", model.API_UserName },
         { "MerchantName", model.MerchantName },
         { "Partner_Email", model.Partner_Email },
         { "OrderId", model.OrderId.ToString() },
         { "PaymentOKURL", model.PaymentOKURL },
         { "PaymentFailURL", model.PaymentFailURL },
         { "CheckSumHeader", model.CheckSumHeader },
         { "CheckSum", model.CheckSum },
         { "API_Version", model.API_Version },
         { "Customer_FirstName", model.Customer_FirstName },
         { "Customer_LastName", model.Customer_LastName },
         { "Customer_City", model.Customer_City },
         { "Customer_Zip", model.Customer_Zip },
         { "Customer_Address", model.Customer_Address },
         { "Customer_Country", model.Customer_Country },
         { "Customer_Email", model.Customer_Email },
         { "Customer_MobileNumber", model.Customer_MobileNumber },
         { "Details", model.Details },
         { "PaymentNotifyURL", model.PaymentNotifyURL },
         { "SubscriptionType", model.SubscriptionType },
         { "SubscriptionStart", model.SubscriptionStart },
         { "SubscriptionEnd", model.SubscriptionEnd },
         { "WebsiteKey", model.WebsiteKey }
     });
 }
        public async Task <string> GetPaymentUrl(IPaymentTransaction bankCardOrder)
        {
            var creditVoucherOtherInfo = bankCardOrder.Info.DeserializeJson <CreditVoucherOtherPaymentInfo>();

            var postModel = new CreditVouchersPostToAggregatorFormModel
            {
                Action                = _creditVouchersSettings.Action,
                AmountToPay           = bankCardOrder.Amount * 100,      // ref to API documentation
                AmountCurrency        = _creditVouchersSettings.AssetId, //TODO
                PaymentType           = _creditVouchersSettings.PaymentType,
                API_UserName          = _creditVouchersSettings.ApiUserName,
                Partner_Email         = _creditVouchersSettings.ParthnerEmail,
                OrderId               = bankCardOrder.Id,
                PaymentOKURL          = string.Format(_creditVouchersSettings.PaymentOkUrlFormat, bankCardOrder.Id),
                PaymentFailURL        = string.Format(_creditVouchersSettings.PaymentFailUrlFormat, bankCardOrder.Id),
                API_Version           = _creditVouchersSettings.ApiVersion,
                Customer_FirstName    = creditVoucherOtherInfo.FirstName,
                Customer_LastName     = creditVoucherOtherInfo.LastName,
                Customer_City         = creditVoucherOtherInfo.City,
                Customer_Zip          = creditVoucherOtherInfo.Zip,
                Customer_Address      = creditVoucherOtherInfo.Address,
                Customer_Country      = creditVoucherOtherInfo.Country,
                Customer_Email        = creditVoucherOtherInfo.Email,
                Customer_MobileNumber = creditVoucherOtherInfo.ContactPhone,
                PaymentNotifyURL      = _creditVouchersSettings.PaymentNotifyUrlFormat
            };

            postModel.CheckSumHeader = _creditVouchersSecurity.CalculateHeaderCheckSum(postModel.GetPropertiesDictionary());
            postModel.CheckSum       = _creditVouchersSecurity.CalculateCheckSum(postModel.GetPropertiesDictionary(), postModel.CheckSumHeader);

            using (var client = new HttpClient())
            {
                var postedValues = postModel.GetPropertiesDictionary().Where(p => !string.IsNullOrEmpty(p.Value)).ToList();
                var resp         = await client.PostAsync(_creditVouchersSettings.AggregatorPaymentUrl, new FormUrlEncodedContent(postedValues));

                var respContent = await resp.Content.ReadAsStringAsync();

                resp.EnsureSuccessStatusCode();

                var respModel = JsonConvert.DeserializeObject <CreditVouchersPostToAggregatorResponceModel>(respContent);
                if (respModel.Status == CreditVoucherResponceStatus.Success)
                {
                    // mode=iframe is for Mobile version
                    var result = respModel.RedirectURL +
                                 ((respModel.RedirectURL ?? "").Contains("?") ? "&" : "?") +
                                 "mode=iframe";

                    return(result);
                }

                var logResp = $"Responce from credit voucher api. " +
                              $"Url: {_creditVouchersSettings.AggregatorPaymentUrl} , " +
                              $"ResponceStatusCode: {resp.StatusCode}, " +
                              $"ResponceBody:  {respContent} ";
                var errorsDescriptions = respModel.Errors.Select(p => $"{p.Key}: {string.Join(", ", p.Value)}");

                throw new ArgumentException($"CreditVouchers validation failed:{string.Join("; ", errorsDescriptions)}. Responce: {logResp}")
                      {
                      };
            }
        }