ThinkPHP 8.0对接第三方支付的核心是守住三点:原始请求体不被破坏(用getRawBody或php://input)、验签逻辑不绕过(校验header及时间戳)、回调处理具备幂等性(用唯一索引+任务队列)。

必须用 getRawBody 获取原始回调数据
微信、支付宝、易宝等平台的异步通知都是以原始 JSON 或 XML 发送,且签名依赖完整未解析的 body。TP8 的 $request->post() 或 $request->param() 会自动做 form 解析或 JSON decode,导致验签失败。
- 微信支付 v3 回调:必须用
$request->getRawBody()获取原始字符串,并校验 WECHATPAY-TIMESTAMP、WECHATPAY-NONCE、WECHATPAY-SIGNATURE 三个 header - 支付宝回调:虽然通常为 form 表单格式,但为防未来升级或自定义参数,也建议统一用
file_get_contents('php://input')或$request->getRawBody()(TP8 已兼容) - 时间戳超 5 分钟的请求必须直接拒绝,防止重放攻击
推荐使用 Yansongda/pay 统一接入
TP8 官方未内置支付模块,但 Yansongda/pay 已全面适配 PHP 8.x 和 ThinkPHP 8,是目前最稳定的选择。它屏蔽了微信/支付宝/银联等平台差异,提供一致接口。
- 安装:
composer require yansongda/pay:~4.0(注意选 4.x 版本,支持 PHP 8) - 配置:在
config/pay.php中定义各渠道参数,密钥全部走env()加载,不硬编码 - 下单示例:
Pay::wechat()->scan($orderData)返回二维码链接,Pay::alipay()->wap($orderData)返回跳转 URL
回调接口必须独立、无状态、可重入
不要把验签、订单更新、库存扣减全写在控制器里。TP8 支持中间件 + 事件 + 任务队列,应分层处理:
- 在中间件中完成原始数据获取 + 签名验证 + 时间戳校验,失败直接中断
- 控制器只做“接收”动作,验证通过后推送到
Job或触发Event - 实际业务逻辑(如更新订单状态、发消息、扣库存)放在
Job中,并用数据库唯一索引(如notify_id + trade_no)保证幂等
特别注意 PHP 8 兼容细节
TP8 默认启用严格类型和错误报告,很多老支付 SDK 会直接报错:
立即学习“PHP免费学习笔记(深入)”;
- 禁用已废弃函数:如
mysql_connect()、mcrypt_encrypt()—— 易宝、老版支付宝 SDK 可能含这些 - 检查扩展:确保
openssl、curl、mbstring、json全部启用 - 签名算法优先用
sha256或rsa2,避免 MD5(部分平台已弃用) - 日志记录要捕获完整上下文:原始 body、header、返回结果,方便排查验签失败



















