Я работаю над реализацией размещенной проверки, и предполагается, что размещенная проверка перенаправляет пользователя обратно на мой веб-сайт, чтобы я мог показать пользовательскую страницу квитанции.
Это образец строки запроса, которую я получу обратно:
trnApproved = 0 & trnId = 10000000 & MessageId = 71 & MessageText = Отклонено & AuthCode = 000000 & responseType = Т & trnAmount = 20,00 & trnDate = 9% 2f23% 2f2011 + 9% 3A30% 3a56 + AM & trnOrderNumber = 1000000 & trnLanguage = анг & trnCustomerName = FirstName + LastName & trnEmailAddress = something_something% 40gmail.com & trnPhoneNumber = 1235550123 & avsProcessed = 0 & avsId = 0 & avsResult = 0 & avsAddrMatch = 0 & avsPostalMatch = 0 & avsMessage = Адрес + Проверочный + не + выполняется + для + это + транзакции. & cvdId = 3 & cardType = VI & trnType = Р & PAYMENTMETHOD = CC & ref1 = 9dae6af7-7c22-4697-b23a-413d8a129a75 & ref2 = & REF3 = & REF4 = & REF5 = & = 33dacf84682470f267b2cc6d528b1594 значения хэша
Чтобы проверить запрос, я должен удалить &hashValue=f3cf58ef0fd363e0c2241938b04f1068
из конца строки запроса, а затем добавить ключ. Затем я выполняю MD5-хеш всей строки, и результат должен быть 33dacf84682470f267b2cc6d528b1594
, такой же, как и у оригинала.
Это легко, за исключением того, что некоторые поля вызывают у меня проблемы. Это код, который я использую (взят из фиктивного приложения, так что вы можете игнорировать некоторые плохие коды):
// Split up the query string parameters
string[] parameters = GetQueryString().Split(new[] { "&" }, StringSplitOptions.None);
var querySet = new List<string>();
// Rebuild the query string, encoding the values.
foreach (string s in parameters)
{
// Every field that contains a "." will need to be encoded except for trnAmount
querySet.Add(param.Contains("trnAmount") ? param : UrlEncodeToUpper(param));
}
// Create the querystring without the hashValue, we need to calculate our hash without it.
string qs = string.Join("&", querySet.ToArray());
qs = qs.Substring(0, qs.IndexOf("&hashValue"));
qs = qs + "fb76124fea73488fa11995dfa4cbe89b";
var encoding = new UTF8Encoding();
var md5 = new MD5CryptoServiceProvider();
var hash = md5.ComputeHash(encoding.GetBytes(qs));
var calculatedHash = BitConverter.ToString(hash).Replace("-", String.Empty).ToLower();
Это метод UrlEncode, который я использую.
private static string UrlEncodeToUpper(string value)
{
// Convert their encoding into uppercase so we can do our hash
value = Regex.Replace(value, "(%[0-9af][0-9a-f])", c => c.Value.ToUpper());
// Encode the characters that they missed
value = value.Replace("-", "%2D").Replace(".", "%2E").Replace("_", "%5F");
return value;
}
Это все работает (пока кто-то не введет персонажа, которого я не учел), за исключением того, что это кажется более сложным, чем должно быть. Я знаю, что я не единственный, кто должен внедрить эту HCO в приложение ASP.NET, поэтому я не думаю, что простая проверка должна быть такой сложной.
Мне не хватает более простого способа сделать это? Необходимость циклически проходить по полям, кодировать некоторые из них, пропуская другие, преобразовывать их кодировку в верхний регистр и затем выборочно заменять символы, выглядит немного ... странно.