下单那一刻资金承诺就成立了 —— 会员付款会锁会员余额,商户代付会锁商户预付。
下单
POST /v1/remittances
x-idempotency-key: <你自己的订单号>
{
"payee_id": "pye_…",
"payout_amount": "1200.00",
"slippage_bps": 100,
"asset": "USDT",
"funding_source": "member",
"purpose_code": "…",
"line": "express",
"reference": "…"
}
这是这条线上钱开始动的那一刻。
三件与直觉不同的事
一、走廊不从请求里读
以收款人自带的那一份为准。你传什么走廊我方都不看 ——少一条可被构造的入参。
二、只有「收款人收多少」这一个方向
下单没有 source_amount。上游那一侧 payout_amount 是定死边,必须逐字等于报价的买入额。
要按「我出多少」下单:先用 POST /v1/remit/quotes 反算出payout_amount,再拿它下单。
三、没有 quote_id
试算不产生可下单的凭据,下单也不收 ——价格在下单那一刻重新算,见试算。
四、slippage_bps 是硬必填
下单前先用 GET /v1/remit/products 读这条线允许的滑点区间,再把你让终端用户确认过的那一档 slippage_bps 原样带回来。
缺它、带字符串、或超出区间,都会收到 invalid_fields,且 fields[0].key会明确指向 slippage_bps。
五、funding_source=merchant 代表商户代付
缺省是 member:钱从这个会员余额里扣。
传 funding_source = "merchant":这笔单改由你的预付备付金承担,会员侧不会锁余额;但 x-on-behalf-of 仍然必填,因为收款人归属、KYC、订单归属与通知对象都还是这个会员。
成功返回意味着什么
funding_source = member时:会员的可用余额已按locked_amount冻进锁定桶(含滑点预留)funding_source = merchant时:会员余额不动,你的预付备付金按批发价冻结- 限额已经预留
⚠ 第 1 步是这条线上最要紧的一件事:钱已经不在会员的可用余额里了。
之后的每一条路径 —— 成功、失败、取消、退款 —— 都必须能把它还回去或结算掉。
locked_amount = 客户实付 × (1 + 滑点),比用户看到的实付数更大。会员付款时,会员余额不够这个数就下不了单。
三种成功状态,处置完全不同
status | 意思 | 你该做什么 |
|---|---|---|
dispatching | 已放行,分发执行器在跑 | 正常跟进 |
reviewing / platform_reviewing | 等我方人工审核 | 这是制度性关卡,不是出了问题 —— 商户单一律先过一遍总后台 |
pending | 你的预付余额不足,排队中 | 去充预付,我方自动推进 |
⚠
pending时会员的钱一分未动、限额未预留、上游没有订单 ——只有一张排队的订单行。队列深度看
GET /v1/merchant/pending。
⚠⚠ 会员侧永远看不到
pending的原因。 你的界面上对终端用户只能说「处理中」,不能说「商户余额不足」。
幂等键 = 一次「确认」一把
付款重试沿用同一把键,拿回首次那笔(duplicated: true)。换新键 == 第二笔真实付款。
收到 504 或网络错误时必须同键重试,别新生成 ——我方可能已经建单并冻了钱。
⚠
duplicated: true时没有quote字段(这一次没有真的报价),而
status是那张既有订单此刻的状态 —— 可能已经是completed了。别把它当成「刚刚下单成功」去发通知。
下单前会被拒的几件事
| 前置条件 |
|---|
收款人在这个会员名下且状态可用(看 upstream_status,不是 status) |
会员该资产可用余额 ≥ locked_amount |
| 会员已过这条线要求的 KYC 层级,且未被封禁/拉黑 |
| 金额在最低起汇额、单笔上限、日限额之内 |
purpose_code 在这条产品线允许的用途码清单内 |
个人线(pobo):这个会员已有一个 active 的上游子账户 |
需要处理的两种停顿
下单之后订单可能停下来等人:
- 需要补件 —— 合规要更多资料
- 需要重新确认 —— 价格变动超出了滑点预留
两者都会发 remittance.order.action_required 事件。见补件与重新确认。