プレイブック
有料だが注文なし: 改善 (Healing Paid But Unordered)
インシデント対応ガイド: 顧客は請求したが注文はされなかった。多目的のバスケットの乱雑さ。重複除去を慎重にクリーニングします。
分散型決済エンジン
一部 15 の 22
取得と完了の間のギャップを埋める一連の分散型支払いアーキテクチャ。
前のセクションでは、コンセンサス ワーカーがドリフトを検出する方法について説明しました。このセクションでは、そのドリフトの最も迷惑な形式を扱います。顧客は実際には PSP 側で請求されていますが、システムには見返りの命令がありません。
このシナリオでは、2 つの悪い解決策が魅力的に見えるため、パニックが発生します。それは、すぐに返金する (顧客が本当に注文を望んでいた可能性があり、不必要な返金と再試行のサイクルを開始する) か、黙って新しい注文を作成する (どのカートがどの取引に対応するかを知らずに間違った注文を生成するリスクがある) です。```text PSP kaydı: Charge #789 → Succeeded, amount: 249.00 Local kayıt: (hiçbir Order veya Payment satırı yok) │ ▼ Bu paranın hangi sepete ait olduğunu belirle │ ▼ Sipariş oluştur (heal) VEYA güvenle refund et
## 最初に説明した概念```text
📦 Orphan Charge
PSP tarafında başarılı ama local sistemde hiçbir kayda bağlanamayan ücretlendirme.
📦 Multi-Intent Cart
Aynı sepet için birden fazla ödeme intent'i oluşturulmuş durum (örn. kullanıcı sayfayı iki kez yeniledi).
📦 Heal (İyileştirme)
Orphan charge'ı doğru sepete/siparişe geriye dönük olarak bağlama işlemi.
📦 Correlation ID
Bir ödeme intent'ini oluşturduğu sepete/isteğe bağlayan, ödeme akışının başında üretilen kimlik.
```孤立請求は、相関 ID がどこかで失われたことが原因で発生することがよくあります。インテントの作成中に記録された ID は、注文作成ステップに到達する前に中断されます。
## インシデント対応ガイド: 最初のステップ
孤立した請求が (通常は調整担当者または顧客からの苦情を通じて) 検出された場合、最初のステップは何もアクションを起こすことではなく、相関チェーンを再確立することです。```text
1. PSP'nin charge metadata'sından correlation id'yi çıkar
2. Bu id ile local sistemde bir cart/intent kaydı ara
3. Kayıt bulunduysa → hangi aşamada kesintiye uğradığını belirle
4. Kayıt bulunamadıysa → refund'a yönel (heal edilecek bir hedef yok)
```相関 ID は常に PSP のメタデータ フィールドに書き込む必要があります (料金の作成時)。これは、孤立請求を遡及的に解決できるようにする最も重要な設計上の決定です。
## マルチインテント カート: どのお金がどの注文に属するか
顧客がチェックアウト ページを 2 回開いた場合 (タブの更新、ダブルクリック、ネットワーク遅延後の再試行)、同じカートに対して 2 つの異なる支払い意図が発生する可能性があります。 PSP 側で両方が成功した場合、システムが直面する問題は、もはや「配当の損失」ではなく、「どちらの配当が勝ち、もう一方はどうなるか」ということになります。```text
Cart #A
├─ Intent #1 → PSP: Succeeded
└─ Intent #2 → PSP: Succeeded (aynı sepet, iki farklı charge)
```ここでの正しい動作は、カートをロックし (同じカートに対して新しいインテントが作成されないようにする)、1 つのインテントのみを「勝者」として選択し、もう 1 つを自動的に返金することです。両方を注文に添付すると、二重価格が作成されます。
## Dedup を慎重にクリーニング: 「積極的な」削除が危険な理由
オーファン料金を清算する際の最大の落とし穴は、「同じ金額、同じ顧客、最近の時間」などの緩やかな基準に基づいて重複排除ロジックを作成することです。この基準では、2 つの別々の意図的な注文 (顧客が実際に 2 つの異なるものを購入した) を 1 つの注文として誤って扱う可能性があります。```text
❌ Gevşek dedup
Aynı müşteri + aynı tutar + 5 dakika içinde → tek sipariş say
✓ Sıkı dedup
Aynı correlation id VEYA aynı idempotency key → tek sipariş say
```重複排除の決定は、常にシステム自体によって生成された ID (相関 ID、冪等キー) に基づいて行う必要があります。量や時間などの間接的なシグナルは、主要な基準としてではなく、検証の追加層としてのみ使用する必要があります。
## 修復または返金: 決定基準
|ステータス |正しいアクション |
| --- | --- |
|相関 ID に一致する不完全なカートが見つかりました |治癒 — 注文の作成、支払いの接続 |
|相関 ID がどのレコードとも一致しません。払い戻し — バインドする対象がありません |
|同じバスケット内の 2 つの成功したインテント | 1 つを回復し、もう 1 つを払い戻す |
|カートはすでに別の支払いで完了しています |返金 - 二重請求 |
各修復プロセスは、誰が、どのプロセスが、いつ、どのような証拠に基づいてこの順序を作成したかという独自の監査レコードを作成する必要があります。この記録は、同じシナリオが将来再発するのを防ぐためにも使用されます。
## 混同されやすい区別```text
❌ Orphan charge her zaman refund edilmeli
✓ Correlation id ile eşleşen bir hedef varsa heal etmek doğru olabilir
❌ Aynı tutar + aynı müşteri = aynı sipariş
✓ Dedup, sistemin kendi ürettiği kimliğe (correlation id) dayanmalı
❌ Multi-intent bir hata durumudur, göz ardı edilebilir
✓ Multi-intent normal bir kullanıcı davranışıdır (yenileme, çift tıklama), tasarlanmalıdır
```## 修復と払い戻しの決定の比較
|基準 |癒す |払い戻し |
| --- | --- | --- |
|相関 ID の一致 |はい |なし、または不明瞭 |
|カスタマーエクスペリエンス |秩序は目に見えるが、中断は感じられない |返金、注文なし |
|リスク |不一致のリスク |顧客の不満のリスク |
## インシデント対応チェックリスト
1. オーファン担当の PSP メタデータに相関 ID はありますか?それ以外の場合、これは設計上の欠陥の兆候です。
2. 重複排除の決定は、量/時間などの間接的な信号、またはシステムによって生成された ID に基づいていますか?
3. マルチインテントのシナリオでは、最初のインテントが成功した後にカートはロックされますか?
4. 各修復プロセスでは、誰が、いつ、どのような証拠情報を含む監査記録が作成されますか?
5. 返金決定の前に、ターゲットが実際に見つからなかったことを 2 回確認しますか?
## この記事で覚えておくべきこと
1. 孤立請求を解決する鍵は、支払いフローの最初に相関 ID を安全に生成することです。
2. マルチインテント カートは通常のシナリオです。バスケットのロックと単一の勝利意図の選択を考慮して設計する必要があります。
3. 重複排除の決定は、量や時間などの間接的なシグナルに基づいて行うべきではなく、常に ID に基づいて行う必要があります。
4. 治療するか返金するかという問題は、反射的な行動ではなく、証拠に基づいて決定されるべきです。
> パニック時の最も安全な行動は、すぐに解決できるものではありません。正しい証拠が見つかるまでは何もしないことです。
次のセクションでは、そのような差異の根本に迫ります。PSP、秩序、金融の間で分散トランザクション (2PC) を設定することがなぜ罠であり、なぜ物語 + 調整が本当の答えなのかに迫ります。
FAQ
よくある質問
オーファンチャージとは何ですか?
PSP 側では価格設定は成功しますが、ローカル システム上のどのレコードにもリンクできません。
マルチインテント カートとは何ですか?
同じカートに対して複数の支払いインテントが作成されました (例: ユーザーがページを 2 回更新した)。
「オーファン料金は必ず返金されるべき」は本当ですか?
相関 ID に一致するターゲットが存在する場合、修復は正しく行われる可能性があります。
このセクションでは何を修正しますか?
このシナリオでは、2 つの悪い解決策が魅力的に見えるため、パニックが発生します。それは、すぐに返金する (顧客が本当に注文を望んでいた可能性があり、不必要な返金と再試行のサイクルを開始する) か、黙って新しい注文を作成する (どのカートがどの取引に対応するかを知らずに間違った注文を生成するリスクがある) です。孤立請求を解決する鍵は、支払いフローの最初に相関 ID を安全に生成することです。前のセクションでは、コンセンサス ワーカーがドリフトを検出する方法について説明しました。このセクションでは、そのドリフトの最も迷惑な形式を扱います。顧客は実際には PSP 側で請求されていますが、システムには見返りの命令がありません。
学んだエンジニアリング原則
- 孤立請求を解決する鍵は、フローの開始時に相関 ID を安全に生成することです。
- 重複排除の決定は、量や時間などの間接的な信号ではなく、常に ID に基づく必要があります。
- パニック時の最も安全な行動は、適切な証拠が見つかるまで何もしないことです。
続きを読む
続きを読む
シリーズの次のシリーズ
結果整合性が分散トランザクションよりも優れている理由
PSP、Order、Financeの間に2PCを設定するのは罠です。佐賀と調整は、分散型支払いの一貫性に対する本当の答えです。
シリーズの次のシリーズ
支払調整員建設
スイーパーによるドリフトの改善方法: PSP が成功している間、ローカル登録が期限切れになる可能性があります。古い FinalizePending を回復する方法。
同じシリーズ
Webhook でのオプティミスティック同時実行性
Webhook による同期応答が同時に同じ支払いに触れた場合、バージョン トークンとリースは競合をどのように解決しますか?端末支払いでのクライアント シークレットの読み取りが古い…