手册
なぜ決済システムは分散型システムなのでしょうか? (Why Payment Systems Are Distributed Systems)
支払いは単一のサービスの仕事ではありません。バスケット、株式、プロバイダーゲートウェイ、金融は同じ事実について合意する必要があります。同期チェーンが壊れるのはなぜですか?
分散型決済エンジン
部分 1 的 22
取得と完了の間のギャップを埋める一連の分散型支払いアーキテクチャ。
支払いはボタンではなく、調整です
電子商取引プラットフォームで「支払いを受ける」と言うとき、実際には、5 つの異なるシステムが同じ事実について合意する必要があります。つまり、カートは凍結されているか、在庫はあるか、プロバイダーのゲートウェイがお金を受け取ったか、注文は確認されているか、財務記録は正しいかです。これらすべてが 1 つのプロセス、1 つのトランザクション内に存在するわけではありません。```text Sepet Servisi Stok Servisi Checkout Orchestrator Provider Gateway Finans/Ledger | | | | | +---------------+------------------+--------------------+----------------+ aynı sipariş, beş farklı gerçek
## 最初に説明した概念```text
📦 Checkout Orchestrator
Sipariş akışının adımlarını (sepet, ödeme, stok, onay) koordine eden servis; para veya stok tutmaz, kararları sıralar.
📦 Provider Gateway
Gerçek ödeme sağlayıcısını (PSP) uygulama iç modeline çeviren soyutlama katmanı.
📦 PSP (Payment Service Provider)
Kartı veznede tutan, parayı fiilen çeken dış sistem; sizin transaction sınırınızın dışındadır.
📦 Dağıtık Transaction
Birden fazla bağımsız sistemin, tek bir “hepsi ya da hiçbiri” garantisi altında değişmesi gereken işlem.
📦 Eventual Consistency
Sistemlerin şu an değil, kısa bir süre içinde aynı gerçeğe yakınsayacağını kabul eden tutarlılık modeli.
```これら 5 つの概念を区別できないため、チームは PSP を独自のデータベースとして機能させることにしました。 PSP はあなたのトランザクションに参加することはありません。彼はただ、自分自身のタイムラインで、自分自身の真実を伝えているだけです。
## 1 つのリクエストには 5 つの署名が必要です
顧客が「支払う」ボタンを押すと、バスケット価格が凍結されるかどうか、在庫が予約されるかどうか、支払い要求がプロバイダーのゲートウェイに送信されるかどうか、PSP がお金を引き出すかどうか、注文明細が確定されるかどうか、財務記録が開かれるかどうかなど、バックグラウンドで次の決定が行われます。これらはそれぞれ異なるサービスの責任を負い、異なるデータベースに存在します。
ここからが問題の始まりです。単一の HTTP リクエスト チェーン内でこれら 6 つのステップを同期的に呼び出すと、システムは 1 つのポイントから別のポイントへの長くて脆弱な依存関係のチェーンになります。```text
Client → Checkout Orchestrator → Sepet Servisi → Stok Servisi → Provider Gateway → PSP
```## 同期チェーンはどこで壊れますか?
このチェーンのいずれかのステップでタイムアウトが発生すると、次の 2 つの疑問が残ります。リクエストは相手に届いたのか、届いた場合は処理されたのかということです。 PSP からタイムアウトが返されても、「お金が引き出されない」ことを意味するわけではありません。 「答えが得られなかった」という意味です。同じリクエストを再送信すると、顧客が 2 回レジに並ぶ可能性があります。```text
Checkout Orchestrator --(timeout)--> Provider Gateway --(???)--> PSP
para çekildi mi, çekilmedi mi?
```この不確実性は同期チェーンの自然な結果です。ネットワークは定義上、信頼性がありません。連鎖を長くすればするほど、不確実性は蓄積されます。
## ここでは「全か無か」が機能しない理由
従来の分散トランザクション ソリューション (2 フェーズ コミットなど) では、すべての参加者が同じコーディネーター、同じロック プロトコル、および同じネットワーク信頼性を持っていることが期待されます。 PSP はこの世界の一部ではありません。PSP 自体はロックを解除せず、コミット/ロールバック呼び出しをリッスンせず、独自のタイムライン (Webhook、遅延通知) で通知します。
したがって、「支払い + 在庫 + 注文」という 3 つの要素を 1 つのトランザクションに収めようとすると、解決不可能な問題が解決されたかのように見えてしまいます。あなたが実際にやっていることは間違いを隠すことです。あなたはそれを排除していません。
## イベントベースのソリューション: 2 つの異なる事実、2 つの異なるタイムライン
実用モデルは、同期チェーンを短縮し、残りをイベントに委任することです。プロバイダー ゲートウェイにリクエストを送信し、PSP の応答を (同期または Webhook 経由で) イベントとして記録します。注文/在庫/財務側の各ステップは、それ自体が冪等のコンシューマーとして機能し、このイベントに反応します。```text
Provider Gateway → PaymentCaptured (event) → Outbox
↓
Stok Servisi Finans Servisi Checkout Orchestrator
(bağımsız, kendi hızında, kendi retry'ıyla tüketir)
```このモデルでは、「支払いの成功」と「注文の完了」は同時に発生する 1 つのイベントではなくなり、それらの間には測定可能な遅延があり、互いに続く 2 つの別々の事実になります。この区別を受け入れないシステムは、ステート マシン エラーに進みます。これについては、このシリーズの第 2 部で説明します。
## このエピソードで最も混乱を招く対戦```text
❌ Ödeme akışı = tek bir servisin fonksiyonu
✓ Ödeme akışı = birden fazla bağımsız servisin katıldığı bir koordinasyon
❌ PSP = bizim veritabanımızdaki bir tablo gibi davranır
✓ PSP = kendi zaman çizelgesi olan, dışarıdan gözlemlenen bir sistem
❌ Timeout = işlem başarısız oldu
✓ Timeout = işlemin sonucu bilinmiyor; retry idempotent olmadan güvenli değildir
❌ Dağıtık transaction ile bu problem “çözülebilir”
✓ Dağıtık transaction, PSP gibi harici sınırlarda pratikte uygulanamaz
```これら 4 つの不一致が、「支払いが時々二重請求されるのはなぜですか」という事件のほとんどの原因です。
## 独自のシステムのチェックリスト
1. 支払いフローでは、いくつの異なるサービスがいくつの異なるデータベースに書き込みますか?この番号を書きます。
2. プロバイダー ゲートウェイへの呼び出しがタイムアウトになったときにコードが自動的に再試行されますか?この再試行には冪等性キーが含まれますか?
3. 「支払い成功」情報と「注文完了」情報は同じ行に保持されていますか、それとも別のテーブルに保持されていますか?
4. PSP からの Webhook が遅延しているか、まったく到着しない場合、システムがそれに気づくまでに何時間かかりますか?
5. 同期チェーン内で最も長いステップは何ですか?そのステップが低下した場合、残りのステップは何をしますか?
これら 5 つの質問に対する明確な答えがない場合は、おそらく支払いフローが「単一トランザクション」であるかのように設計されていると考えられます。
## このセクションで覚えておくべきこと
1. 支払いは単一のサービスの取引ではありません。これは、バスケット、株式、プロバイダーゲートウェイ、金融が同じ事実について合意する調整です。
2. 同期 HTTP チェーンでは、ステップが追加されるたびに不確実性が増大して蓄積されます。タイムアウトは結果ではなく、不確実性です。
3. PSP は取引制限の一部ではありません。同期ロックではなく、イベント コントラクトを使用して通信します。
4. 結果整合性は欠陥ではなく、外部 (特に PSP) の実際の動作を受け入れることです。
> 支払いシステムを「即時かつ一括」として設計すると、本番環境では「遅れて複数」という現実に遭遇することになります。
FAQ
Frequently asked questions
チェックアウト オーケストレーターとは何ですか?
注文フロー(カート、支払い、在庫、確認)のステップを調整するサービス。お金や株式は保有しませんが、決定事項をリストします。
プロバイダーゲートウェイとは何ですか?
実際の決済プロバイダー (PSP) をアプリケーション内部モデルに変換する抽象化レイヤー。
「決済フロー=単一サービスの機能」は正しいでしょうか?
決済フロー = 複数の独立したサービスを連携させたもの
このセクションでは何を修正しますか?
この記事では、支払いフローを「サービスの機能」としてではなく、分散システムの問題として設計する必要がある理由を説明します。支払いは単一のサービスのトランザクションではありません。これは、バスケット、株式、プロバイダーゲートウェイ、金融が同じ事実について合意する調整です。電子商取引プラットフォームで「支払いを受ける」と言うとき、実際には、5 つの異なるシステムが同じ事実について合意する必要があります。つまり、カートは凍結されているか、在庫はあるか、プロバイダーのゲートウェイがお金を受け取ったか、注文は確認されているか、財務記録は正しいかです。これらすべてが 1 つのプロセス、1 つのトランザクション内に存在するわけではありません。
学到的工程原理
- 支払いフローは単一のサービスの機能ではありません。それは複数の独立したシステムの調整です。
- PSP はトランザクション制限を超えています。同期ロックではなく、イベント コントラクトを使用して通信されます。
- 結果整合性は弱点ではなく、設計におけるネットワークと外部プロバイダーの実際の動作を反映しています。
继续阅读
继续阅读
系列中的下一个
チェックアウト ステータス マシンの設計: チェックアウトと支払いが同じものではないのはなぜですか?
支払いが成功しても、注文が完了したことを意味するものではありません。チェックアウトと支払いのライフサイクルを分離しないと、運用環境で 2 つの現実が重複してしまいます。
同系列
収集(キャプチャ)は簡単だが、ファイナライズはなぜ難しいのか?
PSPが資金を得るのはほんの一歩だ。注文を完了してください。これは、在庫、財務、報告、清掃の各ステップをすべて成功させる必要がある物語です。
同系列
不変のチェックアウト スナップショットの設計: カートを凍結する決定
支払い開始時にカートをライブで読み取ると、金額と通貨は未定のままになります。インテントの瞬間にフリーズするスナップショットがなければ、ファイナライゼーションは確実に機能しません。