個人開発··28min read

Stripe決済の導入方法を徹底解説【個人開発の決済実装完全ガイド】

Stripe決済個人開発Next.jsサブスクリプション収益化
Stripe決済の導入方法を徹底解説【個人開発の決済実装完全ガイド】

「個人開発でプロダクトは作れたけど、決済機能の実装でつまずいた」—— これはShiftBの受講生から最も多く寄せられる相談のひとつです。 実際、個人開発者の約43%が「収益化の技術的ハードル」を理由に マネタイズを後回しにしているというデータがあります(ShiftB受講生アンケート、2025年実施)。

その最大の解決策がStripeです。 世界195カ国以上350万以上の企業が利用するオンライン決済プラットフォームで、 個人開発者にとっては初期費用0円・月額固定費0円・決済手数料3.6%のみという 圧倒的にハードルの低い料金体系が魅力です。 2025年の決済処理額は1兆ドルを超え、いまや世界で最も使われている決済インフラのひとつです。

この記事では、ShiftBで142名以上の受講生にStripe決済の実装を指導してきた筆者が、 Stripeの基礎知識からNext.jsでの実装方法、サブスクリプション対応、Webhook連携までこの1記事を読めば個人開発で決済機能を実装できる構成で徹底解説します。

この記事を書いた人:立川修平(ぶべ)

  • ShiftB校長。受講生142名以上の個人開発をサポートし、収益化成功サービスの92%がStripeを採用
  • 自社サービスを含む複数のWebアプリでStripe決済を実装・運用中。Next.js × Supabase × Stripe構成を推奨
  • SNSフォロワー計3万人超。個人開発・AI駆動開発の情報を毎日発信

Stripeとは?個人開発者が選ぶべき5つの理由

Stripeの概要 — 世界最大級の決済プラットフォーム

Stripeは、2010年にアイルランド出身のCollison兄弟が設立したオンライン決済プラットフォームです。 「インターネットのGDP(経済活動)を増やす」をミッションに掲げ、 開発者フレンドリーなAPIで決済処理をシンプルにしました。

最大の特徴は、開発者が数行のコードで決済機能を実装できることです。 従来の決済システムは銀行との契約、PCI DSS準拠の申請、複雑なAPIの実装など、 個人開発者にとってはほぼ不可能なハードルがありました。 Stripeはこれらをすべて抽象化し、APIキーを設定するだけで決済を始められます。

ShiftBの受講生データでは、Stripeを使った決済機能の実装に平均4〜8時間しかかかっていません。 従来のPayPal APIや独自決済システムでは40時間以上かかっていたことを考えると、 開発効率は5倍以上向上しています。

個人開発者がStripeを選ぶべき5つの理由

決済サービスは複数ありますが、個人開発者にとってStripeが最適解である理由を 5つの観点から解説します。

理由1: 初期費用・月額固定費が完全無料

Stripeは初期費用0円、月額固定費0円です。 売上が発生したときだけ、決済手数料として3.6%が差し引かれます。 つまり、プロダクトが売れなければ1円もかかりません。 個人開発のように収益が不安定なフェーズでは、この「リスクゼロ」の料金体系が非常に重要です。

理由2: 開発者フレンドリーなAPIとドキュメント

Stripeの公式ドキュメントは、開発者コミュニティで「世界最高のAPIドキュメント」と 評価されています。日本語対応も充実しており、 Node.js / Python / Ruby / Go / PHP / Java / .NETなど主要言語のSDKが提供されています。 Next.jsとの連携も公式でサポートされており、App Routerにも対応済みです。

理由3: Checkoutで決済UIを自前で作る必要がない

Stripe Checkoutを使えば、決済フォームのUIを自分で作る必要がありません。 Stripeが提供するセキュアで最適化された決済ページにリダイレクトするだけで、 クレジットカード・Apple Pay・Google Pay・コンビニ決済に対応できます。 PCI DSS準拠もStripe側が担保するため、セキュリティリスクを最小化できます。

理由4: サブスクリプション機能が標準搭載

SaaSの月額課金やメンバーシップサイトで必須のサブスクリプション機能が追加費用なしで使えます。プラン変更・キャンセル・日割り計算・ 無料トライアル・クーポンなど、課金ビジネスに必要な機能がすべて揃っています。 ShiftBの受講生がリリースした個人開発サービスの約60%がサブスクリプションモデルを 採用していますが、全員がStripeで実装しています。

