yii2整合支付宝和微信支付回调的核心是验签可靠、状态幂等、响应及时;必须以异步回调为准,严格按官方流程验签解密,查单校验后再更新状态,并通过日志、锁机制和兜底查单保障商用级健壮性。

Yii2整合支付宝和微信支付回调,核心在于验签可靠、状态幂等、响应及时。商用场景下,不能只依赖同步跳转,必须以异步回调为准,且要能抗重放、防重复、可对账。
支付宝回调:关键三步走
支付宝异步通知(notify_url)是唯一可信的支付结果来源,同步返回(return_url)仅作用户体验用,不可用于更新订单状态。
-
监听地址必须公开可访问:如
/payment/alipay/notify,需在支付宝后台配置,且域名已备案、HTTPS有效 -
验签必须严格按官方SDK流程:读取原始POST数据(
file_get_contents('php://input')),用商户私钥+支付宝公钥验证签名,不拼接$_POST,不忽略空字段 -
业务处理前先查单:收到通知后,先用
out_trade_no查本地订单是否存在、是否已支付;只有未支付且状态为“待支付”才执行更新,避免重复入账 -
响应必须是纯XML且无空格:
<xml><return_code></return_code><return_msg></return_msg></xml>,多一个换行或空格都会导致支付宝持续重发
微信回调:加密+验签+解密缺一不可
微信2021年后全面升级为V3版回调,所有通知内容均AES-GCM加密,不再传明文。
由于微信的大热,为了更好的方便使用微信的用户查询一些信息,这篇文章是入门级的微信公众平台开发教程,需要的朋友可以参考下 这篇入门教程将引导你完成如下任务: 创建百度云平台应用启用微信公众平台开发模式获取订阅、文字、图片、语音、视频消息回复文本、图文及音乐消息程序开发
-
先提取请求头验签信息:从
Wechatpay-Serial、Wechatpay-Timestamp、Wechatpay-Nonce、Wechatpay-Signature中获取必要参数 - 用平台证书验证签名:下载微信支付平台证书(.pem),用其公钥验证请求头签名,失败则直接返回401
-
解密resource.ciphertext:使用商户APIv3密钥 + nonce + associated_data 解密出原始JSON,再解析
event_type是否为TRANSACTION.SUCCESS -
订单号必须双向核对:解密后的
resource.data.out_trade_no与本地订单号比对,同时检查resource.data.trade_state是否为SUCCESS,二者缺一不可
共性设计:商用级健壮性保障
真实生产环境里,支付回调不是“一次成功就完事”,而是要应对网络抖动、重复推送、时序错乱等复杂情况。
-
加数据库行锁或乐观锁:更新订单状态时,用
UPDATE order SET status = 'paid' WHERE id = ? AND status = 'unpaid',影响行为0说明已被处理过 - 记录完整原始回调日志:包括请求头、原始body、解密后数据、处理结果,保留至少90天,便于对账和审计
-
异步任务兜底查单:对超过5分钟未收到回调的订单,启动定时任务调用支付宝/微信的
query_order接口主动轮询,确保最终一致性 - 禁止在回调中触发重定向或渲染页面:回调是服务端到服务端通信,输出只能是XML或空响应,任何echo/print_r都会破坏协议
调试与上线 checklist
上线前务必逐项确认,少一项都可能引发资金风险。
- 支付宝:沙箱环境测试通过 → 签名验签开关开启 → 异步地址白名单放行 → 商户私钥权限为600且不在web可访问目录
- 微信:V3密钥和平台证书已正确加载 → notify_url在商户平台设置为全路径(含https)→ 回调域名已加入JSAPI授权目录(若用JSAPI)
- 通用:日志写入不阻塞主流程(建议用队列异步落盘)→ 所有支付相关SQL加索引(out_trade_no、trade_no、create_time)→ 监控告警接入(如连续5次回调失败触发钉钉通知)










