skills/kyuhyi/bsd_claude_skills/payment-integration

payment-integration

SKILL.md

๐Ÿ’ณ Next.js ๊ฒฐ์ œ ์‹œ์Šคํ…œ ํ†ตํ•ฉ ์Šคํ‚ฌ

์ด ์Šคํ‚ฌ์€ BSD ๋ฐ”์ด๋ธŒ์ฝ”๋”ฉ ์ˆ˜๊ฐ•์ƒ๋“ค์ด Next.js์™€ Node.js๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์•ˆ์ „ํ•˜๊ณ  ์ „๋ฌธ์ ์ธ ๊ฒฐ์ œ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•์Šต๋‹ˆ๋‹ค.

๐Ÿ“‹ ์ด ์Šคํ‚ฌ์ด ํ•˜๋Š” ์ผ

  1. ํ”Œ๋žซํผ ์ „๋žต: ๋น„์ฆˆ๋‹ˆ์Šค ๋ชจ๋ธ(์ผํšŒ์„ฑ/๊ตฌ๋…)์— ๋งž๋Š” ์ตœ์ ์˜ PG์‚ฌ(Toss, Stripe) ์„ ์ •
  2. Next.js ํ†ตํ•ฉ: ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๊ฒฐ์ œ ์š”์ฒญ ๋ฐ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ์Šน์ธ ๋กœ์ง ๊ตฌํ˜„
  3. ์›นํ›…(Webhook) ์—ฐ๋™: ๊ฒฐ์ œ ์™„๋ฃŒ, ์ทจ์†Œ ๋“ฑ ์ด๋ฒคํŠธ๋ฅผ ๋น„๋™๊ธฐ๋กœ ์ฒ˜๋ฆฌํ•˜์—ฌ DB ๋™๊ธฐํ™”
  4. ๋ณด์•ˆ ๋ฐ ๊ฒ€์ฆ: ๋ฐ์ดํ„ฐ ์œ„๋ณ€์กฐ ๋ฐฉ์ง€ ๋ฐ ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๊ธˆ์•ก ๊ฒ€์ฆ ๋กœ์ง ๊ตฌํ˜„
  5. ๊ตฌ๋… ๊ด€๋ฆฌ: Stripe Billing ๋“ฑ์„ ํ™œ์šฉํ•œ ์ž๋™ ๊ฒฐ์ œ ๋ฐ ๋ฉค๋ฒ„์‹ญ ์—ฐ๋™

๐ŸŽฏ ์–ธ์ œ ์ด ์Šคํ‚ฌ์„ ์‚ฌ์šฉํ•˜๋‚˜์š”?

  • "Next.js ์‡ผํ•‘๋ชฐ์— ํ† ์ŠคํŽ˜์ด๋จผ์ธ  ์œ ์ ฏ(Payment Widget)์„ ๋„ฃ๊ณ  ์‹ถ์–ด์š”"
  • "Stripe๋ฅผ ์‚ฌ์šฉํ•ด ๊ธ€๋กœ๋ฒŒ ๊ตฌ๋… ์„œ๋น„์Šค๋ฅผ ๋งŒ๋“ค๊ณ  ์‹ถ์–ด์š”"
  • "๊ฒฐ์ œ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์ž๋™์œผ๋กœ ์•Œ๋ฆผํ†ก์„ ๋ณด๋‚ด๊ณ  ์ˆ˜๊ฐ• ๊ถŒํ•œ์„ ์—ด์–ด์ฃผ๊ณ  ์‹ถ์–ด์š”"

๐Ÿ› ๏ธ ์ถ”์ฒœ ๊ธฐ์ˆ  ์Šคํƒ

1. Payment Gateways

  • Toss Payments: ๊ตญ๋‚ด ๊ฒฐ์ œ ์ตœ๊ฐ•์ž, ์œ„์ ฏ ๊ธฐ๋ฐ˜์˜ ๊ฐ„ํŽธํ•œ ์—ฐ๋™
  • Stripe: ๊ธ€๋กœ๋ฒŒ ๋ฐ ๊ตฌ๋… ๊ฒฐ์ œ ํ‘œ์ค€

