状態レビュー中 担当注文チーム 関係するコンテキスト注文 · 決済 · 在庫

概要

支払済みの注文を、出荷指示の前であればお客様自身がキャンセルできるようにする。いまはサポート窓口への問い合わせで オペレーターが手作業で取り消しており、出荷に間に合わないケースが月に数十件ある。

キャンセルは注文の中だけで閉じず、決済(返金)と在庫(引当の解除)をまたぐ。返金は外部の決済代行を呼ぶため失敗や タイムアウトがあり得る。この文書は、その間も注文の状態を矛盾させない方法を決める。

ゴールと非ゴール

ゴール

  • 出荷指示前の注文を、お客様が画面からキャンセルできる
  • キャンセルした注文は、必ず返金と在庫の解除まで到達する
  • キャンセル済みの注文に出荷指示が出ることはない

非ゴール

  • 出荷後の返品・返金(別の Design Doc で扱う)
  • 注文の一部だけのキャンセル
  • ポイントやクーポンの払い戻し

設計

注文に「返金待ち」の状態を足し、キャンセルの受付と返金の実行を分ける。受付は注文集約の中で同期的に確定させ、 返金はイベントを受けたワーカーが非同期に進める。

状態遷移

「返金待ち」の間は出荷指示を受け付けない。キャンセルの可否と出荷指示は同じトランザクションで判定する。

処理の流れ

お客様への応答は受付の時点で返す。返金の結果はメールで知らせる。

データの変更

注文の状態に refund_pending を足し、返金の記録を別テーブルに持つ。

検討した代替案

案 やり方 見送った理由
A. 同期で返金 キャンセル API の中で返金まで完了させる 決済代行のタイムアウトがそのままキャンセルの失敗になる
B. 返金待ちを挟む採用 注文を「返金待ち」にして即応答し、返金はワーカーで進める —
C. 申請と承認 キャンセル申請として受け、オペレーターが承認する 人手が律速になり、出荷前に間に合わない

未決事項

  1. 返金が一定時間失敗し続けたとき、「返金待ち」のまま残すか、オペレーター対応の状態に移すか。
  2. キャンセル受付の締め切りを「出荷指示前」ではなく「出荷予定の N 時間前」にするか。