FINTECH 101 — 交易到底是如何运作的

发布: (2025年12月19日 GMT+8 00:06)
6 min read
原文: Dev.to

Source: Dev.to

核心思维模型

四大支柱:

  1. 交易状态
  2. 回调 / Webhook
  3. 对账与状态查询
  4. 重试、冲正与幂等性

如果你误解了其中任何一点,最终会亏钱。

Source:

交易状态(非响应)

在金融科技领域,我们跟踪 状态,而不仅仅是 HTTP 响应。

规范的交易生命周期

状态描述
INITIATED请求在内部创建
PROCESSING已发送至处理器
PENDING处理器已接受但尚未最终确认
SUCCESS金额已确认交付
FAILED金额未交付
REVERSED金额已扣除随后返还
TIMEOUT在 SLA 时间内未收到响应

这些状态实际代表的含义

状态含义
INITIATED您的系统已创建该交易
PENDING处理器或网络仍在处理中
SUCCESS价值已交付(流量、数据、金钱等)
FAILED价值未交付
REVERSED金额已扣除但已退款

黄金法则
交易只能以 SUCCESSFAILEDREVERSED(临时)结束。

在金融科技系统中,请求可以在技术上成功,而金融行为本身未完成(例如,余额不足、银行确认待定、合规检查失败)。这些属于正常的业务结果,而非系统错误。

使用 HTTP 响应码来表示技术成功,并使用单独的业务状态来表示交易结果,可避免混淆、防止不安全的重试,并使支付流程更易于理解。

概念 vs. 目的

概念目的
Response Code技术结果
Status业务状态

示例

{
  "code": "99",
  "status": "PENDING",
  "message": "Transaction is being processed"
}

HTTP 200 仅表示“我们收到了你的请求”;它 表示交易成功。status 字段才是事实的真相。

金额表示

绝不要使用浮点数(float)或双精度(double)来存储金额。
计算机使用二进制(base‑2),而人类使用十进制(base‑10)。一些简单的小数在二进制中无法精确表示,导致四舍五入误差和账本不匹配。

正确做法:最小单位

将金额存储为最小货币单位。

错误正确
100.00(十进制)存储10000(整数)存储

经验法则

  • 数据库: BIGINT(例如,1050 表示 10.50)
  • 代码: 整数运算(1050 + 20
  • 前端: 仅在显示时转换(例如,GH₵10.70

Source:

回调(Webhooks)

什么是回调?

当交易因网络延迟、银行离线或处理器超时而仍处于待处理状态时,就会发生回调。

典型的回调流程

  1. 你发送请求。
  2. 处理器响应 → PENDING
  3. 你将交易保存为 PENDING
  4. 稍后,处理器调用 your endpoint
  5. 你更新交易 → SUCCESS / FAILED

回调失败

  • 网络问题
  • 处理器宕机
  • 处理器漏洞

由于回调可能会失败,金融科技系统还会使用 status enquiry(拉取)来恢复真实状态。

  • Push: 处理器主动通知你(回调)。
  • Pull: 你主动向处理器查询(status enquiry)。

幂等性

噩梦情景

  1. 用户点击 “Pay”。
  2. 网络故障。
  3. 用户再次点击。
  4. 产生两笔收费。

解决方案:幂等键

  • 拒绝重复的引用。
  • 强制数据库唯一性 (UNIQUE(reference)).

重试

当出现以下情况时,重试是危险的:

  • 无响应(超时)
  • 网络错误

成功 之后进行重试可能导致重复收费,而在 失败 的业务结果之后进行重试可能是没有必要的。

逆转

当出现以下情况时需要进行逆转:

  • 已产生 SUCCESS 借记但交付失败。
  • 在 SLA 期限后未收到回调。

逆转流程

  1. 检测不匹配。
  2. 调用逆转 API。
  3. 更新交易 → REVERSED
  4. 通知用户。

您的记录永远不可能与处理器的记录完全一致。任何不匹配都应进行调查并予以纠正。

日志要求

  • 请求负载
  • 响应负载
  • 状态转换
  • 时间戳

最终思维模型(永远保持)

  • 永远不要相信第一次响应。
  • 金钱系统最终是一致的。
  • Status 是真相,而不是 HTTP 响应码。
  • 会计永远占上风。

如果你用这种思维方式构建金融科技,你不仅能通过测试——还能在生产环境中生存下来。

Back to Blog

相关文章

阅读更多 »

幂等性

在分布式系统中,假设每个请求都能到达其目的地且每个响应都能返回给发送者并不总是成立。当一个传…

Go 中的依赖注入,简化为字段标签

核心理念:所有依赖注入都是使用结构体字段标签声明的,除此之外没有其他。 - 没有 provider sets。 - 没有 DSL。 - 没有运行时反射。 容器……