3. Stripe決済
Stripeアカウントの作成とAPIキーの取得
Stripeの公式サイト でアカウントを作成し、
「開発者」 → 「APIキー」 から 公開可能キー(pk_) と 秘密キー(sk_) を取得します
.env.local
STRIPE_PUBLIC_KEY=pk_test_XXXXXXXXXXXXXXXXXXXXXXXX
STRIPE_SECRET_KEY=sk_test_XXXXXXXXXXXXXXXXXXXXXXXX
NEXT_PUBLIC_STRIPE_PUBLIC_KEY=pk_test_XXXXXXXXXXXXXXXXXXXXXXXX
APIキーを記述します(NEXT_PUBLIC_STRIPE_PUBLIC_KEY はクライアント側で使うため NEXT_PUBLIC_ を付けています?)
ライブラリのインストール
npm install stripe @stripe/stripe-js <--- stripeはサーバー側(API)で使います
<--- @stripe/stripe-jsはクライアント側(決済ページ)で使います
pages/api/checkout.ts
import { NextApiRequest, NextApiResponse } from "next";
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { <--- .env.localの値を参照
apiVersion: "2023-10-16", <--- 使用するStripe APIのバージョンを指定します
});
export default async function handler(req: NextApiRequest, res: NextApiResponse) { <--- apiのreqとres
if (req.method !== "POST") {
return res.status(405).json({ error: "Method not allowed"});
}
try {
const { items } = req.body;
const session = await stripe.checkout.sessions.create({ <--- stripeのcheckoutセッションを作成
payment_method_types: ["card"], <--- 決済方法はカード決済のみ
line_items: items.map((item: any) => ({ <--- 商品情報
price_data: {
currency: "jpy",
product_data: { name: item.name },
unit_amount: item.price * 100, <--- 商品の単価を整数で指定(日本円は100倍します)
},
quantity: item.quantity,
})),
mode: "payment", <--- 支払いモード(Not受け取りモード)
succes_url: `${req.headers.origin}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${req.headers.origin}/cancel`, <--- 支払いが成功・失敗したときのリダイレクトURL
});
res.json({ id: session.id });
} catch (error) {
res.status(500).json({ error: "failed to create checkout session"});
}
}
stripeとnext.jsをつなぐAPIをつくります
components/CheckoutButton.tsx
import { loadStripe } from "@stripe/stripe-js";
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY!);
export default function CheckoutButton({ items }: { items: any[] }) {
const handleCheckout = async() => {
const res = await fetch("/api/checkout", { <--- pages/api/checkout.tsに商品情報を渡します
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ items }),
});
const { id } = await res.json();
const stripe = await stripePromise;
stripe?.redirectToCheckout({ sessionId: id });
};
return <button onClick={handleCheckout}>購入する</button>
}
カートの商品をStripe Checkoutに送信するボタンです
pages/success.tsx
import { useRouter } from "next/router";
export default function Success() {
const router = useRouter();
const sessionId = router.query.session_id;
return (
<div>
<h1>決済完了</h1>
<p>注文ID: {sessionId}</p>
<button onClick={() => router.push('/')}>ホームに戻る</button>
</div>
);
}
決済完了ページです
流れ
pages/index.tsxで商品リストを作成します→カートに商品を追加→CheckoutButtonを使って購入→Stripeの決済画面に遷移→決済完了後pages/success.tsxにリダイレクト
BACK