首页 / 西瓜支付

聚合支付 API 对接全流程:回调验签、幂等处理与联调要点

2026-10-29 · 货币金融服务

聚合支付与四方支付的 API 对接,本质是把多个上游通道的差异收敛到一套统一网关之后。商户系统只面对一套签名规则、一套请求参数、一套回调格式,通道切换、路由策略、余额监控由网关侧承担。本文从工程实现角度梳理对接流程与几个必须处理好的技术点。

一、整体对接流程 典型的接入顺序是:申请测试商户号与密钥 → 阅读接口文档确定产品类型(扫码支付、被扫、H5、APP、代付与资金结算)→ 构造请求并签名 → 调用下单接口获取支付凭证(二维码串或跳转链接)→ 用户完成支付 → 网关异步回调通知 → 商户主动查单兜底 → 每日对账文件核对。每一环都要记录请求原文、响应原文、时间戳与耗时,日志中的密钥、证件号、卡号需脱敏。

二、签名与验签 签名规则各通道略有差异,但模式基本一致:取全部非空业务参数(排除 sign、sign_type),按参数名字典序升序拼接成 key1=value1&key2=value2 的形式,末尾追加 &key=商户密钥,再按约定算法(MD5 或 HMAC-SHA256)计算并转大写。要点:统一 UTF-8 编码;金额一律用最小单位整数(分)传输;参数值为空时不参与签名;时间戳字段注意有效期窗口,防止重放。

验签是回调处理的第一道关。收到回调后必须先验签、再解析业务,顺序不能颠倒。验签通过后还要做三项校验:merchant_id 是否为本商户、out_trade_no 是否存在、回调金额与本地订单金额是否一致。任何一项不符都直接丢弃并告警,不进入业务逻辑。

三、幂等处理 支付链路上有三个幂等点: 1)下单幂等。商户订单号 out_trade_no 是全局唯一键,同一订单号重复提交应返回首次结果,而不是新建一笔。数据库对 out_trade_no 建唯一索引,重复插入捕获冲突后查询返回。 2)回调幂等。同一笔订单可能收到多次通知(超时重试、多通道重复推送)。处理方式是把订单状态做成状态机:init → paying → paid → settled,只有处于非终态的订单才允许推进,落库时用 UPDATE ... WHERE status = 'paying' 的条件更新或分布式锁,保证并发下只生效一次。已处于 paid 的订单再次收到回调,直接返回成功应答即可。 3)出款与退款幂等。以商户侧的退款单号、代付单号为幂等键,独立于原支付订单号,避免重复出款。

回调应答也要注意:多数网关以返回字符串 success(或约定 code)判定通知成功,返回其他内容或 HTTP 非 200 都会触发重试。因此业务处理耗时较长的场景,建议先落库应答、再异步处理。

四、联调注意事项 - 全程使用沙箱或测试环境,用测试商户号跑通下单、回调、查单、退款、对账全链路,不要拿生产密钥做调试。 - 回调地址必须公网可达,测试阶段可用内网穿透;接口需按文档支持表单或 JSON 格式,不要自行假设。 - 设置合理的连接与读取超时,通常应小于上游网关的超时时间,避免自己先超时后上游仍然成功,造成单边账。 - 回调可能乱序或延迟,不要依赖通知顺序,一切以主动查单结果为准。 - 网络异常时不要盲目重试下单,先查单确认状态,再决定重发。 - 密钥与证书单独存放,支持轮换;不要出现在客户端或前端代码中。 - 每日下载对账文件,与本地订单逐笔核对,处理长款与短款差错。

五、几个常见坑 签名拼接时中文参数未编码、回调未校验金额导致金额被篡改、把回调当作唯一入账依据而不做查单兜底、订单号规则设计不当导致重复、时间戳过期被判定为签名失败。这些问题在联调阶段用日志复现一遍,比上线后排查成本低得多。

相关站点