AI 코딩 도구

Claude Code 결제 연동: Stripe + Sepay 처음부터 끝까지 (2026)

2026년 8월 20일11분 읽기

Claude Code로 Next.js나 Node 앱을 위한 실제 결제 플로우를 만들 수 있어요. 먼저 게이트웨이(해외 고객은 Stripe, 베트남 고객은 Sepay/VietQR)를 고르고, Claude Code에게 저장소를 읽혀 checkout 라우트와 webhook 핸들러를 생성하게 한 다음, 마지막으로 여러분이 테스트하고 검토해요. 핵심은 다섯 단계예요. 게이트웨이 선택, CLAUDE.md로 Claude Code에 지시, checkout 만들기, 멱등한 webhook 작성, 그리고 테스트와 보강. 돈이 걸린 일이라 사람이 항상 검토해요. 에이전트가 프로덕션 명령을 혼자 실행하게 두면 안 돼요.

왜 결제 연동에 Claude Code를 쓸까요?

결제 연동은 반복이 많으면서도 실수하기 쉬운 종류의 작업이에요. checkout 라우트를 만들고, 리다이렉트를 처리하고, webhook을 쓰고, 서명을 검증하고, 주문을 저장하고, 모든 테스트 케이스를 커버해야 하죠. 문서를 보며 손으로 하면 오후 한나절이 통째로 사라지고, 세부 하나(예를 들어 멱등하지 않은 webhook)만 놓쳐도 고객에게 이중 청구가 될 수 있어요.

여기서 Claude Code의 강점은 단순한 코드 제안이 아니라 빌더처럼 동작한다는 점이에요. 한 세션 안에서 저장소 구조를 읽고, App Router인지 Express인지 파악한 다음, 알맞은 API 라우트를 생성하고, 게이트웨이의 페이로드에 맞는 webhook 핸들러를 만들고, 테스트 명령을 여러분의 터미널에서 바로 실행해요. '문서를 몇 시간씩 파고드는' 것에서 '몇 분 만에 diff를 검토하는' 것으로의 변화는 진짜 차이인데, 특히 Stripe와 Sepay를 한 번에 연결해야 할 때 그래요. Claude Code에 API를 아직 맡겨본 적이 없다면, 먼저 Claude Code로 백엔드 API 만들기 가이드를 읽고 잘 지시하는 법을 익혀 두세요.

다만 앞서 분명히 말해 둘게요. 결제에는 진짜 돈이 걸려 있어서, 사람이 여전히 모든 줄을 검토해야 해요. Claude Code는 통화 단위를 잘못 검증하거나, 엣지 케이스를 건너뛰거나, 더 이상 권장되지 않는 API를 제안할 수 있어요. 빠른 주니어 개발자처럼 대하세요. 최종 승인은 여전히 여러분 몫이에요. 이 글 전체를 관통하는 원칙은 이거예요. AI가 만들고, 여러분이 검증한다.

게이트웨이 고르기: Stripe vs Sepay vs Polar

프롬프트를 입력하기 전에 게이트웨이를 고르세요. 각각 고유의 플로우와 페이로드가 있으니까요. 베트남과 글로벌 고객을 대상으로 하는 개발자에게 인기 있는 선택지 세 가지예요.

기준StripeSepayPolar
대상 고객해외, 신용카드베트남, VND글로벌 SaaS
결제 수단카드, 지갑, 호스팅형 CheckoutVietQR/NAPAS, 계좌 이체, 카드, 44개 이상 은행Merchant of Record 경유 카드
강점큰 생태계, 마켓플레이스용 Connect매끄러운 국내 정산, 낮은 수수료, 동적 QR글로벌 세금/VAT, 구독, 체험판 처리
적합한 경우해외 판매베트남 고객에게 판매소프트웨어/구독을 국경 넘어 판매

짧게 추천하면 이래요. 베트남 고객에게는 Sepay를 쓰세요(VietQR/NAPAS, 고객이 코드를 스캔해 이체하면 돈이 여러분 은행 계좌로 들어와요). 카드로 결제하는 해외 고객에게는 Stripe를 쓰세요. 세금 처리에 손대고 싶지 않으면서 SaaS를 글로벌하게 판매한다면 Polar를 쓰세요. Polar가 Merchant of Record로 동작하며 VAT를 대신 처리해 주니까요. 많은 앱이 Stripe와 Sepay를 나란히 운영해요. 해외 고객은 Stripe로, 국내 고객은 VietQR로 가죠. 이 글에서는 이 두 게이트웨이를 깊이 다뤄요. Polar의 플로우는 Stripe와 비슷해요(자체 Next.js 어댑터가 있어요).

