测试凭证
接入之前,向平台团队申请把你的商户账户标记为 demo 商户。本页说明沙箱怎么用,以及上线前的清单。
沙箱模型
沙箱是按商户开启的,不是独立环境:demo 商户和正式商户跑在同一个 host、同一套代码上。区别只有一个——demo 商户可以带 isTest: true。
| 项 | demo 商户 | 正式商户 |
|---|---|---|
| Base URL | https://api.168tonpay.xyz/api/v1/compat/godapay | 同左 |
| 真实资金 | ❌(合成 SMS) | ✅ |
isTest: true | 生效,自动注入合成 SMS 并触发 webhook | 返回 400(正式商户禁止) |
因为环境同构,联调通过后切正式不需要改代码:平台清除 demo 标记、你换上正式
merchantId/apiSecret即可。
拿到凭证
联系平台团队后,你会收到:
- Merchant ID:UUID(例如
aef6025b-f435-443c-bb18-f10e65d9314c) - API Secret:用于计算
signature
配置环境
# .env.test
API_BASE=https://api.168tonpay.xyz/api/v1/compat/godapay
MERCHANT_ID=aef6025b-f435-443c-bb18-f10e65d9314c
API_SECRET=xxxxxxxx
验证凭证
发起一笔沙箱收款订单(isTest: true):
# SIGN_STR 已按 key 升序排好;实际请把 <secret> 换成 API_SECRET
SIGN_STR="isTest=true&merchantId=${MERCHANT_ID}&orderNo=TEST-$(date +%s)&playerPhone=01711000000&playerRef=test_player&returnUrl=https://your-server.example/webhook&key=${API_SECRET}"
SIGNATURE=$(printf '%s' "$SIGN_STR" | openssl dgst -md5 -hex | awk '{print $NF}')
curl -X POST "${API_BASE}/pay/order/create" \
-H "Content-Type: application/json" \
-d "{\"merchantId\":\"${MERCHANT_ID}\",\"orderNo\":\"TEST-$(date +%s)\",\"returnUrl\":\"https://your-server.example/webhook\",\"playerPhone\":\"01711000000\",\"playerRef\":\"test_player\",\"isTest\":true,\"signature\":\"${SIGNATURE}\"}"
测试场景
demo 商户带 isTest: true 创建订单后,平台会注入合成 SMS 驱动订单走完生命周期,你能完整测到 webhook 投递。
| 场景 | 怎么触发 |
|---|---|
| 收款成功 | 创建 isTest 订单,等待完成 webhook(status=1) |
| 重复订单号 | 用同一个 orderNo 提交两次(返回原订单,不新建) |
| 金额超限 | 在托管页选择超限金额 |
| 签名错误 | 故意改一字节 signature(返回 INVALID_SIGNATURE) |
| 正式商户误用沙箱 | 正式商户传 isTest: true(返回 400) |
上线前检查清单
- MD5 排序签名生成正确(见 常见签名错误)
- 创建订单 / 打开 payUrl 跑通
- Webhook 端点能正确验签、幂等处理、应答
SUCCESS - Webhook 失败有兜底(定时轮询
/pay/order/query) - 能处理
429 RATE_LIMIT_EXCEEDED并重试 - 凭证只通过环境变量或 secret manager 注入
切到生产
联调通过后,平台清除 demo 标记并签发正式 merchantId / apiSecret。接口形态、签名算法完全一致,代码无需改动。