跳转到主要内容
一笔 Fluz 发卡上的消费并非单一事件,而是商户、卡组织与 Fluz 之间的一场对话,这场对话可能持续数秒、数小时,有时甚至数周——并且在完成之前,会在你这边产生多条记录。 本页说明每个阶段发生了什么、每个阶段会产生哪些 Fluz 记录与 webhook,以及简单粗暴的集成方式最容易在哪些地方算错账。
本页涵盖开环卡交易——即 Fluz 发行到卡组织网络上的虚拟卡消费。礼品卡购买、存款、取款与钱包转账不走这套生命周期,它们各自在自己的通道上结算。参见交易概览以了解容纳所有这些交易的统一账本。

三个阶段

结算是一个银行流程,按卡组织自己的时间表在清算之后运行。Fluz 将清算与结算表示为同一个事件——当一笔交易在 Fluz 上完成清算时,应将其视为最终状态。

一笔购买,多条记录

一笔购买可以产生一条授权、一条或多条清算,还可能产生一条撤销或一条退款。Fluz 通过三个查询来回答不同的问题: 三笔购买,以及各自留下的记录:
退款是一条新记录,而不是对旧记录的修改。退款以独立的 REFUND 交易形式到达。原始 PURCHASE 记录的任何内容都不会改变——其金额保持不变。如果你的系统在退款到账时去减少原始购买金额,你就会把这笔贷记重复计算。请在记录层面进行对账,永远不要修改原始记录。

单消息与双消息流程

卡组织发送多少条消息取决于商户与交易类型。两种流程都是正常的,你的集成必须同时处理这两种情况。

单消息

卡组织发送一条同时完成授权与清算的消息。常见于 PIN 借记、ATM 取款与交通出行场景。没有待处理窗口——交易几乎立即成为最终状态。

双消息

卡组织先发送一条授权,商户随后再提交清算——通常在当晚,但对酒店、租车与差旅场景可能长达数天。两者之间的间隔就是待处理窗口,也是大多数对账问题的发源地。
清算金额可能与授权金额不同。 小费、加油、货币兑换与部分发货都可能使清算金额高于或低于原始冻结金额。请以清算金额为准,永远不要把授权金额当作最终金额。

资金去向

同一生命周期,从账户视角来看:

Fluz 在每个阶段记录的内容

两套数据源,两套状态术语。
  • getVirtualCardTransactions 返回的 transactionStatus 值如 PROCESSING 与 CLEARED。
  • getTransactions 返回的 status 值为 PENDING 与 SETTLED。
它们从两个角度描述同一个生命周期。不要写出在两处都假设同一套术语的代码。→ GraphQL API 的工作原理
被拒绝不是一笔交易。 被拒绝的授权永远不会进入账户账本,因此无论查询哪种状态,它们都不会出现在 getTransactions 中。请通过 getDeclinedTransactions 查询它们,并从拒绝代码中读取原因。

授权

当卡组织请求 Fluz 批准一笔扣款时,Fluz 会依据该卡、该账户以及该卡背后的资金来源评估这笔请求。整个过程在远低于一秒的时间内完成,因为卡组织会超时。
  • 该卡处于 ACTIVE 状态——未锁定、未过期、未超过其 lockDate,也未被一次性使用规则消耗
  • 金额在该卡 spendLimitDuration 对应的 spendLimit 范围内
  • 若该卡是在品牌锁定项目下发行的,商户须匹配该卡的品牌锁定
  • 账户持有人已通过身份验证
  • 该卡背后的资金来源足以覆盖该金额
  • 未超出发卡银行项目自身的限额
卡片本身不持有余额。在授权时,它会从发卡时配置的资金栈中依次提取:
  1. userCashBalanceId 中指定的消费账户,或账户默认值
  2. 预付款(礼品卡)余额,除非 usePrepaymentBalance: false
  3. 奖励余额,除非 useRewardsBalance: false
  4. 外部银行账户,当 primaryFundingSource 为 BANK_ACCOUNT 时
即使该卡的 spendLimit 更高,只要授权金额超出这些资金来源能覆盖的范围,该授权仍会被拒绝。→ 管理虚拟卡资金来源
卡组织请求一个金额,Fluz 记录它所批准的金额。在部分批准的情况下,两者不同,而被冻结的是批准金额。请以 Fluz 记录中的金额为准,不要假设它等于商户所请求的金额。
被拒绝的授权会向商户返回一个响应代码,并在 Fluz 侧生成 declineReason 与 declineCategory。最常见的原因包括金额超出消费限额、卡片被锁定、该卡背后资金不足、品牌锁定卡在错误的商户处使用,以及 CVV 或 AVS 不匹配。→ 拒绝代码

并非购买的授权

被冻结的资金

一笔已批准的授权会减少该卡在不将资金移出账户的情况下仍可消费的额度。在其清算之前:
  • 该卡的 remainingBalance 会反映这笔冻结
  • 该账本记录处于 PENDING 状态
  • expectedClearedDate 会告诉你何时该再次查看