2. Implementation

  • Next.js App Router: API Route Handlers๋ฅผ ํ™œ์šฉํ•œ ๊ฒฐ์ œ ์Šน์ธ
  • Server Actions: ๋ณด์•ˆ์ด ๊ฐ•ํ™”๋œ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ

๐Ÿ’ป ๊ตฌํ˜„ ์˜ˆ์‹œ (Next.js + Toss Payments)

1. Server Side (app/api/payment/confirm/route.ts)

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 });
  }
}

2. Client Side (components/Checkout.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 ํ™œ์šฉ

๐Ÿ’ฌ ์˜ˆ์ œ ๋Œ€ํ™”

์‚ฌ์šฉ์ž: "ํ† ์ŠคํŽ˜์ด๋จผ์ธ ๋กœ ์ •๊ธฐ ๊ฒฐ์ œ ๊ธฐ๋Šฅ์„ Next.js์— ๋„ฃ๊ณ  ์‹ถ์–ด"

Claude: "Next.js App Router์™€ ํ† ์ŠคํŽ˜์ด๋จผ์ธ  ๋นŒ๋ง API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์•ˆ์ „ํ•œ ์ •๊ธฐ ๊ฒฐ์ œ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•ด๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ์นด๋“œ ๋“ฑ๋ก๋ถ€ํ„ฐ ์˜ˆ์•ฝ ๊ฒฐ์ œ ๋กœ์ง, ๊ทธ๋ฆฌ๊ณ  ๊ฒฐ์ œ ๊ฒฐ๊ณผ ์›นํ›… ์ฒ˜๋ฆฌ๊นŒ์ง€ ํฌํ•จ๋œ ์ฝ”๋“œ๋ฅผ ์ƒ์„ฑํ•ด ๋“œ๋ฆด๊ฒŒ์š”..."


๐ŸŽฏ ํ•ต์‹ฌ ์ •๋ฆฌ

์ด ์Šคํ‚ฌ์„ ์‚ฌ์šฉํ•˜๋ฉด: โœ… ์•ˆ์ „ํ•œ ๊ฒฐ์ œ ์•„ํ‚คํ…์ฒ˜: ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ๊ฒ€์ฆ์ด ํฌํ•จ๋œ ๊ฒฌ๊ณ ํ•œ ์‹œ์Šคํ…œ โœ… ์ตœ์‹  ์—ฐ๋™ ๋ฐฉ์‹: Toss UI Widget, Stripe Checkout ๋“ฑ ์ตœ์‹  ํŠธ๋ Œ๋“œ ๋ฐ˜์˜ โœ… ๋น„์ฆˆ๋‹ˆ์Šค ํ™•์žฅ์„ฑ: ์ •๊ธฐ ๊ตฌ๋…, ๋ถ€๋ถ„ ์ทจ์†Œ, ์—์Šคํฌ๋กœ ๋“ฑ ๋ณต์žกํ•œ ๊ธฐ๋Šฅ ์ง€์› โœ… ์•ˆ์ •์ ์ธ ์šด์˜: ์›นํ›… ์ฒ˜๋ฆฌ๋ฅผ ํ†ตํ•œ ๋ฐ์ดํ„ฐ ๋ถˆ์ผ์น˜ ๋ฌธ์ œ ํ•ด๊ฒฐ

BSD ํ•™์ƒ์ด๋ผ๋ฉด: ์ด์ œ ๋‹จ์ˆœํ•œ ์›น์‚ฌ์ดํŠธ๋ฅผ ๋„˜์–ด, ์‹ค์ œ ์ˆ˜์ต์ด ๋ฐœ์ƒํ•˜๋Š” ๋น„์ฆˆ๋‹ˆ์Šค ํ”Œ๋žซํผ์„ ์ง์ ‘ ๊ฐœ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค! ๐Ÿ’ณ

Weekly Installs
2
GitHub Stars
2
First Seen
Feb 14, 2026
Installed on
cursor2
antigravity2
replit2
claude-code2
gemini-cli2
continue1