基本定义
- 方法:
POST - 路径:
/v1/wallet/deduct/pay - Content-Type:
application/json - Auth:统一网关
- Timeout:
15000ms(建议) - 幂等键:
merchant_id + out_trade_no - 描述:按
contract_no查询绑卡列表并扣款;同步返回结果并推送异步通知
请求字段
| 字段 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|
out_trade_no |
string | 是 | 最长 64 | 商户订单号 |
contract_no |
string | 是 | 最长 32 | 签约号 |
agreement_no |
string | 否 | 最长 64 | 指定扣款协议;未传则轮询扣款 |
payment_amount |
integer | 是 | >0;单位分 | 扣款金额 |
goods_info |
string | 是 | 最长 256 | 商品/消费信息说明 |
currency |
string | 否 | 默认 CNY |
币种 |
biz_type |
string | 否 | 最长 32 | 业务类型(预留) |
notify_url |
string | 否 | 最长 256 | 扣款终态异步通知地址 |
risk_control_info |
object | 是 | JSON 对象 | 风控参数 |
risk_control_info 为 JSON 对象(非字符串),常见子字段示例:
| 子字段 | 类型 | 说明 |
|---|---|---|
goods_category |
string | 商品类目 |
user_register_dt |
string | 用户注册时间 |
user_login_method |
string | 用户登录方式 |
user_ip |
string | 用户 IP |
user_device_id |
string | 用户设备 ID |
locationPoint |
string | 经纬度坐标(经度,维度) |
请求示例:
{
"out_trade_no": "DED202505250001",
"contract_no": "C20250525000001",
"payment_amount": 1990,
"goods_info": "会员月卡",
"notify_url": "https://merchant.example.com/callback/wallet/deduct",
"risk_control_info": {
"goods_category": "02",
"user_register_dt": "20220101000000",
"user_login_method": "1",
"user_ip": "192.168.1.1",
"user_device_id": "device_001",
"locationPoint": "121.603493,31.218363"
}
}
响应字段(分支 A:成功 trade_status=SUCCESS)
HTTP 200。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
trade_no |
string | 是 | 平台交易号(扣款订单号) |
out_trade_no |
string | 是 | 商户订单号 |
trade_status |
string | 是 | 固定 SUCCESS |
success_agreement_no |
string | 是 | 扣款成功的协议绑定号 |
payment_amount |
integer | 是 | 扣款金额(分) |
successful_payment_time |
string | 是 | 扣款成功时间,ISO 8601 |
bank_code |
string | 否 | 扣款成功卡银行编码 |
bank_card_type |
string | 否 | 扣款成功卡类型,如 D/C |
bank_card_no_masked |
string | 否 | 扣款成功卡脱敏卡号,格式如 ****5661 |
响应示例:
{
"trade_no": "4101010120250525120000000001",
"out_trade_no": "DED202505250001",
"trade_status": "SUCCESS",
"success_agreement_no": "AGR20250525000001",
"payment_amount": 1990,
"successful_payment_time": "2026-05-25T15:10:01+08:00",
"bank_code": "ICBC",
"bank_card_type": "D",
"bank_card_no_masked": "****5661"
}
响应字段(分支 B:失败 trade_status=FAIL)
HTTP 非 200(如 TRADE_ERROR)
响应示例:
{
"code": "TRADE_ERROR",
"message": "协议号全部扣款失败"
}
响应字段(分支 C:处理中 trade_status=PROCESSING)
HTTP 非 200(如 USER_PAYING)
响应示例:
{
"code": "USER_PAYING",
"message": "扣款处理中,请勿重复提交"
}
防重复扣款
- 同一
merchant_id + out_trade_no不得再次触发扣款。 - 幂等命中已成功:HTTP
200,trade_status=SUCCESS,message可为「订单已支付成功,请勿重复支付」。 - 幂等命中处理中:非
200,code=ORDER_DUPLICATED,trade_status=PROCESSING。 - 幂等命中历史失败:非
200,code=ORDER_DUPLICATED或TRADE_ERROR,trade_status=FAIL,须换out_trade_no。
错误与调用方处理
| HTTP | 网关 code |
触发条件 | 调用方处理 | 可重试 |
|---|---|---|---|---|
200 |
— | 扣款成功;幂等命中已成功 | 按成功分支处理;勿重复扣款 | 否 |
非 200 |
USER_PAYING |
渠道返回处理中 | 轮询 HTTP-008 或等 NOTIFY-002;勿用相同 out_trade_no 重试 |
是 |
非 200 |
TRADE_ERROR |
无可用协议;指定 agreement_no 与签约号不匹配;全部卡扣款失败 |
读 message;查 HTTP-005;失败须换 out_trade_no |
视情况 |
非 200 |
ORDER_DUPLICATED |
幂等命中处理中/历史失败单 | 查 HTTP-008;处理中勿重试;失败换单 | 否 |
非 200 |
INVALID_PARAMETER |
参数校验失败;Header 缺失;risk_control_info 为空 |
修正参数 | 是 |
非 200 |
UPSTREAM_TIMEOUT |
协议列表调用异常 | 查 HTTP-008 确认是否已落单 | 是 |
非 200 |
SYSTEM_ERROR |
系统异常 | 查 HTTP-008 | 是 |