@gj-kit/toss-payments 레시피
각 코드 블록은 패키지 README에서 이미 타입 검사하는 public-contract 예제를 재사용합니다.
1. order store로 confirmation flow 조립하기
섹션 제목: “1. order store로 confirmation flow 조립하기”부팅 때 server key를 파싱하고 confirmation이 가능해지기 전에 호스트 order store를 명시합니다.
완료 상태: 전달한 store에 맞는 결제 흐름만 노출하는 서버 전용 payment kit을 만듭니다.
앱 소유 경계: 부팅 시 API secret을 파싱하고, 승인을 활성화하기 전에 서버 소유 order store를 제공합니다.
import { orThrow } from '@gj-kit/toss-payments';import { createTossPayments, parseApiSecretKey } from '@gj-kit/toss-payments/server';
declare const apiSecretFromEnv: string; // Read this once from your server environment.
export const toss = createTossPayments({ secretKey: orThrow(parseApiSecretKey(apiSecretFromEnv)),});
// Add your OrderStore to enable toss.confirm; the type exposes only wired flows.2. billing과 webhook 경계를 의도적으로 추가하기
섹션 제목: “2. billing과 webhook 경계를 의도적으로 추가하기”각 flow에 필요한 store만 연결해 없는 capability를 실수로 사용할 수 없게 합니다.
코드 리뷰는 통과하고 프로덕션에서 터지는 두 실수, 반쪽만 배선된 kit과 멱등키 없는 billing approve. 여기서는 둘 다 컴파일 에러입니다.
import { idempotencyKey, orThrow } from '@gj-kit/toss-payments';import type { BillingKeyStore, BillingOrder, BillingProfile, OrderStore } from '@gj-kit/toss-payments/server';import { createTossPayments, parseApiSecretKey } from '@gj-kit/toss-payments/server';
declare const apiSecret: string; // app ownsdeclare const orderStore: OrderStore; // app ownsdeclare const billingKeyStore: BillingKeyStore; // app ownsdeclare const profile: BillingProfile; // app ownsdeclare const order: BillingOrder; // app owns
export const toss = createTossPayments({ secretKey: orThrow(parseApiSecretKey(apiSecret)), orders: orderStore, // omit and `toss.confirm` is not on the type billingKeys: billingKeyStore, // omit and `toss.billing` is not on the type});
// toss.billing.approve(profile, order); -> error TS2554: Expected 3 arguments, but got 2.export const charged = toss.billing.approve(profile, order, { idempotencyKey: orThrow(idempotencyKey(`sub:2026-09:${profile.customerKey}`)),});전체 API reference에서 모든 export와 import path를 확인하세요.