流水是账本的投影 —— 每一条都对应一次真实的资金变动。这一页给全部字段取值。
交易流水
GET /v1/transactions?external_member_id=…&cursor=…
游标分页,见分页。
字段
| 字段 | 说明 |
|---|---|
id | txn_ + 数字。按 id 精确查时带不带前缀都认 |
type | 业务类型,见下表。开放枚举 |
status | 各业务线的状态原文,见下面那条警告。开放枚举 |
status_version | 单调递增。合并状态时的判据,见下 |
direction | in / out。这个是封闭枚举,传别的值回 400 |
asset | 资产代号 |
amount | 字符串定点,位数由 amount_scale 决定。恒为正 —— 方向看 direction |
occurred_at | 这件事什么时候发生的(充值取检测到的时刻) |
created_at | 这行流水什么时候落库的。排序与筛选都锚在它上面 |
type 的当前取值
| 值 | 方向 | 是什么 |
|---|---|---|
deposit_crypto | in | 链上充值到账 |
withdrawal | out | 链上提现 |
remittance | out | 汇款 |
qrpay | out | 扫码付 |
exchange | in / out | 站内兑换(一单两条,见下) |
internal_transfer | in / out | 站内转账 |
card_issue_fee | out | 开卡费(含实体卡邮费) |
card_refund | in | 开卡失败退费 |
card_penalty | out | 拒付罚金 |
card_topup | in / out | 充值到卡(一单两条,见下) |
card_withdraw | in | 卡内资金转出(USD 退回钱包) |
card_txn | in / out | 卡消费流水 |
earn_subscribe | out | 理财申购 |
earn_redeem | in | 理财赎回 |
earn_interest | in | 理财派息 |
balance_adjust | in / out | 我方后台的资金调整与冲正 |
⚠
withdrawal(链上提现)与card_withdraw(卡内转出)是两门生意,中文都叫「提现」而已。前者的钱离开我方账本,后者的钱从卡回到钱包。
⚠ 这是开放枚举,不是封闭的。 我方上一条新业务线会加一个新
type,不发版、不通知。所以:
- 你的
switch必须有default,且default是「按direction与
amount照常记账 + 原样显示」,不是丢弃、不是报错。-
?type=传一个不存在的值得到空列表,不是 400 ——这是开放枚举上唯一诚实的行为。
status 是原文,不是归一化的三档
status 直接来自那条业务线自己的明细表:充值有充值的状态串,理财有理财的。没有被压成 success / pending / failed。
这是刻意的 —— 压成三档之后「人工审核中」与「上游确认中」会变成同一个值,而那两件事该给用户看的话不一样。
所以:
- 不要跨类型比较
status。?status=completed只会命中某些类型。 - 要判「成不成」,按类型各判各的,或者干脆用产品线自己的详情端点。
- 认不出的值原样显示,别 default 成「处理中」——那会把一笔失败的单显示成还在跑。
一单两条的两个类型
兑换(exchange)与充值到卡(card_topup)在流水里各有两条:付出腿(direction: out)与到账腿(direction: in)。
它们讲的是同一笔交易。
⚠ 统计时不要把它们当两笔。 「这个会员这个月转出了多少」
如果不排除兑换的付出腿,一次 100 USDT → USD 的兑换会同时算进
「转出 100」与「转入 99.x」,而他一分钱都没离开你的体系。
我方的 App 在全局流水里把到账腿藏起来了;开放 API 两条都给
—— 你要的是完整投影,不是给人看的列表。
status_version:合并状态的唯一判据
同一笔单你可能从三个地方拿到状态:webhook、这个列表、产品线详情。它们到达的顺序没有保证。
合并时只许向前:
if (incoming.status_version > stored.status_version) apply(incoming)
⚠ 少了这一句,一个慢响应会把「已到账」打回「处理中」——
而这类 bug 在测试环境几乎不复现(本地够快)。
增量同步:锚在 created_at
GET /v1/transactions?from=<上一轮见过的最大 created_at>
from / to 与游标都锚在 created_at,不是 occurred_at。
⚠ 别拿
occurred_at做增量水位线。一条occurred_at早、
created_at晚的行(补记的历史流水就是这一类)会被永久跳过。
对账用流水,不用余额
余额是当下的数,流水是过程。要回答「这个月他一共花了多少」必须走流水;拿两个时点的余额相减会漏掉同期的入金。