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

# Honoアダプタ

> NextJSアダプタを使用して、Dodo PaymentsをHono App Routerプロジェクトに統合する方法を学びます。チェックアウト、顧客ポータル、Webhook、および安全な環境設定をカバーします。

<CardGroup cols={2}>
  <Card title="Checkout Handler" icon="cart-shopping" href="#checkout-route-handler">
    Dodo Payments のチェックアウトを Hono アプリに統合します。
  </Card>

  <Card title="Customer Portal" icon="user" href="#customer-portal-route-handler">
    顧客がサブスクリプションや詳細を管理できるようにします。
  </Card>

  <Card title="Webhooks" icon="bell" href="#webhook-route-handler">
    Dodo Payments の webhook イベントを受信して処理します。
  </Card>
</CardGroup>

## インストール

<Steps>
  <Step title="Install the package">
    プロジェクトのルートで次のコマンドを実行します:

    ```bash theme={null}
    npm install @dodopayments/hono
    ```
  </Step>

  <Step title="Set up environment variables">
    プロジェクトのルートに <code>.env</code> ファイルを作成します:

    ```env expandable theme={null}
    DODO_PAYMENTS_API_KEY=your-api-key
    DODO_PAYMENTS_RETURN_URL=https://yourapp.com/success
    DODO_PAYMENTS_WEBHOOK_KEY=your-webhook-secret
    DODO_PAYMENTS_ENVIRONMENT="test_mode" or "live_mode""
    ```

    <Warning>
      <code>.env</code> ファイルやシークレットをバージョン管理に絶対にコミットしないでください。
    </Warning>
  </Step>
</Steps>

## ルートハンドラーの例

<Info>
  すべての例は Hono App Router を使用していることを前提としています。
</Info>

<Tabs>
  <Tab title="Checkout Handler">
    <Info>
      このハンドラーを使用して Hono アプリに Dodo Payments チェックアウトを統合します。静的 (GET)、動的 (POST)、セッション (POST) フローをサポートします。
    </Info>

    <CodeGroup>
      ```typescript Hono Route Handler expandable theme={null}
        // route.ts
        import { Checkout } from '@dodopayments/hono';
        import Hono from 'hono'

        const app = new Hono()

        app.get(
        "/api/checkout",
        Checkout({
            bearerToken: process.env.DODO_PAYMENTS_API_KEY,
            environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
            returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
            type: 'static'
        })
        );

        app.post(
        "/api/checkout",
        Checkout({
            bearerToken: process.env.DODO_PAYMENTS_API_KEY,
            environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
            returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
            type: 'dynamic'
        })
        );
        
        app.post(
        "/api/checkout",
        Checkout({
            bearerToken: process.env.DODO_PAYMENTS_API_KEY,
            environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
            returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
            type: 'session'
        })
        );
      ```
    </CodeGroup>

    <CodeGroup>
      ```curl Static Checkout Curl example expandable theme={null}
      curl --request GET \
      --url 'https://example.com/api/checkout?productId=pdt_fqJhl7pxKWiLhwQR042rh' \
      --header 'User-Agent: insomnia/11.2.0' \
      --cookie mode=test
      ```
    </CodeGroup>

    <CodeGroup>
      ```curl Dynamic Checkout Curl example expandable theme={null}
      curl --request POST \
      --url https://example.com/api/checkout \
      --header 'Content-Type: application/json' \
      --header 'User-Agent: insomnia/11.2.0' \
      --cookie mode=test \
      --data '{
      "billing": {
        "city": "Texas",
        "country": "US",
        "state": "Texas",
        "street": "56, hhh",
        "zipcode": "560000"
      },
      "customer": {
        "email": "test@example.com",
        	"name": "test"
      },
      "metadata": {},
      "payment_link": true,
        "product_id": "pdt_QMDuvLkbVzCRWRQjLNcs",
        "quantity": 1,
        "billing_currency": "USD",
        "discount_codes": ["IKHZ23M9GQ"],
        "return_url": "https://example.com",
        "trial_period_days": 10
      }'
      ```
    </CodeGroup>

    <CodeGroup>
      ```curl Checkout Session Curl example expandable theme={null}
      curl --request POST \
      --url https://example.com/api/checkout \
      --header 'Content-Type: application/json' \
      --header 'User-Agent: insomnia/11.2.0' \
      --cookie mode=test \
      --data '{
      "product_cart": [
        {
          "product_id": "pdt_QMDuvLkbVzCRWRQjLNcs",
          "quantity": 1
        }
      ],
      "customer": {
        "email": "test@example.com",
        "name": "test"
      },
      "return_url": "https://example.com/success"
      }'
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Customer Portal Handler">
    <Info>
      このハンドラーを使用して、顧客が Dodo Payments カスタマーポータル経由でサブスクリプションと詳細を管理できるようにします。
    </Info>

    <CodeGroup>
      ```typescript Hono Route Handler expandable theme={null}
      // route.ts
      import { Checkout } from '@dodopayments/hono';
      import Hono from 'hono'

      const app = new Hono()
      app.get(
          "/api/customer-portal",
          CustomerPortal({
              bearerToken: process.env.DODO_PAYMENTS_API_KEY,
              environment: process.env.DODO_PAYMENTS_ENVIRONMENT
          })
      );
      ```
    </CodeGroup>

    <CodeGroup>
      ```curl Customer Portal Curl example expandable theme={null}
      curl --request GET \
      --url 'https://example.com/api/customer-portal?customer_id=cus_9VuW4K7O3GHwasENg31m&send_email=true' \
      --header 'User-Agent: insomnia/11.2.0' \
      --cookie mode=test
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Webhook Handler">
    <Info>
      このハンドラーを使用して、Hono アプリで Dodo Payments webhook イベントを安全に受信および処理します。
    </Info>

    <CodeGroup>
      ```typescript Hono Route Handler expandable theme={null}
      // route.ts
      import Hono from 'hono'
      import { Webhooks } from '@dodopayments/hono'

      const app = new Hono()
      app.post(
      "/api/webhooks",
          Webhooks({
              webhookKey: process.env.DODO_PAYMENTS_WEBHOOK_KEY,
              onPayload: async (payload) => {
              // Handle Payload Here
              console.log(payload)
              }
          })
      );

      ```
    </CodeGroup>
  </Tab>
