mcpField
F
framework-adapters

framework-adapters

github.com/dodopayments開発13200 回インストール3 週間前に更新
リポジトリ

framework-adapters について

公式アダプターで Dodo Payments を Web フレームワークに統合する開発者向けガイドです。複数のフレームワークで使うチェックアウト、顧客ポータル、Webhook ハンドラーと、環境設定やセキュリティ上の注意点を説明します。

主な機能

  1. 01複数フレームワーク向け公式アダプター
  2. 02チェックアウトのルートハンドラー作成
  3. 03顧客ポータルのセッションリンク生成
  4. 04Webhook 署名の検証とイベント処理
  5. 05環境変数とリクエスト形式の対応

活用シーン

  1. 01Web フレームワークへの決済ルート追加
  2. 02認証付き顧客ポータルの作成
  3. 03決済 Webhook の受信と検証
  4. 04フレームワークに応じたアダプターと処理方式の選択

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/dodopayments/skills --skill framework-adapters

インストール後、Claude Code で/framework-adaptersを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
astro.md
bun.md
convex.md
express.md
fastify.md
hono.md
nuxt.md
remix.md
sveltekit.md
tanstack-start.md

詳細

フレームワークアダプター

公式アダプターパッケージを使用して、Web フレームワークに Dodo Payments を統合する場合は、このスキルを使用してください。フレームワークアダプターは、ルートの配線、環境設定、ハンドラーのセットアップを行うため、チェックアウト、ポータル、Webhook のルートを一から構築する必要はありません。

このスキルを使用する場面

  • Next.js、Express、Fastify、Hono、Astro、Remix、SvelteKit、Nuxt、TanStack、Bun、または Convex でチェックアウトフローを構築しています。
  • カスタマーポータルのセッションエンドポイントをセットアップする必要があります。
  • 署名を検証してイベントをディスパッチする Webhook ハンドラーを追加しています。
  • フレームワークに適したルートの配置や環境変数の処理が必要です。
  • 静的、動的、セッションのどのチェックアウトモードを選ぶか決める必要があります。

フレームワークアダプターの機能

