代会员调用
你的一把 API Key 代表你这个商户。但大部分业务动作的主体是某一个会员 ——
是谁的余额、谁的卡、谁在汇款。x-on-behalf-of 就是把这次调用切到某个会员身上。
POST /v1/remittances
x-auth-token: Bearer eyJ…
x-on-behalf-of: u_88213
哪些端点要
每个端点页顶部有徽章:会员的要,商户的不要。
粗略的判据是「这次动的是谁的钱」:
| 主体 | 例子 |
|---|---|
| 会员 | 余额、流水、上报入金、提现、汇款、发卡、理财、兑换、转账、扫码付、KYC |
| 商户 | 建会员、改会员属性、停用会员、你的预付余额、对账单、产品目录、走廊清单 |
需要会员作用域的端点,没带这个头一律 400 member_context_required ——
不会回落到某个默认会员。
不需要的端点上带了它,我方不会报错:它只是不被读取。所以别拿
「加上去也没报错」当成这个端点认它。
收哪两种标识
两种都收,随便用哪种:
| 形态 | 从哪来 | 例子 |
|---|---|---|
| 你的外部会员号 | 建会员时你传的 external_member_id | u_88213 |
| 我方内部会员 id | 任何会员出参里的 id 字段 | mem_0a3f… |
判据是前不前缀 mem_:带这个前缀就按我方内部 id 查,否则按你的外部号查。
⚠ 这一条是 2026-08-11 补的。此前只认外部号 —— 而我方每一个会员出参的 id
都是 mem_…,于是「把我方发出去的 id 原样传回来」这个最自然的写法拿到的是
member_not_found:一个看起来像「这个会员不存在」、实际是「你用错标识了」的错误。
/v1/members/{id} 这类路径参数用的是同一套解析,两处一致。
回你的那一侧一律用你自己的外部号:审计日志里的 on_behalf、Webhook 事件体里的
会员字段,不管你这次传的是哪一种。
拿不到会员时返回什么
只有一个响应:404 / member_not_found / Member not found.
这一个响应盖住了四种情况,且故意不区分:
| 实际情况 |
|---|
| 这个会员号在我方压根不存在 |
| 存在,但属于另一个商户 |
属于你,但被停用了(suspend) |
| 属于你,但被你拉黑了(黑名单) |
⚠ 跨商户与「不存在」必须同形。 区分开就等于给了一个跨商户会员探测接口:
拿一份手机号或邮箱清单逐个试,能试出「哪些人是别家商户的客户」。
同理,「停用」与「拉黑」也不单独回一个码 —— 告诉调用方对方处在哪个处置阶段,
等于送出一个免费的状态探针。
排查时的意思是:先确认这个会员号确实是你自己建的,再看后台的会员状态。
两件事只能你在后台看,接口不会告诉你是哪一种。
⚠ 停用与拉黑是两个正交的位,不是一个开关的两档。你在后台「解除停用」
不会顺带解除拉黑 —— 解除拉黑要单独做一次,否则这个头会一直被拒。
有一个端点的会员在路径里,不在这个头里
GET /v1/members/{id}/limits 的会员由路径参数定位,它刻意不挂
x-on-behalf-of 的解析。
不是遗漏。两者一起挂的话,/v1/members/A/limits 配上 x-on-behalf-of: B
会返回 B 的数据 —— 路径里那个 A 静默失效,而调用方看到的是一个
「查 A 得到 B」的 200,没有任何报错。
所以调它的时候:会员号写在路径里。路径参数同样两种标识都认。
带上 x-on-behalf-of 不会报错,也不会生效。
一次调用可以切换会员吗
不能,一次请求一个会员。要为 N 个会员做同一件事就发 N 次请求,
每次带各自的 x-idempotency-key。
⚠ 幂等键不带会员维度,而它的同键判据只看请求体、不看请求头。
x-on-behalf-of 是请求头 —— 所以拿同一把键、同一份请求体给两个不同的会员发,
第二个不会得到一笔新订单、也不会得到一个错误,而是第一个会员那笔的
原样回放(响应带 X-Idempotent-Replay: true)。第二个会员什么都没发生,
而你那边看到的是一个 200。
批量循环里把幂等键提到循环外面,就是这个形态。每个会员一把新键。