> ## Documentation Index
> Fetch the complete documentation index at: https://waffo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook - イベントタイプ一覧

> Waffo Webhook の全イベントタイプの詳細な説明とペイロード例。

## イベントタイプ

| eventType                                  | 説明                                                             |
| ------------------------------------------ | -------------------------------------------------------------- |
| `PAYMENT_NOTIFICATION`                     | 決済の成功または失敗                                                     |
| `REFUND_NOTIFICATION`                      | 返金の成功または失敗                                                     |
| `TOKENIZATION_NOTIFICATION`                | Token の生成、ステータス変更、またはカード情報の更新                                  |
| `SUBSCRIPTION_STATUS_NOTIFICATION`         | サブスクリプションのステータス変更 (アクティベーション、キャンセルなど。サブスクリプションの課金イベントにも使用されます) |
| `SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION` | サブスクリプション期間の変更                                                 |
| `SUBSCRIPTION_CHANGE_NOTIFICATION`         | サブスクリプション変更 (アップグレード/ダウングレード) の完了                              |

## 共通構造

すべての Webhook は同じリクエスト構造を使用します。

```
POST {notifyUrl}
Content-Type: application/json
X-SIGNATURE: {Waffo private-key signature}
```

## PAYMENT\_NOTIFICATION

決済完了後に送信されます。

```json theme={null}
{
  "eventType": "PAYMENT_NOTIFICATION",
  "acquiringOrderId": "ACQ123456",
  "merchantOrderId": "ORDER123",
  "paymentRequestId": "REQ123",
  "orderStatus": "PAY_SUCCESS",
  "orderAmount": "100.00",
  "orderCurrency": "USD",
  "finalDealAmount": "100.00"
}
```

## REFUND\_NOTIFICATION

返金完了後に送信され、返金作成時に指定した `refundNotifyUrl` に配信されます。

```json theme={null}
{
  "eventType": "REFUND_NOTIFICATION",
  "acquiringRefundOrderId": "REF123456",
  "refundRequestId": "REFUND_REQ123",
  "refundStatus": "ORDER_FULLY_REFUNDED",
  "refundAmount": "100.00"
}
```

## TOKENIZATION\_NOTIFICATION

Tokenization の完了、Token ステータスの変更、または Token のカード情報が更新されたときに送信されます。Waffo は [Generate token](/docs/ja/developer-docs/integration/tokenization/generate) の呼び出し時に渡された `notifyUrl` にこの通知を送信します。

```json theme={null}
{
  "eventType": "TOKENIZATION_NOTIFICATION",
  "result": {
    "tokenRequestId": "202510111010050001",
    "tokenId": "tok_xxxxxxxxxxxx",
    "tokenType": "CARD",
    "tokenStatus": "UNVERIFIED",
    "tokenData": {
      "maskedCardInfo": "481852******0147",
      "cardHolderName": "Zhang san",
      "cardExpiry": "01/2030",
      "cardBin": "481852",
      "cardScheme": "VISA",
      "cardType": "CREDIT_CARD",
      "cardIssuerName": "INTL HDQTRS-CENTER OWNED",
      "cardIssueCountryCode": "RUS"
    },
    "billingAddress": {
      "countryCode": "USA",
      "region": "CA",
      "city": "Cupertino",
      "postalCode": "95014",
      "address": "One Apple Park Way"
    },
    "merchantUserId": "merchant-user-001",
    "merchantInfo": {
      "merchantId": "your_merchant_id",
      "subMerchantId": ""
    }
  }
}
```

| フィールド            | 説明                                                                             |
| ---------------- | ------------------------------------------------------------------------------ |
| `tokenRequestId` | Tokenization 開始時に加盟店が渡したリクエスト ID。Waffo によってステータス変更が発生した場合、このフィールドは存在しないことがあります |
| `tokenId`        | Token ID。安全に保存し、以降の Token 決済で使用します                                             |
| `tokenType`      | Token タイプ。現在は `CARD`                                                           |
| `tokenStatus`    | Token ステータス: `UNVERIFIED`、`VERIFIED`、`EXPIRED`、`SUSPENDED`                     |
| `tokenData`      | カード概要情報。マスク済みカード番号、有効期限、BIN、カードブランド、カードタイプ、発行会社、発行国を含みます                       |
| `billingAddress` | カード保有者の請求先住所                                                                   |
| `merchantUserId` | 加盟店側のユーザー ID                                                                   |
| `merchantInfo`   | 加盟店情報                                                                          |

## SUBSCRIPTION\_STATUS\_NOTIFICATION

サブスクリプションのステータスが変化したとき (アクティベーション、キャンセル、課金結果などを含む) に送信されます。

```json theme={null}
{
  "eventType": "SUBSCRIPTION_STATUS_NOTIFICATION",
  "subscriptionId": "SUB123456",
  "subscriptionStatus": "ACTIVE"
}
```

