- 사용자 지정 크레딧 entitlement(토큰)과 이를 자동으로 차감하는 meter 생성
- 구독 플랜(초과 사용 허용 및 비허용)과 일회성 충전 제품에 크레딧 연결
- 실제 OpenAI completion endpoint를 연결하고 Dodo Payments을 통해 토큰 결제
- SDK를 통해 고객의 실시간 크레딧 잔액 조회
- webhook signature를 검증하고 Dodo Payments 크레딧 이벤트 라우팅
구축할 내용
NeuralAPI의 가격 모델은 다음과 같습니다:- Dodo Payments 계정(test mode도 가능)
- OpenAI API key
- Node.js 18+
- TypeScript/Node.js 기본 지식
1단계: 토큰 크레딧 Entitlement 생성
먼저 두 구독 플랜과 충전 팩이 공유할 크레딧 entitlement를 생성합니다. 이를 플랫폼에서 사용하는 “토큰” 단위를 정의하는 과정이라고 생각하면 됩니다.
The Credits tab under Products shows all your credit entitlements.
Navigate to Credits
- Dodo Payments dashboard에 로그인합니다.
- 왼쪽 sidebar에서 Products를 클릭합니다.
- Credits 탭을 선택합니다.
- Create Credit을 클릭합니다.
Configure the credit unit
API TokensCredit Type: Custom Unit 선택Unit Name: tokenPrecision: 0 (토큰은 항상 정수입니다)Credit Expiry: 30 days (각 billing cycle마다 크레딧이 초기화됩니다)Skip overage at the credit level
Save and copy the credit ID
cent_xxxxxxxxxxxx와 같은 형식입니다.API Tokens 크레딧 entitlement가 준비되었습니다. 이제 사용량 이벤트가 자동으로 차감을 수행할 수 있도록 meter를 생성합니다.2단계: 토큰 사용량용 Meter 생성
meter는 들어오는 사용량 이벤트를 집계하고 이를 크레딧 차감으로 변환합니다. 3단계에서 제품을 생성할 때 meter를 연결하므로, 플랜 제품을 만들기 전에 생성해야 합니다.Open the Meters section
- dashboard sidebar에서 Products → Meters로 이동합니다.
- Create Meter를 클릭합니다.
Configure the meter
Token Usage MeterEvent Name: api.tokens_used (앱이 전송하는 값과 정확히 일치해야 합니다)Aggregation Type: Sum — 각 이벤트의 토큰 수를 합산합니다.Over Property: tokens — 각 이벤트에서 합산할 값이 있는 metadata key입니다.Measurement Unit: tokensmeter를 저장하고 ID를 복사합니다. 제품에 연결할 때 참조하게 됩니다.3단계: 플랜 제품 생성
두 플랜 모두 일반 Subscription이 아닌 Usage Based Billing 제품이어야 합니다. meter는 UBB 제품에만 연결할 수 있으며 고객이 API를 호출할 때 크레딧을 자동 차감하려면 meter가 필요합니다. UBB 제품은 반복되는 기본 요금($29 / $99)도 지원합니다. 이 기본 요금에 더해 발생한 사용량은 크레딧으로 결제됩니다.

Usage Based Billing pricing type with meter configuration.
Starter Plan ($29/월 — 10M 토큰, 초과 사용 없음)
Create the Starter UBB product
- Products → Create Product로 이동합니다.
- 가격 유형으로 Usage Based Billing을 선택합니다.
- 다음을 입력합니다:
NeuralAPI StarterDescription: 10 million API tokens per month. Perfect for individual developers and small projects.Fixed Price: 29.00 (반복되는 기본 요금으로, 사용량이 없어도 매월 청구됩니다)Billing Cycle: MonthlyCurrency: USDAttach the meter
Token Usage Meter를 추가합니다. 그런 다음 meter에서 다음을 설정합니다:- Bill usage in Credits를 켭니다.
- Credit Entitlement:
API Tokens를 선택합니다. - Meter units per credit:
1— 이벤트의 각 토큰이 차감되는 크레딧 1개에 매핑됩니다. - Free Threshold:
0— 크레딧 할당 자체가 고객의 “free tier”이므로 추가 무료 구간은 필요하지 않습니다.

