こんばんは。
今日は「Next.js 14 で Stripe サブスクリプションを実装する方法」について説明します。
Next.js 14 で Stripe サブスクリプションを実装する方法について、フロントエンドとバックエンドの両方で必要な手順とコード例を以下に示します。フロントエンドでは、カード番号、CVC、有効期限、および顧客名を含む支払いフォームを作成し、バックエンドでは Next.js API を使用して Stripe サブスクリプションを管理します。
必要なパッケージのインストールと環境変数の設定
パッケージのインストール
まず、Stripe の公式ライブラリと必要なパッケージをインストールします。
npm install @stripe/stripe-js @stripe/react-stripe-js stripe
-
@stripe/stripe-js
と@stripe/react-stripe-js
: フロントエンドで Stripe Elements を使用するためのライブラリ。 -
stripe
: バックエンドで Stripe API を操作するためのライブラリ。
環境変数の設定
プロジェクトのルートに .env.local ファイルを作成し、以下の環境変数を設定します。
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=your_publishable_key_here
STRIPE_SECRET_KEY=your_secret_key_here
-
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
: フロントエンドで使用する公開可能キー。 -
STRIPE_SECRET_KEY
: バックエンドで使用する秘密キー。
実装
フロントエンドの実装
フロントエンドでは、Stripe Elements を使用して安全な支払いフォームを作成します。
Stripe プロバイダーの設定
_app.js または _app.tsx ファイルで Elements プロバイダーを設定します。
// pages/_app.js
import { Elements } from '@stripe/react-stripe-js';
import { loadStripe } from '@stripe/stripe-js';
import '../styles/globals.css';
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);
function MyApp({ Component, pageProps }) {
return (
<Elements stripe={stripePromise}>
<Component {...pageProps} />
</Elements>
);
}
export default MyApp;
支払いフォームの作成
pages/subscribe.js
ファイルを作成し、支払いフォームを実装します。
// pages/subscribe.js
import { useState } from 'react';
import {
CardCvcElement,
CardExpiryElement,
CardNumberElement,
useElements,
useStripe,
} from '@stripe/react-stripe-js'
const Subscribe = () => {
const stripe = useStripe();
const elements = useElements();
const [customerName, setCustomerName] = useState('');
const [email, setEmail] = useState('');
const [subscriptionStatus, setSubscriptionStatus] = useState(null);
const [error, setError] = useState(null);
const handleSubmit = async (e) => {
e.preventDefault();
if (!stripe || !elements) {
return;
}
const cardNumberElement = elements.getElement(CardNumberElement)
const cardExpiryElement = elements.getElement(CardExpiryElement)
const cardCvcElement = elements.getElement(CardCvcElement)
if (!cardNumberElement || !cardExpiryElement || !cardCvcElement) {
console.error('Stripe Elements not found')
return
}
try {
const { error, paymentMethod } = await stripe.createPaymentMethod({
type: 'card',
card: cardNumberElement,
billing_details: {
name: cardholderName, // Pass the cardholder name here
},
})
if (error) return
// 顧客情報と支払い情報をバックエンドに送信
const response = await fetch('/api/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: customerName,
email: email,
paymentMethodId: paymentMethod.id,
}),
});
const result = await response.json();
if (result.error) {
setError(result.error);
} else {
setSubscriptionStatus(result.status);
}
} catch (e) {
console.error(e)
}
};
return (
<div>
<h1>サブスクリプション登録</h1>
<form onSubmit={handleSubmit}>
<div>
<label>名前</label>
<input
type="text"
value={customerName}
onChange={(e) => setCustomerName(e.target.value)}
required
/>
</div>
<div>
<label>メールアドレス</label>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
</div>
<div>
<label>カード情報</label>
<CardNumberElement />
</div>
<div>
<label>有効期限</label>
<CardExpiryElement />
</div>
<div>
<label>セキュリティコード</label>
<CardCvcElement />
</div>
<button type="submit" disabled={!stripe}>
購入
</button>
</form>
{subscriptionStatus && <p>サブスクリプションが正常に作成されました!</p>}
{error && <p style={{ color: 'red' }}>{error}</p>}
</div>
);
};
export default Subscribe;
フォーム送信時にバックエンド API /api/subscribe に顧客情報と支払い情報を送信します。
バックエンドの実装
Next.js の API Routes を使用して、サブスクリプションの作成を処理します。
Stripe インスタンスの設定
lib/stripe.js
ファイルを作成し、Stripe インスタンスを設定します。
// lib/stripe.js
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: '2022-11-15',
});
export default stripe;
サブスクリプション API の作成
pages/api/subscribe.js ファイルを作成し、サブスクリプションの作成を処理します。
// pages/api/subscribe.js
import stripe from '../../lib/stripe';
export default async function handler(req, res) {
if (req.method === 'POST') {
const { name, email, paymentMethodId } = req.body;
try {
// 顧客の作成
const customer = await stripe.customers.create({
name: name,
email: email,
payment_method: paymentMethodId,
invoice_settings: {
default_payment_method: paymentMethodId,
},
});
// サブスクリプションの作成
const subscription = await stripe.subscriptions.create({
customer: customer.id,
items: [{ price: PRICE_ID }], // 事前にStripeダッシュボードで作成した価格IDに置き換えてください
expand: ['latest_invoice.payment_intent'],
});
res.status(200).json({ status: subscription.status });
} catch (error) {
res.status(400).json({ error: error.message });
}
} else {
res.setHeader('Allow', 'POST');
res.status(405).end('Method Not Allowed');
}
}
- サブスクリプションの作成: 作成した顧客に対してサブスクリプションを作成します。PRICE_ID(price_XXXXXXXXXX) は事前に Stripe ダッシュボードで設定した価格 ID に置き換えてください。
- エラーハンドリング: エラーが発生した場合、クライアントにエラーメッセージを返します。
以上が Next.js 14 で Stripe サブスクリプションを実装する基本的な手順とコード例です。詳細なカスタマイズや高度な機能については、Stripe の公式ドキュメントを参照してください。
追加の考慮事項
- セキュリティ: 支払い情報は Stripe Elements を使用して安全に処理されますが、常に最新のセキュリティベストプラクティスに従ってください。
- エラーハンドリング: フロントエンドとバックエンドの両方で適切なエラーハンドリングを実装し、ユーザーにわかりやすいフィードバックを提供してください。
- サブスクリプション管理: ユーザーがサブスクリプションを管理(キャンセル、更新など)できるように、追加の機能を実装することを検討してください。
今日は以上です。
ありがとうございました。
よろしくお願いいたします。