Quickstart
API Key 발급부터 첫 구독 생성, 웹훅 검증까지 실행 가능한 코드로 안내합니다.
1. API Key 발급
대시보드(`/dashboard/api-keys`)에 로그인 후 발급 버튼을 누르면 sb_live_로 시작하는 키가 그 자리에서 한 번만 표시됩니다. 재발급 없이는 다시 볼 수 없으니 즉시 안전한 곳에 저장하세요.
2. SDK 설치 및 클라이언트 생성
import { SuperBillingClient } from "@superbilling/sdk-node";
const client = new SuperBillingClient({ apiKey: process.env.SUPERBILLING_API_KEY! });3. 요금제(Plan) 생성
const { data: plan } = await client.plans.create({
name: "Pro",
billingCycle: "monthly",
pricingModel: { kind: "flat", amountKrw: 9900 },
});pricingModel.kind는 "flat"(정액) / "usage"(사용량) / "seat"(좌석) 중 하나입니다. 자동 청구(cron)는 현재 "flat"만 지원합니다.
4. 고객(Customer) 생성
const { data: customer } = await client.customers.create({
externalRef: "user_1234", // 여러분 서비스의 고객 식별자
email: "customer@example.com",
});5. 구독(Subscription) 생성
const { data: subscription } = await client.subscriptions.create({
planId: plan.id,
customerId: customer.id,
});구독이 생성되면 subscription.created 웹훅이 발송됩니다. 정기 청구는 고객이 대시보드에서 카드(Payple)를 등록해야 시작됩니다 — 카드 등록 전까지는 nextBillingAt이 도래해도 청구되지 않습니다.
6. 웹훅 등록 및 서명 검증
대시보드(`/dashboard/webhooks`)에서 엔드포인트 URL을 등록하면 시크릿이 발급됩니다. 이후 모든 웹훅 요청 헤더 X-SuperBilling-Signature에 해당 시크릿으로 서명한 HMAC-SHA256(hex)이 담겨 옵니다.
import { verifyWebhookSignature } from "@superbilling/sdk-node";
// Next.js Route Handler 예시
export async function POST(req: Request) {
const rawBody = await req.text(); // 반드시 raw body 문자열을 그대로 사용
const signature = req.headers.get("x-superbilling-signature") ?? "";
if (!verifyWebhookSignature(rawBody, signature, process.env.SUPERBILLING_WEBHOOK_SECRET!)) {
return new Response("invalid signature", { status: 401 });
}
const event = JSON.parse(rawBody);
// event.type: "subscription.created" | "invoice.payment_succeeded" |
// "invoice.payment_failed" | "subscription.canceled"
return new Response("ok", { status: 200 });
}전송 실패 시 최대 3회(1초/3초 간격)까지 재시도합니다. 3회 모두 실패해도 마지막 시도 결과만 1건으로 기록됩니다.
7. 청구 내역 조회
const { data: invoices } = await client.invoices.list();
const { data: invoice } = await client.invoices.get(invoiceId);
const { data: payments } = await client.payments.list();
const { data: payment } = await client.payments.get(paymentId);8. 구독/요금제/고객 변경
await client.subscriptions.cancel(subscription.id);
await client.subscriptions.reactivate(subscription.id);
await client.plans.update(plan.id, { name: "Pro (개편)" });
await client.plans.delete(plan.id);
await client.customers.update(customer.id, { email: "new@example.com" });
await client.customers.delete(customer.id);알려진 제약
- 카드 등록·실결제 E2E는 Payple 정식 샌드박스 테스트카드가 있어야 끝까지 검증 가능합니다(
PROJECT_STATE.md문제 백로그 참고). - Rate limit은 IP/API Key당 분당 60회이며 서버리스 인스턴스별 메모리 카운터라 정밀하지 않을 수 있습니다.