Toggle 'Bill usage in Credits' on the meter and pick the credit entitlement.
api.tokens_used 이벤트를 고객 잔액에서 실제로 차감하도록 연결합니다.Configure credit issuance for Starter
10000000Allow Overage: Disabled — Starter 고객은 토큰이 소진되면 차단됩니다.Import Default Credit Settings: Enabled — 크레딧 entitlement의 30일 만료를 사용합니다.
Configure credit issuance per cycle on the UBB product.
Pro Plan ($99/월 — 40M 토큰, 초과 사용 허용)
Create the Pro UBB product
NeuralAPI ProDescription: 40 million API tokens per month with overage. Built for production applications.Fixed Price: 99.00Billing Cycle: MonthlyCurrency: USDAttach the meter
Token Usage Meter를 추가하고, Bill usage in Credits를 켜고, API Tokens를 선택한 다음 Meter units per credit을 1, Free Threshold를 0로 설정합니다.Configure credit issuance with overage
40000000Import Default Credit Settings: Disable — 제품별로 초과 사용 설정을 사용자 지정해야 합니다.Allow Overage: EnabledPrice Per Unit: 0.000005 USD/토큰 (즉, 1K 토큰당 5이며, 초과 사용을 억제하기 위해 플랜의 유효 토큰당 요금보다 높게 설정합니다)Overage Behavior: Bill overage at billing — 초과 사용 요금은 다음 invoice에 청구된 후 잔액이 초기화됩니다.제품을 저장하고 제품 ID를 복사합니다.4단계: 토큰 충전 팩 생성
충전 팩은 기존 고객의 잔액에 5,000,000 토큰을 추가하는 일회성 구매 제품입니다.
Single Payment pricing selected for a one-time credit product.
Create a one-time product
- Products → Create Product로 이동합니다.
- 가격 유형으로 Single Payment를 선택합니다.
- 다음을 입력합니다:
Token Top-Up PackDescription: Instantly add 5 million tokens to your NeuralAPI balance.Price: 19.00Currency: USDAttach the token credit
- Entitlements 섹션에서 Credits 옆의 Attach를 클릭합니다.
API Tokens를 선택합니다.- Credits issued를
5000000로 설정합니다. - Import Default Credit Settings을 Disable합니다. 기본 30일 만료를 재정의하려는 목적입니다.
- Credit Expiry를
365 days로 설정합니다. - 제품을 저장합니다.
5단계: 백엔드 구축
이제 구독 checkout, 충전 checkout, 토큰 결제가 적용된 실제 OpenAI completion, 잔액 조회 및 크레딧 webhook 이벤트를 처리하는 Express server를 구축합니다.Set up your project
tsconfig.json을 생성합니다:package.json scripts를 업데이트합니다:Set up environment variables
.env를 생성합니다:DODO_PAYMENTS_WEBHOOK_KEY를 입력합니다.Implement the server
src/server.ts를 생성합니다:A note on how deductions actually happen
- handler가 OpenAI를 호출하고
usage.total_tokens(예: 1532)를 반환받습니다. - 단일 사용량 이벤트를 수집합니다:
event_name: api.tokens_used,metadata: { tokens: 1532 }. Token Usage Meter가 고객별로 이벤트를 집계합니다.- meter가 Bill usage in Credits를 사용해
API Tokens크레딧에 연결되어 있으므로, Dodo Payments가 고객의 만료되지 않은 가장 오래된 지급분에서 1532 크레딧을 차감합니다(FIFO). - 초과 사용이 활성화되어 고객 잔액이 0 미만이 되면 부족분이 추적되고 다음 invoice에 청구됩니다.
6단계: Demo Frontend 추가
브라우저에서 모든 흐름을 테스트할 수 있도록public/index.html를 생성합니다. 고객 ID를 localStorage에 저장하므로 subscribe → generate → top-up이 동일한 identity를 공유하며 로그인된 앱을 재현합니다:
7단계: Webhook 연결
Webhook을 사용하면 server가 잔액 변경에 반응할 수 있습니다. 고객의 잔액이 0이 되기 전에 “잔액 부족” 이메일을 보내는 데 사용합니다.Expose your local server
https://...ngrok-free.app URL을 복사합니다.Register the webhook in Dodo Payments
- dashboard에서 Developers → Webhooks → Add Endpoint로 이동합니다.
- URL:
https://your-tunnel.ngrok-free.app/webhooks/dodo - 최소한 다음 이벤트를 subscribe합니다:
credit.addedcredit.deductedcredit.overage_charged
- 저장하고 Signing Secret을 복사합니다.
- 이를
.env에DODO_PAYMENTS_WEBHOOK_KEY로 붙여넣은 다음npm run dev를 다시 시작합니다.
8단계: 전체 흐름 테스트
Subscribe a test customer
npm run dev를 실행합니다.http://localhost:3000를 엽니다.- Pro Plan을 선택하고 테스트 email과 name을 입력한 후 Get Checkout Link를 클릭합니다. test card details로 checkout을 완료합니다.
- dashboard에서 Customers → most recent로 이동하고
cus_...ID를 복사합니다. - 이를 demo의 “Logged-in customer ID” 필드에 붙여넣고 Save를 클릭합니다.
Generate a real AI response
total_tokens를 반환받은 뒤 사용량 이벤트를 수집하고 응답을 반환합니다.Test the top-up flow
credit.added 이벤트가 표시되어야 합니다.문제 해결
Credits not deducting after usage events
Credits not deducting after usage events
- meter의 이벤트 이름이 전송하는
event_name와 일치하지 않음(api.tokens_used는 대소문자를 구분함) - meter가 제품의
API Tokens크레딧에 연결되지 않음. 제품의 meter 설정으로 이동해 Bill usage in Credits가 켜져 있는지 확인 metadata.tokenskey가 meter의 “Over Property” 필드와 일치하지 않음- 고객의 grant가 만료됨(고객의 크레딧 history 확인)
- Products → Meters: meter를 열고 제품 연결에 연결된 크레딧 이름이 표시되는지 확인
- meter의 Events 탭: 차감 전에도 수집된 이벤트가 여기에 표시되어야 함
- Customers → [Customer] → Credits: 1~2분 이내에 ledger entry가 표시되어야 함
Balance always shows 0 or 'customer not found'
Balance always shows 0 or 'customer not found'
- 고객이 아직 checkout을 완료하지 않음. 크레딧은 결제가 성공한 후에만 지급됨
- 잘못된
customer_id로 조회함(dashboard의cus_...ID를 사용하며 자체 DB ID는 사용하지 않음) .env의CREDIT_ENTITLEMENT_ID가 제품에 연결된 크레딧과 일치하지 않음
Overage not working for Pro plan customers
Overage not working for Pro plan customers
- Pro product의 credit attachment에서 초과 사용이 활성화되지 않음(credit-level 설정은 기본값일 뿐임)
- 고객이 실제로는 Pro가 아니라 Starter를 사용 중임
- 초과 사용 limit가 0으로 설정됨
0.000005인지 확인합니다(= 1백만 토큰당 $5. 앞의 0을 다시 확인하세요. 이 필드는 1K당 가격이 아니라 토큰당 가격을 입력합니다).`Webhook verification failed` in logs
`Webhook verification failed` in logs
- Body parsing 순서:
express.json()가/webhooks/dodo에express.raw()보다 먼저 적용됨. SDK에는 parsing된 JSON이 아니라 request의 raw bytes가 필요함 DODO_PAYMENTS_WEBHOOK_KEY의 signing secret이 잘못됨- Reverse proxy가 header를 재작성함
app.use('/webhooks/dodo', express.raw(...)) line이 server.ts에서 app.use(express.json())보다 앞에 있는지 확인합니다.도움이 필요하신가요?
축하합니다! NeuralAPI에 크레딧 기반 결제를 구축했습니다
이제 플랫폼에 완전한 production-ready 크레딧 결제 시스템이 갖춰졌습니다:Token Credit Entitlement
API Tokens 크레딧Tiered Plans, One Credit
One-Time Top-Up Pack
Auto-Deduction via Meter
Live Balance API
Verified Webhook Pipeline
credit.added, credit.deducted, credit.overage_charged)/credits/:customerId및/api/generate에 auth 적용 — 현재는 누구나 임의의 customer ID로 호출할 수 있습니다. 사용자를 인증하고 server-side에서 해당 사용자의 customer ID를 조회하세요.- 안정적인
event_ids — 예제에서는Date.now() + random를 사용합니다. production에서는 request ID를 사용해 retry가 idempotent하도록 하세요(Dodo Payments가event_id별로 중복 제거함). - customer↔user mapping 저장 — 첫 checkout 후 DB에
customer_id를 저장하여 수동으로 붙여넣는 단계를 없애세요. - 구독 종료 시 동작 결정 — 플랜 크레딧은 자연 만료(지급 후 30일)까지 고객 ledger에 남고 충전 크레딧은 365일 동안 유효합니다. 하지만 cookbook의
/api/generate는 구독 상태가 아니라 잔액만 확인합니다. 따라서 취소된 고객도 남은 토큰을 사용할 수 있습니다. 이는 소비자 친화적인 기본 동작입니다. 더 엄격한 access control이 필요하면 (a)subscription.cancelledwebhook을 수신해 구독 상태에 따라/api/generate를 허용하거나, (b) Dodo의 ledger API를 호출해 취소 시 사용하지 않은 플랜 크레딧을 차감하되 충전 크레딧은 유지하세요. - Usage Billing dashboard를 모니터링하여 metering 이상을 조기에 발견하세요.