Claude Code 決済連携: Stripe + Sepay を A から Z まで(2026)
Claude Code を使えば、Next.js や Node アプリ向けの実際の決済フローを構築できます。まずゲートウェイ(海外の顧客には Stripe、ベトナムの顧客には Sepay/VietQR)を選び、Claude Code にリポジトリを読ませて checkout ルートと webhook ハンドラーを生成させ、最後にあなたがテストとレビューを行います。中心となるのは5つのステップです。ゲートウェイを選ぶ、CLAUDE.md で Claude Code に指示する、checkout を作る、冪等な webhook を書く、そしてテストして堅牢化する。お金が関わるため、必ず人間がレビューします。エージェントに本番コマンドを単独で実行させてはいけません。
なぜ決済連携に Claude Code を使うのか?
決済連携は、繰り返しが多い一方でミスを起こしやすい種類の作業です。checkout ルートを作り、リダイレクトを処理し、webhook を書き、署名を検証し、注文を保存し、あらゆるテストケースをカバーする。ドキュメントを見ながら手作業でやると午後が丸ごと消えますし、細部を1つ見落とす(たとえば冪等でない webhook)だけで、顧客に二重請求してしまうこともあります。
ここでの Claude Code の強みは、単なるコード補完ではなくビルダーとして振る舞う点です。1回のセッションでリポジトリ構造を読み取り、App Router なのか Express なのかを判断し、適切な API ルートを生成し、ゲートウェイのペイロードに合った webhook ハンドラーを作り、テストコマンドをあなたのターミナルから直接実行します。「ドキュメントを何時間も掘り下げる」から「差分を数分でレビューする」への変化は本物の違いで、特に Stripe と Sepay を同時に組み込まなければならないときに効いてきます。Claude Code に API を書かせたことがまだない場合は、まず Claude Code でバックエンド API を構築するガイドを読んで、上手な指示の出し方を学んでください。
ただし最初にはっきり言っておきます。決済には実際のお金が関わるため、人間が依然としてすべての行をレビューしなければなりません。Claude Code は通貨の単位を間違えて検証したり、エッジケースを飛ばしたり、非推奨の API を提案したりすることがあります。速いジュニア開発者のように扱ってください。最終的に承認するのはあなたです。この記事全体を貫く原則はこうです。AI が作り、あなたが検証する。
ゲートウェイの選び方: Stripe vs Sepay vs Polar
プロンプトを打つ前にゲートウェイを選びましょう。それぞれ独自のフローとペイロードを持っているからです。ベトナムおよびグローバルの顧客を対象とする開発者に人気の選択肢が3つあります。
| 評価基準 | Stripe | Sepay | Polar |
|---|---|---|---|
| 対象の顧客 | 海外、クレジットカード | ベトナム、VND | グローバル SaaS |
| 決済手段 | カード、ウォレット、ホスト型 Checkout | VietQR/NAPAS、銀行振込、カード、44以上の銀行 | Merchant of Record 経由のカード |
| 強み | 大きなエコシステム、マーケットプレイス向けの Connect | スムーズな国内決済、低手数料、動的 QR | グローバルな税/VAT、サブスクリプション、トライアルに対応 |
| 最適な場面 | 海外に販売するとき | ベトナムの顧客に販売するとき | ソフトウェア/サブスクリプションを越境販売するとき |
手短な推奨はこうです。ベトナムの顧客には Sepay を使いましょう(VietQR/NAPAS、顧客はコードをスキャンして送金し、お金はあなたの銀行口座に入ります)。カードで支払う海外の顧客には Stripe を使いましょう。税処理に手を出したくない状態で SaaS をグローバルに販売するなら Polar を使いましょう。Polar は Merchant of Record として振る舞い、VAT を代わりに処理してくれるからです。多くのアプリは Stripe と Sepay を並行して運用しています。海外の顧客は Stripe を通り、国内の顧客は VietQR を通ります。この記事ではこの2つのゲートウェイを掘り下げます。Polar のフローは Stripe に似ています(独自の Next.js アダプターがあります)。
始める前に準備するもの
Claude Code を開く前のチェックリストです(さっと目を通して、足りないものを埋めてください)。
- すでにローカルで動作している Next.js または Node/Express アプリ。
- テストモードの Stripe アカウント、またはサンドボックスの Sepay アカウント(キーは
SP-TEST-*のような形です)。 .envに保管し絶対にコミットしないシークレットキー。まず.envを.gitignoreに追加してください。- インストール済みの Claude Code と、スタックや規約を記述したリポジトリ内の
CLAUDE.md(以下で使います)。 - ゲートウェイが webhook を呼び出せる公開エンドポイント。ローカルでは Stripe CLI やトンネルを使い、本番では実際の HTTPS を使います。
シークレットキーの扱いは決済セキュリティの中で最ももろい部分なので、Claude Code の権限を安全に管理する方法も読んでおき、エージェントがうっかりシークレットを読んだりログに出力したりしないようにしてください。
決済作業のための Claude Code への指示の出し方
出力の品質は、ほぼ完全に指示の出し方で決まります。決済において最も重要なのは、CLAUDE.md のコンテキストと具体的なプロンプトの2つです。
Claude Code が推測しなくて済むように、次のようなコンテキストを数行 CLAUDE.md に追加します。
# Payment context
- Stack: Next.js 15 App Router, TypeScript, Prisma + PostgreSQL
- Gateways: Stripe (international) + Sepay/VietQR (VN customers)
- Env: all secrets live in .env, NEVER commit, NEVER print to logs
- Convention: use Stripe Checkout Sessions only, NO legacy Charges/Card Element
- Safety: NEVER run production commands, NEVER refund; test mode/sandbox only
次はプロンプトです。曖昧な「Stripe を連携して」と具体的なものを比べてみましょう。
Read app/ and prisma/schema.prisma. Create a POST route app/api/checkout/route.ts
that creates a Stripe Checkout Session (mode payment) from the priceId in the body
and returns session.url. Use the existing env vars. Do not touch other files.
Then document a Stripe CLI test in the README; do not run any live commands.
具体的なプロンプトは、Claude Code の変更範囲を絞り込み、あなたの実際の DB スキーマを使わせ、余計なファイルを「でっち上げる」のを防ぎます。fetch/MCP 経由でゲートウェイのドキュメント(Stripe ドキュメント、developer.sepay.vn)を参照させ、古い記憶ではなく最新の API に従わせることもできます。
Claude Code での Stripe フロー(海外の顧客)
最近の Stripe フローは4つのステップに収まります。Checkout Sessions(Stripe がホストする)を優先し、レガシーな Charges/Card Element は避けましょう。古い方式で、PCI の負担が増えるからです。
- Checkout Session を作成するルート。
priceIdを受け取り、セッションを作成し、クライアントがリダイレクトするためのsession.urlを返すルートを生成するよう Claude Code に指示します。 - 成功/キャンセルのリダイレクト。
success_urlとcancel_urlを渡します。成功ページで注文を「支払い済み」にしてはいけません。webhook を待ちましょう。 - webhook
checkout.session.completed。 ビジネスロジックを処理する前に、constructEventで署名を検証します。 - Stripe CLI でテストを、デプロイ不要でローカルマシン上で直接行います。
// app/api/checkout/route.ts
import { NextResponse } from "next/server";
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
export async function POST(req: Request) {
const { priceId } = await req.json();
const session = await stripe.checkout.sessions.create({
mode: "payment",
line_items: [{ price: priceId, quantity: 1 }],
success_url: `${process.env.APP_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.APP_URL}/cancel`,
});
return NextResponse.json({ url: session.url });
}
// app/api/webhooks/stripe/route.ts
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
export async function POST(req: Request) {
const body = await req.text(); // raw body is required to verify
const sig = req.headers.get("stripe-signature")!;
let event: Stripe.Event;
try {
event = stripe.webhooks.constructEvent(
body, sig, process.env.STRIPE_WEBHOOK_SECRET!
);
} catch {
return new Response("Invalid signature", { status: 400 });
}
if (event.type === "checkout.session.completed") {
// idempotent: check whether event.id was already processed before writing the order
}
return new Response("ok", { status: 200 });
}
ローカルで2つのコマンドを使い、コストゼロでテストします。
stripe listen --forward-to localhost:3000/api/webhooks/stripe
stripe trigger checkout.session.completed
本番稼働までの全フローと公式チェックリストは、Stripe のドキュメント(docs.stripe.com、2026年8月アクセス)を参照してください。Stripe は頻繁に更新するので、公開前に本番の API バージョンを確認しましょう。
Claude Code での Sepay/VietQR フロー(ベトナムの顧客)
Sepay はベトナムの顧客によく合います。VietQR コードまたはバーチャル口座を生成し、顧客がスキャンして送金すると、Sepay が入金を確認する webhook を発火します。4ステップのフローです。
- 注文を作成し、VietQR を生成します(またはバーチャル口座)。その注文に対して、あとで照合できる送金メモを付けます。
- 顧客が QR をスキャンして送金します。銀行アプリを通じて行います。
- Sepay の webhook が、
transferType: "in"とともに、transferAmount、content、referenceCodeを含めて取引を報告します。 - 検証し、重複排除し、5秒以内に
{"success": true}を返します そうすれば Sepay は再送しません。
// app/api/webhooks/sepay/route.ts
import { db } from "@/lib/db";
export async function POST(req: Request) {
const auth = req.headers.get("authorization");
if (auth !== `Apikey ${process.env.SEPAY_API_KEY}`) {
return new Response("Unauthorized", { status: 401 });
}
const data = await req.json();
// data: { id, transferType, transferAmount, content, referenceCode }
if (data.transferType !== "in") {
return Response.json({ success: true }); // ignore outgoing transactions
}
const existed = await db.transaction.findUnique({
where: { sepayId: data.id },
});
if (existed) return Response.json({ success: true }); // dedupe by id
await db.transaction.create({
data: {
sepayId: data.id,
amount: data.transferAmount,
content: data.content,
ref: data.referenceCode,
},
});
// TODO: reconcile content with the order, then update its status to "paid"
return Response.json({ success: true });
}
取引の保存と注文との照合は、データ層にきれいに収めるべきです。整然とした orders/transactions テーブルを設計するために、データベースで注文と取引を保存する方法を参照してください。Sepay には独自のサンドボックスと 2 req/s のレート制限があるので、Claude Code に公式ドキュメント(developer.sepay.vn、2026年8月アクセス)を読ませて、正しいエンドポイントとペイロードを守らせましょう。
webhook と冪等性 ― 最も間違えやすい部分
ここは手動チュートリアルが飛ばしがちな箇所であり、そして被害が最も大きくなる箇所でもあります。決済ゲートウェイはwebhook がちょうど1回だけ配信されることを保証しません。不安定なネットワーク、タイムアウト、再送のすべてが、同じイベントを何度も到着させます。ハンドラーが冪等でないと、注文が重複して書き込まれたり、残高が二重に加算されたり、商品が2回発送されたりします。
ルールはこうです。イベント識別子で重複排除する。Sepay ではそれが取引の id、Stripe では event.id です。処理済みの id を保存し(DB のユニークインデックス)、以前に見たものはスキップします。より複雑なケースでは、複合キー(たとえば orderId とイベントタイプ)を使います。
覚えておくべきタイミングと再送の制約です。
- Sepay: ハンドラーは5秒以内に 2xx を返さなければなりません。さもないと Sepay は Fibonacci スケジュールでおよそ5時間かけて最大7回まで自動再送します。つまり同じ取引が7回到着しうるので、重複排除は必須です。
- Stripe: 2xx を受け取らないと独自のスケジュールで再送します。やはり
event.idで重複排除する必要があります。
実践的なコツです。まずイベントを保存し、ビジネスロジックはあとで処理する。イベントレコードを(冪等に)書き込んでから、重い処理を別のステップで実行します。そうすれば処理が失敗しても、再送は安全なままです。ここは Claude Code に「webhook が2回到着する」ケースのテストを書かせるのに良い場面です。念を押さないとたいてい忘れます。
本番稼働前のテストとセキュリティ
実際のお金を動かす前に、このチェックリストを一通り確認してください(手動チュートリアルが最も見落としがちな点でもあります)。
テスト:
- Stripe: Stripe CLI(
stripe listen/stripe trigger)とテストカードを使います。実際のお金は関わりません。 - Sepay:
SP-TEST-*キーでサンドボックスを使い、入金取引をシミュレートして webhook を確認します。 - 失敗ケースをテストします。不正な署名、webhook の2回到着、注文と一致しない金額。
セキュリティ:
- シークレットキーを絶対に公開しない ― サーバー側のみで、クライアントバンドルに含めず、ログに出力しないこと。
- すべての webhook を検証する。Stripe は HMAC 署名(
constructEvent)で、Sepay は API Key ヘッダーAuthorization: Apikey ...で。 - 本番では HTTPS を必須にします。webhook エンドポイントには IP ホワイトリストの導入も検討しましょう。
- Checkout Sessions / PaymentIntents / SetupIntents のみを使い、PCI の範囲を狭めるためにレガシーな Sources/Tokens/Charges は避けます。生の PAN に触れると、複雑な PCI 準拠の枠に入ってしまいます ― やめましょう。
本番稼働: Stripe には独自の本番稼働チェックリストがあります(ライブキーへの切り替え、本番 webhook の設定)。Sepay はNAPAS QR/カードの承認が必要で、通常3〜7日かかります ― その分を見込んでおきましょう。公開する前に、Claude Code でのセキュリティと監査レビューをもう一度実行し、キーの漏洩や検証の抜けを見つけましょう。
既製スキルではるかに速く出荷する(AgentKit)
ハンドラーを1つずつ手書きしたくないなら、より速い道があります。AgentKit Engineer Kit の ak-payment-integration スキルです。このスキルはすでに3つのゲートウェイ ― SePay、Polar、Stripe ― をパッケージ化しており、checkout、webhook 検証(すぐ使えるスクリプト付き)、QR、サブスクリプション、複数プロバイダーの注文までカバーします。だから Claude Code はそれを有効化するだけで、各ゲートウェイのドキュメントを掘り下げる代わりに数分で構築できます。
混同を避けるために一言。ここでの AgentKit は agentkit.best(リンク経由で20%オフ) にある Claude Code 向けのキット(ak CLI)であり、OpenAI の AgentKit ではありません。 Engineer Kit の価格は $99 です(サイトに継続課金の記載はありません)。このスキルが実際に何を解決するのか知りたいなら、決める前に Engineer Kit の詳細レビューと AgentKit とは何かを読んでください ― 1つのフローしか必要ないなら、1つのスキルのために買うのはやめましょう。
AI にお金を触らせるときの限界と注意点
決済は YMYL に近いので、このセクションはコードと同じくらい重要です。Claude Code に決済を任せるときの、いくつかの譲れない境界です。
- お金に関わるコードは必ずレビューする。 金額計算、単位変換、注文のステータスを更新する条件を注意深く読みます。
- エージェントに本番コマンドや返金を単独で実行させない。 Claude Code はテストモード/サンドボックスに留め、ライブコマンドはレビューのあとにあなた自身が押します。
- 金額と単位を検証する。 Stripe は最小単位(セント)で数えます。VND には小数点以下がありません ― ここは AI が変換でよくつまずくところです。
- webhook のエッジケースを徹底的にテストする(2回到着、誤った署名、一致しない金額)とともに、紛争が起きたときの照合のためにログを保持する。
結論。AI は速く動く助けになりますが、お金に対する責任は依然としてあなたのものです。スピードは、頭の冴えた1回のレビューの代わりにはなりません。
よくある質問(FAQ)
Claude Code は決済を完全に連携してくれますか?
大部分は構築してくれます。リポジトリを読み、checkout ルートを生成し、webhook ハンドラーを書き、テストを書きます。ただしコードのレビュー、ゲートウェイへの登録、本番キーの設定、本番稼働コマンドの実行は、あなた自身が行わなければなりません。お金が関わるため、最終承認者は人間です。
ベトナムの顧客には Stripe と Sepay のどちらを選ぶべきですか?
VND で支払うベトナムの顧客には、VietQR/NAPAS、44以上の銀行をまたぐ送金、そしてお金が直接銀行口座に入ることから、Sepay のほうが合います。Stripe は海外に販売してクレジットカードを受け付けるときに合います。多くのアプリは両方を並行して運用しています。
webhook が取引をまったく受信しない場合はどうすればいいですか?
エンドポイントが公開されていて HTTPS であること、署名/API Key の検証が正しいこと、ハンドラーが5秒以内に 2xx を返すことを確認してください。Sepay はおよそ5時間かけて最大7回まで自動再送するので、ハンドラーが冪等であれば、あとの再送でも正しく記録されます。
実際のお金を使わずに決済フローをテストするにはどうすればいいですか?
テストモードを使います。Stripe には Stripe CLI(stripe listen/stripe trigger)とテストカードがあり、Sepay には SP-TEST-* キーのサンドボックスがあります。どちらも実際のお金に触れずに取引と webhook をシミュレートできます。
コーディングが得意でなくてもこの記事に沿って進められますか?
Claude Code が生成する差分を読んでレビューするための、基本的なコーディング知識は必要です ― お金が絡むので、理解していないコードをマージすべきではありません。Claude Code は手で打つ量を減らしてくれますが、コードを読んで理解する力は依然として不可欠です。
ak-payment-integration スキルは手書きとどう違いますか?
手書きは1行1行を制御できますが、3つのゲートウェイのドキュメントを掘り下げる時間がかかります。ak-payment-integration スキルは SePay/Polar/Stripe 向けに checkout、webhook 検証、QR、サブスクリプションをパッケージ化しており、より速く構築できます。その代わり、アプリごとに独自のビジネスロジックがあるので、出力はやはりレビューすべきです。
まとめと次のステップ
5つのステップをおさらいします。ゲートウェイを選ぶ(海外には Stripe / ベトナムの顧客には Sepay)、CLAUDE.md で Claude Code に指示する、checkout を作る、冪等な webhook を書く、そして本番稼働前にテストして堅牢化する。成否を分けるのは冪等な webhook と1回の人間によるレビューです。これは実際のお金だからです。ここから、完全なバックエンド API を構築するに進んだり、リリース前にセキュリティ監査を締めたりできます。
決済フローをもっと速く構築したいですか? Engineer Kit の ak-payment-integration スキルは、Stripe/Sepay/Polar 向けに checkout、webhook 検証、QR をパッケージ化しています ― 各ゲートウェイのドキュメントを掘り下げずに複数のゲートウェイを組み込む必要があるときに便利です。