プレイブック
生のプロバイダー データの代わりにセマンティック イベント (Semantic Events Over Raw Provider Payloads)
プロバイダー ゲートウェイによって受信された Webhook は、PSP のイベント名または PaymentCaptured/PaymentFailed などのセマンティック イベントとともにダウンストリームに到達する必要がありますか?
分散型決済エンジン
一部 10 の 22
取得と完了の間のギャップを埋める一連の分散型支払いアーキテクチャ。
前のセクションで、オーケストレーターが PSP SDK をまったく認識すべきではないことを見ました。同じ制限が、同期呼び出しの 1 ステップ先、つまりプロバイダーからの Webhook で再び表示されます。
PSP Webhook は通常、独自の内部データ モデル (プロバイダー固有のイベント タイプ名、プロバイダー固有のステータス コード、プロバイダー固有のオブジェクト構造) を保持します。このペイロードをメッセージ キューまたはイベント ストリームにそのまま置くことは、プロバイダーのスキーマをすべての下流コンシューマに漏洩することを意味します。```text PSP Webhook { type: 'charge.succeeded', data: { object: {...} } } ▼ Provider Gateway (çeviri) ▼ Semantik event PaymentCaptured { paymentId, amount, currency }
## 最初に説明した概念```text
📦 Semantik Event
İş diliyle adlandırılmış, provider'a hiç referans vermeyen olay: PaymentCaptured, PaymentFailed.
📦 Ham Provider Payload
PSP'nin webhook body'sinde gönderdiği, kendi iç modelini taşıyan orijinal veri.
📦 Çeviri Katmanı (Translator)
Ham payload'ı okuyup semantik event'e dönüştüren, gateway içinde yaşayan bileşen.
📦 Event Sözleşmesi Sahipliği
Semantik event'in alanlarını ve anlamını kimin belirlediği; burada her zaman gateway.
````charge.succeeded` はプロバイダーの内部用語です。 `PaymentCaptured` はドメインの現実です。この 2 つは同時に変更されません。プロバイダーはイベント名を変更できますが、セマンティック イベント名は一定のままです。
## 未加工のペイロードをそのまま輸送するコスト
最も速く統合する方法は、Webhook 本体を解析せずにメッセージ ブローカーをプッシュすることです。これは短期的には機能します。消費者も同じペイロードを解析します。ただし、これにより、プロバイダーのスキーマ変更が各コンシューマーに直接伝播されます。 PSP がドメインの名前を変更すると、制御不能なイベントによってほとんどのシステムが一度に破壊されます。```text
Ham payload yayılırsa
PSP şema değişikliği → N tüketici aynı anda etkilenir
Semantik event yayılırsa
PSP şema değişikliği → sadece gateway'in çeviri katmanı güncellenir
```## 翻訳レイヤーは何を行い、何をしませんか?
変換層は、プロバイダー固有のステータス コードをセマンティック列挙型にマッピングし、一貫性のないフィールドまたは欠落しているフィールドを正規化し、必要に応じてローカル レコードから欠落しているデータ (金額、通貨など) を補完します。すべきではないのは、ビジネス上の意思決定を行うことです。「なぜこの支払いが失敗したのか、何をすべきか」という質問に対する答えは、翻訳層の仕事ではなく、オーケストレーターの仕事です。```text
Webhook geldi
→ provider event tipini oku
→ statü eşleme tablosuna bak
→ semantik event oluştur
→ local correlation id ile eşle
→ yayınla (Outbox üzerinden)
```## マッピング テーブルは具体的な設計ツールです
プロバイダーには数十のイベント タイプがある場合があります。セマンティック イベント セットははるかに小さく、安定している必要があります。
|プロバイダーイベント |セマンティックイベント |
| --- | --- |
|充電に成功しました |支払いキャプチャ |
|充電に失敗しました |支払いに失敗しました |
|請求.紛争.作成されました |支払いに関する紛争 |
|支払い_意図.要求_アクション |支払いアクション必須 |
この表はコードレビューで読み取れる必要があります。新しいプロバイダー イベントが到着したとき、「これはどのセマンティック イベントに対応するか」という質問は、コード ベース全体に点在する if-else チェーンではなく、1 行の決定で行う必要があります。
## 注文と再配達の保証は引き続き有効です
変換レイヤーは、Webhook が繰り返し到着する、または順番どおりに到着しないシナリオも処理する必要があります。ネットワーク エラーにより、プロバイダーが同じ Webhook を 2 回送信する場合があります。セマンティック イベントを生成する場合、イベントの生成が冪等であることが必要です。同じ Webhook ID が 2 回目に発生したときに、同じセマンティック イベントが再発行されるべきではありません (または、ダウンストリームの冪等になるように設計されている)。
## 混同されやすい区別```text
❌ Webhook = Event
✓ Webhook bir bildirim tetikleyicisidir; semantik event iş dilindeki gerçektir
❌ Ham payload'ı saklamak gereksizdir
✓ Ham payload tanılama için saklanır, ama yalnızca gateway'in kendi arşivinde
❌ Eşleme tablosu bir kere yazılır, bitmiştir
✓ Provider yeni event tipleri ekledikçe tablo canlı bir sözleşmedir
```## 生のパスを使用したセマンティック翻訳
|基準 |生パス |意味翻訳 |
| --- | --- | --- |
|下流のプロバイダー情報 |必須 |不要 |
|スキーマ変更に対する脆弱性 |高 |低い |
|診断用の生データ |道に迷うかも |ゲートウェイに保存 |
|新しいPSPを追加 |消費者への影響 |マッピング テーブルにのみ影響します |
## 翻訳レイヤーを設計する際のチェックリスト
1. ダウンストリームの消費者はプロバイダー固有のドメインまたはステータス コードを読み取りますか?
2. マッピング テーブルは 1 か所で定義されていますか、それともコード ベース全体に分散されていますか?
3. 生の Webhook ペイロードは、診断用にゲートウェイ独自のアーカイブに保存されていますか?
4. 同じ Webhook が 2 回到着すると、同じセマンティック イベントが 2 回ブロードキャストされますか?
5. 新しいプロバイダー イベント タイプがまだマッピングされていない場合、そのイベント タイプが到着するとどうなりますか? それは静かに飲み込まれるのでしょうか、それとも目に見えるアラートを生成しますか?
5 番目の質問は特に重要です。静かに飲み込まれた未知のイベントは、運用環境における最も危険な形式のデータ損失の 1 つです。
## この記事で覚えておくべきこと
1. ダウンストリームでは、プロバイダーのイベント名やステータス コードが表示されることはありません。
2. 変換層はマッピング テーブルと正規化ロジックであり、ビジネス上の意思決定を行いません。
3. 生のペイロードは診断のために保存されますが、その保存はゲートウェイ自体の境界内に限られます。
4. 不明なプロバイダー イベントは黙って飲み込まれるべきではなく、目に見える信号を生成する必要があります。
> イベントが意味論的かどうかを理解する最も簡単な方法は、プロバイダーのドキュメントからではなく、独自のドメイン辞書からその名前を読み取ることです。
次のセクションでは、これらのセマンティック イベントによって運ばれる障害情報について詳しく説明します。すべての `PaymentFailed` が同じ意味を持つわけではないため、障害分類が必要です。
FAQ
よくある質問
セマンティックイベントとは何ですか?
プロバイダーへの参照のないビジネス名イベント: PaymentCaptured、PaymentFailed。
Raw プロバイダー ペイロードとは何ですか?
PSP によって Webhook 本体内で送信される元のデータ。これには独自の内部モデルが含まれます。
「Webhook=イベント」は正しいでしょうか?
Webhook は通知トリガーです。意味上の出来事はビジネス言語における真実です
このセクションでは何を修正しますか?
このセクションでは、翻訳層が無視できない責任である理由について説明します。ダウンストリームでは、プロバイダーのイベント名やステータス コードが表示されることはありません。前のセクションで、オーケストレーターが PSP SDK をまったく認識すべきではないことを見ました。同じ制限が、同期呼び出しの 1 ステップ先、つまりプロバイダーからの Webhook で再び表示されます。
学んだエンジニアリング原則
- ダウンストリームプロバイダーのイベント名ではなく、ドメインの実際を確認する必要があります。
- マッピング テーブルはライブ コントラクトであり、ワンタイム コードではありません。
- 不明なプロバイダー イベントは黙って飲み込むのではなく、表示される必要があります。
続きを読む
続きを読む
シリーズの次のシリーズ
支払いエラーの分類法
タイムアウト、429、5xx、ビジネスの低下とインフラストラクチャのエラーは同じものではありません。カテゴリごとに異なる再試行ポリシーが必要です。
シリーズの次のシリーズ
SDK (ソフトウェア開発キット) を漏らさないプロバイダーの抽象化: ゲートウェイの限界
プロバイダー ゲートウェイは PSP SDK をどのように所有しているのですか。なぜチェックアウト オーケストレーターはセマンティック インターフェイスのみを参照する必要があるのでしょうか?カードとウォレットの流れは異なります...
同じシリーズ
支払い証明書と支払いステータス: 混同すべきではない理由
PSPがそう言っているのが証拠です。状態はあなたが決めるものです。これら 2 つを同じレジストリに保存しておくと、回復中にどちらを信頼すればよいかがわかります。