アプリに決済を追加する方法:チェックアウト、サブスクリプション、Webhook
アプリに決済を追加する最も簡単な方法は、Stripeを使うことです。「購入」ボタンだけが必要で注文を手作業で処理できるなら Payment Link を使います。アプリが誰が支払ったかを知り、自動的に反応する必要があるなら Stripe Checkout を使います。定期課金には、Checkoutのサブスクリプションモードと、Stripeのカスタマーポータルを組み合わせます。最も単純な場合を除き、どの方法でも Webhook が必要です。Webhookは、支払いが成功したときにStripeが呼び出すサーバーのエンドポイントです。本番のキーに切り替える前に、すべてをStripeのテストキーとテスト用カードでテストしてください。
このガイドでは、それぞれの方法を説明し、多くのチュートリアルが省略しがちなWebhookの部分と、実際にお金を受け取る前に確認すべき点を扱います。Stripeの詳細は、2026年9月時点のStripe公式ドキュメントに基づいています。
そもそも決済プロバイダーを使う理由
カード番号を自分のフォームで集めることは決してしないでください。カードの生データを扱うと、PCI DSS(カード業界のセキュリティ基準)の対象になり、重大な責任を負うことになります。Stripeのような決済プロバイダーは、決済フォームをホストし、カードを保存し、銀行による認証を処理し、結果をアプリに伝えます。アプリが受け取るのは「顧客Xが商品Yに支払った」という情報だけです。
このガイドでStripeを使うのは、広く使われており、ドキュメントが充実していて、ほとんどのAIアプリビルダーが対応しているからです。ほかのプロバイダーも存在します。中には「マーチャント・オブ・レコード」と呼ばれ、売上税の処理を代わりに引き受けてくれるものもあります。税務の対応が気がかりであれば、そのモデルを比較する価値があります。
Stripeで決済を受け付ける3つの方法
| 方法 | コードの必要性 | アプリが誰の支払いか把握できるか | 向いている用途 |
|---|---|---|---|
| Payment Links | 不要 | Webhookを追加した場合のみ | 数種類の固定商品の販売、寄付、需要の検証 |
| Checkout(単発) | 決済セッションを作成するサーバーコードが必要 | はい(Webhook経由) | ストア、有料ダウンロード、単発の購入 |
| Checkout(サブスクリプション) | サーバーコードとWebhook処理が必要 | はい(Webhook経由) | SaaS、会員制、定期的な課金すべて |
Payment Links
Payment Linkは、Stripeダッシュボードで作成する、Stripeがホストする決済ページです。コードは不要です。得られるURLは、アプリのボタンの裏側に置いたり、メールで共有したり、QRコードとして表示したりできます。Stripeのドキュメントによると、Payment Linksは商品、サブスクリプションを販売したり、寄付を受け付けたりでき、顧客が支払う内容を選べるようにしたり、購入回数を制限したりできます。
注意点として、アプリは特定のログインユーザーが支払ったかどうかを自動では把握しません。寄付ページや、Stripeのメール通知を見て手作業で注文を発送する小さなショップであれば、それで問題ありません。「支払うとProの機能が使える」という仕組みには向きません。
Stripe Checkout
Checkoutは、特定の購入のためにサーバーがその場で作成する決済ページです。サーバーはStripeに何を購入するのかを伝え(必要であれば、どの顧客が購入するのかも伝え)、Stripeが返したURLに顧客を送ります。Stripeのドキュメントでは、Checkoutは単発とサブスクリプションの両方の支払いに対応し、Stripeがホストする完全なページ、サイトに埋め込むページ、または埋め込みフォームとして提供されると説明されています。
流れは次のとおりです。
- 顧客がアプリで購入をクリックします。
- サーバーが、シークレットキーを使ってCheckout Sessionを作成します。その際、ユーザーや注文と結びつけるIDを含めます。
- 顧客はStripeにリダイレクトされ、支払いを行います。
- Stripeが顧客を成功ページに戻します。
- Stripeが
checkout.session.completedイベントをWebhookに送ります。サーバーはそれを受けて、注文を支払い済みにするか、アクセスを解除します。
ステップ2はサーバー上で行う必要があります。シークレットキーを使うためです。これが、Checkoutにバックエンドが必要な主な理由です。
サブスクリプション
サブスクリプションは、Stripeで設定した定期価格を使い、サブスクリプションモードのCheckoutを利用します。最初の支払いは、上記の流れと同じように進みます。その後の更新、カードの失効、期間の途中でのアップグレード、解約などは時間をかけて発生します。多くの場合、顧客がアプリにいないときに起きるため、アプリはWebhookを通じてのみそれを知ります。
顧客が自分でサブスクリプションを管理できるようにするには、Stripeが提供するホスト型のカスタマーポータルを使います。Stripeのドキュメントによると、顧客はそこで支払い方法や請求情報の更新、プランの変更やキャンセル、請求書の閲覧やダウンロードができます。Stripeダッシュボードで設定し、「請求を管理」ボタンを追加して、顧客をそのポータルに案内します。こうすると、それらの画面を自分で作る必要がなくなります。
Webhook:省略できない部分
Webhookとは、何かが起きたときにStripeがサーバーに送るHTTPリクエストです。(Webhookの一般的な考え方は、Webhookとはを参照してください。)Stripeの履行ガイドでは、注文の履行を完了ページだけに頼ってはいけないと明記されています。顧客は支払いを済ませた後、完了ページが読み込まれる前に接続が切れることがあるためです。サブスクリプションや、支払いの遅延が発生する支払い方法では、Webhookが必須です。
処理すべきイベント
| イベント | 意味 | アプリの処理 |
|---|---|---|
checkout.session.completed | Checkoutが完了した | 注文を支払い済みにするか、アクセスを開始する |
checkout.session.async_payment_succeeded | 遅延する支払い方法(銀行引き落としなど)が後で成立した | 今すぐ履行する |
checkout.session.async_payment_failed | 遅延していた支払いが失敗した | 顧客に伝え、履行はしない |
invoice.paid | サブスクリプションの支払いが成功した(更新を含む) | アクセスを延長する |
invoice.payment_failed | 更新の支払いが失敗した | 利用者に警告する。Stripeは再試行する場合がある |
customer.subscription.updated | プランが変更された、または解約が予定された | 利用者のプランを更新する |
customer.subscription.deleted | サブスクリプションが終了した | 有料アクセスを削除する |
正しいWebhookハンドラーの規則
これらは、Stripeのwebhookドキュメントに書かれている内容そのものです。AIが生成したハンドラーは、時々これらのどれかを見落とします。
- 署名を検証する。 各イベントには
Stripe-Signatureヘッダーが含まれます。ハンドラーは、エンドポイントの署名シークレット(whsec_から始まる)を使ってそれを検証します。これを行わないと、誰でも偽の「支払い成功」をサーバーに送れてしまいます。 - 生のリクエストボディを使う。 フレームワークがボディを先に解析したり変更したりすると、署名の検証は失敗します。
- 素早く2xxを返し、時間のかかる処理はその後で行う。タイムアウトは失敗として扱われます。
- 重複を扱う。 Stripeは同じイベントを複数回配信することがあります。処理済みのイベントIDを記録するか、履行処理を二重に実行しても安全な作りにしてください。
- 順序を前提にしない。 Stripeは、イベントが発生した順に届くことを保証していません。
- 再送を想定する。 本番モードでは、Stripeは失敗した配信を最大3日間再試行します。そのため、短時間の障害で支払いを失うことはありませんが、ハンドラーは遅れて届くイベントに対応できる必要があります。
Webhookには公開されたHTTPSのアドレスが必要です。そのため、通常はアプリを公開してからでないと動きません。(開発者は、Stripe CLIを使えば、イベントをローカルマシンに転送できます。)
決済フロー全体のプロンプト
「Proパック」の単発購入を、Stripe Checkoutで追加してください(価格IDは STRIPE_PRICE_ID に入れます)。Checkout Sessionは、シークレットに保存された STRIPE_SECRET_KEY を使ってサーバー上で作成し、ログイン中のユーザーのIDをセッションに含めてください。
POST /api/stripe/webhookエンドポイントを追加し、生のリクエストボディを使って STRIPE_WEBHOOK_SECRET で Stripe の署名を検証してください。checkout.session.completedを処理し、そのユーザーを「Proパックあり」に設定してください。同じイベントが2回届いても安全にしてください。成功ページとキャンセルページを作成してください。シークレットキーをブラウザに決して公開しないでください。
サブスクリプションの場合は、次を追加します。「STRIPE_PRICE_ID を使ってサブスクリプションモードにしてください。invoice.paid、invoice.payment_failed、customer.subscription.updated、customer.subscription.deleted を処理してください。「請求を管理」ボタンを追加し、このユーザーのStripeカスタマーポータルを開くようにしてください。」
テストモード
Stripeには、サンドボックス(テスト)と本番の環境があり、それぞれに別々のキーがあります。サンドボックスのキーは pk_test_、sk_test_、rk_test_ で始まります。本番のキーは pk_live_、sk_live_、rk_live_ で始まります。テスト取引では、お金は動きません。
Stripeのテストドキュメントにあるテスト用カードは次のとおりです(有効期限は未来の日付、CVCは任意の3桁)。
| カード番号 | 結果 |
|---|---|
4242 4242 4242 4242 | 支払いが成功する |
4000 0000 0000 0002 | カードが拒否される |
4000 0000 0000 3220 | 3Dセキュア認証が必要になり、その後成功する |
少なくとも次の点をテストしてください。
- 支払いが成功すると、正しいユーザーに正しいものが解除される
- 拒否されたカードには、わかりやすいメッセージが表示され、何も解除されない
- 支払いの直後にブラウザのタブを閉じても、アクセスは付与される(これはWebhookが機能していることを確認するものです。完了ページだけの動作ではありません)
- Stripeのページでキャンセルすると、アプリに戻り、何も請求されない
- サブスクリプションの場合:カスタマーポータルで解約し、アクセスが適切なタイミングで終わることを確認する
本番公開
- Stripeアカウントを有効化し、事業者情報と銀行情報を登録します。
- 本番キーに差し替えます。キーはアプリのシークレットに保存します。Stripeは、無制限のシークレットキーではなく、連携に必要な権限だけを持つ制限付きキーの利用を推奨しています。
- 本番用のWebhookエンドポイントを作成し、公開済みのアプリを指すようにします。これにはテスト用とは別の署名シークレットがあるため、設定を更新してください。
- 本番モードで商品と価格を作り直します。テストモードのIDは、本番モードには存在しません。
- 実際に少額の購入を1件行い、返金します。
すべてのキーは、コードやチャットではなく、プロジェクトのシークレットに保存してください。キーとWebhookの検証について詳しくは、AIで作ったアプリのセキュリティチェックリストを参照してください。
税金、返金、書類
決済には、コードだけでは解決できない義務が伴います。これは税務上のアドバイスではありません。会計士に確認してください。
- 売上税、VAT、GST。 ご自身と顧客がどこにいるかによって、登録し、税を課し、申告する必要がある場合があります。Stripe Taxは、チェックアウト時に税額を計算して徴収し、売上が納税義務を生じさせる可能性のある場所を監視し、登録や申告を支援できます。ただし、責任はご自身に残ります。マーチャント・オブ・レコードの決済サービスは、これらをより多く引き受ける代替手段です。
- 返金と紛争。 公開前に返金ポリシーを決め、サイトに掲載してください。紛争(チャージバック)は起こり得るため、何が購入され、何が届けられたかの記録を残してください。
- 領収書と請求書。 Stripeは領収書をメールで送れます。ただし、事業者にはきちんとした請求書が必要な場合があります。
- 手数料。 どの決済サービスも、取引ごとに手数料がかかります。記事に書かれた数字を信用するのではなく、各プロバイダーの最新の料金ページを確認してください。
アプリに合った構成
- 寄付や数種類の商品だけ: Payment Links。寄付サイトの作り方も参照してください。
- カートのあるストア: 明細項目を持つCheckoutとWebhook。オンラインストアの作り方を参照してください。
- SaaSや会員制: サブスクリプションモードのCheckout、Webhook、カスタマーポータル。SaaS MVPの作り方とSaaS製品の価格設定方法を参照してください。
- 販売者に支払いを分配するマーケットプレイス: 別の、より厳格な規制を伴う構成(Stripe Connectなど)が必要です。これは別途計画してください。
Mythexでの決済の追加
Mythexで構築したアプリの決済は、ご自身のStripeアカウントとキーを使います。アプリ向けに「Stripeに接続」をワンクリックで行う機能はありません。一般的な流れは次のとおりです。
- Stripeのテストキーを取得します。
STRIPE_SECRET_KEY(Webhookシークレットは後で)を、プロジェクトのシークレットに追加します。/secrets、プロジェクトの設定、またはエージェントがキーを必要とした際に表示されるシークレットのカードから追加できます。- 上記のようなプロンプトで、エージェントにCheckoutの追加を依頼します。
- プレビューでテスト用カードを使ってテストします。Webhookにはあなたのアプリの公開URLが必要なので、Webhookを登録する前に公開してください。
- 本番キーに切り替えた後、本番のアプリが新しいキーを読み込めるように、もう一度公開してください。
ドキュメントのStripeで決済を受け付けると、バックエンドでWebhookを処理するも参照してください。
よくある質問
アプリで決済を受け付ける最も簡単な方法は何ですか?
Stripe Payment Linkを使うのが最も簡単で、コードは不要です。Stripeダッシュボードでリンクを作成し、アプリからそのリンクへ移動できるようにします。アプリが誰が支払ったかを知り、何かを自動で解除する必要がある場合は、Webhookと組み合わせたStripe Checkoutを使ってください。
決済を受け付けるにはWebhookが必要ですか?
アプリが支払いに反応する必要がある場合は、必要です。例えば、アカウントを解除する、注文を支払い済みにする、更新を処理する、といったケースです。Stripeのドキュメントでは、顧客が支払いを済ませても完了ページに到達しないことがあるため、完了ページだけに頼るべきではないとされています。また、サブスクリプションにはWebhookが必須です。
実際のお金を使わずに決済をテストするには、どうすればよいですか?
Stripeのサンドボックス(テスト)用APIキーと、テスト用のカード番号を使ってください。例えば、有効期限が未来の日付で、CVCが任意の3桁の番号であれば、4242 4242 4242 4242 を使えます。テスト取引では実際のお金は動きません。
Stripeは売上税や付加価値税(VAT)を代わりに処理してくれますか?
Stripe Taxは、チェックアウト時に税額を計算して徴収し、登録が必要になる可能性がある地域を監視できます。ただし、税務上の責任は引き続きご自身にあります。ご自身の状況については、会計士に確認してください。