> ## 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.

# Stripe 移行ツール

> 既存の Stripe 呼び出しを維持し、3 ステップで期限が近づいたサブスクリプションを Waffo へ引き継ぎます。

**できること：** Stripe の支払い済み期間が終了する前に、ユーザーは Waffo でカード入力と必要な 3DS 認証を完了できます。期限前には請求せず、引き継ぎ時刻に Waffo が初回請求を自動的に開始します。待機中の状態を照会でき、引き継ぎ前に解約すれば初回請求も停止できます。

**連携は 3 ステップです：** `WaffoStripe.client(...)` へ切り替え、対象サブスクリプションにルーティングタグと引き継ぎ時刻を追加し、Waffo Webhook を接続します。既存の `com.stripe.*` 型と呼び出し方法は維持できます。[クイックスタート](#クイックスタート)にコード変更全体を示します。本番利用前には、連携ガイドに従って冪等キーとサブスクリプションの対応関係も永続化してください。

<Note>
  現在利用できるのは Java 版の `com.waffo:waffo-java-stripe` です。Node.js、Python、Go 版は今後提供予定です。
</Note>

## Waffo ネイティブ SDK との違い

Waffo には異なる 2 つの連携方法があります。先に用途に合う方を確認してください。

|          | ネイティブ SDK                       | Stripe 移行ツール                              |
| -------- | ------------------------------- | ----------------------------------------- |
| アーティファクト | `waffo-java`、`waffo-node` など    | `waffo-java-stripe`                       |
| 実装       | Waffo の `openapi.json` から生成     | プロジェクトが提供する公式 `stripe-java` を包む手書きの互換レイヤー |
| 使用する型    | Waffo の API とデータ型               | 既存の `com.stripe.*` を維持                    |
| 対応範囲     | Waffo API 全体                    | サブスクリプション Checkout の一部                    |
| 適したケース   | 新規連携、または Waffo API に合わせて書き換える場合 | 既存の Stripe サブスクリプションを少ない変更で移行する場合         |

**新規連携では[ネイティブ SDK](/docs/ja/developer-docs/sdk/java)を使用してください。** このアダプターは、すでに Stripe 上でサブスクリプションを運用しており、コード変更のコストを抑えたい場合に適しています。

## 移行ツールの役割

<CardGroup cols={2}>
  <Card title="ルーティング" icon="route">
    リクエストごとに Waffo へ送るか Stripe へそのまま送るかを判断するため、呼び出し側に分岐は不要です。
  </Card>

  <Card title="パラメーター変換" icon="languages">
    Stripe の `SessionCreateParams` を、金額、期間、通貨、支払い方法、Cashier の言語を含む Waffo サブスクリプション作成リクエストへ変換します。
  </Card>

  <Card title="レスポンス変換" icon="arrow-right-left">
    Waffo のレスポンスを Stripe の `Session` と `Subscription` に戻すため、既存の getter をそのまま使えます。
  </Card>

  <Card title="通知変換" icon="bell">
    Waffo のサブスクリプション通知を Stripe の `Event` に変換し、既存の Webhook 分岐を再利用できます。
  </Card>
</CardGroup>

## 動作の仕組み

アダプターは標準の `StripeClient` を返し、各リクエストを次のルールで振り分けます。

| ルール      | 条件                                                     | 送信先         |
| -------- | ------------------------------------------------------ | ----------- |
| 作成ルーティング | サブスクリプションモードの Checkout 作成で `metadata.source=waffo` がある | Waffo       |
| 取得ルーティング | オブジェクト id が `wsub_` または `wcs_` で始まる                    | Waffo       |
| パススルー    | その他すべて                                                 | 変更せず Stripe |

**タグのない呼び出しには影響しません。** 1 回払い、タグのないサブスクリプション、顧客、価格の各オブジェクトは移行前と同じように動作します。一部のサブスクリプションだけを Waffo に移し、Stripe と並行運用できます。

サブスクリプション支払いは次のように進みます。

<Steps>
  <Step title="サブスクリプション Checkout を作成">
    通常どおり `client.checkout().sessions().create(params)` を呼び出し、`params` に `metadata.source=waffo` を 1 行追加します。アダプターが Waffo の作成リクエストへ変換します。
  </Step>

  <Step title="Cashier URL を取得">
    戻り値は Stripe の `Session` のままで、`session.getUrl()` に Waffo Cashier URL が入ります。既存のリダイレクト処理は変更不要です。
  </Step>

  <Step title="ユーザーが支払う">
    ユーザーは Waffo Cashier で支払いを完了します。この区間をアプリケーションが処理する必要はありません。
  </Step>

  <Step title="通知を受信して変換">
    Waffo は設定した `notifyUrl` に通知します。エンドポイントで `WaffoStripeWebhooks.handle(...)` を呼び出して `WaffoStripeWebhookResult` を受け取り、`result.getEvent()` から Stripe の `Event` を取得します。
  </Step>

  <Step title="既存のビジネスロジックを実行">
    `switch (event.getType())` で `customer.subscription.created` や `invoice.paid` を処理する既存コードをそのまま使用できます。
  </Step>
</Steps>

## 対応するシナリオ

初期リリースは**リダイレクト型 Cashier のサブスクリプション**を対象にしています。

| シナリオ                                                         | 結果                              | 必要な対応                                                                     |
| ------------------------------------------------------------ | ------------------------------- | ------------------------------------------------------------------------- |
| サブスクリプションモード、リダイレクト型 Cashier、単一 line item、カードまたは継続課金可能なウォレット | Waffo へルーティング                   | ルーティングタグを追加し、永続化済みの冪等キーを明示的に渡す                                            |
| Stripe サブスクリプションの支払い済み期間が終了間近                                | Waffo で事前にカード認証を完了し、引き継ぎ時刻に初回請求 | Stripe の期間終了時刻を `billing_cycle_anchor` に設定し、`proration_behavior=none` を指定 |

フォールバック条件、理由コード、解約機能の境界は、連携ガイドの[未対応の Stripe 利用方法](/docs/ja/developer-docs/tools-and-references/references/stripe-adapter-integration#未対応の-stripe-利用方法)を参照してください。

## 有効期限が近づいた Stripe サブスクリプションを Waffo へ移行

Stripe サブスクリプションの現在の支払い済み期間が時刻 `T` に終了するとします。既存の Stripe フローで更新を `T` に停止し、同じユーザー向けに `T` から始まる Waffo サブスクリプションを事前に作成します。

<Steps>
  <Step title="引き継ぎ時刻を取得">
    Stripe サブスクリプションから支払い済み期間の終了時刻 `T` を取得します。
  </Step>

  <Step title="Waffo の開始時刻を設定">
    Waffo へルーティングするリクエストで `subscription_data.billing_cycle_anchor` を `T` に設定し、`proration_behavior=none` を指定します。
  </Step>

  <Step title="事前に認証">
    `T` より前にユーザーが Waffo Cashier を開き、カード入力と必要な 3DS 認証を完了します。この時点では初回料金を請求しません。
  </Step>

  <Step title="待機状態を確認">
    待機中に `wsub_…` を照会します。`billing_cycle_anchor` と `current_period_end` は `T` と一致し、`metadata.waffo_current_period=0` は最初の請求期間がまだ始まっていないことを示します。
  </Step>

  <Step title="引き継ぎ時に自動請求">
    `T` に到達すると、Waffo が初回請求を自動的に開始します。ユーザーの再操作は不要です。
  </Step>
</Steps>

ユーザーが `T` より前に移行を取り消す場合、`Subscription.cancel("wsub_…")` は Waffo サブスクリプションを即時解約し、予定されていた初回請求を停止します。

<Note>
  Stripe 移行ツールが処理するのは Waffo 側の申請、照会、解約です。元の Stripe サブスクリプションは変更しません。既存の Stripe コードまたは Dashboard を使い、同じ `T` に旧サブスクリプションを終了してください。
</Note>

## クイックスタート

以下の 3 ステップで主要なコード変更を示します。コード変更に加えて、リクエスト送信前に冪等キーを永続化し、作成後に Waffo サブスクリプション id と業務注文の対応を保存してください。以下は既存クラスへ組み込む主要部分のコード片です。

### ステップ 1：クライアント生成を変更

<CodeGroup>
  ```java 変更後 theme={null}
  import com.stripe.Stripe;
  import com.stripe.StripeClient;
  import com.waffo.stripe.WaffoStripe;                             // 追加
  import com.waffo.stripe.config.WaffoConfig;                      // 追加

  com.waffo.types.config.WaffoConfig waffoJavaConfig =
          com.waffo.types.config.WaffoConfig.fromEnv();

  WaffoConfig routing = WaffoConfig.builder()
          .waffoConfig(waffoJavaConfig)
          .notifyUrl("https://your-app.example/webhooks/waffo")
          .build();

  Stripe.apiKey = System.getenv("STRIPE_SECRET_KEY");
  StripeClient client = WaffoStripe.client(routing);                // 生成方法を変更
  ```

  ```java 変更前 theme={null}
  import com.stripe.StripeClient;

  StripeClient client = new StripeClient(System.getenv("STRIPE_SECRET_KEY"));
  ```
</CodeGroup>

戻り値の `client` は標準の `StripeClient` です。既存のクライアントと置き換えても、呼び出し側のコードは変わりません。

### ステップ 2：ルーティングタグと冪等キーを追加

<CodeGroup>
  ```java 変更後 theme={null}
  SessionCreateParams params = SessionCreateParams.builder()
          .setMode(SessionCreateParams.Mode.SUBSCRIPTION)
          .setSuccessUrl("https://your-app.example/subscription/success")
          .setCancelUrl("https://your-app.example/subscription/cancel")
          .addLineItem(SessionCreateParams.LineItem.builder()
                  .setPrice("price_123")
                  .setQuantity(1L)
                  .build())
          .putMetadata("source", "waffo")                          // 追加：Waffo へルーティング
          .build();

  RequestOptions options = RequestOptions.builder()
          .setIdempotencyKey(persistedSubscriptionRequest)          // 呼び出し前に永続化
          .build();

  Session session = client.checkout().sessions().create(params, options);
  saveSubscriptionMapping(orderId, session.getSubscription());     // 追加：wsub_ と業務注文の対応を保存
  redirect(session.getUrl());
  ```

  ```java 変更前 theme={null}
  SessionCreateParams params = SessionCreateParams.builder()
          .setMode(SessionCreateParams.Mode.SUBSCRIPTION)
          .setSuccessUrl("https://your-app.example/subscription/success")
          .setCancelUrl("https://your-app.example/subscription/cancel")
          .addLineItem(SessionCreateParams.LineItem.builder()
                  .setPrice("price_123")
                  .setQuantity(1L)
                  .build())
          .build();

  Session session = client.checkout().sessions().create(params);
  redirect(session.getUrl());
  ```
</CodeGroup>

この例では `uiMode` を意図的に設定していません。Stripe の既定値はリダイレクト型で、移行ツールも未設定をリダイレクト型として扱います。これにより `stripe-java` 24.11.x、32.x、33.x で同じコードを使用できます。32.x または 33.x の `HOSTED_PAGE` に置き換えないでください。そのシリアライズ値 `hosted_page` は非リダイレクト型と判定されます。

`stripe-java` が自動生成する冪等キーに依存しないでください。32 文字以内の安定したキーを明示的に渡して永続化し、再試行でも同じキーを使用してください。詳細は[連携ガイド](/docs/ja/developer-docs/tools-and-references/references/stripe-adapter-integration)を参照してください。

### ステップ 3：Waffo Webhook を連携

アプリケーションには新しい HTTP エンドポイントが必要ですが、既存の Stripe Webhook は変更しません。SDK の `handle(...)` は署名検証、解析、イベント変換、確認レスポンスの生成まで行います。エンドポイントは、変換結果をビジネスロジックへ渡し、SDK が生成した確認レスポンスを Web フレームワークのレスポンスへマッピングします。

<CodeGroup>
  ```java 変更後 theme={null}
  @PostMapping(value = "/webhooks/waffo", produces = MediaType.APPLICATION_JSON_VALUE)
  public ResponseEntity<String> onWaffo(@RequestBody String body,
                                        @RequestHeader("X-SIGNATURE") String signature) throws StripeException {
      WaffoStripeWebhookResult result = webhooks.handle(body, signature);   // 署名検証、変換、確認レスポンス生成

      if (result.getPaymentNotification() != null) {
          subscriptionPaymentHandler.handle(result.getPaymentNotification().getResult());
      }

      Event event = result.getEvent();
      if (event != null) {
          existingStripeWebhookDispatcher.dispatch(event);
      }

      return ResponseEntity.ok()                                            // SDK の結果を Spring HTTP レスポンスへマッピング
              .contentType(MediaType.APPLICATION_JSON)
              .body(result.getResponseBody());
  }
  ```

  ```java 変更前 theme={null}
  import com.stripe.net.Webhook;

  @PostMapping("/webhooks/stripe")
  public ResponseEntity<String> onStripe(@RequestBody String body,
                                         @RequestHeader("Stripe-Signature") String signature) {
      try {
          Event event = Webhook.constructEvent(body, signature, endpointSecret);
          existingStripeWebhookDispatcher.dispatch(event);
          return ResponseEntity.ok("ok");
      } catch (SignatureVerificationException e) {
          return ResponseEntity.badRequest().build();
      }
  }
  ```
</CodeGroup>

`WaffoStripeWebhookResult` には確認レスポンスの本文が含まれています。最後の数行は、それを Spring の `ResponseEntity` へマッピングしているだけです。別の Web フレームワークでは同等のマッピングを行ってください。詳細は[連携ガイド](/docs/ja/developer-docs/tools-and-references/references/stripe-adapter-integration)を参照してください。

<Card title="連携ガイド" icon="book-open" href="/docs/ja/developer-docs/tools-and-references/references/stripe-adapter-integration">
  設定項目、Webhook の処理方法、未対応の Stripe 利用方法、連携チェックリスト、Sandbox 検証要件を確認できます。
</Card>

### AI 移行スキルを使用する

Claude Code、Codex、Cursor を使用している場合は、スキャンと変更を AI に任せられます。

```bash theme={null}
npx @waffo/waffo-stripe-migrate
```

インストール後、プロジェクト内で AI に「Stripe を移行」と指示します。AI は Stripe の呼び出しを検出し、ルーティングできない箇所を示し、承認後にコードを変更して Sandbox 検証まで案内します。

<Warning>
  スキャン結果はリスクを見つけるための情報であり、検証結果ではありません。どの方法で連携しても、プロジェクト自身の API から Sandbox のエンドツーエンド検証を完了してください。
</Warning>

## バージョンと前提条件

| 項目            | 内容                                                                                                  |
| ------------- | --------------------------------------------------------------------------------------------------- |
| アーティファクト      | `com.waffo:waffo-java-stripe`                                                                       |
| 現在のバージョン      | 0.2.0（[Maven Central](https://central.sonatype.com/artifact/com.waffo/waffo-java-stripe/0.2.0) で公開） |
| `stripe-java` | プロジェクト側で提供。最低 24.11.0、33.x まで検証済み                                                                   |
| `waffo-java`  | 3.0.0。アダプターから推移的に導入                                                                                 |
| ビルド対象         | Java 8。JDK 8 または 17 でビルド可能                                                                          |

`stripe-java` は provided 依存関係です。アダプターはバージョンを上げ下げしません。24.11.0 以上を使用してください。

導入前に次を確認してください。

* Waffo とサブスクリプション契約を締結し、Sandbox 認証情報を取得している。
* 使用する通貨が契約範囲に含まれている。`paymethodconfig/inquiry` で確認できます。
* Waffo 通知を受け取る公開 HTTPS エンドポイントがある。

## 関連リソース

* [連携ガイド](/docs/ja/developer-docs/tools-and-references/references/stripe-adapter-integration) — 完全な手順と技術仕様
* [Waffo Java SDK](/docs/ja/developer-docs/sdk/java) — 新規連携向けのネイティブ SDK
* [サブスクリプションと継続課金](/docs/ja/essentials/subscription-recurring) — Waffo のサブスクリプション概要
* [GitHub リポジトリ](https://github.com/waffo-com/waffo-stripe) — ソースコードと変更履歴