시작하기 전에 준비할 것

Claude Code를 열기 전 체크리스트예요(빠르게 훑어보고 빠진 건 채워 넣으세요).

  • 이미 로컬에서 실행되는 Next.js 또는 Node/Express 앱.
  • 테스트 모드의 Stripe 계정, 또는 샌드박스의 Sepay 계정(키는 SP-TEST-* 같은 형태예요).
  • .env에 보관하고 절대 커밋하지 않는 시크릿 키. 먼저 .env.gitignore에 추가하세요.
  • 설치된 Claude Code, 그리고 스택과 관례를 설명하는 저장소 안의 CLAUDE.md(아래에서 사용해요).
  • 게이트웨이가 webhook을 호출할 공개 엔드포인트. 로컬에서는 Stripe CLI나 터널을 쓰고, 프로덕션에서는 실제 HTTPS를 쓰세요.

시크릿 키를 다루는 일은 결제 보안에서 가장 취약한 부분이에요. 그러니 Claude Code 권한을 안전하게 관리하기도 함께 읽어 두고, 에이전트가 실수로 시크릿을 읽거나 로그에 출력하지 않도록 하세요.

결제 작업을 위해 Claude Code에 지시하는 법

출력 품질은 거의 전적으로 지시하는 방식에 달려 있어요. 결제에서 가장 중요한 두 가지는 CLAUDE.md의 컨텍스트구체적인 프롬프트예요.

Claude Code가 추측하지 않아도 되도록, 이런 컨텍스트를 몇 줄 CLAUDE.md에 추가하세요.

# Payment context
- Stack: Next.js 15 App Router, TypeScript, Prisma + PostgreSQL
- Gateways: Stripe (international) + Sepay/VietQR (VN customers)
- Env: all secrets live in .env, NEVER commit, NEVER print to logs
- Convention: use Stripe Checkout Sessions only, NO legacy Charges/Card Element
- Safety: NEVER run production commands, NEVER refund; test mode/sandbox only

다음은 프롬프트예요. 모호한 '나 대신 Stripe 연동해 줘'와 구체적인 것을 비교해 보세요.

Read app/ and prisma/schema.prisma. Create a POST route app/api/checkout/route.ts
that creates a Stripe Checkout Session (mode payment) from the priceId in the body
and returns session.url. Use the existing env vars. Do not touch other files.
Then document a Stripe CLI test in the README; do not run any live commands.

구체적인 프롬프트는 Claude Code의 변경 범위를 좁히고, 여러분의 실제 DB 스키마를 쓰게 하며, 불필요한 파일을 '지어내는' 것을 막아요. fetch/MCP로 게이트웨이 문서(Stripe 문서, developer.sepay.vn)를 가리켜, 낡은 기억이 아니라 최신 API를 따르게 할 수도 있어요.

Claude Code로 하는 Stripe 플로우(해외 고객)

최신 Stripe 플로우는 네 단계에 들어가요. Checkout Sessions(Stripe 호스팅)를 우선하고, 레거시 Charges/Card Element는 피하세요. 오래된 방식이라 PCI 부담이 커지니까요.

  1. Checkout Session을 만드는 라우트. priceId를 받아 세션을 만들고, 클라이언트가 리다이렉트할 session.url을 반환하는 라우트를 생성하도록 Claude Code에 지시하세요.
  2. 성공/취소 리다이렉트. success_urlcancel_url을 넘기세요. 성공 페이지에서 주문을 '결제됨'으로 표시하지 마세요 — webhook을 기다리세요.
  3. webhook checkout.session.completed. 비즈니스 로직을 처리하기 전에 constructEvent로 서명을 검증하세요.
  4. Stripe CLI로 테스트를 배포 없이 로컬 머신에서 바로 하세요.
// app/api/checkout/route.ts
import { NextResponse } from "next/server";
import Stripe from "stripe";

const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);

export async function POST(req: Request) {
 const { priceId } = await req.json();
 const session = await stripe.checkout.sessions.create({
 mode: "payment",
 line_items: [{ price: priceId, quantity: 1 }],
 success_url: `${process.env.APP_URL}/success?session_id={CHECKOUT_SESSION_ID}`,
 cancel_url: `${process.env.APP_URL}/cancel`,
 });
 return NextResponse.json({ url: session.url });
}
// app/api/webhooks/stripe/route.ts
import Stripe from "stripe";
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);

