何をもって決済完了とするか
加盟店サーバーが settled を確認し、注文との対応を検証したうえで、一度だけ商品提供を行います。
決済成立の根拠
完了の確認経路は次のとおりです。
payment.settledWebhook:raw body の署名と時刻を検証し、ボディのidで冪等に処理する- ステータス確認 API のサーバー間照会:作成時に保存した決済 ID で
settledを確認する
Webhook を使う場合は結果通知の主経路にし、必要時の確定照会と通知欠落時の定期突合に API を使います。両方が届くことを商品提供の必須条件にすると、通知欠落時に成立済み注文が止まるため、そのような条件にはしません。
ブラウザからの status、復帰 URL のクエリ、タブが戻ったことは、いずれも成立の根拠に使えません。
注文との対応と一度だけの提供
- 自社注文に保存した決済 ID と一致することを確認する。
- Webhook の場合は加盟店・注文・作成時金額との対応も確認する。不一致は調査へ回す。
- 注文の状態を条件付きで更新し、商品提供用 outbox を同じ DB トランザクションで作る。
- 外部の商品提供・メール送信は注文 ID などの冪等キーを使って実行する。
受信したイベントを先に「処理済み」にしてから外部処理するだけでは、途中停止時に商品提供を取りこぼします。受信と業務処理の冪等性を参照してください。
金額と終端
Webhook の金額は文字列です。成立した決済の受取額は net_received_jpy、手数料は fee_jpy で確認します。これらは payment.settled ではチェーン上の実額で、実額を取れなかった回だけ作成時の見積りです。payment.failed・payment.canceled・payment.expired では資金が動いていないため、どちらも "0" です(amount_jpy は注文額のまま)。失敗・取消・失効の通知の金額を入金として計上しないでください。状態照会 API には金額がないため、保存した注文・作成応答と照合し、照会応答から金額を推測しないでください。
settled は終端です。通知の配信失敗や、その後の返金で元の決済が別の状態になることはありません。提供できない注文への成立通知は運用対応に回してください。