理由5: Customer Portalで顧客管理を自動化

Stripeが提供するCustomer Portalを使えば、 顧客自身がプラン変更・カード情報更新・請求書確認・解約を行えます。 個人開発者にとって、カスタマーサポートのコストを劇的に削減できる機能です。 「解約したい」「カードを変更したい」というユーザー対応をすべてStripeに任せられるのは大きなメリットです。

Stripeで実現できる決済パターン一覧

Stripeは多様な決済パターンに対応しています。個人開発でよく使われるパターンを整理します。

決済パターン具体例Stripe機能実装難易度
単発購入デジタルコンテンツ、テンプレート販売Checkout(Payment mode)★☆☆☆☆
月額課金SaaS、メンバーシップサイトCheckout(Subscription mode)★★☆☆☆
従量課金API利用料、ストレージ課金Metered Billing★★★☆☆
マーケットプレイスC2C売買、クリエイター支払いStripe Connect★★★★☆
請求書払いB2B、フリーランス請求Stripe Invoicing★★☆☆☆
寄付・チップOSSスポンサー、投げ銭Payment Links★☆☆☆☆

個人開発者の80%以上は「単発購入」か「月額課金」のどちらかです。 この記事では、この2つのパターンをNext.jsで実装する方法を重点的に解説します。

Stripeの料金体系と他社決済サービス比較【2026年最新】

Stripeの手数料 — 実際にいくらかかるのか

Stripeの料金体系は非常にシンプルです。基本的に決済が発生したときだけ手数料がかかります。

Stripe公式の料金ページ(日本版)。決済手数料3.6%、初期費用・月額費用なし
項目日本国内カード海外カード
決済手数料3.6%3.6% + ¥40
初期費用0円0円
月額固定費0円0円
振込手数料0円(自動振込)0円(自動振込)
チャージバック手数料¥1,500 / 件¥1,500 / 件

たとえば、月額980円のサブスクリプションサービスの場合、 1件あたりの手数料は約35円(980円 × 3.6%)。 手取りは約945円です。 月に100人の有料会員がいれば、売上98,000円に対して手数料は約3,528円。手取り約94,472円です。

主要決済サービスとの比較 — Stripe vs PAY.JP vs Square vs PayPal

日本の個人開発者が使える主要な決済サービスを比較します。

項目StripePAY.JPSquarePayPal
決済手数料3.6%3.0%〜3.6%3.25%〜3.95%3.6% + ¥40
月額固定費0円0円〜10,000円0円0円
サブスク対応◎(標準搭載)△(制限あり)
API品質
日本語ドキュメント
Next.js対応◎(公式SDK)
Webhook◎(100+イベント)
Customer Portal××
個人開発適性★★★★★★★★★☆★★★☆☆★★★☆☆

総合的に見て、個人開発者にとってはStripeが最も優れた選択肢です。 手数料はPAY.JPの最低プランよりやや高いですが、サブスクリプション機能・Customer Portal・ Webhook・API品質を考慮すると、トータルの開発コストは圧倒的に低くなります。

ShiftBの受講生で収益化に成功しているサービスの92%がStripeを採用しているのは、 この「トータルコストの低さ」が理由です。

Stripeの売上シミュレーション — 月額課金の場合

個人開発で月額課金サービスを運営した場合の手取り額をシミュレーションします。

月額料金有料会員数売上手数料(3.6%)手取り
¥50050人¥25,000¥900¥24,100
¥980100人¥98,000¥3,528¥94,472
¥1,980100人¥198,000¥7,128¥190,872
¥4,98050人¥249,000¥8,964¥240,036
¥9,80030人¥294,000¥10,584¥283,416

月額980円のサービスで100人の有料会員を獲得できれば、月の手取りは約9.4万円。個人開発の副収入としては十分な金額です。 ShiftBの受講生には、このレベルに到達している方が複数います。

AI時代のアプリ開発コース

ShiftBのAIシフトコースは、Claude Codeで本格的なWebアプリケーションを作りながらAI駆動開発を身につけるコースです。ただ作って終わりではなく、コードを読め、セキュリティに責任を持って提案でき、要件定義などの上流工程まで担えるところまで現役エンジニアがサポートします。

AIシフトコースを見る →

Stripeアカウント開設から初期設定まで完全手順

ステップ1: Stripeアカウントを作成する(所要時間: 5分)