如果清算始终没有到来,冻结不会永远留在那里——卡组织的过期规则会释放它,资金会回到该卡的可用余额中。大多数授权会在大约一周内过期;差旅与住宿类冻结的时间更长。具体窗口由卡组织与商户设定,而非由 Fluz 设定。

撤销

撤销是在一笔授权清算_之前_将其取消。冻结被释放,资金回到卡上。撤销可以是全额的,也可以是部分的。 常见原因:
  • 商户放弃了这笔交易,或终端超时
  • 商品缺货,或持卡人在发货前取消
  • 发送了重复授权
  • 授权在没有清算的情况下过期
清算之后的”撤销”实际上是退款。一旦交易完成清算,就没有冻结可以释放了。此后返回的资金会以贷记形式到账——一条独立的 REFUND 记录——应按此处理。是否存在对应的清算,是区分这两种情况的分界线。

清算与结算

清算是商户提交最终金额,通常作为夜间批处理的一部分。Fluz 使用卡组织的参考标识符将其与未结授权匹配,并完成该记录。 需要为以下现实情况做好准备:
  • 金额会变化。 小费、加油、外汇与部分发货都会改变这个数字。
  • 可能不止一次清算。 一次分批发货会针对同一笔授权分多次清算,且这些部分可能乱序到达。
  • 清算可能在没有授权的情况下到达。 卡组织在某些情况下允许商户强制入账——离线终端、机上消费、交通票务聚合。Fluz 会监控这类情况,但你的账本必须能够接受一笔”已经清算、没有待处理阶段”的购买。
  • 匹配并不保证成功。 在极少数情况下,一笔清算上的标识符与其所属的授权对不上,该清算会作为独立记录出现。
不要仅凭卡组织参考标识符进行对账。 它们在一笔交易的整个生命周期内不保证保持一致,在不同卡组织之间也不稳定。请在你创建订单时,就把 Fluz 的 record_id 与 reference_id 存到你自己的订单上。→ 对照你自己的系统进行对账

退款

商户退还价值时,会通过卡组织送回一笔贷记。Fluz 会在卡片数据源中将其记为 REFUND,在账本中记为一笔贷记。它可能以稍后清算的授权形式到达,也可能直接作为一笔清算到达。 两种会打破简单粗暴匹配逻辑的情况:
  • 未关联的退款。 卡组织发送这笔贷记时可能不带任何指向原始购买的引用,或使用不同的标识符。它会作为一笔没有关联对象的独立贷记到达。
  • 批量退款。 多笔针对不同原始购买的退款可能共享卡组织标识符,并成组到达。
正因如此,不要假设退款与购买之间是一对一关系。请将退款作为针对该卡的独立贷记进行对账,并以余额作为事实来源。

外币

以其他货币完成的购买会以美元清算,原始金额会保留在记录中: 这三个字段是一起返回的——要么全部有值,要么全部为 null。换算发生在清算时,因此即使商户扣款金额相同,一笔外币授权与其清算在美元口径上通常也会有差异。

常见消息序列

除了这两条正常流程之外,以下序列值得为其编写测试覆盖。

针对该生命周期进行开发

1

将待处理与已清算视为不同的东西

永远不要把一笔待处理的授权展示为已完成的购买,也不要把授权与清算相加求和。如果你需要一个数字,请汇总已清算记录,并将冻结单独展示。
2

订阅全部三种交易事件

TRANSACTION_CREATE、TRANSACTION_UPDATE 与 TRANSACTION_DECLINE。只监听创建事件的集成会让每笔交易永远停留在其授权金额上。→ Webhooks
3

按 updatedGte 而非 createdGte 进行同步

一条以 PENDING 状态创建、之后完成清算的记录,变化的是其更新时间戳,而非创建时间戳。按创建日期同步会悄无声息地漏掉每一次结算。
4

从快照中对账余额

每条账本记录都携带每个余额的事后状态。请读取这些字段,而不要自己汇总金额——它们已经计入了手续费、返现与未结冻结。
5

让处理器具备幂等性

Webhook 会重试,清算也可能乱序到达。请以 Fluz 记录标识符为键,让重放成为无操作。

测试该生命周期

Staging 卡片是真实的卡片记录,但不在真实卡组织网络上,因此交易是注入产生的,而非刷卡产生的。你可以演练一笔授权、一次独立清算、一次拒绝、一次撤销、一次退款与一次零元探测——每一种都会产生与生产环境相同的记录与 webhook。 → 模拟虚拟卡交易

后续步骤

交易概览

统一账本——一条记录包含什么,以及如何对账。

获取虚拟卡交易

卡片级活动、筛选条件、外汇字段与分页。

获取被拒绝的交易

从未成为交易的授权。

拒绝代码

每一种拒绝原因与类别,以及应如何处理。

模拟虚拟卡交易

在一张 staging 卡上进行测试消费,观察生命周期运行。

Webhooks

订阅交易事件,验证签名,处理重试。