export async function POST(req: Request) {
 const body = await req.text(); // raw body is required to verify
 const sig = req.headers.get("stripe-signature")!;
 let event: Stripe.Event;
 try {
 event = stripe.webhooks.constructEvent(
 body, sig, process.env.STRIPE_WEBHOOK_SECRET!
 );
 } catch {
 return new Response("Invalid signature", { status: 400 });
 }
 if (event.type === "checkout.session.completed") {
 // idempotent: check whether event.id was already processed before writing the order
 }
 return new Response("ok", { status: 200 });
}

로컬에서 명령 두 개로, 비용 없이 테스트해요.

stripe listen --forward-to localhost:3000/api/webhooks/stripe
stripe trigger checkout.session.completed

본격 출시까지의 전체 플로우와 공식 체크리스트는 Stripe 문서(docs.stripe.com, 2026년 8월 접속)를 참고하세요. Stripe는 자주 업데이트하니, 공개 전에 라이브 API 버전을 확인하세요.

Claude Code로 하는 Sepay/VietQR 플로우(베트남 고객)

Sepay는 베트남 고객에게 잘 맞아요. VietQR 코드나 가상 계좌를 생성하면, 고객이 스캔해 이체하고, Sepay가 입금을 확인하는 webhook을 발생시켜요. 네 단계 플로우예요.

  1. 주문을 만들고 VietQR을 생성하세요(또는 가상 계좌). 그 주문에 대해, 나중에 대조할 수 있는 이체 메모를 붙이세요.
  2. 고객이 QR을 스캔해 이체해요 — 자기 뱅킹 앱을 통해서요.
  3. Sepay webhooktransferType: "in"과 함께 transferAmount, content, referenceCode를 담아 거래를 보고해요.
  4. 검증하고, 중복을 제거하고, 5초 안에 {"success": true}를 반환하세요 — 그래야 Sepay가 재시도하지 않아요.
// app/api/webhooks/sepay/route.ts
import { db } from "@/lib/db";

export async function POST(req: Request) {
 const auth = req.headers.get("authorization");
 if (auth !== `Apikey ${process.env.SEPAY_API_KEY}`) {
 return new Response("Unauthorized", { status: 401 });
 }
 const data = await req.json();
 // data: { id, transferType, transferAmount, content, referenceCode }
 if (data.transferType !== "in") {
 return Response.json({ success: true }); // ignore outgoing transactions
 }
 const existed = await db.transaction.findUnique({
 where: { sepayId: data.id },
 });
 if (existed) return Response.json({ success: true }); // dedupe by id
 await db.transaction.create({
 data: {
 sepayId: data.id,
 amount: data.transferAmount,
 content: data.content,
 ref: data.referenceCode,
 },
 });
 // TODO: reconcile content with the order, then update its status to "paid"
 return Response.json({ success: true });
}

거래를 저장하고 주문과 대조하는 일은 데이터 계층에 깔끔하게 두는 게 좋아요. 정돈된 orders/transactions 테이블을 설계하려면 데이터베이스로 주문과 거래 저장하기를 참고하세요. Sepay에는 자체 샌드박스와 초당 2건(2 req/s) 속도 제한이 있으니, Claude Code에 공식 문서(developer.sepay.vn, 2026년 8월 접속)를 읽혀 올바른 엔드포인트와 페이로드를 지키게 하세요.

webhook과 멱등성 — 가장 틀리기 쉬운 부분

여기가 수동 튜토리얼이 대충 넘어가는 지점이자, 피해가 가장 큰 지점이에요. 결제 게이트웨이는 webhook이 정확히 한 번 전달된다고 보장하지 않아요. 불안정한 네트워크, 타임아웃, 재시도가 모두 같은 이벤트를 여러 번 도착하게 만들어요. 핸들러가 멱등하지 않으면 주문이 중복 기록되거나, 잔액이 두 번 적립되거나, 상품이 두 번 발송돼요.

규칙은 이거예요. 이벤트 식별자로 중복을 제거한다. Sepay에서는 거래 id, Stripe에서는 event.id예요. 처리한 id를 저장하고(DB의 유니크 인덱스), 전에 본 것이면 건너뛰세요. 더 복잡한 경우에는 복합 키(예를 들어 orderId와 이벤트 타입)를 쓰세요.

기억해 둘 타이밍과 재시도 제약이에요.

  • Sepay: 핸들러는 5초 안에 2xx를 반환해야 해요. 그렇지 않으면 Sepay가 Fibonacci 일정으로 약 5시간에 걸쳐 최대 7번까지 자동 재시도해요. 즉 같은 거래가 7번 도착할 수 있으니 중복 제거는 필수예요.
  • Stripe: 2xx를 못 받으면 자체 일정으로 재시도해요. 역시 event.id로 중복을 제거해야 해요.