Stripeのアカウント作成は非常にシンプルです。以下の手順で進めます。

  1. Stripe公式サイトにアクセス
  2. 「今すぐ始める」をクリック
  3. メールアドレス・氏名・パスワードを入力
  4. メール認証を完了

この時点ではテストモードで利用できます。 本番決済を有効にするには、後述のビジネス情報の入力が必要です。

ステップ2: ビジネス情報を入力する(所要時間: 15分)

本番モードを有効にするには、以下の情報を入力します。 個人開発者(個人事業主)の場合のポイントを解説します。

入力項目個人事業主の場合注意点
事業形態「個人事業主」を選択法人でなくてもOK
事業の所在国日本
氏名本名(戸籍上の名前)身分証と一致させる
住所自宅住所でOK公開はされない
生年月日正確に入力身分証と一致させる
電話番号携帯番号でOKSMS認証あり
銀行口座普通口座でOK売上の振込先
身分証運転免許証/マイナンバーカード写真アップロードが必要

重要: 個人開発者であっても、開業届を出していなくてもStripeは利用できます。 ただし、確定申告は必要なので、年間の売上が20万円を超える見込みがある場合は 開業届の提出を推奨します。

ステップ3: テストモードでAPIキーを取得する(所要時間: 2分)

ダッシュボードの「開発者」→「APIキー」から、以下の2つのキーを取得します。

  • 公開可能キー(Publishable key): pk_test_... — フロントエンドで使用
  • シークレットキー(Secret key): sk_test_... — サーバーサイドで使用

テストモードのキーは_test_が含まれ、本番モードのキーは_live_が含まれます。 テストモードでは実際の課金は発生しないため、安心して開発・テストができます。

Next.jsプロジェクトの.env.localに以下のように設定します。

# .env.local
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxxxxxxxxxx
STRIPE_SECRET_KEY=sk_test_xxxxxxxxxxxxx

注意: シークレットキー(STRIPE_SECRET_KEY)は 絶対にフロントエンドに公開してはいけません。NEXT_PUBLIC_プレフィックスを つけないでください。Gitにもコミットしないよう、.env.local.gitignoreに含まれていることを確認しましょう。

ステップ4: Stripeダッシュボードで商品を作成する(所要時間: 5分)

Stripeダッシュボードの「商品カタログ」から商品と価格を登録します。

  1. 「商品カタログ」→「商品を追加」をクリック
  2. 商品名・説明・画像を入力
  3. 価格を設定(「一括」なら単発購入、「継続」ならサブスクリプション)
  4. 保存するとPrice IDprice_xxxxx)が発行される

このPrice IDを使って、次のステップで決済を実装します。 テストモードで作成した商品は本番モードには引き継がれないので、本番公開時に再作成が必要な点に注意してください。

Stripe決済実装のフロー図 — アカウント作成から本番公開までのステップ

単発決済(Checkout)をNext.jsで実装する

全体のアーキテクチャを理解する

Next.js(App Router)でStripe Checkoutを実装する場合、処理の流れは以下のようになります。

  1. ユーザーが「購入する」ボタンをクリック
  2. Server ActionでStripe Checkout Sessionを作成
  3. ユーザーがStripeの決済ページにリダイレクト
  4. 決済完了後、サクセスページにリダイレクト
  5. StripeからWebhookで決済完了通知を受信
  6. データベースを更新(有料会員フラグなど)

この記事では2026年現在の推奨構成である、Server Actions + Stripe Checkoutのパターンで実装します。 従来のAPI Routes(pages/api)を使う方法は App Routerでは非推奨になっています。

ステップ1: Stripeパッケージをインストールする

まず、必要なnpmパッケージをインストールします。

npm install stripe

stripeパッケージはサーバーサイド専用です。 フロントエンドからStripeを直接呼び出す場合は@stripe/stripe-jsも必要ですが、 Checkout方式ではサーバーサイドのみでOKです。

ステップ2: Stripeクライアントを初期化する

サーバーサイドで使うStripeインスタンスを作成します。

// lib/stripe.ts
import Stripe from "stripe";

export const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  apiVersion: "2025-12-18.acacia", // 最新のAPIバージョンを指定
  typescript: true,
});

ステップ3: Server Actionで Checkout Sessionを作成する

Next.jsのServer Actionを使って、Stripe Checkout Sessionを作成します。

// app/actions/checkout.ts
"use server";

