thinkphp集成第三方支付与短信接口的关键在于稳落地:支付需防重复、验签名、保幂等,短信要控频次、分通道、留痕迹;均须脱离控制器硬编码,走服务层封装、配置驱动与异步处理路径。

ThinkPHP集成第三方支付与短信接口,关键不在“加功能”,而在“稳落地”——支付要防重复、验签名、保幂等;短信要控频次、分通道、留痕迹。两者都得脱离控制器硬编码,走服务层封装 + 配置驱动 + 异步处理的路子。
支付接口:用Yansongda/pay统一接入,但别跳过验签细节
Yansongda/pay是目前ThinkPHP项目中最省心的选择,支持微信H5、扫码、小程序,也兼容支付宝WAP和APP支付。但它默认不处理原始请求体,而微信v3回调必须校验WECHATPAY-TIMESTAMP、WECHATPAY-NONCE、WECHATPAY-SIGNATURE三者,且拒绝超5分钟的请求。
- 在中间件中调用
$request->getRawBody()获取原始JSON/XML,再传给Pay::wechat()->verify(),千万别用$request->post()或$request->param()解析后再验签 - 回调逻辑必须拆到Job或独立Service里,比如
HandleWechatNotifyService,内部用DB事务包裹订单状态更新、库存扣减、消息推送 - 配置项(如商户证书路径、私钥、APIv3密钥)全放
.env,不要写死在代码里;证书文件建议放在runtime/cert/下,由部署脚本同步
短信接口:按场景封装,避免一个SmsService打天下
短信不是“发出去就行”。验证码要限频(如1分钟1条)、营销短信要带退订入口、通知类短信要支持失败重试+通道降级(阿里云挂了切腾讯云)。
- 建三个服务类:
VerificationSmsService(带Redis计数器)、NoticeSmsService(对接多通道,自动选可用通道)、MarketingSmsService(含模板审核状态检查+用户免打扰开关) - 所有短信请求统一走Guzzle客户端封装,设置固定
timeout=3、connect_timeout=2,超时直接抛异常进日志,不阻塞主流程 - 发送记录必须落库(哪怕只是
sms_log表),字段至少含手机号、模板ID、通道名、返回码、响应时间、是否成功——对账和投诉溯源全靠它
共性要点:配置、日志、环境隔离不能省
支付和短信都涉及敏感凭证和外部依赖,线上出问题90%源于配置错位或日志缺失。
-
config/services.php里明确区分alipay、wechat_pay、aliyun_sms、tencent_sms等键,每个键下包含enable开关,便于灰度或临时关闭某通道 - 所有SDK调用前后打结构化日志,例如
[sms][aliyun] to 138****1234, template:SMS_10001, cost:127ms, code:OK,方便ELK聚合分析 - 开发环境禁用真实支付和短信,用
MockSmsService和DummyPayService返回模拟成功,且前端加水印“测试环境”
安全底线:HTTPS、签名、幂等号缺一不可
微信回调地址必须是HTTPS,支付宝notify_url也建议强制HTTPS;所有支付回调必须验证签名,所有短信请求必须带业务唯一ID(如order_no或verify_id)用于幂等去重。
- 微信回调验签失败时,返回
401 Unauthorized而非空响应,避免被刷量 - 支付宝异步通知收到后,先查本地订单是否存在且未支付,再调用
verify(),防止伪造通知 - 短信发送前生成
request_id = md5($phone . $template_id . time()),写入缓存5分钟,重复ID直接跳过
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