SDK では 2 つのハンドラーが提供されています。

* `onSubscriptionStatus()` — このイベントを直接処理します
* `onSubscriptionPayment()` — `onSubscriptionStatus` が登録されていない場合のフォールバック処理

## SUBSCRIPTION\_PERIOD\_CHANGED\_NOTIFICATION

サブスクリプションの期間が終局状態に達したときに送信され、更新 (継続課金) 結果の追跡に使用します。

```json theme={null}
{
  "eventType": "SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION",
  "subscriptionId": "SUB123456",
  "period": "3",
  "orderStatus": "PAY_SUCCESS"
}
```

## SUBSCRIPTION\_CHANGE\_NOTIFICATION

サブスクリプション変更 (アップグレード/ダウングレード) が完了したときに送信されます。

```json theme={null}
{
  "eventType": "SUBSCRIPTION_CHANGE_NOTIFICATION",
  "result": {
    "subscriptionRequest": "new-sub-req-001",
    "originSubscriptionRequest": "orig-sub-req-001",
    "subscriptionId": "waffo-sub-12345",
    "subscriptionChangeStatus": "SUCCESS",
    "subscriptionAction": "UPGRADE",
    "remainingAmount": "50.00",
    "currency": "HKD"
  }
}
```

| subscriptionChangeStatus | 説明          |
| ------------------------ | ----------- |
| `SUCCESS`                | 変更成功        |
| `CLOSED`                 | 変更失敗 / クローズ |

## 加盟店の応答

すべての Webhook に対して HTTP 200 を返す必要があり、応答ボディは `{"message":"success"}` でなければなりません。**また `X-SIGNATURE` 応答ヘッダーも必ず含める必要があります** (加盟店の秘密鍵で応答ボディを署名してください)。

<Warning>
  Waffo は HTTP ステータスコードと応答ボディの両方を検証します。応答フォーマットが不正であったり署名が欠けている場合、Waffo は配信失敗として扱い再送します。
</Warning>

### SDK を使用する (推奨)

SDK の `handleWebhook()` メソッドは、署名検証、イベントルーティング、応答の署名を自動的に実行します。

```typescript theme={null}
const result = await waffo.webhook().handleWebhook(body, signature);
res.setHeader('X-SIGNATURE', result.responseSignature);
res.status(200).send(result.responseBody);
```

### 手動応答

SDK を使わない場合、応答ボディは以下のいずれかである必要があります。

* `{"message":"success"}` — 処理成功
* `{"message":"failed"}` — 処理失敗。Waffo は再送します
* `{"message":"unknown"}` — ステータス不明。Waffo は再送します

**再送ポリシー**: `failed` または `unknown` を返した場合、Waffo は最大 8 回 (初回を含む) 再送します。間隔は 30 秒から 8 時間まで徐々に長くなります。詳細は[再送と障害復旧](/docs/ja/developer-docs/webhook/retry)をご覧ください。

***

## サブスクリプション通知の選択ガイド

サブスクリプションのシナリオでは 3 種類の通知が関係します。必要なものをサブスクライブしてください。

<Warning>
  `SUBSCRIPTION_STATUS_NOTIFICATION` と `SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION` は非同期で配信される Webhook で、キュー消費・再送・ネットワーク遅延などの影響により受信順序は保証されません。受信順序をビジネス状態管理の根拠にしないでください。正しい処理方法（冪等な重複排除、いずれかのコールバック受信後に `subscription/inquiry` で最終状態を確認）は [処理のベストプラクティス](/docs/ja/developer-docs/webhook/best-practices) を参照してください。
</Warning>

| イベント                                       | 発火タイミング                                          | 最適な用途                              |
| ------------------------------------------ | ------------------------------------------------ | ---------------------------------- |
| `SUBSCRIPTION_STATUS_NOTIFICATION`         | サブスクリプションのメインステータスが変化したとき (アクティベーション、キャンセル、クローズ) | サブスクリプションのライフサイクル管理: ユーザーへの権限付与や剥奪 |
| `SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION` | 各更新期間の終局状態 (再試行中は通知されず、最終結果のみ)                   | 中間の再試行を気にせず、各請求期間の最終結果を追跡したい場合     |
| `PAYMENT_NOTIFICATION`                     | 毎回の決済試行 (初回期間 + 以降の各期間の毎回の再試行)                   | 失敗理由、決済日時など試行ごとの詳細を取得したい場合         |

<Tip>
  **推奨する組み合わせ:**

  * **最小限の連携**: `SUBSCRIPTION_STATUS_NOTIFICATION` + `SUBSCRIPTION_PERIOD_CHANGED_NOTIFICATION` をサブスクライブ
  * **フル連携**: すべて 3 種類をサブスクライブ。`PAYMENT_NOTIFICATION` を使って再試行ごとの詳細な失敗理由を取得します
</Tip>
