Skip to main content

概要

Webhookを使用すると、決済の完了、失敗、返金などのイベントをリアルタイムで受け取ることができます。 ZAFA PAYは決済ステータスが変更されると、登録されたWebhookエンドポイントにHTTP POSTリクエストを送信します。
Webhookエンドポイントは、加盟店管理画面(https://app.zafapay.com)の**「Webhook」**タブから管理できます。各エンドポイントには署名検証用の個別のWebhook Secretがあります。

Webhookエンドポイント

複数のWebhookエンドポイントを登録してイベント通知を受け取ることができます。各エンドポイントには個別のURL、シークレット、およびオプションのイベントフィルターがあります。 Webhookエンドポイントは、加盟店管理画面の**「Webhook」**タブから作成・管理できます。

イベントタイプ

ペイロード

string
イベントタイプ(例: payment.succeeded
string
トランザクションID
string
加盟店ID
string
加盟店名
string
決済ステータス(succeeded, failed, canceled, refunded, chargeback
string
決済金額(文字列形式。例: "100.00"
string
通貨コード
string
決済方法(card, depotなど)
string
保存されたカードのID(pmi_xxx形式)。リカーリング決済またはsave_cardを使用した場合のみ
boolean
リカーリング(継続課金)決済の場合はtrue
boolean
カードが将来の決済用に保存された場合のみtrueで含まれる
string
加盟店側の注文ID(決済作成時に指定した値)
string
商品名(決済作成時に指定した値)
string
顧客ID(決済作成時に指定した値)
string
顧客のメールアドレス(決済作成時に指定した値)
string
顧客の電話番号(決済作成時に指定した値)
string
返金済み金額(文字列形式。payment.refundedイベントのみ)
object
エラー詳細(payment.failedイベントのみ)
string
カードブランド(visa, mastercard, amex, jcbなど)
string
カード番号の下4桁
string
カード名義人
number
カード有効期限(月)
number
カード有効期限(年)
string
カード発行国(ISO 3166-1 alpha-2コード、例: US, JP, SG)。BINルックアップデータが利用可能な場合のみ含まれます。
string
カードの資金源タイプ(credit, debit, prepaid)。BINルックアップデータが利用可能な場合のみ含まれます。
object
決済作成時に指定したメタデータ
string
トランザクション作成日時(ISO 8601形式)
string
Webhook送信日時(ISO 8601形式)

ペイロード例

payment.succeeded(決済成功)

  • payment_method_idsave_cardが有効な場合、またはリカーリング決済の場合のみ含まれます
  • save_cardは初回決済でカードを保存した場合のみtrueで含まれます
  • is_recurringはリカーリング決済の場合trueになります

payment.failed(決済失敗)

errorオブジェクトはpayment.failedイベントでのみ含まれます。recommended_actionの値に応じて適切な対応を行ってください(retry, contact_customer, use_different_card, none)。

payment.canceled(決済キャンセル)

payment.canceled は以下の2つのケースで送信されます:
  1. マーチャントによる void — 決済確定前のオーソリ/キャプチャ済み決済を POST /v1/payments/{id}/void で取り消した場合。
  2. 顧客による 3DS 中のキャンセル — ホスト型 3DS チャレンジ画面で顧客が「お支払いをキャンセル」をクリックした場合。同じ決済リンクで即座に再決済可能になります(別のカードでリトライ等)。
両ケースとも同じイベント形式です。区別が必要な場合は GET /v1/payments/{id} でトランザクションの直前状態を確認するか、独自の状態管理を併用してください。

payment.refunded(返金完了)

amount_refundedフィールドはpayment.refundedイベントでのみ含まれます。部分返金の場合は返金済み金額が設定されます。

payment.chargeback(チャージバック発生)

チャージバックが発生した場合、取引金額が加盟店から引き落とされる可能性があります。速やかに対応してください。

署名検証

Webhookリクエストには署名ヘッダーが含まれます。エンドポイントのWebhook Secretを使用して署名を検証することで、リクエストがZAFA PAYから送信されたことを確認できます。

署名ヘッダー

検証方法

署名は生のリクエストボディを、エンドポイントのWebhook Secretをキーとして HMAC-SHA256 でハッシュ化し、hexエンコードしたものです。
HMAC はJSONをパースする前の、送信されたバイト列そのものに対して計算してください。パース済みオブジェクトを再シリアライズすると(JSON.stringify(req.body))キー順・エスケープ・空白が変わることがあり、ダイジェストが一致せず正当なWebhookが検証に失敗します。Expressの場合は express.json() ではなく express.raw() を使います。
Node.js

レスポンス

Webhookを正常に受信した場合は、HTTPステータスコード 2xx を返してください。

リトライ

ZAFA PAYは以下の場合にWebhookを自動的にリトライします:
  • HTTPステータスコード 2xx 以外が返された場合
  • 接続タイムアウトが発生した場合(10秒)

リトライスケジュール

合計6回のリトライが約9時間にわたって実行されます。すべてのリトライが失敗した場合、イベントはデッドレターキュー(DLQ)に移動され、手動での対応が必要になります。
リトライによる重複通知を防ぐため、transaction_idをキーにして冪等性を確保してください。

ベストプラクティス

1

署名を必ず検証する

不正なリクエストを防ぐため、署名検証は必須です
2

冪等性を確保する

同じイベントが複数回送信される可能性があるため、transaction_idをキーにして重複処理を防いでください
3

すぐにレスポンスを返す

Webhook処理は非同期で行い、すぐに 200 を返してください。処理に時間がかかるとタイムアウトでリトライが発生します
4

エラーをログに記録する

デバッグのため、受信したペイロードと処理結果をログに記録してください