Use Cases

Claude CodeでStripe Checkout決済を実装する方法

Claude Codeを活用したStripe Checkoutの実装ガイド。セッション作成、Webhook処理、サブスクリプション管理まで実践的なコード例で解説します。

Stripe Checkout実装をClaude Codeで効率化する

Stripe Checkoutはホスト型の決済UIで、PCI DSS準拠の手間を最小限に抑えながら安全な決済を実装できます。Claude Codeを使えば、複雑な決済フローの構築もスムーズに進められます。

Checkout セッションの作成

> Stripe Checkoutセッションを作成するAPIを実装して。
> 単品購入とサブスクリプション両方に対応して。
// src/api/checkout.ts
import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
  apiVersion: '2024-12-18.acacia',
});

// 単品購入のCheckoutセッション
export async function createCheckoutSession(
  priceId: string,
  customerId?: string
) {
  const session = await stripe.checkout.sessions.create({
    mode: 'payment',
    payment_method_types: ['card'],
    customer: customerId,
    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`,
    metadata: {
      source: 'web',
    },
  });

  return session;
}

// サブスクリプションのCheckoutセッション
export async function createSubscriptionSession(
  priceId: string,
  customerId?: string
) {
  const session = await stripe.checkout.sessions.create({
    mode: 'subscription',
    payment_method_types: ['card'],
    customer: customerId,
    line_items: [
      {
        price: priceId,
        quantity: 1,
      },
    ],
    subscription_data: {
      trial_period_days: 14,
      metadata: { plan: 'pro' },
    },
    success_url: `${process.env.APP_URL}/dashboard?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${process.env.APP_URL}/pricing`,
  });

  return session;
}

Webhook処理

> StripeのWebhookを処理するエンドポイントを実装して。
> 署名検証と主要なイベントハンドリングをして。
// src/api/webhook.ts
import Stripe from 'stripe';

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
const webhookSecret = process.env.STRIPE_WEBHOOK_SECRET!;

export async function handleWebhook(
  body: string | Buffer,
  signature: string
) {
  let event: Stripe.Event;

  try {
    event = stripe.webhooks.constructEvent(body, signature, webhookSecret);
  } catch (err) {
    throw new Error(`Webhook signature verification failed`);
  }

  switch (event.type) {
    case 'checkout.session.completed': {
      const session = event.data.object as Stripe.Checkout.Session;
      await handleCheckoutComplete(session);
      break;
    }
    case 'invoice.payment_succeeded': {
      const invoice = event.data.object as Stripe.Invoice;
      await handlePaymentSucceeded(invoice);
      break;
    }
    case 'customer.subscription.deleted': {
      const subscription = event.data.object as Stripe.Subscription;
      await handleSubscriptionCanceled(subscription);
      break;
    }
    default:
      console.log(`Unhandled event type: ${event.type}`);
  }

  return { received: true };
}

async function handleCheckoutComplete(session: Stripe.Checkout.Session) {
  const customerId = session.customer as string;
  const customerEmail = session.customer_details?.email;
  // DBにユーザー情報を保存、メール送信など
  console.log(`Checkout completed for ${customerEmail}`);
}

async function handlePaymentSucceeded(invoice: Stripe.Invoice) {
  // サブスクリプションの更新処理
  console.log(`Payment succeeded: ${invoice.id}`);
}

async function handleSubscriptionCanceled(subscription: Stripe.Subscription) {
  // アクセス権の無効化処理
  console.log(`Subscription canceled: ${subscription.id}`);
}

フロントエンドの実装

> Next.jsで価格表ページとCheckoutボタンを作って。
// app/pricing/page.tsx
'use client';

import { useState } from 'react';

const plans = [
  { name: 'Basic', price: '¥980/月', priceId: 'price_basic_monthly' },
  { name: 'Pro', price: '¥2,980/月', priceId: 'price_pro_monthly' },
  { name: 'Enterprise', price: '¥9,800/月', priceId: 'price_enterprise_monthly' },
];

export default function PricingPage() {
  const [loading, setLoading] = useState<string | null>(null);

  const handleCheckout = async (priceId: string) => {
    setLoading(priceId);
    try {
      const res = await fetch('/api/checkout', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ priceId }),
      });
      const { url } = await res.json();
      window.location.href = url;
    } catch (error) {
      console.error('Checkout error:', error);
    } finally {
      setLoading(null);
    }
  };

  return (
    <div className="grid grid-cols-3 gap-6 max-w-4xl mx-auto p-8">
      {plans.map((plan) => (
        <div key={plan.priceId} className="border rounded-lg p-6 text-center">
          <h3 className="text-xl font-bold">{plan.name}</h3>
          <p className="text-3xl font-bold my-4">{plan.price}</p>
          <button
            onClick={() => handleCheckout(plan.priceId)}
            disabled={loading === plan.priceId}
            className="bg-indigo-600 text-white px-6 py-2 rounded-lg"
          >
            {loading === plan.priceId ? '処理中...' : '購入する'}
          </button>
        </div>
      ))}
    </div>
  );
}

まとめ

Stripe Checkoutを使えば、安全で高品質な決済体験を素早く構築できます。Claude Codeを活用すれば、WebhookやサブスクリプションなどのStripe固有の実装パターンも効率的に進められます。決済統合の基本Webhook実装ガイドも参考にしてください。

Stripeの詳細はStripe公式ドキュメントを参照してください。

#Claude Code #Stripe #決済 #Checkout #サブスクリプション