checkout-integration について
Dodo Paymentsの決済を組み込む開発スキルです。ホスト型セッション、埋め込み決済、固定決済リンクに加え、トライアル、画面設定、Webhookによる決済確認を扱います。
主な機能
- 01ホスト型Checkout Sessionsの作成
- 02固定決済リンクの利用
- 03埋め込み・オーバーレイ決済
- 04顧客情報とカスタム項目の収集
- 05割引コードと通貨設定
- 06Webhookによる決済確認
活用シーン
- 01単発決済フローの構築
- 02トライアル付きサブスクリプション決済
- 03サイト上での決済オーバーレイ表示
- 04注文への割引コードと顧客項目の設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ dodopayments/ skills --skill checkout-integrationインストール後、Claude Code で/checkout-integrationを入力して読み込まれたか確認します。
同梱ファイルreferences/overlay-checkout.mdreferences/server-examples.md
詳細
Dodo Payments チェックアウトの統合
client.checkoutSessions.create(...) を使用して、ホスト型のチェックアウトページやオーバーレイ型のチェックアウトモーダルを作成します。新しい決済統合には、こちらの方法を推奨します。
このスキルを使う場面
- 1 回限りの決済チェックアウトフローを構築する
- 任意のトライアル付きサブスクリプションチェックアウトを作成する
- オーバーレイまたはインラインモーダルにチェックアウトを埋め込む
- チェックアウト時に顧客の請求情報やカスタムフィールドを収集する
- 割引コードを適用する、または通貨選択に対応する
- 決済完了後に顧客をリダイレクトする
チェックアウト方法
Dodo Payments では、決済を受け付ける方法が 3 つあります。
| 方法 | 最適な用途 | セットアップ |
|---|---|---|
| Checkout Sessions(推奨) | ほとんどの統合。完全な制御が可能 | サーバーサイド SDK 呼び出し |
| Static Payment Links | コード不要で共有できる再利用可能な URL | ダッシュボードまたは直接 URL |
| Overlay/Inline Checkout | チェックアウトをサイト上に表示する | クライアントサイド SDK |
レガシー: POST /payments または POST /subscriptions で作成する Dynamic Payment Links は非推奨です。代わりに Checkout Sessions を使用してください。
主な概念
最小通貨単位での金額指定: すべての価格はセント(または相当する最小単位)で指定します。10 USD の請求額は 1000 です。
Checkout Session: ホスト型チェックアウト URL を生成する使い切りのセッションです。24 時間後に期限切れになります(confirm=true の場合は 15 分後)。
リターン URL: 決済後に顧客が移動する先です。Dodo は payment_id(1 回限りの決済)または subscription_id(サブスクリプション)、status、および利用可能な場合は license_key と email を追加します。これは UI 上のヒントにすぎず、決済の証明にはなりません。
Webhook による利用権付与: ブラウザーのリダイレクトは信頼できる唯一の情報源ではありません。アクセスを許可する前に、必ず webhook で決済を検証してください。検証については webhook-integration スキルを参照してください。
Checkout Session を作成する
基本的な 1 回限りの決済
import DodoPayments from 'dodopayments';
const client = new DodoPayments({
bearerToken: process.env.DODO_PAYMENTS_API_KEY,
environment: 'test_mode', // or 'live_mode'
});
const session = await client.checkoutSessions.create({
product_cart: [
{ product_id: 'pdt_example', quantity: 1 }
],
customer: {
email: '[email protected]',
name: 'Jane Doe'
},
return_url: 'https://yoursite.com/checkout/success'
});
console.log('Redirect to:', session.checkout_url);
レスポンスフィールド:
session_id:一意のチェックアウトセッション IDcheckout_url:ホスト型チェックアウト URL(顧客をここにリダイレクトします)。confirm=trueの場合は null ですclient_secret:confirm=trueの場合にのみ存在しますpublishable_key:confirm=trueの場合にのみ存在します。インライン SDK フローではclient_secretと組み合わせて使用しますpayment_id:confirm=trueの場合にのみ存在します
publishable_key は、confirm モードのインラインチェックアウトで返されるセッション単位の値です。Stripe のような
パブリッシュ可能な API キー ではありません。Dodo はそのような認証情報を発行せず、すべての API キーは秘密情報であり、サーバーサイドでのみ使用します。
複数の商品を指定する場合
const session = await client.checkoutSessions.create({
product_cart: [
{ product_id: 'pdt_item_1', quantity: 2 },
{ product_id: 'pdt_item_2', quantity: 1 }
],
customer: { email: '[email protected]' },
return_url: 'https://yoursite.com/success'
});
既存の顧客を指定する場合
const session = await client.checkoutSessions.create({
product_cart: [
{ product_id: 'pdt_example', quantity: 1 }
],
customer: { customer_id: 'cus_existing_id' },
return_url: 'https://yoursite.com/success'
});
請求先住所と納税者 ID を指定する場合
const session = await client.checkoutSessions.create({
product_cart: [
{ product_id: 'pdt_example', quantity: 1 }
],
customer: {
email: '[email protected]',
name: 'Jane Doe'
},
billing_address: {
country: 'US',
street: '123 Main St',
city: 'San Francisco',
state: 'CA',
zipcode: '94105'
},
tax_id: 'VAT123456789',
customer_business_name: 'Acme Corp',
return_url: 'https://yoursite.com/success'
});
割引コードを指定する場合
const session = await client.checkoutSessions.create({
product_cart: [
{ product_id: 'pdt_example', quantity: 1 }
],
customer: { email: '[email protected]' },
discount_codes: ['PROMO10', 'WELCOME5'], // max 20, ordered
feature_flags: {
allow_discount_code: true
},
return_url: 'https://yoursite.com/success'
});
トライアル付きサブスクリプションを指定する場合
const session = await client.checkoutSessions.create({
product_cart: [
{ product_id: 'pdt_monthly_subscription', quantity: 1 }
],
subscription_data: {
trial_period_days: 14
},
customer: { email: '[email protected]' },
return_url: 'https://yoursite.com/success'
});
カスタムフィールドを指定する場合
const session = await client.checkoutSessions.create({
product_cart: [
{ product_id: 'pdt_example', quantity: 1 }
],
customer: { email: '[email protected]' },
custom_fields: [
{
key: 'company_size',
label: 'Company Size',
field_type: 'dropdown',
options: ['1-10', '11-50', '51-200', '200+'],
required: true
},
{
key: 'use_case',
label: 'Primary Use Case',
field_type: 'text',
placeholder: 'e.g., analytics, reporting',
required: false
}
],
return_url: 'https://yoursite.com/success'
});
メタデータを指定する場合
const session = await client.checkoutSessions.create({
product_cart: [
{ product_id: 'pdt_example', quantity: 1 }
],
customer: { email: '[email protected]' },
metadata: {
order_id: 'order_12345',
referral_code: 'FRIEND20',
campaign: 'summer_sale'
},
return_url: 'https://yoursite.com/success'
});
Next.js App Router
詳しいガイド:references/server-examples.md。
内容:
- API Route
- Client Component
- Success Page
Express.js
詳しいガイド:references/server-examples.md。
Python(FastAPI)
詳しいガイド:references/server-examples.md。
オーバーレイチェックアウト
詳しいガイド:references/overlay-checkout.md。
内容:
- インストール
- サーバールート
- ブラウザーオーバーレイモードとインラインモード
Static Payment Links
コード不要で共有できるリンクです。サーバーサイドの API 呼び出しは不要です。
基本形式
https://checkout.dodopayments.com/buy/{productid}
テストモードのホストは test.checkout.dodopayments.com です(例:https://test.checkout.dodopayments.com/buy/{productid})。テストモードの商品はライブホストには存在しません。
例:
https://checkout.dodopayments.com/buy/pdt_example
クエリパラメーターを指定する場合
https://checkout.dodopayments.com/buy/pdt_example?quantity=2&[email protected]&redirect_url=https%3A%2F%2Fyoursite.com%2Fsuccess
サポートされているパラメーター:
quantity:商品の数量redirect_url:成功時のリダイレクト URLemail:顧客のメールアドレスを事前入力fullName、firstName、lastName:名前を事前入力country、city、state、zipCode、addressLine:住所を事前入力paymentCurrency:通貨を指定metadata_*:カスタムメタデータ(例:metadata_orderId=123)
セッションの取得とプレビュー
セッションステータスを取得する
const status = await client.checkoutSessions.retrieve('cks_session_id');
console.log(status.id);
console.log(status.payment_status);
プレビューセッション(作成なし)
const preview = await client.checkoutSessions.preview({
product_cart: [
{ product_id: 'pdt_example', quantity: 1 }
],
customer: { email: '[email protected]' },
billing_currency: 'EUR'
});
console.log('Preview total:', preview.current_breakup.total_amount);
カスタマイズ
テーマと外観
const session = await client.checkoutSessions.create({
product_cart: [{ product_id: 'pdt_example', quantity: 1 }],
customer: { email: '[email protected]' },
customization: {
theme: 'dark', // 'light', 'dark', or 'system'
force_language: 'en',
show_order_details: true,
theme_config: {
font_size: 'md',
font_weight: 'normal',
radius: '8px',
pay_button_text: 'Complete Purchase',
light: {
bg_primary: '#ffffff',
text_primary: '#000000',
button_primary: '#0066ff'
}
}
},
return_url: 'https://yoursite.com/success'
});
機能フラグ
const session = await client.checkoutSessions.create({
product_cart: [{ product_id: 'pdt_example', quantity: 1 }],
customer: { email: '[email protected]' },
feature_flags: {
allow_discount_code: true,
allow_currency_selection: true,
allow_customer_editing_email: true,
allow_phone_number_collection: true,
require_phone_number: false,
allow_tax_id: true
},
return_url: 'https://yoursite.com/success'
});
決済後のフロー
リターン URL の処理
決済後、顧客はクエリパラメーター付きで return_url にリダイレクトされます。
# One-time payment
https://yoursite.com/success?payment_id=pay_xxx&status=succeeded&email=customer%40example.com
# Subscription (with license keys)
https://yoursite.com/success?subscription_id=sub_xxx&status=active&license_key=LK-001,LK-002&email=customer%40example.com
クエリパラメーター:
payment_id(単発決済の場合)またはsubscription_id(サブスクリプションの場合)status:成功時はsucceeded(単発決済)またはactive(サブスクリプション)、決済が拒否された場合はfailed、後から確定する場合はprocessing(またはrequires_*の値)、セッションの有効期限が切れた場合はexpiredlicense_key:製品がライセンスキーを発行する場合に含まれます(複数の場合はカンマ区切り)email:顧客のメールアドレスが登録されている場合に含まれます
session_id パラメーターはありません。processing またはステータスがない場合は「不明」として扱い、Webhook を待ってください。
サーバー側で決済を検証する
ブラウザーのリダイレクトを信用しないでください。references/server-examples.md の Express Webhook ルートを使用します。このルートは express.json() の前に署名付きの生の本文を受け取り、検証済みの payment.succeeded で event.data.customer.customer_id を使用して単発購入を履行し、検証済みの subscription.active でのみサブスクリプションへのアクセスを許可します。
Webhook の署名検証については、webhook-integration スキルで説明しています。
よくある間違い
1. リターン URL からアクセスを許可する リターン URL へのリダイレクトは、決済の証明にはなりません。クエリパラメーターを基にアクセスを許可したり注文を履行したりせず、検証済みの Webhook イベントを待ってください。
2. 非推奨の API を使用する
新しい統合では client.payments.create() や client.subscriptions.create() を使用しないでください。どちらも非推奨です。client.checkoutSessions.create() を使用してください。
3. environment フラグを設定し忘れる
デフォルトは live_mode です。実際のカードに課金されないよう、開発中は必ず environment: 'test_mode' を設定してください。
4. 非推奨の discount_code を使用する
discount_codes(配列)を使用してください。単数形の discount_code 文字列は非推奨です(後方互換性のため、引き続き受け付けられます)。同じリクエストで discount_codes と併用することはできません。
5. 金額の単位を間違える
すべての金額は通貨の最小単位(USD の場合はセント)で指定します。10 ドルは 10 ではなく 1000 です。
6. チェックアウト URL を再利用する チェックアウト URL は一度しか使用できません。チェックアウトを試みるたびに、新しいセッションを作成してください。
7. confirm=true の動作を無視する
confirm=true の場合、セッションはすぐに確定され、チェックアウト URL の有効期限は24時間ではなく15分になります。必要な顧客情報がすべて揃っている場合にのみ使用してください。
8. Webhook 用の生の本文を忘れる
Webhook の署名検証には、再シリアライズされた JSON オブジェクトではなく、生のリクエスト本文が必要です。express.json() の前に express.raw({ type: 'application/json' }) を使って Webhook ルートをマウントしてください。
9. クライアントが指定した製品 ID を信用する
ブラウザーから任意の pdt_ ID を受け入れないでください。ユーザーを認証し、公開プランのスラッグを受け取り、サーバー上で許可リストに登録された製品 ID に対応付け、正の整数でない数量は拒否してください。