실용적인 팁이에요. 이벤트를 먼저 저장하고, 비즈니스 로직은 나중에 처리한다. 이벤트 레코드를 (멱등하게) 기록한 다음, 무거운 로직을 별도 단계에서 실행하세요. 그러면 로직이 실패해도 재시도가 여전히 안전해요. 여기는 Claude Code에게 'webhook이 두 번 도착하는' 경우의 테스트를 작성하게 하기 좋은 지점이에요 — 짚어 주지 않으면 대개 잊어버려요.

출시 전 테스트와 보안

진짜 돈을 켜기 전에 이 체크리스트를 한 번 훑으세요(수동 튜토리얼이 가장 자주 놓치는 부분이기도 해요).

테스트:

  • Stripe: Stripe CLI(stripe listen/stripe trigger)와 테스트 카드를 쓰세요. 진짜 돈은 안 들어요.
  • Sepay: SP-TEST-* 키로 샌드박스를 쓰고, 입금 거래를 시뮬레이션해 webhook을 확인하세요.
  • 실패 케이스를 테스트하세요. 잘못된 서명, webhook 두 번 도착, 주문과 맞지 않는 금액.

보안:

  • 시크릿 키를 절대 노출하지 마세요 — 서버 사이드에서만, 클라이언트 번들에 넣지 말고, 로그에 출력하지 마세요.
  • 모든 webhook을 검증하세요. Stripe는 HMAC 서명(constructEvent)으로, Sepay는 API Key 헤더 Authorization: Apikey ...로요.
  • 프로덕션에서는 HTTPS를 필수로 하세요. webhook 엔드포인트에는 IP 화이트리스트도 고려하세요.
  • Checkout Sessions / PaymentIntents / SetupIntents만 쓰세요. PCI 범위를 줄이려면 레거시 Sources/Tokens/Charges는 피하세요. 원시 PAN을 다루면 복잡한 PCI 준수 범주에 들어가요 — 하지 마세요.

출시: Stripe에는 자체 출시 체크리스트가 있어요(라이브 키로 전환, 프로덕션 webhook 설정). Sepay는 NAPAS QR/카드 승인이 필요하고, 보통 3~7일이 걸려요 — 그 시간을 감안하세요. 공개하기 전에 Claude Code로 하는 보안 및 감사 검토를 한 번 더 돌려 키 유출과 검증 누락을 잡아내세요.

미리 만들어진 스킬로 훨씬 빠르게 출시하기(AgentKit)

핸들러를 하나하나 손으로 쓰고 싶지 않다면 더 빠른 길이 있어요. AgentKit Engineer Kit의 ak-payment-integration 스킬이에요. 이 스킬은 이미 세 게이트웨이 — SePay, Polar, Stripe — 를 패키지로 묶어 checkout, webhook 검증(바로 쓸 수 있는 스크립트 포함), QR, 구독, 다중 프로바이더 주문까지 다뤄요. 그래서 Claude Code는 이걸 활성화하기만 하면, 각 게이트웨이 문서를 파고드는 대신 몇 분 만에 만들어 내요.

혼동을 막기 위해 한마디. 여기서 AgentKit은 agentkit.best(링크로 20% 할인)에 있는 Claude Code용 키트(ak CLI)이지, OpenAI의 AgentKit이 아니에요. Engineer Kit 가격은 $99예요(사이트에 반복 요금 표기는 없어요). 이 스킬이 실제로 무엇을 해결하는지 보고 싶다면, 결정하기 전에 Engineer Kit 상세 리뷰AgentKit이란 무엇인가를 읽어 보세요 — 플로우 하나만 필요하다면 스킬 하나 때문에 사지는 마세요.

AI에게 돈을 맡길 때의 한계와 주의점

결제는 YMYL에 가까워서, 이 섹션은 코드만큼이나 중요해요. Claude Code에 결제를 맡길 때의 몇 가지 확고한 경계예요.

  • 돈과 관련된 코드는 항상 검토하세요. 금액 계산, 단위 변환, 주문 상태를 갱신하는 조건을 꼼꼼히 읽으세요.
  • 에이전트가 프로덕션 명령이나 환불을 혼자 실행하게 두지 마세요. Claude Code는 테스트 모드/샌드박스에 두고, 라이브 명령은 검토 후 여러분이 직접 누르세요.
  • 금액과 단위를 검증하세요. Stripe는 최소 단위(센트)로 세요. VND는 소수점이 없어요 — 여기가 AI가 변환에서 자주 미끄러지는 곳이에요.
  • webhook 엣지 케이스를 철저히 테스트하고(두 번 도착, 잘못된 서명, 맞지 않는 금액), 분쟁이 생겼을 때 대조할 수 있도록 로그를 보관하세요.

