泽御付支付系统对接PHP项目回调签名校验排错完整示例
接入泽御付支付时,回调签名校验是判断支付结果是否可信的关键环节。
很多开发者遇到的“回调验签失败”“订单状态不更新”等问题,根源往往不在业务逻辑,而是参数排序、密钥类型或编码格式没对齐。
本文用一个可直接运行的 PHP 示例,从准备、签名校验、排错到验证,完整跑一遍回调处理流程。
对接前要准备的三个信息
开始写代码前,先确认这些内容是否已拿到:
- 商户号(merchant_id):泽御付后台开通支付产品后生成,用于标识你的商户身份。
- 回调密钥(sign_key):用于生成和校验签名的密钥,通常是一串较长的随机字符串,不要泄露。
- 回调通知地址(notify_url):你服务器上接收支付结果通知的 PHP 接口地址,必须能在公网直接访问,且不能带参数。
建议在泽御付商户后台提前配置好白名单或调试模式,避免线上环境误拦截测试请求。
回调参数与签名算法拆解
泽御付支付回调会向 notify_url 发送 POST 请求,常见参数至少包含:
merchant_id
order_no // 商户订单号
amount // 支付金额,单位元,字符串
trade_no // 支付平台流水号
trade_status // 支付状态,如 SUCCESS
sign // 签名值
签名的生成规则一般是:把所有非空参数按参数名 ASCII 升序排序,拼成 key=value&key=value 形式,末尾拼接 &key=你的sign_key,再对整串做 MD5(或 HMAC-SHA256)得到小写字符串。
具体算法必须与泽御付官方文档确认,但绝大多数支付系统都遵循这种“排序 + 拼接 + 哈希”的套路。
校验时,先从回调数据中取出 sign 字段,再对剩余参数按同样规则重新计算签名,与取出的 sign 做比对。
一致则校验通过,不一致直接返回失败。
PHP 回调签名校验完整代码
下面是一个可以直接放在项目里的示例,使用原生 PHP,无框架依赖。
假设接收的是 POST JSON 数据,如果你的回调是表单格式,改为 $_POST 即可。
$val) {
if ($val === '' || $val === null) {
continue; // 过滤空值
}
$sign_str .= $key . '=' . $val . '&';
}
// 去掉末尾多余的 & 并拼接密钥
$sign_str = rtrim($sign_str, '&') . '&key=' . $sign_key;
// 5. 计算签名(以 MD5 为例,如官方用 SHA256 则替换 hash() 参数)
$local_sign = strtolower(md5($sign_str));
// 6. 比对签名
if (!hash_equals($local_sign, strtolower($sign))) {
// 验签失败:记录日志,返回失败,泽御付会继续重试
error_log('[Zeyufu callback] sign mismatch: ' . $sign_str);
http_response_code(400);
echo 'fail';
exit;
}
// 7. 验签通过,校验订单金额和状态(示例)
$order_no = $data['order_no'] ?? '';
$amount = $data['amount'] ?? '0';
$status = $data['trade_status'] ?? '';
if ($status !== 'SUCCESS') {
echo 'success'; // 非成功状态也要及时应答,避免重复通知
exit;
}
// 此处需要查询本地订单,比较金额是否一致,注意浮点数比较用字符串或 bccomp
// 然后更新订单状态、发货等业务逻辑
// 8. 处理完成后,必须输出 success(某些支付平台要求)
echo 'success';
代码中的 hash_equals 可以防止时序攻击,验签失败时返回非 200 状态码,让支付平台按策略重新推送。
高频报错与处理建议
回调一直收到 fail 或验签不通过:优先记录下参数和签名串,和泽御付官方调试工具生成的签名做对比。
常见原因是 ksort 排序时大小写不一致,或者参数名含有下划线时的 ASCII 编码差异。
金额校验总是不对:金额在支付平台和商户之间存在单位差异(元 vs 分)。
确认泽御付文档中 amount 单位,示例中假设为元。
务必用字符串比较,不要用 float == 判断。
回调地址请求超时:检查防火墙是否放行支付平台 IP 段,PHP max_execution_time 是否过短。
回调处理中不要写日志、发邮件等耗时操作,异步处理更好。
响应格式不对:泽御付要求回调后输出什么内容,以官方文档为准。
有些平台要求输出 success,有些要求输出 ok,甚至 SUCCESS。
建议先按文档写死,再用测试单验证。
如何确认对接真的成功
完成代码部署后,建议按顺序做三项验证:
- 在泽御付商户后台发起一笔 0.01 元的测试支付,使用真实回调流程。
- 查看服务器 Web 日志和 PHP 错误日志,确认
notify_url收到请求,且没有执行到异常分支。 - 在代码中临时记录
$sign_str到日志文件,和泽御付后台提供的验签工具结果比对,如果完全一致,则签名算法正确。
正式上线前,再检查一步:确认回调处理逻辑是幂等的。
同一订单可能被重复通知,重复更新或重复发货会造成损失。
如果你正在处理泽御付支付系统对接 PHP 项目回调签名校验问题,建议先按上述示例把签名串完整打出来,逐字符比对。
多数验签失败都能通过这一步定位到原因;
如果仍然无法解决,可以向泽御付技术支持提供订单号、回调原始报文和服务端签名串,方便他们快速协助定位。