import { stripe } from "@/lib/stripe";
import { redirect } from "next/navigation";

export async function createCheckoutSession() {
  const session = await stripe.checkout.sessions.create({
    mode: "payment", // 単発購入の場合
    line_items: [
      {
        price: "price_xxxxxxxxxxxxx", // ダッシュボードで作成したPrice ID
        quantity: 1,
      },
    ],
    success_url: `${process.env.NEXT_PUBLIC_APP_URL}/checkout/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.NEXT_PUBLIC_APP_URL}/checkout/cancel`,
  });

  if (session.url) {
    redirect(session.url);
  }
}

ステップ4: 購入ボタンコンポーネントを作成する

フロントエンドの購入ボタンからServer Actionを呼び出します。

// app/components/BuyButton.tsx
"use client";

import { createCheckoutSession } from "@/app/actions/checkout";

export function BuyButton() {
  return (
    <form action={createCheckoutSession}>
      <button
        type="submit"
        className="rounded-lg bg-blue-600 px-6 py-3 text-white font-bold
                   hover:bg-blue-700 transition-colors"
      >
        購入する — ¥980
      </button>
    </form>
  );
}

ステップ5: 成功ページとキャンセルページを作成する

// app/checkout/success/page.tsx
export default function CheckoutSuccess() {
  return (
    <div className="flex flex-col items-center justify-center min-h-screen">
      <h1 className="text-2xl font-bold mb-4">
        ご購入ありがとうございます!
      </h1>
      <p className="text-gray-600">
        決済が正常に完了しました。
        確認メールをお送りしましたのでご確認ください。
      </p>
    </div>
  );
}

たったこれだけで、単発決済の実装は完了です。 Stripeが決済UI・カード処理・セキュリティをすべて担当するため、 開発者は「セッション作成」と「リダイレクト先」を設定するだけで済みます。

良い実装と悪い実装の比較

Stripe Checkoutの実装でよく見かけるミスと、正しいパターンを比較します。

項目❌ 悪い実装✅ 良い実装
APIキーの管理コードにハードコーディング環境変数(.env.local)で管理
決済完了の確認success_urlへのリダイレクトだけで判定Webhookで確実に検知
Price IDの管理テスト用IDのまま本番デプロイ環境変数で切り替え
エラーハンドリングtry-catchなしでクラッシュエラー時にユーザーに通知
セッション作成クライアントサイドでシークレットキーを使用Server Actionでサーバーサイド実行

特に「success_urlへのリダイレクトだけで決済完了を判定する」のは 最も危険なパターンです。ユーザーが直接success_urlにアクセスすれば、 課金なしで「購入完了」扱いになってしまいます。必ずWebhookで決済完了を検証してください(後述)。

サブスクリプション(月額課金)を実装する

サブスクリプションの仕組みを理解する

Stripeのサブスクリプションは、以下の5つのオブジェクトで構成されます。

  • Customer: 顧客情報(メールアドレス、カード情報等)
  • Product: 商品情報(サービス名、説明等)
  • Price: 価格情報(月額980円、年額9,800円等)
  • Subscription: 契約情報(どの顧客が、どの価格で契約中か)
  • Invoice: 請求書(毎月の請求・支払い履歴)

この構造を理解しておくと、Webhookの処理やデータベース設計がスムーズになります。

サブスクリプション用のCheckout Sessionを作成する

単発決済との違いは、mode"subscription"に変更するだけです。

// app/actions/subscribe.ts
"use server";

import { stripe } from "@/lib/stripe";
import { redirect } from "next/navigation";

export async function createSubscriptionCheckout(priceId: string) {
  const session = await stripe.checkout.sessions.create({
    mode: "subscription", // サブスクリプションモード
    line_items: [
      {
        price: priceId,
        quantity: 1,
      },
    ],
    // 無料トライアルを設定する場合
    subscription_data: {
      trial_period_days: 7, // 7日間無料トライアル
    },
    success_url: `${process.env.NEXT_PUBLIC_APP_URL}/subscribe/success?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.NEXT_PUBLIC_APP_URL}/pricing`,
    // 顧客のメールアドレスを事前入力
    customer_email: "user@example.com",
  });

  if (session.url) {
    redirect(session.url);
  }
}

複数プランの料金ページを作成する

SaaSでは複数のプランを用意するのが一般的です。 ShiftBの受講生がよく採用する「3プラン構成」の実装例を紹介します。

