GCash 原生支付接入怎么做?API 对接、验签与生产切换完整流程
一、什么叫「原生接入」,和「三方跳转」有什么不一样
菲律宾商户在选 GCash 收款方案时,第一件要分清的事就是「原生」还是「跳转」。这两条路的差别不只是技术,更是客单价、客诉率和拒付率的差别。作为在马尼拉本地经营多年的中国技术负责人,我踩过这两种坑,下面把差异摊开讲清楚。
原生接入指商户后端直接调用聚合网关的 API,拉起 GCash 客户端支付授权,用户在自家 App/H5 里全程完成付款,收银台是自家的。三方跳转则是把用户丢到收银台域名,由第三方页面完成扫码或输入,回来后再通过回调告知结果。
| 维度 | 原生接入 | 三方跳转收银台 |
|---|---|---|
| 用户体验 | 不跳出商户品牌页,流畅 | 会跳到陌生域名,弃单率偏高 |
| 技术工作量 | 需要处理签名/回调/对账 | 只需生成一个跳转 URL |
| 可控字段 | 订单号、金额、备注、扩展参数全可自定义 | 受收银台模板限制 |
| 合规责任 | 商户方承担更多参数校验 | 大部分校验在网关侧完成 |
| 适合场景 | 自有 App、有开发团队、订单量较大 | MVP 阶段、H5 落地页、快速试跑 |
再补一句:很多技术负责人第一次评估时,只看「跳转两天就能上」的表面便利,结果客单价高、复购强的业务上线两周就发现跳出型收银台弃单率明显高于自家 App 页,回头再改原生已经晚了。选型这一步值得跟业务负责人一起坐下来算账,不要只让技术拍板。
二、对接前要准备的六样东西
不要还没拿全材料就急着写代码,不然联调阶段会来回踢皮球。经验清单:
- 商户号
merchant_id(网关分配) - API 密钥
api_key和签名密钥secret_key(两把不同的钥匙,别混用) - 结算银行账户信息(菲律宾本地对公户)
- 回调地址
notify_url(必须是公网 HTTPS) - 白名单出网 IP(网关侧会做 IP 校验)
- 联调用的沙箱账号(测试 GCash 号 + 测试金额区间)
关于商户号申请路径,可以参考支付 API 对接教程里的资料清单,以及GCash 商户号申请那篇的行业资质要求。
三、原生下单接口:一段真 curl 请求样例
下单接口的核心是「参数拼装 + 签名 + POST JSON」。以下是典型的 GCash 拉起支付请求,字段名各家网关略有出入但结构一致:
curl -X POST https://apix.paysmartph.com/api/pay/create \
-H "Content-Type: application/json" \
-H "X-Merchant-Id: M20260001" \
-d '{
"merid": "M20260001",
"tno": "ORDER20260925001",
"amt": "1288.00",
"channel": "GCASH",
"subject": "Order Payment",
"notify_url": "https://shop.example.ph/api/pay/notify",
"return_url": "https://shop.example.ph/order/success",
"client_ip": "203.0.113.10",
"nonce": "a8f3d2c1b0e9",
"timestamp": 1758787200,
"sign": "7A2E9F1C4B6D8E0A2F4C6B8D0E2F4A6C"
}'返回体一般会带回 pay_url(H5 拉起链接)或 deeplink(移动端唤起 GCash App 的 URL Scheme)。你只需要把这个链接扔给前端,由用户在 GCash App 里确认扣款即可。
四、HMAC 验签怎么做才靠谱
签名是原生接入最容易出问题的一环。踩坑排名前三:字段排序不一致、空字符串是否参与签名、字符编码差异。给一段可直接抄的 Node.js HMAC-SHA256 验签例子:
const crypto = require('crypto');
function verifySign(payload, secretKey) {
// 1. 抽出 sign 字段本身,不参与签名
const { sign, ...rest } = payload;
// 2. key 按 ASCII 升序排序
const keys = Object.keys(rest).sort();
// 3. 拼成 key1=value1&key2=value2 形式,空值跳过
const raw = keys
.filter(k => rest[k] !== '' && rest[k] !== null && rest[k] !== undefined)
.map(k => `${k}=${rest[k]}`)
.join('&');
// 4. HMAC-SHA256 → 转大写十六进制
const expected = crypto
.createHmac('sha256', secretKey)
.update(raw, 'utf8')
.digest('hex')
.toUpperCase();
return expected === sign;
}
验签这一步必须放在回调处理的最开头,任何数据库操作、任何日志落库都要在验签通过之后再做,否则可能被伪造回调触发订单状态漂移。回调接收后的幂等、去重、对账处理,建议翻一下商户回调 notify_url那篇的踩坑清单。
SMARTPAY 是持 BSP OPS/EMI 双牌照的独立支付网关,提供 GCash、Maya、QRPH 等本地通道对接服务,非 GCash 官方主体。牌照使得回调与结算全链路受 BSP 监管,商户对账追溯有据。
五、回调处理与幂等设计
GCash 网关的成功回调可能重复推送(网络重试机制),因此回调处理必须做幂等。推荐做法:
- 用
tno(商户订单号)做唯一键,数据库加唯一索引 - 处理前先查订单当前状态,若已是「支付成功」则直接返回
SUCCESS - 状态机严格化:待支付 → 支付中 → 支付成功/失败,不允许倒退
- 回调应答体固定用
SUCCESS字符串,避免 JSON 结构差异 - 业务侧再挂一个「主动查单」任务,兜底那些回调完全丢失的场景
- 回调处理耗时控制在秒级以内,超时会被网关判为失败继续重试,反而放大压力
- 回调入库先落原始报文,再触发业务逻辑,方便事后追溯网关侧的原始参数
另有一个容易被忽略的坑:业务方在测试期把回调地址临时改到内网穿透工具(比如 ngrok),上线后忘了切回自家域名,结果生产订单全部走到废弃地址上,只能靠对账文件手动补单。上线前一定要人工确认回调 URL 是线上真实域名。
关于对账,如果业务量到了每天几千单以上,一定要建立自动对账流程,拿网关的对账文件与自家订单库对齐,而不是靠客服人肉查。商户对账那篇里介绍了对账文件字段与差异处理的常见路径,可以借鉴。
六、沙箱到生产的完整检查清单
沙箱阶段必测的七个异常路径
沙箱阶段要把每个异常路径都跑一遍,不要只跑 happy path。生产上线后再补测,故障成本会翻几倍:
- 金额小数位数(有的网关只接受两位小数)
- 订单号重复提交是否返回相同
pay_url - 用户取消支付后的回调形态
- 超时未支付订单的关单机制
- 回调签名故意错乱一位,自家验签能否拦截
- 大额限额单笔触发风控时的报错码
- 并发下单同一个
tno,数据库唯一索引是否兜住
再补一条我们内部会强制执行的规则:沙箱阶段的所有测试用例必须转成自动化脚本,不要只留在人工回归清单里。因为后续每一次网关侧升级都要跑一遍回归,人肉测试成本高又容易漏,自动化跑一遍几分钟出结果。
从沙箱切到生产的逐项 checklist
沙箱通过不等于生产没事。生产切换前逐项过一遍,这是我们内部的标准流程:
- 切换
base_url:从api-sandbox换到apix域名 - 换密钥:沙箱密钥销毁,生产密钥用密钥管理服务加密存储,不进 Git
- 回调 URL 走线上域名,HTTPS 证书有效期检查
- 出网 IP 报给网关侧加白名单
- 数据库连接池扩容,回调峰值不会打挂
- 接入监控告警:回调延迟超阈值、验签失败率异常、订单成功率骤降都要报警
- 先跑小额真实订单,人肉核对到账、结算周期与商户对账单,确认无误后再放量
结算周期这一步别小看,如果对通道到账节奏还有疑问,可以先看QRPH 手续费与结算做横向对照,再结合自家现金流做决策。合规红线部分,BSP 合规那篇讲了持牌网关的监管框架,建议开发前通读一遍。
七、常见问题 FAQ
GCash 原生接入必须有菲律宾本地公司吗?
官方直连 GCash for Business 一般要求本地实体;通过持牌支付网关做原生对接,资料门槛会相对精简,具体以网关侧的审核结论为准,不能一概承诺。
H5 页面能不能实现原生体验?
可以。H5 场景下网关会返回一个 pay_url,浏览器打开后 GCash App 通过 deeplink 唤起完成扣款,再回跳回商户页面,用户不需要手动切换 App。
回调没收到怎么办?
先自查三点:回调 URL 是否公网可达、是否被 CDN/WAF 拦截、服务器是否返回了 SUCCESS。三点排除后再联系网关侧拉推送日志。同时建议把「主动查单」定时任务作为兜底,不要单点依赖回调。
签名总是失败,怎么定位?
九成是拼串顺序或空值处理不一致。把网关给的原始拼串日志和自己的日志逐字符比对,一目了然。另外注意 timestamp 是数字类型还是字符串类型,Boolean 类型如何序列化。
沙箱能测多久?
没有统一时限,只要商户资料在审批中,沙箱账号一般都可用。建议不要过度依赖沙箱,尽早申请生产上线,拿真实小额单验证全链路。
原生接入的技术投入大概多久?
一个熟悉 HTTP+HMAC 的后端工程师,从拿到文档到跑通首笔沙箱订单大约需要几个工作日;完成幂等、对账、监控、异常路径覆盖再叠加一段联调时间,不同团队差异较大。
可不可以同时对接 GCash + Maya + QRPH?
可以,而且强烈建议这么做。多通道路由能显著降低单一通道风控中断带来的收款损失。SMARTPAY 一次接入即可拿到 GCash、Maya、QRPH 等主流菲律宾支付通道能力,具体路由策略可以在商户后台自定义。
接口返回的错误码怎么处理才对?
建议把错误码分成三档:业务错误(比如金额格式不对)直接抛前端提示、通道临时错误(比如上游繁忙)进入自动重试队列并做退避、致命错误(比如商户号无效)则触发内部告警而不是让用户看到。分层处理才能既保护用户体验又不会淹没运维视野。
八、下一步与联系方式
原生接入不是难事,难的是把幂等、对账、监控、异常路径这些「不出问题时没人在意」的地方做扎实。真正的成本节省来自减少客诉与人工补单,而不是接口本身。如果你已经理清了原生接入的技术要点,想尽快落地菲律宾本地收款,欢迎联系 SMARTPAY 拿沙箱账号和对接文档:📩 [email protected] | Telegram @LouisSMARTPAY