PayU Verification of Payment API 返回错误怎么办?
支付阿杰
结论
先检查这两个地方:
- 请求地址里应包含
postservice.php:
https://test.payu.in/merchant/postservice.php?form=2
不能写成:
https://test.payu.in/merchant/postservice?form=2
- Verification of Payment API 通常使用
SHA-512计算 hash,而不是SHA-256。支付接口能正常工作,并不代表验证接口使用相同的 hash 算法和拼接规则。
请求还应采用 application/x-www-form-urlencoded 格式,并提交 key、command、var1 和 hash 四个字段。
正确的请求格式
验证单笔交易时,通常需要提交以下参数:
key=<merchant_key>
command=verify_payment
var1=<transaction_id>
hash=<generated_hash>
参与签名的字符串是:
key|command|var1|salt
在当前场景中,对应为:
PAYU_KEY|verify_payment|transactionId|PAYU_SALT
var1 必须填写支付请求中使用的 txnid,不要填入 PayU 返回的 mihpayid、订单号或其他业务流水号。
C# 示例
using System.Net.Http;
using System.Security.Cryptography;
using System.Text;
public static string GetSha512(string value)
{
using var sha512 = SHA512.Create();
byte[] bytes = Encoding.UTF8.GetBytes(value);
byte[] hashBytes = sha512.ComputeHash(bytes);
return Convert.ToHexString(hashBytes).ToLowerInvariant();
}
public async Task<string> VerifyPaymentAsync(string transactionId)
{
const string command = "verify_payment";
string valueToHash =
$"{PAYU_KEY}|{command}|{transactionId}|{PAYU_SALT}";
string hash = GetSha512(valueToHash);
using var httpClient = new HttpClient();
var form = new Dictionary<string, string>
{
["key"] = PAYU_KEY,
["command"] = command,
["var1"] = transactionId,
["hash"] = hash
};
using var content = new FormUrlEncodedContent(form);
HttpResponseMessage response = await httpClient.PostAsync(
"https://test.payu.in/merchant/postservice.php?form=2",
content
);
string responseBody = await response.Content.ReadAsStringAsync();
return responseBody;
}
如何确认 hash 算法是否正确
不要只看函数名称,可以直接检查最终 hash 的十六进制长度:
SHA-256:64 个十六进制字符SHA-512:128 个十六进制字符
如果 GetSHA256() 返回 64 个字符,它就不适用于要求 SHA-512 的接口。最好单独实现 GetSha512(),以免混淆支付签名和验证签名。
签名原文也要逐项检查:
transactionId前后是否带有空格。PAYU_KEY或PAYU_SALT是否来自错误的环境配置。|是否多拼接或少拼接了一个。- 是否把
mihpayid当成了txnid。 - 是否先对整个签名字符串进行了 URL 编码,再计算 hash。
- 生成 hash 后,是否又改变了大小写或字符内容。
为什么只显示 “Sorry Some Problem Occurred”
出现这个页面,通常说明请求没有进入预期的 API 响应流程。可能的原因有:
- URL 路径错误,例如遗漏了
.php。 - 在浏览器中直接访问了只接受
POST的地址。 - 请求正文使用 JSON,而接口需要表单数据。
- 必填字段缺失,或者字段名写错。
- hash 算法、签名顺序或凭据不正确。
- 测试地址使用了生产环境的 key 或 salt。
调试时,不要让浏览器直接渲染响应页面。应记录以下信息:
HTTP status code
Content-Type
原始 response body
最终请求 URL
提交的字段名
待签名字符串
hash 长度
日志可以记录字段结构和 hash,但不要在生产日志中输出完整的 PAYU_SALT。
建议的排查顺序
- 将地址改为:
https://test.payu.in/merchant/postservice.php?form=2
- 确认请求方法是
POST,并将Content-Type设置为:
application/x-www-form-urlencoded
- 确认提交了以下字段:
key
command
var1
hash
- 将
command固定为:
verify_payment
-
确认
var1填写的是原支付请求中的txnid。 -
使用下面的内容生成签名,并按照当前 PayU 文档的要求采用
SHA-512:
key|verify_payment|txnid|salt
- 确认测试环境地址搭配的是测试环境的 merchant key 和 salt。
如果当前账户对应的 PayU 文档明确指定了其他 endpoint 或 hash 算法,应以该账户、地区和接口版本的文档为准。针对这段代码,最先需要检查的是 URL 是否遗漏 .php、是否误用了 SHA-256,以及请求编码是否正确。
备注:内容仅供参考。