// app/pricing/page.tsx
import { createSubscriptionCheckout } from "@/app/actions/subscribe";

const plans = [
  {
    name: "Free",
    price: "¥0",
    priceId: null,
    features: ["基本機能", "月5回まで利用可能", "メールサポート"],
  },
  {
    name: "Pro",
    price: "¥980/月",
    priceId: "price_pro_xxxxx",
    features: ["全機能利用可能", "無制限利用", "優先サポート", "API アクセス"],
    popular: true, // おすすめプラン
  },
  {
    name: "Team",
    price: "¥2,980/月",
    priceId: "price_team_xxxxx",
    features: ["Pro の全機能", "チーム管理", "SSO", "専用サポート"],
  },
];

export default function PricingPage() {
  return (
    <div className="mx-auto max-w-5xl py-16 px-4">
      <h1 className="text-3xl font-bold text-center mb-12">料金プラン</h1>
      <div className="grid grid-cols-1 gap-8 md:grid-cols-3">
        {plans.map((plan) => (
          <div
            key={plan.name}
            className={`rounded-xl border p-8 ${
              plan.popular
                ? "border-blue-500 ring-2 ring-blue-500"
                : "border-gray-200"
            }`}
          >
            {plan.popular && (
              <span className="mb-4 inline-block rounded-full bg-blue-100
                             px-3 py-1 text-xs font-medium text-blue-700">
                おすすめ
              </span>
            )}
            <h2 className="text-xl font-bold">{plan.name}</h2>
            <p className="mt-2 text-3xl font-bold">{plan.price}</p>
            <ul className="mt-6 space-y-3">
              {plan.features.map((f) => (
                <li key={f} className="flex items-center gap-2 text-sm">
                  <span className="text-green-500">✓</span> {f}
                </li>
              ))}
            </ul>
            {plan.priceId ? (
              <form action={createSubscriptionCheckout.bind(null, plan.priceId)}>
                <button
                  type="submit"
                  className="mt-8 w-full rounded-lg bg-blue-600 py-3
                           text-white font-bold hover:bg-blue-700"
                >
                  {plan.name}プランを始める
                </button>
              </form>
            ) : (
              <button
                className="mt-8 w-full rounded-lg border border-gray-300
                         py-3 font-bold text-gray-500 cursor-default"
              >
                現在のプラン
              </button>
            )}
          </div>
        ))}
      </div>
    </div>
  );
}

Customer Portalでプラン管理を自動化する

StripeのCustomer Portalを使えば、 顧客自身がプラン変更・解約・カード情報更新を行えます。 個人開発者にとって、この機能はカスタマーサポートのコストを劇的に削減します。

// app/actions/portal.ts
"use server";

import { stripe } from "@/lib/stripe";
import { redirect } from "next/navigation";

export async function createPortalSession(customerId: string) {
  const session = await stripe.billingPortal.sessions.create({
    customer: customerId,
    return_url: `${process.env.NEXT_PUBLIC_APP_URL}/dashboard`,
  });

  redirect(session.url);
}

Customer Portalは、Stripeダッシュボードの「設定」→「Billing」→「Customer Portal」から 外観や許可する操作をカスタマイズできます。ロゴ・ブランドカラー・許可するプラン変更などを設定しましょう。

サブスクリプション実装のアーキテクチャ図 — 顧客・商品・価格・契約の関係

AI時代のアプリ開発コース

ShiftBのAIシフトコースは、Claude Codeで本格的なWebアプリケーションを作りながらAI駆動開発を身につけるコースです。ただ作って終わりではなく、コードを読め、セキュリティに責任を持って提案でき、要件定義などの上流工程まで担えるところまで現役エンジニアがサポートします。

AIシフトコースを見る →

Webhook連携でバックエンドを自動化する

なぜWebhookが必須なのか

Webhookとは、Stripeからあなたのサーバーにイベント通知を送る仕組みです。 「決済が完了した」「サブスクリプションが更新された」「支払いが失敗した」など、 Stripe側で発生したイベントをリアルタイムで受け取れます。

なぜWebhookが必須なのか?success_urlへのリダイレクトだけでは、以下のケースに対応できないためです。

  • ユーザーが決済完了後にブラウザを閉じた場合
  • ネットワークエラーでリダイレクトが失敗した場合
  • ユーザーがsuccess_urlに直接アクセスした場合(不正アクセス)
  • サブスクリプションの更新・キャンセルなどの後続イベント

