イベントと受信
Webhook は加盟店サーバーへ決済の終端結果を通知します。通知の形は Webhook リファレンスにまとめています。
payment.settled:決済が成立した。対応する注文を一度だけ支払い済みにするpayment.failed:決済が失敗した。未提供の注文を失敗として処理し、必要に応じて調査するpayment.canceled:利用者がマイページで決済を取り消した。未提供の注文を終了する。発行予約の取消とは区別するpayment.expired:期限が切れた。未提供の注文を終了する。署名しないまま失効した決済も含む
payment.settled 以外の通知では、fee_jpy と net_received_jpy は "0" で、amount_jpy は注文額のままです(金額の扱い)。
同じ決済が複数の終端に到達することはありません。通知自体は再送されるため、複数回届く可能性があります。
受信処理
- raw body の署名と時刻を検証する。
- 署名の検証直後、業務処理より前に、テスト通知かどうかを判定する。
- JSON の形を検証し、未知のイベント種別は注文を変更せず無視する。
- 署名検証済みボディの
idをキーにイベントを永続化する。 - 永続化に成功してから
2xxを返す。業務処理は再試行可能なワーカーで実行する。 - 決済 ID と注文の対応を検証し、冪等な注文更新を行う。
Webhook の送信先は加盟店で 1 つなので、同じ加盟店の店頭の QR コード決済の通知も届きます。店頭の決済の order_id は null です。orderId は決済の作成時に省略できるため、order_id が null かどうかでは店頭の決済と見分けられません。payment_intent_id が自社の注文に対応しない通知も、1〜5 は同じように行って 2xx を返してください。そのうえで、注文は変更せずに処理済みにします。別の注文に結び付けないでください。
通知されない状態
nonce_conflict は、送金が行われたかどうかも含めて結末を特定できないため、通知しません。未確定注文を 状態照会 APIで突合し、運用調査につなげてください。途中の状態も Webhook で逐次通知しません。
加盟店アカウントイベントや返金完了は、決済 Webhook のイベントにはありません。
テスト通知
テスト通知の本文の定義は、OpenAPI 仕様書の TestWebhookEvent にあります。
加盟店コンソールのメニューの「お店と QR コード」から対象のネットショップを開き、「組み込みの準備」タブの「お支払い完了のお知らせ先」にある「テスト送信」から、受信先の動作を確かめるテスト通知を送れます。受信側の対応を済ませたことを確認するチェックボックスにチェックを入れて「テスト通知を送る」を押します。保存済みの URL へ 1 回だけ送り、再送はしません。1 分間に 5 回までです。
テスト通知は新しいイベント種別ではなく、本文に test: true が入ります。 通常の通知には test というキーがありません。本文の形(ID の接頭辞など)はリファレンスを参照してください。
受信側は、署名を検証した直後、業務処理より前に、受信した生の本文を JSON.parse した値で test === true かを判定します。判定に通ったら、注文・決済の状態を変えずに 2xx を返します。
const parsed = JSON.parse(rawBody.toString('utf8')); // 署名の検証のあと
if (parsed.test === true) return res.sendStatus(200); // 注文を変えずに応答する
生のボディを JSON.parse した直後の値で test === true を見てください。不要なキーを捨てる検証を通したあとの値では判定しないでください。未知のキーが落とされて test が消え、本物の成立通知に見えます。テスト通知を成立通知として処理すると、存在しない注文を支払い済みにするおそれがあります。画面のチェックは受信側の安全を保証するものではないので、対応を済ませてから送ってください。
ペイロードは Webhook リファレンスを参照してください。