Quickstart
API Key 발급부터 첫 구독 생성, 웹훅 검증까지 실행 가능한 코드로 안내합니다.
1. API Key 발급
대시보드(/dashboard/api-keys)에 로그인 후 발급 버튼을 누르면 sb_live_ 또는 sb_test_로 시작하는 키가 그 자리에서 한 번만 표시됩니다. 재발급 없이는 다시 볼 수 없으니 즉시 안전한 곳에 저장하세요. 두 환경 접두사는 로그·코드리뷰에서 즉시 식별하기 위한 라벨링 용도이며, 실제 데이터/PG 연동은 분리되지 않습니다(샌드박스 격리는 아직 지원하지 않음).
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 },
trialDays: 7, // 무료체험 일수(선택, 기본 0). 체험 종료 시점에 자동으로 첫 청구가 시작됩니다.
});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 웹훅이 발송됩니다. 정기 청구는 고객이 대시보드(/dashboard/pg-credentials)에서 카드(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);
// 요금제를 삭제하면 기존 구독자 결제가 함께 끊깁니다.
// 신규 가입만 막고 기존 구독자는 유지하려면 삭제 대신 판매 중단(archive)을 사용하세요.
await fetch(`https://api.superbilling.io/v1/plans/${plan.id}/archive`, {
method: "POST",
headers: { Authorization: `Bearer ${apiKey}` },
});
// 다시 판매를 재개하려면 unarchive(DELETE)를 호출합니다.
await fetch(`https://api.superbilling.io/v1/plans/${plan.id}/archive`, {
method: "DELETE",
headers: { Authorization: `Bearer ${apiKey}` },
});
await client.customers.update(customer.id, { email: "new@example.com" });
await client.customers.delete(customer.id);알려진 제약
- 카드 등록·실결제 E2E는 Payple 정식 샌드박스 테스트카드가 있어야 끝까지 검증 가능합니다.
- Rate limit은 IP/API Key당 분당 60회이며 서버리스 인스턴스별 메모리 카운터라 정밀하지 않을 수 있습니다.