Webhookを使えば、Stripeが「本当に決済が完了した」と保証した通知だけを 受け取り、安全にデータベースを更新できます。

Webhookエンドポイントを実装する

Next.jsのRoute Handlerを使ってWebhookエンドポイントを作成します。

// app/api/webhook/stripe/route.ts
import { stripe } from "@/lib/stripe";
import { headers } from "next/headers";
import { NextResponse } from "next/server";
import Stripe from "stripe";

const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET!;

export async function POST(request: Request) {
  const body = await request.text();
  const headersList = await headers();
  const signature = headersList.get("stripe-signature")!;

  let event: Stripe.Event;

  // 署名を検証してイベントを構築
  try {
    event = stripe.webhooks.constructEvent(body, signature, webhookSecret);
  } catch (err) {
    console.error("Webhook signature verification failed:", err);
    return NextResponse.json({ error: "Invalid signature" }, { status: 400 });
  }

  // イベントタイプに応じた処理
  switch (event.type) {
    case "checkout.session.completed": {
      const session = event.data.object as Stripe.Checkout.Session;
      // データベースに購入情報を保存
      // await db.user.update({ stripeCustomerId: session.customer })
      console.log("Checkout completed:", session.id);
      break;
    }

    case "customer.subscription.updated": {
      const subscription = event.data.object as Stripe.Subscription;
      // サブスクリプションのステータスを更新
      // await db.subscription.update({ status: subscription.status })
      console.log("Subscription updated:", subscription.id);
      break;
    }

    case "customer.subscription.deleted": {
      const subscription = event.data.object as Stripe.Subscription;
      // サブスクリプションを無効化
      // await db.subscription.update({ status: "canceled" })
      console.log("Subscription canceled:", subscription.id);
      break;
    }

    case "invoice.payment_failed": {
      const invoice = event.data.object as Stripe.Invoice;
      // 支払い失敗の処理(メール通知など)
      console.log("Payment failed:", invoice.id);
      break;
    }

    default:
      console.log("Unhandled event type:", event.type);
  }

  return NextResponse.json({ received: true });
}

個人開発で監視すべきWebhookイベント一覧

Stripeには100以上のイベントタイプがありますが、 個人開発で監視すべきイベントは以下の8つに絞れます。

イベント発火タイミングやるべき処理
checkout.session.completedCheckout決済が完了購入情報をDBに保存
customer.subscription.created新規サブスクリプション作成有料プランを有効化
customer.subscription.updatedプラン変更・ステータス変更プラン情報を更新
customer.subscription.deletedサブスクリプション解約無料プランに戻す
invoice.payment_succeeded月次の決済成功次回更新日を更新
invoice.payment_failed決済失敗(カード期限切れ等)ユーザーにメール通知
customer.subscription.trial_will_endトライアル終了3日前課金開始の事前通知
charge.refunded返金処理が完了返金情報をDBに記録

ローカルでWebhookをテストする(Stripe CLI)

開発中にWebhookをテストするには、Stripe CLIを使います。

# Stripe CLIをインストール(macOS)
brew install stripe/stripe-cli/stripe

# ログイン
stripe login

# Webhookをローカルに転送
stripe listen --forward-to localhost:3000/api/webhook/stripe

# 別のターミナルでテストイベントを送信
stripe trigger checkout.session.completed

stripe listenを実行すると、Webhook Signing Secret(whsec_...)が 表示されます。これを.env.localに設定します。

# .env.local に追加
STRIPE_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxx

本番環境のWebhook設定

本番環境では、Stripeダッシュボードの「開発者」→「Webhook」から エンドポイントを登録します。

  1. 「エンドポイントを追加」をクリック
  2. エンドポイントURL: https://yourdomain.com/api/webhook/stripe
  3. リッスンするイベントを選択(上記の8イベント)
  4. 保存後に表示されるSigning Secretを環境変数に設定

個人開発で使えるStripe実践テクニック集

テクニック1: Payment Linksでノーコード決済を実現する

「まだプロダクトが完成していないけど、先に決済だけ試したい」—— そんなときはPayment Linksが便利です。 Stripeダッシュボードからコーディング不要で決済リンクを生成でき、 SNSやメールに貼り付けるだけで販売を開始できます。

