payment-integration
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinese💳 Next.js 결제 시스템 통합 스킬
💳 Next.js支付系统集成技能
이 스킬은 BSD 바이브코딩 수강생들이 Next.js와 Node.js를 사용하여 안전하고 전문적인 결제 시스템을 구축할 수 있도록 돕습니다.
本技能帮助BSD Vibecoding学员使用Next.js和Node.js构建安全且专业的支付系统。
📋 이 스킬이 하는 일
📋 本技能能实现什么
- 플랫폼 전략: 비즈니스 모델(일회성/구독)에 맞는 최적의 PG사(Toss, Stripe) 선정
- Next.js 통합: 클라이언트 사이드 결제 요청 및 서버 사이드 승인 로직 구현
- 웹훅(Webhook) 연동: 결제 완료, 취소 등 이벤트를 비동기로 처리하여 DB 동기화
- 보안 및 검증: 데이터 위변조 방지 및 서버 사이드 금액 검증 로직 구현
- 구독 관리: Stripe Billing 등을 활용한 자동 결제 및 멤버십 연동
- 平台策略:根据商业模式(一次性/订阅)选择最优的支付网关(Toss、Stripe)
- Next.js集成:实现客户端支付请求及服务器端授权逻辑
- Webhook联动:异步处理支付完成、取消等事件以同步数据库
- 安全与验证:实现数据防篡改及服务器端金额验证逻辑
- 订阅管理:利用Stripe Billing等实现自动支付及会员体系联动
🎯 언제 이 스킬을 사용하나요?
🎯 何时使用本技能?
- "Next.js 쇼핑몰에 토스페이먼츠 유젯(Payment Widget)을 넣고 싶어요"
- "Stripe를 사용해 글로벌 구독 서비스를 만들고 싶어요"
- "결제가 완료되면 자동으로 알림톡을 보내고 수강 권한을 열어주고 싶어요"
- "想在Next.js商城中添加Toss Payments支付组件(Payment Widget)"
- "想使用Stripe打造全球订阅服务"
- "支付完成后自动发送通知短信并开通学习权限"
🛠️ 추천 기술 스택
🛠️ 推荐技术栈
1. Payment Gateways
1. Payment Gateways
- Toss Payments: 국내 결제 최강자, 위젯 기반의 간편한 연동
- Stripe: 글로벌 및 구독 결제 표준
- Toss Payments:韩国支付领军者,基于组件的便捷集成
- Stripe:全球及订阅支付标准
2. Implementation
2. Implementation
- Next.js App Router: API Route Handlers를 활용한 결제 승인
- Server Actions: 보안이 강화된 데이터 처리
- Next.js App Router:利用API Route Handlers实现支付授权
- Server Actions:增强安全性的数据处理
💻 구현 예시 (Next.js + Toss Payments)
💻 实现示例 (Next.js + Toss Payments)
1. Server Side (app/api/payment/confirm/route.ts)
1. Server Side (app/api/payment/confirm/route.ts)
typescript
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const { paymentKey, orderId, amount } = await req.json();
// 1. 서버 사이드 금액 검증 로직 추가 필수
// const product = await db.product.findUnique({ where: { orderId } });
// if (product.price !== amount) throw new Error('Invalid amount');
const secretKey = process.env.TOSS_SECRET_KEY;
const basicToken = Buffer.from(`${secretKey}:`).toString("base64");
const response = await fetch(
"https://api.tosspayments.com/v1/payments/confirm",
{
method: "POST",
headers: {
Authorization: `Basic ${basicToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ paymentKey, orderId, amount }),
}
);
const result = await response.json();
if (response.ok) {
// DB 업데이트 등 후처리 수행
return NextResponse.json(result);
} else {
return NextResponse.json(result, { status: response.status });
}
}typescript
import { NextResponse } from "next/server";
export async function POST(req: Request) {
const { paymentKey, orderId, amount } = await req.json();
// 1. 必须添加服务器端金额验证逻辑
// const product = await db.product.findUnique({ where: { orderId } });
// if (product.price !== amount) throw new Error('Invalid amount');
const secretKey = process.env.TOSS_SECRET_KEY;
const basicToken = Buffer.from(`${secretKey}:`).toString("base64");
const response = await fetch(
"https://api.tosspayments.com/v1/payments/confirm",
{
method: "POST",
headers: {
Authorization: `Basic ${basicToken}`,
"Content-Type": "application/json",
},
body: JSON.stringify({ paymentKey, orderId, amount }),
}
);
const result = await response.json();
if (response.ok) {
// 执行数据库更新等后续处理
return NextResponse.json(result);
} else {
return NextResponse.json(result, { status: response.status });
}
}2. Client Side (components/Checkout.tsx)
2. Client Side (components/Checkout.tsx)
tsx
"use client";
import { loadTossPayments } from "@tosspayments/payment-sdk";
export default function Checkout() {
const handlePayment = async () => {
const tossPayments = await loadTossPayments(
process.env.NEXT_PUBLIC_TOSS_CLIENT_KEY!
);
await tossPayments.requestPayment("카드", {
amount: 50000,
orderId: "ORDER_123",
orderName: "Next.js 마스터클래스",
successUrl: `${window.location.origin}/success`,
failUrl: `${window.location.origin}/fail`,
});
};
return <button onClick={handlePayment}>50,000원 결제하기</button>;
}tsx
"use client";
import { loadTossPayments } from "@tosspayments/payment-sdk";
export default function Checkout() {
const handlePayment = async () => {
const tossPayments = await loadTossPayments(
process.env.NEXT_PUBLIC_TOSS_CLIENT_KEY!
);
await tossPayments.requestPayment("카드", {
amount: 50000,
orderId: "ORDER_123",
orderName: "Next.js 마스터클래스",
successUrl: `${window.location.origin}/success`,
failUrl: `${window.location.origin}/fail`,
});
};
return <button onClick={handlePayment}>50,000원 결제하기</button>;
}⚠️ 보안 체크리스트
⚠️ 安全检查清单
- 금액 검증: 반드시 서버 사이드에서 실제 DB의 가격과 비교 검증
- API Key 관리: Secret Key는 절대 클라이언트에 노출하지 말고 로 관리
.env - 멱등성(Idempotency): 중복 결제 방지를 위한 활용
Idempotency-Key
- 金额验证:务必在服务器端与实际数据库中的价格进行对比验证
- API Key管理:Secret Key绝对不能暴露给客户端,需通过管理
.env - 幂等性(Idempotency):使用防止重复支付
Idempotency-Key
💬 예제 대화
💬 示例对话
사용자: "토스페이먼츠로 정기 결제 기능을 Next.js에 넣고 싶어"
Claude:
"Next.js App Router와 토스페이먼츠 빌링 API를 사용하여 안전한 정기 결제 시스템을 구축해드리겠습니다. 카드 등록부터 예약 결제 로직, 그리고 결제 결과 웹훅 처리까지 포함된 코드를 생성해 드릴게요..."
用户:"想在Next.js中添加Toss Payments定期支付功能"
Claude:
"我将使用Next.js App Router和Toss Payments Billing API构建安全的定期支付系统。会生成包含卡片注册、预约支付逻辑及支付结果Webhook处理的代码..."
🎯 핵심 정리
🎯 核心总结
이 스킬을 사용하면:
✅ 안전한 결제 아키텍처: 서버 사이드 검증이 포함된 견고한 시스템
✅ 최신 연동 방식: Toss UI Widget, Stripe Checkout 등 최신 트렌드 반영
✅ 비즈니스 확장성: 정기 구독, 부분 취소, 에스크로 등 복잡한 기능 지원
✅ 안정적인 운영: 웹훅 처리를 통한 데이터 불일치 문제 해결
BSD 학생이라면: 이제 단순한 웹사이트를 넘어, 실제 수익이 발생하는 비즈니스 플랫폼을 직접 개발할 수 있습니다! 💳
使用本技能可实现:
✅ 安全的支付架构:包含服务器端验证的稳健系统
✅ 最新集成方式:采用Toss UI Widget、Stripe Checkout等最新趋势
✅ 业务扩展性:支持定期订阅、部分取消、托管等复杂功能
✅ 稳定运营:通过Webhook处理解决数据不一致问题
如果是BSD学员:现在你可以超越简单的网站,直接开发能产生实际收益的商业平台了! 💳