</Tabs>

## チェックアウトルートハンドラー

<Info>
  Dodo Payments は Web サイトへの支払い統合のために 3 種類の支払いフローをサポートしており、このアダプターはすべての支払いフローをサポートします。
</Info>

* **静的支払いリンク:** 迅速でコード不要の支払い収集のための即時共有可能なURL。
* **動的支払いリンク:** APIまたはSDKを使用してカスタム詳細を持つ支払いリンクをプログラム的に生成します。
* **チェックアウトセッション:** 事前に設定された製品カートと顧客詳細を持つ安全でカスタマイズ可能なチェックアウト体験を作成します。

<AccordionGroup>
  <Accordion title="Static Checkout (GET)">
    ### サポートされているクエリパラメーター

    <ParamField query="productId" type="string" required>
      製品識別子（例: <code>?productId=pdt\_nZuwz45WAs64n3l07zpQR</code>）。
    </ParamField>

    <ParamField query="quantity" type="integer">
      製品の数量。
    </ParamField>

    <ParamField query="fullName" type="string">
      顧客のフルネーム。
    </ParamField>

    <ParamField query="firstName" type="string">
      顧客の名。
    </ParamField>

    <ParamField query="lastName" type="string">
      顧客の姓。
    </ParamField>

    <ParamField query="email" type="string">
      顧客のメールアドレス。
    </ParamField>

    <ParamField query="country" type="string">
      顧客の国。
    </ParamField>

    <ParamField query="addressLine" type="string">
      顧客の住所。
    </ParamField>

    <ParamField query="city" type="string">
      顧客の市区町村。
    </ParamField>

    <ParamField query="state" type="string">
      顧客の州/都道府県。
    </ParamField>

    <ParamField query="zipCode" type="string">
      顧客の郵便番号。
    </ParamField>

    <ParamField query="disableFullName" type="boolean">
      フルネーム入力を無効にします。
    </ParamField>

    <ParamField query="disableFirstName" type="boolean">
      名入力を無効にします。
    </ParamField>

    <ParamField query="disableLastName" type="boolean">
      姓入力を無効にします。
    </ParamField>

    <ParamField query="disableEmail" type="boolean">
      メール入力を無効にします。
    </ParamField>

    <ParamField query="disableCountry" type="boolean">
      国入力を無効にします。
    </ParamField>

    <ParamField query="disableAddressLine" type="boolean">
      住所入力を無効にします。
    </ParamField>

    <ParamField query="disableCity" type="boolean">
      市区町村入力を無効にします。
    </ParamField>

    <ParamField query="disableState" type="boolean">
      州入力を無効にします。
    </ParamField>

    <ParamField query="disableZipCode" type="boolean">
      郵便番号入力を無効にします。
    </ParamField>

    <ParamField query="paymentCurrency" type="string">
      支払い通貨を指定します（例: <code>USD</code>）。
    </ParamField>

    <ParamField query="showCurrencySelector" type="boolean">
      通貨セレクターを表示します。
    </ParamField>

    <ParamField query="paymentAmount" type="integer">
      支払い金額を指定します（例: <code>1000</code> は \$10.00）。
    </ParamField>

    <ParamField query="showDiscounts" type="boolean">
      割引フィールドを表示します。
    </ParamField>

    <ParamField query="metadata_*" type="string">
      <code>metadata\_</code> で始まるクエリパラメーターはメタデータとして渡されます。
    </ParamField>

    <Warning>
      <code>productId</code> が欠落している場合、ハンドラーは 400 応答を返します。無効なクエリパラメーターも 400 応答になります。
    </Warning>

    ### レスポンス形式

    静的チェックアウトは、チェックアウトURLを含むJSONレスポンスを返します:

    ```json theme={null}
    {
      "checkout_url": "https://checkout.dodopayments.com/..."
    }
    ```
  </Accordion>

  <Accordion title="Dynamic Checkout (POST)">
    * パラメーターを POST リクエストの JSON ボディとして送信します。
    * 一回限りの支払いと定期支払いの両方をサポートしています。
    * サポートされている POST ボディ フィールドの完全な一覧については、次を参照してください:
      * [Request body for a One Time Payment Product](https://docs.dodopayments.com/api-reference/payments/post-payments)
      * [Request body for a Subscription Product](https://docs.dodopayments.com/api-reference/subscriptions/post-subscriptions)

    ### レスポンス形式

    動的チェックアウトは、チェックアウトURLを含むJSONレスポンスを返します:

    ```json theme={null}
    {
      "checkout_url": "https://checkout.dodopayments.com/..."
    }
    ```
  </Accordion>

  <Accordion title="Checkout Sessions (POST)">
    チェックアウトセッションは、ワンタイム購入とサブスクリプションの両方に対して完全な支払いフローを処理し、カスタマイズ制御が可能なより安全なホスト型チェックアウト体験を提供します。

    詳細とサポートされているフィールドの完全なリストについては、[チェックアウトセッション統合ガイド](https://docs.dodopayments.com/developer-resources/checkout-session)を参照してください。

    ### レスポンス形式

    チェックアウトセッションは、チェックアウトURLを含むJSONレスポンスを返します:

    ```json theme={null}
    {
      "checkout_url": "https://checkout.dodopayments.com/session/..."
    }
    ```
  </Accordion>
</AccordionGroup>

## 顧客ポータルルートハンドラー

顧客ポータルルートハンドラーを使用すると、Dodo Paymentsの顧客ポータルをHonoアプリケーションにシームレスに統合できます。

### クエリパラメーター

<ParamField query="customer_id" type="string" required>
  ポータルセッション用の顧客 ID（例: <code>?customer\_id=cus\_123</code>）。
</ParamField>

<ParamField query="send_email" type="boolean">
  <code>true</code> に設定すると、顧客にポータルリンクをメールで送信します。
</ParamField>

<Warning>
  <code>customer\_id</code> が欠落している場合は 400 を返します。
</Warning>

## Webhookルートハンドラー

* **メソッド:** POSTリクエストのみがサポートされています。他のメソッドは405を返します。
* **署名検証:** <code>webhookKey</code>を使用してWebhook署名を検証します。検証に失敗した場合は401を返します。
* **ペイロード検証:** Zodで検証されます。無効なペイロードには400を返します。
* **エラーハンドリング:**
  * 401: 無効な署名
  * 400: 無効なペイロード
  * 500: 検証中の内部エラー
* **イベントルーティング:** ペイロードタイプに基づいて適切なイベントハンドラーを呼び出します。

### サポートされている Webhook イベント ハンドラー

<CodeGroup>
  ```typescript Typescript expandable theme={null}
  onPayload?: (payload: WebhookPayload) => Promise<void>;
  onPaymentSucceeded?: (payload: WebhookPayload) => Promise<void>;
  onPaymentFailed?: (payload: WebhookPayload) => Promise<void>;
  onPaymentProcessing?: (payload: WebhookPayload) => Promise<void>;
  onPaymentCancelled?: (payload: WebhookPayload) => Promise<void>;
  onRefundSucceeded?: (payload: WebhookPayload) => Promise<void>;
  onRefundFailed?: (payload: WebhookPayload) => Promise<void>;
  onDisputeOpened?: (payload: WebhookPayload) => Promise<void>;
  onDisputeExpired?: (payload: WebhookPayload) => Promise<void>;
  onDisputeAccepted?: (payload: WebhookPayload) => Promise<void>;
  onDisputeCancelled?: (payload: WebhookPayload) => Promise<void>;
  onDisputeChallenged?: (payload: WebhookPayload) => Promise<void>;
  onDisputeWon?: (payload: WebhookPayload) => Promise<void>;
  onDisputeLost?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionActive?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionOnHold?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionRenewed?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionPlanChanged?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionCancelled?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionFailed?: (payload: WebhookPayload) => Promise<void>;
  onSubscriptionExpired?: (payload: WebhookPayload) => Promise<void>;
  onLicenseKeyCreated?: (payload: WebhookPayload) => Promise<void>;
  ```
</CodeGroup>

***

## LLMへのプロンプト

```
あなたはHono開発者アシスタントの専門家です。あなたのタスクは、ユーザーが既存のHonoプロジェクトに@dodopayments/honoアダプタを統合する手順を案内することです。

@dodopayments/honoアダプタは、Dodo Paymentsのチェックアウト、顧客ポータル、およびWebhook機能のためのルートハンドラーを提供し、Honoアプリに直接接続できるように設計されています。

まず、必要なパッケージをインストールします。ユーザーのプロジェクトに適したパッケージマネージャー（npm、yarn、またはbun）を使用してください:

npm install @dodopayments/hono

---

以下のように応答を構成してください:

1. ユーザーに統合したい機能を尋ねます。

"@dodopayments/honoアダプタのどの部分をプロジェクトに統合したいですか？次の中から1つ以上を選択できます:

- チェックアウトルートハンドラー（製品のチェックアウトを処理するため）
- 顧客ポータルルートハンドラー（顧客のサブスクリプション/詳細を管理するため）
- Webhookルートハンドラー（Dodo PaymentsのWebhookイベントを受信するため）
- すべて（3つすべてを統合）"

---

2. ユーザーの選択に基づいて、各選択した機能の詳細な統合手順を提供します。

---

**チェックアウトルートハンドラーが選択された場合:**

**目的**: このハンドラーは、ユーザーをDodo Paymentsのチェックアウトページにリダイレクトします。

**統合**:
Honoアプリに静的（GET）と動的（POST）チェックアウト用の2つのルートを作成します。

import { Checkout } from '@dodopayments/hono';
import Hono from 'hono'

const app = new Hono()

app.get(
  "/api/checkout",
  Checkout({
    bearerToken: process.env.DODO_PAYMENTS_API_KEY,
    environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
    returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
    type: 'static'
  })
);

app.post(
  "/api/checkout",
  Checkout({
    bearerToken: process.env.DODO_PAYMENTS_API_KEY,
    environment: process.env.DODO_PAYMENTS_ENVIRONMENT,
    returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
    type: 'session' // または動的リンクの場合は'dynamic'
  })
);

設定オプション:

    bearerToken: あなたのDodo Payments APIキー（DODO_PAYMENTS_API_KEY環境変数に保存することを推奨）。

    returnUrl（オプション）: チェックアウト成功後にユーザーをリダイレクトするURL。

    environment: "test_mode"または"live_mode"

    type: "static"（GET）または"dynamic"（POST）または"session"（POST）

GET（静的チェックアウト）はクエリパラメータを期待します:

    productId（必須）

    quantity、顧客フィールド（fullName、emailなど）、およびメタデータ（metadata_*）はオプションです。

POST（動的チェックアウト）は、支払い詳細（1回限りまたはサブスクリプション）を含むJSONボディを期待します。完全なPOSTスキーマについては、ドキュメントを参照してください:

    一回限りの支払い: https://docs.dodopayments.com/api-reference/payments/post-payments

    サブスクリプション: https://docs.dodopayments.com/api-reference/subscriptions/post-subscriptions

POST（チェックアウトセッション） - （推奨）よりカスタマイズ可能なチェックアウト体験。チェックアウトURLを含むJSONを返します: パラメータはJSONボディとして送信されます。一回限りの支払いと定期的な支払いの両方をサポートします。返されるもの: {"checkout_url": "https://checkout.dodopayments.com/session/..."}。サポートされているフィールドの完全なリストについては、次を参照してください:

  チェックアウトセッション統合ガイド: https://docs.dodopayments.com/developer-resources/checkout-session

顧客ポータルルートハンドラーが選択された場合:

目的: このルートは、顧客がDodo Paymentsポータルを通じてサブスクリプションを管理できるようにします。

統合:

import { Checkout } from '@dodopayments/hono';
import Hono from 'hono'

const app = new Hono()
app.get(
  "/api/customer-portal",
  CustomerPortal({
    bearerToken: process.env.DODO_PAYMENTS_API_KEY,
    environment: process.env.DODO_PAYMENTS_ENVIRONMENT
  })
);

クエリパラメータ:

    customer_id（必須）: 例: ?customer_id=cus_123

    send_email（オプション）: trueの場合、顧客にポータルリンクがメールされます。

customer_idが欠けている場合、400を返します。

Webhookルートハンドラーが選択された場合:

目的: Dodo Paymentsからの受信Webhookイベントを処理して、アプリ内のイベントをトリガーします。

統合:

import Hono from 'hono'
import { Webhooks } from '@dodopayments/hono'

const app = new Hono()
app.post(
  "/api/webhooks",
  Webhooks({
    webhookKey: process.env.DODO_PAYMENTS_WEBHOOK_KEY,
    onPayload: async (payload) => {
      // ここでペイロードを処理します
      console.log(payload)
    }
  })
);

機能:

    POSTメソッドのみが許可されており、他は405を返します。

    署名検証はwebhookKeyを使用して行われます。無効な場合は401を返します。

    Zodベースのペイロード検証。無効なスキーマの場合は400を返します。

    すべてのハンドラーは非同期関数です。

サポートされているWebhookイベントハンドラー:

次のいずれかのハンドラーを渡すことができます:

    onPayload

    onPaymentSucceeded

    onPaymentFailed

    onPaymentProcessing

    onPaymentCancelled

    onRefundSucceeded

    onRefundFailed

    onDisputeOpened, onDisputeExpired, onDisputeAccepted, onDisputeCancelled, onDisputeChallenged, onDisputeWon, onDisputeLost

    onSubscriptionActive, onSubscriptionOnHold, onSubscriptionRenewed, onSubscriptionPaused, onSubscriptionPlanChanged, onSubscriptionCancelled, onSubscriptionFailed, onSubscriptionExpired

    onLicenseKeyCreated

環境変数の設定:

プロジェクト内でこれらの環境変数を定義してください:

DODO_PAYMENTS_API_KEY=your-api-key
DODO_PAYMENTS_RETURN_URL=https://yourapp.com/success
DODO_PAYMENTS_WEBHOOK_KEY=your-webhook-secret
DODO_PAYMENTS_ENVIRONMENT="test_mode"または"live_mode""

これらをコード内で次のように使用します:

process.env.DODO_PAYMENTS_API_KEY
process.env.DODO_PAYMENTS_WEBHOOK_KEY

セキュリティノート: シークレットをバージョン管理にコミットしないでください。ローカルでは.envファイルを使用し、デプロイ環境ではシークレットマネージャーを使用してください（例: AWS、Vercel、Herokuなど）。

コード内で以下のように使用します:

process.env.DODO_PAYMENTS_API_KEY
process.env.DODO_PAYMENTS_WEBHOOK_KEY

セキュリティに関する注意: 秘密情報をバージョン管理にコミットしないでください。ローカルでは.envファイルを使用し、デプロイ環境ではシークレットマネージャーを使用してください（例: AWS、Vercel、Herokuなど）。
```
