PAYATHON 2026

PayU Verification of Payment API 返回错误怎么办?

支付阿杰

结论

先检查这两个地方:

  1. 请求地址里应包含 postservice.php:
https://test.payu.in/merchant/postservice.php?form=2

不能写成:

https://test.payu.in/merchant/postservice?form=2
  1. 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。

建议的排查顺序

  1. 将地址改为:
https://test.payu.in/merchant/postservice.php?form=2
  1. 确认请求方法是 POST,并将 Content-Type 设置为:
application/x-www-form-urlencoded
  1. 确认提交了以下字段:
key
command
var1
hash
  1. 将 command 固定为:
verify_payment
  1. 确认 var1 填写的是原支付请求中的 txnid。

  2. 使用下面的内容生成签名,并按照当前 PayU 文档的要求采用 SHA-512:

key|verify_payment|txnid|salt
  1. 确认测试环境地址搭配的是测试环境的 merchant key 和 salt。

如果当前账户对应的 PayU 文档明确指定了其他 endpoint 或 hash 算法,应以该账户、地区和接口版本的文档为准。针对这段代码,最先需要检查的是 URL 是否遗漏 .php、是否误用了 SHA-256,以及请求编码是否正确。

备注:内容仅供参考。