GCash API对接文档速查:接口列表、参数表、错误码与签名规则(2026)
文档速查:为什么要单独写、以及一份合格的API对接文档该有哪几块
我们自己在GCash收款API对接教程里,已经把注册开户、拿商户号、联调上线的整条流程讲了一遍。但后台反馈里一直有一类问题没被单独回答:技术负责人已经决定要对接了,不需要再看一遍"为什么选原生通道""怎么申请商户号",打开浏览器搜的就是"API对接文档"这四个字——想要的是一份能直接拿去对照开发的参考手册,而不是又一篇讲道理的长文。这篇就按照文档该有的样子来写,接口列表、请求参数表、响应字段表、错误码表、签名规则、回调规范逐项给,尽量少讲背景,多给可以直接核对的字段。
判断一份"对接文档"是不是真的能拿来开发,其实就看六件事有没有齐:接口列表(有哪些接口、分别做什么)、请求参数表(每个字段的类型、是否必填、含义)、响应字段表(回包里每个字段代表什么)、错误码表(出错了怎么定位)、签名规则(怎么生成、怎么校验)、回调规范(异步通知怎么设计)。市面上不少所谓的对接文档只写了接口地址加一句"请自行对接",连参数类型都标不全,拿着这种文档联调基本靠猜。
这六块内容不是随便哪家都愿意公开到字段级别的。SMARTPAY持有BSP颁发的OPS(运营支付系统)与EMI(电子货币机构)双牌照,把接口文档做到字段级别公开本身也是合规经营的一部分——商户和开发者应该在正式签约前就能核实清楚要对接的接口长什么样,而不是等付了钱才拿到文档。
接口列表:先搞清楚自己到底要接哪几个接口
很多团队一上来就想把所有接口都接一遍,其实没必要。先按业务场景圈出真正要用的接口,能省掉后面大量联调和维护成本。纯电商收款,核心只需要统一下单、订单查询、退款三个接口;如果还涉及给员工发工资或者给渠道结算佣金,才需要加上代付接口;财务对账则依赖对账单下载接口。
| 接口名称 | 接口路径(示例) | 请求方式 | 用途 |
|---|---|---|---|
| 统一下单 | /api/v1/pay/create | POST | 发起一笔收款请求,获取跳转链接或二维码 |
| 订单查询 | /api/v1/pay/query | POST | 按商户订单号查询支付状态 |
| 关闭订单 | /api/v1/pay/close | POST | 关闭尚未支付的订单,释放库存 |
| 退款申请 | /api/v1/refund/create | POST | 对已支付订单发起全额或部分退款 |
| 代付下单 | /api/v1/payout/create | POST | 发起一笔代付/出款请求 |
| 余额查询 | /api/v1/account/balance | GET | 查询商户账户可用余额 |
| 对账单下载 | /api/v1/settlement/file | GET | 按日期获取交易对账文件 |
需要提醒的是,代付类接口和收款类接口在权限开通上通常是分开审核的,不要默认申请了商户号就自动拥有全部接口权限。这也是持牌机构和不持牌代理的一个明显区别——涉及资金代付的接口,持有BSP OPS/EMI牌照的网关会按合规要求单独核验商户资质,而不是随便开个后台账号就放开权限。
具体哪些接口需要单独申请、接入前要准备什么,可以对照支付SDK怎么选里关于接入方式的部分先确认清楚。
请求参数表:哪些字段必填,哪些最容易漏
下面是统一下单接口的请求参数,这也是开发者联调时出错最集中的一个接口。
| 字段名 | 类型 | 是否必填 | 说明 |
|---|---|---|---|
| merid | String | 是 | 商户号,由后台分配 |
| tno | String | 是 | 商户系统内唯一订单号,不可重复 |
| amt | String | 是 | 订单金额,精确到小数点后两位 |
| channel | String | 是 | 支付通道标识,如GCASH、QRPH、MAYA |
| notify_url | String | 是 | 异步回调地址,需公网可访问 |
| return_url | String | 否 | 支付完成后跳转地址 |
| timestamp | String | 是 | 请求发起时间戳,用于防重放 |
| sign | String | 是 | 按签名规则生成的签名值 |
几个最容易踩的坑:amt字段几乎所有文档都要求以字符串形式传递、精确到小数点后两位,如果按数字类型传或者只传整数,大概率会被参数校验拦下;notify_url必须是公网可访问的https地址,本地测试环境用内网地址是收不到回调的;timestamp用来做防重放校验,客户端和服务器时间差太大同样会导致请求被拒绝。下面是一个统一下单的请求示例:
curl -X POST https://apix.example.com/api/v1/pay/create \
-H "Content-Type: application/json" \
-d '{
"merid": "M10086",
"tno": "ORDER20260929001",
"amt": "100.00",
"channel": "GCASH",
"notify_url": "https://merchant.example.com/notify/gcash",
"timestamp": "1727598000",
"sign": "3F2A9C7E1B0D..."
}'
这里的amt、merid、tno都是示例占位,实际字段命名和取值范围要以商户后台分配的接口凭证为准。
响应字段与状态机:回包里到底要盯住哪几个值
下单接口的响应不代表支付已经完成,只代表请求被网关受理。不少开发者第一次接的时候会把"接口返回成功"和"用户已经付款"这两件事搞混,这也是我们在技术支持环节经常看到的一类误解。
| 字段名 | 类型 | 说明 |
|---|---|---|
| code | String | 接口调用结果码,SUCCESS表示请求受理成功 |
| tno | String | 回传商户订单号,用于核对 |
| trade_no | String | 网关侧生成的交易流水号 |
| status | String | 订单状态:PENDING/SUCCESS/FAIL/CLOSED |
| pay_url | String | 跳转支付链接或二维码内容 |
| sign | String | 网关对响应内容的签名,用于验签 |
正确的做法是:接口返回code为SUCCESS,只说明下单请求本身合法、被网关接受了;真正的支付结果要看status字段,或者等待异步回调通知,不要只依赖前端跳转回来的return_url就判断订单已完成——用户完全可能在跳转之前就关掉了页面。建议把"查询接口"和"回调通知"当成互相校验的两条线,而不是只信任其中一条。
签名规则:接入失败里最大头的坑
从我们接触到的开发者反馈看,签名相关的问题几乎是接入过程中返工次数最多的一类,原因往往不是算法本身复杂,而是几个容易被忽略的细节:参数要按字典序排序后再拼接、空值参数是否参与签名要看具体文档约定、字符编码统一用UTF-8、密钥拼接的位置(放在最前还是最后)、生成的哈希值大小写是否统一。任何一个环节和文档约定不一致,签名校验就会失败,而且报错信息往往只提示"签名错误",不会告诉你具体哪个字段拼错了,只能逐项回查。
下面是一个Node.js签名生成的示例,展示的是最基础的签名逻辑:
const crypto = require('crypto');
function buildSign(params, secretKey) {
const keys = Object.keys(params)
.filter(k => k !== 'sign' && params[k] !== '' && params[k] !== undefined)
.sort();
const raw = keys.map(k => `${k}=${params[k]}`).join('&') + `&key=${secretKey}`;
return crypto.createHash('md5').update(raw, 'utf8').digest('hex').toUpperCase();
}
const params = {
merid: 'M10086',
tno: 'ORDER20260929001',
amt: '100.00',
channel: 'GCASH',
notify_url: 'https://merchant.example.com/notify/gcash',
timestamp: '1727598000'
};
params.sign = buildSign(params, process.env.SMARTPAY_SECRET_KEY);
console.log(params);
建议把签名逻辑写成一个独立的工具函数,请求和验签都调用同一份实现,而不是在每个业务接口里各写一遍——后者是团队协作时最容易出现"两边签名算法悄悄不一致"的根源。
回调通知规范:异步通知怎么设计才不丢单
notify_url收到的回调,本质上是网关主动告诉商户系统"这笔订单状态变化了",而不是商户系统查询的结果,所以要按"通知"而不是"确认"的逻辑去处理。几个必须做到的设计点:第一,收到回调之后先验签,签名不对的请求直接丢弃,不能默认信任;第二,按tno做幂等处理,同一笔订单的回调网关侧可能会重复发送,商户系统这边不能重复入账;第三,商户系统处理完之后要按约定格式返回确认(通常是一个固定字符串),网关没收到正确确认会按重试机制继续发送,直到达到重试上限。
关于商户回调更完整的落地方案,包括如何设计验签中间件、如何和对账系统打通,可以参考GCash商户回调怎么做这篇。
错误码表:自查排错的第一道关卡
遇到接口报错,先查错误码表,大部分问题不需要联系技术支持就能自己定位。
| 错误码 | 含义 | 排查方向 |
|---|---|---|
| SIGN_ERROR | 签名校验不通过 | 核对参数排序、密钥拼接位置与字符编码 |
| PARAM_MISSING | 必填参数缺失 | 对照请求参数表逐项检查 |
| MERCHANT_NOT_FOUND | 商户号不存在或未启用 | 确认商户号与环境(测试/生产)是否匹配 |
| ORDER_DUPLICATE | 商户订单号重复 | 检查订单号生成规则是否唯一 |
| CHANNEL_UNAVAILABLE | 指定支付通道暂不可用 | 切换备用通道或稍后重试 |
| CALLBACK_TIMEOUT | 商户回调地址无响应 | 检查notify_url是否公网可达、返回内容是否规范 |
这里列的是最常遇到的几类,完整的错误码清单以及每一类更细的排查步骤,可以对照GCash支付对接错误码大全逐条核对。养成"先查表再提工单"的习惯,能省下不少来回沟通的时间。
常见问题
API对接文档去哪里申请查看?
通常需要先完成商户号申请、拿到测试环境的接口凭证之后,才能获取到完整的字段级文档和沙箱环境地址。单纯问询阶段能看到的是接口能力介绍,具体字段和示例代码要在商户关系确定之后才会开放。
签名算法用什么方式生成,由谁决定?
由网关侧的接口版本决定,不是商户能自己选的。同一个商户号下,不同接口甚至可能采用不同的签名方式,对接前一定要按文档里该接口对应的规则实现,不能照搬其他接口或者其他平台的签名逻辑。
回调地址一直收不到通知,应该从哪里排查?
先确认notify_url是不是公网可访问的https地址,内网地址、需要登录验证的地址、证书过期的地址都会导致回调失败;再检查防火墙或者WAF规则有没有把网关的回调请求拦截;最后确认商户系统收到请求后有没有按约定格式返回确认,格式不对会被网关判定为处理失败继续重试。
沙箱环境和生产环境的接口地址一样吗?
不一样,两套环境的域名、商户号、密钥都是分开的,沙箱环境用来联调测试,不会产生真实资金变动。切换到生产环境前,一定要确认代码里所有的接口地址、商户号、密钥都已经换成生产环境对应的值,这也是上线前最容易被漏掉的一步。生产切换的完整流程和验签要点,可以参考QRPH商户API接入怎么做里关于生产切换的部分,思路是通用的。
文档更新了,老版本接口还能用多久?
接口升级通常会保留一段兼容期,但具体多久要以官方通知为准,不同接口的兼容策略也可能不同。建议对接完成后关注商户后台或者技术群里的版本更新通知,避免因为老接口突然下线导致业务中断。
公司没有专职开发,能不能自己对接?
如果有基础的后端开发能力,按这篇列出的接口列表、参数表和签名规则,是可以独立完成基础对接的。但涉及生产环境上线前的安全校验(比如签名密钥的存储方式、回调接口的鉴权),建议还是找有经验的开发把关,毕竟这条链路直接连着资金。
对接总是失败,是文档问题还是网络问题?
先看返回的错误码,如果是SIGN_ERROR或者PARAM_MISSING这类,基本可以排除网络问题,回头核对签名逻辑和参数格式;如果是请求超时、连接失败这类,再去排查网络链路和防火墙设置。养成先看错误码再排查网络的顺序,能少走很多弯路。
如果你已经准备好开发对接、需要拿到完整的字段级文档和沙箱环境凭证,可以直接联系SMARTPAY技术团队。Telegram咨询:@LouisSMARTPAY,邮箱:[email protected]。