必须验签且返回纯文本success,因支付宝强制要求且不保证源ip;需用php://input读原始数据并过滤sign字段;验签后须核验订单存在性、trade_status及app_id一致性,并全程utf-8编码。

Webman 接入支付宝 SDK 后,notify_url 收到的异步回调必须验签,否则任何伪造请求都能篡改订单状态——这不是“建议”,是支付宝强制要求,且验签失败时必须返回纯文本 success,否则会被持续重试。
为什么不能只校验 notify_url 请求来源 IP?
支付宝明确声明:异步通知不保证固定源 IP,也不提供可信 IP 白名单。依赖 $_SERVER['REMOTE_ADDR'] 或 Nginx 的 allow 规则做访问控制,等于裸奔。真实攻击者可伪造 POST 请求,带合法参数但无有效签名,绕过所有 IP 层防护。
AlipayAopClient::rsaCheckV1() 验签前必须清理原始 POST 数据
Webman 默认使用 Swoole 的 $_POST,但支付宝异步通知是 raw body(application/x-www-form-urlencoded 格式),而 Swoole 有时会因 Content-Type 解析异常导致 $_POST 为空或字段丢失。直接传 $_POST 给 rsaCheckV1() 必然失败。
Webman 2.2.0版本强化了 TCP/UDP 服务支持,优化路由组管理,并增强异步任务处理能力。结合协程与连接池技术,Webman 能轻松应对高并发场景,适用于网站、接口服务、即时通讯、物联网及游戏开发,兼具高性能、灵活扩展与稳定可靠,是多场景 PHP 服务开发的理想选择。
- 必须用
file_get_contents('php://input')读取原始数据 - 再用
parse_str()解析为关联数组,确保字段名和值与支付宝原始提交完全一致(注意空格、换行、编码) - 过滤掉
sign和sign_type字段后再传给验签函数 - 示例关键代码:
$raw = file_get_contents('php://input');<br>$data = [];<br>parse_str($raw, $data);<br>unset($data['sign'], $data['sign_type']);<br>$result = AlipayAopClient::rsaCheckV1($data, $alipay_public_key, 'RSA2');
验签通过后仍需二次核验业务参数
验签只证明“数据来自支付宝且未被篡改”,不等于“这笔通知对应你系统里的某笔有效订单”。常见疏漏点:
-
out_trade_no必须查库确认存在且状态为「待支付」,否则直接拒收(防重放、防错单) -
trade_status必须是TRADE_SUCCESS或TRADE_FINISHED,TRADE_CLOSED等状态不能更新为已支付 - 必须检查
app_id是否与你配置的 APPID 一致,避免多应用混用密钥导致交叉验证 - 验签通过 + 参数合法后,才可更新订单状态,并立即返回
success(纯文本,无 HTML、无 JSON、无换行)
最容易被忽略的是:验签函数本身不处理字符编码,若你的数据库或日志记录用了 GBK,而支付宝始终用 UTF-8 提交,out_trade_no 中含中文或特殊符号时会导致查库失败——务必全程统一 UTF-8。