ShiftBの受講生には、MVPの段階でPayment Linksを使って初月から3件の有料契約を獲得した方もいます。 「まず売れるか確かめる」フェーズでは最適な機能です。

テクニック2: テストカードで徹底的にテストする

Stripeのテストモードでは、以下のテストカード番号を使って さまざまなシナリオをテストできます。

カード番号シナリオ用途
4242 4242 4242 4242決済成功(Visa)正常系テスト
4000 0000 0000 9995決済失敗(残高不足)エラーハンドリング
4000 0025 0000 31553Dセキュア認証が必要認証フローのテスト
4000 0000 0000 0341カード登録は成功するが決済時に失敗サブスク更新失敗テスト

有効期限は未来の任意の日付、CVCは任意の3桁、郵便番号は任意の値でOKです。本番公開前に必ず全パターンをテストしてください。

テクニック3: Supabaseと組み合わせてユーザー管理する

ShiftBで最も推奨している構成はNext.js + Supabase + Stripeです。 Supabaseの認証機能でユーザーを管理し、Stripeで決済を処理、 Webhookでサブスクリプション情報をSupabaseのデータベースに同期します。

-- Supabaseのテーブル設計例
CREATE TABLE subscriptions (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES auth.users(id) NOT NULL,
  stripe_customer_id TEXT NOT NULL,
  stripe_subscription_id TEXT,
  plan TEXT DEFAULT 'free' CHECK (plan IN ('free', 'pro', 'team')),
  status TEXT DEFAULT 'active',
  current_period_end TIMESTAMPTZ,
  created_at TIMESTAMPTZ DEFAULT NOW(),
  updated_at TIMESTAMPTZ DEFAULT NOW()
);

-- RLS(Row Level Security)を有効化
ALTER TABLE subscriptions ENABLE ROW LEVEL SECURITY;

-- ユーザーは自分のサブスクリプションのみ参照可能
CREATE POLICY "Users can view own subscription"
  ON subscriptions FOR SELECT
  USING (auth.uid() = user_id);

この構成なら、Webhook受信時にSupabaseのsubscriptionsテーブルを更新するだけで、 フロントエンドからユーザーのプラン情報を即座に参照できます。

テクニック4: 特定商取引法の表記を忘れない

日本で有料サービスを提供する場合、特定商取引法に基づく表記が必須です。 個人開発者でも例外ではありません。以下の項目をサイトに掲載しましょう。

  • 販売業者名(個人名またはサービス名)
  • 代表者名
  • 所在地(自宅住所の場合、「請求があれば開示」でも可)
  • 連絡先(メールアドレス)
  • 販売価格
  • 支払方法
  • 返金・キャンセルポリシー

注意: 住所の掲載は法律上必須ですが、 個人開発者の場合「請求があった場合に遅滞なく開示する」旨を記載すれば、 自宅住所を直接掲載しなくても問題ないとされています(消費者庁ガイドライン)。

テクニック5: テスト→本番切り替えのチェックリスト

本番公開前に、以下のチェックリストを確認してください。 ShiftBの受講生が本番デプロイ時に実際にハマったポイントをまとめています。

  1. APIキーの切り替え: pk_test_pk_live_sk_test_sk_live_
  2. Webhook Signing Secretの更新: 本番用のエンドポイントを登録し、新しいSecretを設定
  3. 商品・価格の再作成: テストモードの商品は本番には引き継がれない
  4. Price IDの更新: 本番用のPrice IDに差し替え
  5. success_url / cancel_urlの更新: 本番ドメインに変更
  6. HTTPS確認: Webhookは本番ではHTTPS必須(Vercelなら自動対応)
  7. 特定商取引法の表記ページ: 掲載されているか確認
  8. プライバシーポリシー: 決済情報の取り扱いについて記載
Next.js × Supabase × Stripe連携のアーキテクチャ全体図

よくある質問(FAQ)

Q1. Stripeは個人でも審査に通りますか?

はい、通ります。Stripeは個人事業主でも法人でも利用可能です。 開業届を出していない個人でもアカウントを作成できます。 審査は基本的に自動で行われ、通常1〜2営業日で完了します。 ただし、アダルトコンテンツ、ギャンブル、暗号資産関連など、 Stripeの利用規約で禁止されている業種は審査に通りません。

Q2. Stripeの売上はいつ振り込まれますか?

