A 실전 가이드 to Building an E-Commerce Site: Claude Code 활용 가이드
A practical guide to building an e-commerce site: 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>
);
}
정리
Claude Code를 활용하면 ECサイトの複雑な機能群を整合性のとれたコードで一気に구축할 수 있습니다。決済処理의 상세 정보는Stripe決済の통합가이드、状態관리のパターンは状態관리の구현를 참고하세요.
Stripeの公式튜토리얼(stripe.com/docs)もあわせて확인するのがおすすめです。
#Claude Code
#EC
#Stripe
#Next.js
#TypeScript
Related Posts
Use Cases
Use Cases
Claude Code로 리팩토링을 자동화하는 방법
Claude Code를 활용해 코드 리팩토링을 효율적으로 자동화하는 방법을 알아봅니다. 실전 프롬프트와 구체적인 리팩토링 패턴을 소개합니다.
Use Cases
Use Cases
Claude Code로 사이드 프로젝트 개발 속도를 극대화하는 방법 [예제 포함]
Claude Code를 활용해 개인 프로젝트 개발 속도를 획기적으로 높이는 방법을 알아봅니다. 실전 예제와 아이디어부터 배포까지의 워크플로를 포함합니다.
Use Cases
Use Cases
Complete CORS Configuration Guide: Claude Code 활용 가이드
complete cors configuration guide: Claude Code 활용. 실용적인 팁과 코드 예시를 포함합니다.