A Practical Guide to Building an E-Commerce Site with Claude Code
A practical guide to building an e-commerce site using Claude Code with real-world code examples.
ECサイト構築にClaude Codeを使う
ECサイトには商品管理、カート、決済、在庫管理、注文管理と多くの機能が必要です。Claude Codeを使えば、これらの機能を一貫した設計で効率的に構築できます。
商品データモデル
> Next.jsでECサイトを構築して。
> 商品一覧・詳細・カート・チェックアウトのページと、
> Stripe決済を統合して。在庫管理も含めて。
// src/types/product.ts
export interface Product {
id: string;
name: string;
slug: string;
description: string;
price: number;
compareAtPrice?: number;
images: string[];
category: string;
variants: ProductVariant[];
stock: number;
isActive: boolean;
}
export interface ProductVariant {
id: string;
name: string; // 例: "Mサイズ / ブルー"
sku: string;
price: number;
stock: number;
attributes: Record<string, string>;
}
export interface CartItem {
productId: string;
variantId?: string;
quantity: number;
price: number;
}
カート機能の実装
// src/stores/cart-store.ts
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface CartState {
items: CartItem[];
addItem: (item: CartItem) => void;
removeItem: (productId: string) => void;
updateQuantity: (productId: string, quantity: number) => void;
clearCart: () => void;
totalPrice: () => number;
totalItems: () => number;
}
export const useCartStore = create<CartState>()(
persist(
(set, get) => ({
items: [],
addItem: (item) =>
set((state) => {
const existing = state.items.find(
(i) => i.productId === item.productId && i.variantId === item.variantId
);
if (existing) {
return {
items: state.items.map((i) =>
i.productId === item.productId
? { ...i, quantity: i.quantity + item.quantity }
: i
),
};
}
return { items: [...state.items, item] };
}),
removeItem: (productId) =>
set((state) => ({
items: state.items.filter((i) => i.productId !== productId),
})),
updateQuantity: (productId, quantity) =>
set((state) => ({
items: state.items.map((i) =>
i.productId === productId ? { ...i, quantity } : i
),
})),
clearCart: () => set({ items: [] }),
totalPrice: () => get().items.reduce((sum, i) => sum + i.price * i.quantity, 0),
totalItems: () => get().items.reduce((sum, i) => sum + i.quantity, 0),
}),
{ name: 'cart-storage' }
)
);
チェックアウトAPI
// src/app/api/checkout/route.ts
import { NextRequest, NextResponse } from 'next/server';
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
export async function POST(request: NextRequest) {
const { items } = await request.json();
// 在庫確認
for (const item of items) {
const product = await getProduct(item.productId);
if (!product || product.stock < item.quantity) {
return NextResponse.json(
{ error: `${product?.name || '商品'}の在庫が不足しています` },
{ status: 400 }
);
}
}
const session = await stripe.checkout.sessions.create({
mode: 'payment',
payment_method_types: ['card'],
line_items: items.map((item: CartItem) => ({
price_data: {
currency: 'jpy',
product_data: { name: item.productId },
unit_amount: item.price,
},
quantity: item.quantity,
})),
success_url: `${process.env.APP_URL}/order/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${process.env.APP_URL}/cart`,
shipping_address_collection: {
allowed_countries: ['JP'],
},
});
return NextResponse.json({ url: session.url });
}
商品一覧コンポーネント
// src/components/ProductCard.tsx
import Image from 'next/image';
import Link from 'next/link';
import { Product } from '@/types/product';
export function ProductCard({ product }: { product: Product }) {
const discount = product.compareAtPrice
? Math.round((1 - product.price / product.compareAtPrice) * 100)
: 0;
return (
<Link href={`/products/${product.slug}`} className="group">
<div className="relative aspect-square overflow-hidden rounded-lg">
<Image
src={product.images[0]}
alt={product.name}
fill
className="object-cover group-hover:scale-105 transition-transform"
/>
{discount > 0 && (
<span className="absolute top-2 right-2 bg-red-500 text-white text-xs px-2 py-1 rounded">
{discount}% OFF
</span>
)}
</div>
<h3 className="mt-2 font-medium">{product.name}</h3>
<div className="flex items-center gap-2">
<span className="text-lg font-bold">${product.price.toLocaleString()}</span>
{product.compareAtPrice && (
<span className="text-sm text-gray-400 line-through">
${product.compareAtPrice.toLocaleString()}
</span>
)}
</div>
</Link>
);
}
Zusammenfassung
Claude Codeを使えば、ECサイトの複雑な機能群を整合性のとれたコードで一気に構築できます。決済処理の詳細はStripe決済の統合ガイド、状態管理のパターンは状態管理の実装を参照してください。
Stripeの公式チュートリアル(stripe.com/docs)もあわせて確認するのがおすすめです。
Related Posts
So beschleunigen Sie Ihre Nebenprojekte mit Claude Code [Mit Beispielen]
Erfahren Sie, wie Sie persönliche Entwicklungsprojekte mit Claude Code drastisch beschleunigen. Inklusive realer Beispiele und eines praktischen Workflows von der Idee bis zum Deployment.
So automatisieren Sie Refactoring mit Claude Code
Erfahren Sie, wie Sie Code-Refactoring mit Claude Code effizient automatisieren. Inklusive praktischer Prompts und konkreter Refactoring-Muster für reale Projekte.
Vollständiger CORS-Konfigurationsleitfaden mit Claude Code
Erfahren Sie alles über die CORS-Konfiguration mit Claude Code. Mit praktischen Tipps und Codebeispielen.