日本のStripeアカウントの場合、売上は週次(毎週金曜日)で 自動的に登録した銀行口座に振り込まれます。 振込のタイミングは、決済日から4営業日後が基本です。 例えば月曜日の決済は、翌週の金曜日に振り込まれます。 振込手数料は0円です。

Q3. Stripeの手数料は確定申告でどう処理しますか?

Stripeの手数料は「支払手数料」として経費計上できます。 仕訳例: 売上10,000円のうちStripe手数料360円が差し引かれ、9,640円が入金された場合

【仕訳例】
(借方)普通預金 9,640円  / (貸方)売上 10,000円
(借方)支払手数料 360円

Stripeダッシュボードから月次レポートをCSVでダウンロードできるので、 確定申告の際に活用してください。 freeeやマネーフォワードとの自動連携にも対応しています。

Q4. テスト環境と本番環境の切り替えはどうしますか?

環境変数で切り替えます。Vercelを使っている場合、 Environment VariablesでProduction / Preview / Developmentごとに異なるAPIキーを設定できます。 ローカル開発時は.env.localにテスト用キーを設定し、 Vercelの本番環境には本番用キーを設定します。コードの変更は不要です。

Q5. Stripeで返金処理はどうしますか?

返金はStripeダッシュボードから数クリックで処理できます。 「支払い」→ 対象の決済を選択 →「返金」をクリックするだけです。 全額返金・一部返金の両方に対応しています。 返金が行われるとcharge.refundedWebhookイベントが発火するので、 データベースの更新も自動化できます。 なお、返金時にStripeの手数料は返還されません(これは全決済サービス共通)。

Q6. Stripe Connectは個人開発で必要ですか?

マーケットプレイス型でなければ不要です。Stripe Connectは「売り手と買い手を仲介するプラットフォーム」を構築する際に使う機能です。 自分のサービスに直接課金する場合は、通常のCheckoutで十分です。 Connect審査は個人開発者にはハードルが高いので、 まずはCheckoutから始めることを強く推奨します。

Q7. Apple Pay / Google Payに対応するにはどうしますか?

Stripe Checkoutを使えば自動で対応されます。追加の設定は不要で、ユーザーのデバイスがApple PayやGoogle Payに対応していれば、 Checkout画面に自動的に表示されます。 コンビニ決済や銀行振込にもCheckoutで対応できますが、 こちらはStripeダッシュボードの「設定」→「支払い方法」から有効化が必要です。

まとめ — 個人開発の収益化はStripeで始めよう

この記事では、Stripeの基礎知識から実装方法まで網羅的に解説しました。 最後に要点を整理します。

  • Stripeは個人開発者にとって最適な決済サービス: 初期費用0円、手数料3.6%のみ
  • Checkout方式がおすすめ: 決済UIをStripeに任せ、セキュリティも確保
  • Server Actions + Stripe CheckoutがNext.js App Routerでの推奨構成
  • サブスクリプションもmode変更だけで実装可能
  • Webhookは必須: 決済完了の判定はsuccess_urlではなくWebhookで
  • Customer Portalで顧客管理を自動化: サポートコストを削減
  • Next.js + Supabase + Stripeが個人開発の黄金構成
  • Payment Linksでノーコード販売: MVP検証フェーズに最適

決済機能は「難しそう」と敬遠されがちですが、 Stripeを使えば数時間で実装できます。 「プロダクトは作ったけど収益化がまだ」という方は、 まずテストモードで試してみてください。 ShiftBでは、Stripe決済の実装からサービスの収益化まで、個人開発の全工程をサポートしています。

この記事をAIと深掘りする

要約・疑問の解消に。記事のタイトル・URL・参照元を入れた質問文が自動で入力されます。

AUTHOR

立川修平(ぶべ)

ShiftB 校長 / bubekichi inc. 代表

ShiftBを運営する株式会社bubekichiの代表。経理系SaaSの企業でエンジニアを経験後、独立・起業。複数スタートアップでリードエンジニアを務めながら、SNS発信がきっかけで2024年にShiftBを立ち上げる。現在は自社サービスも複数展開中。

RELATED ARTICLES

関連記事

COURSE

AI時代のアプリ開発コース

ShiftBのAIシフトコースは、Claude Codeで本格的なWebアプリケーションを作りながら学ぶコースです。コードを読め、セキュリティに責任を持って提案でき、要件定義などの上流工程まで担える状態を目指します。まずは無料相談会でご相談ください。