手册

付款错误分类 (Payment Failure Taxonomy)

超时、429、5xx、业务下降和基础设施错误不是一回事。每个类别都需要不同的重试策略。

分布式支付引擎

部分 11 的 22

一系列分布式支付架构弥合了捕获和完成之间的差距。

Distributed payment engine architecture diagram

在上一节中,我们看到诸如 PaymentFailed 之类的语义事件隐藏了提供程序的状态代码。但即使是单个 PaymentFailed 事件也是不够的;因为“失败”这个词涵盖了截然不同的现实。

卡被拒绝、网络超时、PSP返回429、PSP返回500都可以显示为“失败”;但每一个都需要完全不同的行动。本章讨论构建一个分类法,使这些差异变得可见。```text PaymentFailed ├─ Business Decline (kart reddedildi — retry etme) ├─ Timeout (belirsiz sonuç — dikkatli retry) ├─ Rate Limited (429) (çok istek — backoff ile retry) └─ Infrastructure (5xx) (provider tarafı arıza — retry)


## 第一次提到的概念```text
📦 Business Decline
PSP'nin, kartın kendisiyle ilgili bir nedenle isteği reddetmesi: yetersiz bakiye, dolandırıcılık şüphesi.

📦 Transient Hata
Aynı isteğin tekrar denenmesi mantıklı olan, geçici bir arıza: timeout, 5xx, 429.

📦 Permanent Hata
Tekrar denemenin sonucu değiştirmeyeceği hata: geçersiz kart numarası, desteklenmeyen para birimi.

📦 Belirsiz Sonuç
İsteğin PSP'ye ulaşıp ulaşmadığının bilinmediği durum: bağlantı timeout'u.
```重试业务下降是浪费时间;不重试不确定的结果是错过付款的真正风险。分类法的存在是为了区分这两种风险。

## 四个基本类别

**业务下降**:PSP 收到请求,对其进行处理并做出决定 - 该卡被拒绝。这不是系统错误,而是业务决策。再试一次不会改变结果;有必要向用户建议另一种支付方式。

**超时/不确定结果**:请求已发送,但响应从未到来。这里的危险是——付款可能发生在 PSP 端,只是您丢失了响应。这一类别不能通过盲目的“再试一次”来解决。首先,应对情况进行质疑(使用幂等性密钥),然后做出决定。

**速率限制 (429)**:PSP 暂时拒绝您控制请求量。这不是一个错误,而是一个信号。立即重试会使情况变得更糟;需要进行退避等待。

**基础设施 (5xx)**:PSP 端出现故障。如果请求尚未被处理,通常可以安全地重试 - 但如果不断收到 5xx,则这是一个断路器信号。```text
Hata alındı
  │
  ├─ PSP isteği net biçimde reddetti mi? → Business Decline → retry etme
  │
  ├─ Yanıt hiç gelmedi mi? → Belirsiz Sonuç → önce durumu sorgula
  │
  ├─ 429 mu? → Rate Limited → backoff ile retry
  │
  └─ 5xx mi? → Infrastructure → retry, ama circuit breaker'ı izle
```## 为什么单个“重试”规则是不够的

使用相同重试逻辑处理所有错误的工作人员将以两种方式失败:它将毫无意义地重试业务拒绝(延迟用户体验,有时会推动卡网络限制),或者根本不重试而留下不明确的结果(导致系统忘记实际上成功的付款)。该分类法通过将每个错误放入正确的框中来降低这两种风险。

## 我们如何在代码中表示分类法

语义事件的 `failureReason` 字段必须包含这四个类别之一,而不是提供程序的原始错误文本。提供商网关负责将原始错误映射到此类别 - 这是上一节中转换层的扩展。

|失败原因 |重试是否合适?行动|
| --- | --- | --- |
|业务下滑 |没有 |向用户建议另一种方法 |
|模糊超时 |先查询 |状态查询然后决定 |
|价格有限 |是的 |后退重试 |
|基础设施错误|是的 |观看重试+断路器|

## 经常混淆的区别```text
❌ Her hata retry edilmelidir
✓ Business decline retry edilmemelidir; sonuç değişmez

❌ Timeout = hata yok, sadece tekrar dene
✓ Timeout = belirsizlik; önce gerçek durum sorgulanmalı

❌ 429 bir arızadır
✓ 429 bir sinyaldir; sistem sizi kasıtlı olarak yavaşlatıyor
```## 类别之间的快速比较

|类别 |结果清楚了吗?重试有意义吗?典型原因 |
| --- | --- | --- | --- |
|业务下滑 |是的 |没有 |卡、余额、欺诈 |
|超时 |没有 |先查询 |网络、PSP 缓慢 |
|价格有限 |是的 |是的(等待)|音量控制|
|基础设施|是的 |是的 | PSP端故障|

## 设置分类时的清单

1. Provider 返回的每个错误代码是否清楚地映射到四个类别之一?
2、当新的未映射错误码到来时,系统是默认查询状态还是盲目重试? (真正的默认值:查询状态。)
3、超时场景下,是否真的实现了预重试状态检查?
4. 429 的退避时间是否考虑 PSP 的 `Retry-After` 标头(如果有)?
5. 是否将 5xx 频率作为触发断路器的指标进行监控?
6、业务下滑后的用户流量是否不会进入重试周期?

## 本文中您应该记住的内容

1.“失败”不是单一的状态;它们是四种不同的现实,需要至少四种不同的行动。
2、业务下降不重试; timeout不是盲目重试,而是先查询。
3、429是信号,5xx是故障;两者都会重试,但纪律不同。
4. 分类法使错误可以从您自己的 `failureReason` 枚举中读取,而不是从原始提供程序文本中读取。

> 如果在不了解错误的情况下编写了重试策略;不但无益,反而会无声无息地造成伤害。

在下一节中,我们将为这四个类别(退避、抖动、上限和断路器)中的每一个设置实际的重试算法。

FAQ

Frequently asked questions

什么是业务衰退?

PSP 拒绝该请求的原因与该卡本身有关:资金不足、涉嫌欺诈。

什么是瞬态误差?

暂时失败,再次尝试相同的请求是有意义的:超时、5xx、429。

难道真的是“每一个错误都必须重试”吗?

业务衰退不应重演;结果没有改变

本节修复了什么?

卡被拒绝、网络超时、PSP返回429、PSP返回500都可以显示为“失败”;但每一个都需要完全不同的行动。本章讨论构建一个分类法,使这些差异变得可见。 “失败”不是单一的状态;它们是四种不同的现实,需要至少四种不同的行动。在上一节中,我们看到诸如 `PaymentFailed` 之类的语义事件隐藏了提供程序的状态代码。但即使是单个 `PaymentFailed` 事件也是不够的;因为“失败”这个词涵盖了截然不同的现实。

学到的工程原理

  • 失败不是个案;每个类别都需要不同的操作。
  • 不确定的结果不是盲目重试,而是先质疑。
  • 429 是一个信号,而不是故障——这是符合纪律的。

继续阅读

继续阅读

系列中的下一个

系列中的下一个

同系列

Paylaş