Dodo は、フレームワーク固有のルートハンドラーでコア SDK をラップする @dodopayments/* パッケージを公開しています。独自の HTTP ハンドラーを記述する代わりに、アダプターのハンドラーをインポートして、ルートに直接マウントします。

各アダプターは、次の 3 種類のハンドラーを提供します。

  • Checkout: 静的(GET のみ)、動的(POST。非推奨の POST /payments / POST /subscriptions エンドポイントを使って支払いまたはサブスクリプションを作成します。既存の統合向けです)、またはセッション(チェックアウトセッションのペイロードを指定する POST。新しい統合ではこちらを使用してください)。
  • CustomerPortal: 有効期限付きのポータルセッションリンクを生成します。
  • Webhooks: Webhook の署名を検証し、型付きイベントをディスパッチします。

セキュリティ — CustomerPortal は認証を行いません。 すべての CustomerPortal ハンドラーは、受け取った ?customer_id= の値に対応するポータルを開きます。そのままマウントすると、ID を推測または列挙することで、誰でも任意の顧客のポータルを開けてしまいます。このルートには独自の認証を適用し、顧客 ID はサインイン済みセッションからサーバー側で解決してください。クライアントから受け取ってはいけません。以下のポータルの例では、この方法を使用しています。

アダプターによってエクスポート名は統一されていません。 ほとんどのアダプターは Checkout / CustomerPortal / Webhooks をエクスポートしますが、異なるものが 2 つあり、戻り値の形式も異なります。インポートを記述する前に、この表を確認してください。

アダプターCheckout のエクスポートPortal のエクスポートハンドラーの形式
nextjs、hono、astro、bun、remix、tanstackCheckoutCustomerPortalリクエストハンドラーを返します
expresscheckoutHandler(小文字)CustomerPortal(req, res) を返します
fastifyCheckoutCustomerPortal{ getHandler, postHandler } を返します
sveltekitCheckoutCustomerPortal{ GET, POST } / { GET } を返します
nuxtcheckoutHandler(自動インポート)customerPortalHandlerインポート文は不要です
convexcheckout(dodo.api() から)customerPortal(dodo.api() から、identify を使用)createDodoWebhookHandler

アダプターは、Webhook 検証のための生のボディの保持、環境変数のマッピング、フレームワーク固有のリクエスト/レスポンス形式への対応を行います。チェックアウトのペイロード設計には checkout-integration スキルを、Webhook のビジネスロジックには webhook-integration を、ポータルの動作には customer-management を使用してください。

フレームワークの選択とインストール

フレームワークパッケージインストール
Next.js@dodopayments/nextjsnpm install @dodopayments/nextjs
Express@dodopayments/expressnpm install @dodopayments/express
Fastify@dodopayments/fastifynpm install @dodopayments/fastify
Hono@dodopayments/hononpm install @dodopayments/hono
Astro@dodopayments/astronpm install @dodopayments/astro
Remix@dodopayments/remixnpm install @dodopayments/remix
SvelteKit@dodopayments/sveltekitnpm install @dodopayments/sveltekit
Nuxt@dodopayments/nuxtnpm install @dodopayments/nuxt
TanStack Start@dodopayments/tanstacknpm install @dodopayments/tanstack
Bun@dodopayments/bunbun add @dodopayments/bun
Convex@dodopayments/convexnpm install @dodopayments/convex

環境変数

ほとんどのアダプターでは、次の標準名を使用します。

DODO_PAYMENTS_API_KEY=dodo_test_...
DODO_PAYMENTS_WEBHOOK_KEY=your-webhook-secret
DODO_PAYMENTS_ENVIRONMENT=test_mode
DODO_PAYMENTS_RETURN_URL=https://yourdomain.com/checkout/success

Nuxt では、プライベートランタイム設定のプレフィックスを使用します。

NUXT_PRIVATE_BEARER_TOKEN=dodo_test_...
NUXT_PRIVATE_WEBHOOK_KEY=your-webhook-secret
NUXT_PRIVATE_ENVIRONMENT=test_mode
NUXT_PRIVATE_RETURN_URL=https://yourdomain.com/checkout/success

Convex では、ダッシュボードの環境変数を使用します(ローカルの .env ではありません)。

DODO_PAYMENTS_API_KEY=dodo_test_...
DODO_PAYMENTS_ENVIRONMENT=test_mode
DODO_PAYMENTS_WEBHOOK_SECRET=your-webhook-secret

Webhook キーの命名: アダプターによって、DODO_PAYMENTS_WEBHOOK_KEY を参照するものと、DODO_PAYMENTS_WEBHOOK_SECRET を使用するものがあります。正しい変数名を使用できるよう、フレームワークのアダプタードキュメントとダッシュボードの設定を確認してください。

environment の型を絞り込む

アダプターの設定では、environment の型として Pick<ClientOptions, "environment">、つまりリテラルユニオン型 "test_mode" | "live_mode" を使用します。process.env.X の型は string | undefined であるため、代入できません。どのアダプターでも、直接渡すと型エラーになります。

アダプターの設定を作成する場所でインポートできるよう、このヘルパーを一度定義してください。

// lib/dodo-env.ts
export const dodoEnvironment =
  process.env.DODO_PAYMENTS_ENVIRONMENT === "live_mode" ? "live_mode" : "test_mode";

test_mode をデフォルトにするのは意図的です。変数が存在しない場合や名前に誤りがある場合に、ライブモードに暗黙的に切り替わることがあってはなりません。以下のすべての例では dodoEnvironment を使用します。

Next.js

パッケージ: @dodopayments/nextjs
ルートの配置場所: app/api/checkout/route.ts、app/api/customer-portal/route.ts、app/api/webhook/route.ts

チェックアウト(ルートごとにいずれかのモードを選択)
// app/api/checkout/route.ts
import { Checkout } from "@dodopayments/nextjs";
import { dodoEnvironment } from "@/lib/dodo-env";

export const GET = Checkout({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
  environment: dodoEnvironment,
  type: "static",
});

export const POST = Checkout({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  returnUrl: process.env.DODO_PAYMENTS_RETURN_URL,
  environment: dodoEnvironment,
  type: "session",
});
カスタマーポータル
// app/api/customer-portal/route.ts
import { NextRequest } from "next/server";
import { CustomerPortal } from "@dodopayments/nextjs";
import { dodoEnvironment } from "@/lib/dodo-env";
// your auth helper
import { getSessionUser } from "@/lib/auth";

const portal = CustomerPortal({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  environment: dodoEnvironment,
});

export async function GET(req: NextRequest) {
  const user = await getSessionUser(req);
  if (!user?.dodoCustomerId) return new Response("Unauthorized", { status: 401 });

  // Overwrite any client-supplied ?customer_id= with the signed-in user's ID.
  const url = new URL(req.url);
  url.searchParams.set("customer_id", user.dodoCustomerId);
  return portal(new NextRequest(url, req));
}
Webhook
// app/api/webhook/route.ts
import { Webhooks } from "@dodopayments/nextjs";

export const POST = Webhooks({
  webhookKey: process.env.DODO_PAYMENTS_WEBHOOK_KEY,
  onPayload: async (payload) => {
    console.log("Webhook received:", payload.type);
  },
});

Express

完全なガイド:references/express.md。

以下を扱います。

  • チェックアウト
  • カスタマーポータル
  • Webhook

Fastify

完全なガイド:references/fastify.md。

以下を扱います。

  • チェックアウト
  • Webhook

Hono

完全なガイド:references/hono.md。

以下を扱います。

  • チェックアウト
  • カスタマーポータル
  • Webhook

Astro

完全なガイド:references/astro.md。

以下を扱います。

  • チェックアウト
  • Webhook

Remix

完全なガイド:references/remix.md。

以下を扱います。

  • チェックアウト
  • カスタマーポータル
  • Webhook

SvelteKit

完全なガイド:references/sveltekit.md。

以下を扱います。

  • チェックアウト
  • Webhook

Nuxt

完全なガイド:references/nuxt.md。

以下を扱います。

  • チェックアウト
  • Webhook

TanStack Start

完全なガイド:references/tanstack-start.md。

以下を扱います。

  • チェックアウト

Bun

完全なガイド:references/bun.md。

以下を扱います。

  • チェックアウトとポータル

Convex

完全なガイド:references/convex.md。

よくある間違い

  1. POST ハンドラーの重複: Next.js と Astro のドキュメントには、export const POST の宣言が 2 つ記載されています。ルートごとにチェックアウトモードを 1 つ選ぶか、両者を振り分けるルーティングロジックを追加してください。

  2. Webhook 変数名の誤り: アダプターが DODO_PAYMENTS_WEBHOOK_KEY と DODO_PAYMENTS_WEBHOOK_SECRET のどちらを使用するか確認してください。ドキュメントには一貫性がないため、アダプターが実際に参照する名前を使用してください。

  3. 生のボディの保持忘れ: Webhook ハンドラーには、再解析された JSON オブジェクトではなく、リクエストの生のボディを渡す必要があります。Fastify では明示的な文字列ボディパーサーが必要ですが、ほかのフレームワークでは自動的に処理されます。例外は Express です。 Webhooks ハンドラーは解析済みの req.body を使って検証するため、ルートの前に express.json() を登録し、検証がすべて失敗する原因となる express.raw() は使用しないでください。Webhook の署名検証については、webhook-integration スキルで説明しています。

  4. フレームワークごとの規約の混同: 各フレームワークには、それぞれ異なるリクエスト/レスポンス形式があります。Next.js のハンドラーを Express で使用したり、その逆を行ったりしないでください。使用しているフレームワークに対応したアダプターを使ってください。

  5. シークレットのハードコード: API キーと Webhook シークレットは、必ず環境変数から読み込み、コードや設定ファイルには記述しないでください。

  6. 環境設定の省略: DODO_PAYMENTS_API_KEY と DODO_PAYMENTS_ENVIRONMENT がないと、アダプターは動作しません。テストの前に設定してください。

  7. CustomerPortal の未認証公開: ポータルハンドラーは、リクエストに含まれる ?customer_id= を信頼します。上記の例のように、サーバー上でサインイン済みセッションから ID を取得してください。そうしないと、誰でも任意の顧客のポータルを開けてしまいます。

  8. @dodopayments/core の直接使用: core パッケージは内部依存関係であり、公開されているエントリーポイントとしてはドキュメント化されていません。使用するスタックに対応したフレームワークアダプターを使ってください。

リソース

コメント