결론은 이래요. AI는 빠르게 움직이도록 도와주지만, 돈에 대한 책임은 여전히 여러분 몫이에요. 속도가 정신 맑은 검토 한 번을 대신할 수는 없어요.

자주 묻는 질문(FAQ)

Claude Code가 결제를 완전히 연동해 주나요?

대부분은 만들어 줘요. 저장소를 읽고, checkout 라우트를 생성하고, webhook 핸들러를 쓰고, 테스트를 써요. 하지만 코드 검토, 게이트웨이 가입, 프로덕션 키 설정, 출시 명령 실행은 여러분이 직접 해야 해요. 돈이 걸린 일이라 최종 승인자는 사람이에요.

베트남 고객에게는 Stripe와 Sepay 중 무엇을 골라야 하나요?

VND로 결제하는 베트남 고객에게는 VietQR/NAPAS, 44개 이상 은행 간 이체, 그리고 돈이 바로 은행 계좌로 들어오는 점 덕분에 Sepay가 더 잘 맞아요. Stripe는 해외에 판매하고 신용카드를 받을 때 맞아요. 많은 앱이 둘을 병행해요.

webhook이 거래를 전혀 받지 못하면 어떻게 하나요?

엔드포인트가 공개되어 있고 HTTPS인지, 서명/API Key 검증이 올바른지, 핸들러가 5초 안에 2xx를 반환하는지 확인하세요. Sepay는 약 5시간에 걸쳐 최대 7번까지 자동 재시도하니, 핸들러가 멱등하다면 나중 재시도로도 올바르게 기록돼요.

진짜 돈을 쓰지 않고 결제 플로우를 테스트하려면요?

테스트 모드를 쓰세요. Stripe에는 Stripe CLI(stripe listen/stripe trigger)와 테스트 카드가 있고, Sepay에는 SP-TEST-* 키로 쓰는 샌드박스가 있어요. 둘 다 진짜 돈을 건드리지 않고 거래와 webhook을 시뮬레이션할 수 있어요.

코딩을 잘 못해도 이 글을 따라 할 수 있나요?

Claude Code가 만들어 내는 diff를 읽고 검토하려면 기본적인 코딩 지식이 필요해요 — 돈이 걸려 있으니 이해하지 못하는 코드를 병합하면 안 돼요. Claude Code가 손으로 타이핑하는 양을 줄여 주지만, 코드를 읽고 이해하는 능력은 여전히 필수예요.

ak-payment-integration 스킬은 직접 손으로 쓰는 것과 어떻게 다른가요?

직접 쓰면 모든 줄을 통제할 수 있지만 세 게이트웨이 문서를 파고드는 시간이 들어요. ak-payment-integration 스킬은 SePay/Polar/Stripe용 checkout, webhook 검증, QR, 구독을 패키지로 묶어 더 빠르게 만들어 줘요. 대신 앱마다 고유의 비즈니스 로직이 있으니 출력은 여전히 검토해야 해요.

결론과 다음 단계

다섯 단계를 다시 정리해요. 게이트웨이 선택(해외는 Stripe / 베트남 고객은 Sepay), CLAUDE.md로 Claude Code에 지시, checkout 만들기, 멱등한 webhook 작성, 그리고 출시 전에 테스트하고 보강하기. 성패를 가르는 지점은 멱등한 webhook과 사람의 검토 한 번이에요. 진짜 돈이니까요. 여기서부터 완전한 백엔드 API 만들기로 나아가거나, 릴리스 전에 보안 감사를 단단히 조일 수 있어요.

결제 플로우를 더 빠르게 만들고 싶으세요? Engineer Kit의 ak-payment-integration 스킬은 Stripe/Sepay/Polar용 checkout, webhook 검증, QR을 패키지로 묶어요 — 각 게이트웨이 문서를 파고들지 않고 여러 게이트웨이를 연결해야 할 때 편리해요.

AgentKit 번들 살펴보기 — 지금 $149 ($198에서) →

J

Jasmine

작성자 · Jasmine Daily

Jasmine Daily를 써 내려가는 사람 - 생각과 경험, 그리고 하루하루의 순간을 적어 두어요. 솔직하고, 서두르지 않고, 완벽하지 않게.

Jasmine Daily

아직 읽을 이야기가 더 있어요.

이 글이 마음에 닿았다면, 일기의 다른 페이지들도 몇 장 넘겨 보세요.

다음 읽을거리

관련 글