Skip to main content

사전 요구 사항

시작하기 전에 다음이 필요합니다:
  • Dodo Payments merchant account
  • 대시보드의 Developer → API Keys에서 발급한 API key를 DODO_PAYMENTS_API_KEY에 저장
  • Developer → Webhooks에서 발급한 webhook secret을 DODO_PAYMENTS_WEBHOOK_KEY에 저장
  • Products에서 생성된 subscription product 하나 이상
자세한 내용은 Integration Guide Prerequisites를 참조하세요.

API 통합

Checkout Session

subscription product를 사용해 Checkout Session을 생성하여 subscription을 만듭니다. 고객이 payment method를 승인하면 Checkout을 완료하는 즉시 subscription이 활성화됩니다.
동일한 checkout session에서 subscription product와 one-time product를 결합할 수 있습니다. 이를 통해 setup fee, SaaS와 하드웨어 번들 및 이와 유사한 사용 사례를 구현할 수 있습니다. 예시는 Checkout Sessions를 참조하세요.하나의 checkout에서 두 개 이상의 subscription product를 판매할 수도 있습니다. 고객은 한 번 결제하고 product별로 독립적인 subscription 하나씩을 받으며, 각 subscription에는 고유한 billing cycle이 적용됩니다. 이러한 cart에는 one-time product를 담을 수 없습니다. Multi-Subscription Cart를 참조하세요.

API Response

응답에는 다음이 포함됩니다 checkout_url:
고객을 이 URL로 리디렉션하세요. 고객은 payment method를 인증하고 subscription이 활성화됩니다.

Webhooks

subscription event가 발생하면 Webhooks가 서버에 알립니다. dashboard의 Developer → Webhooks에서 endpoint를 설정하세요. webhook endpoint를 설정하려면 Webhooks를 참조하세요.

Subscription Event Types

subscription lifecycle을 관리하려면 다음 event를 추적하세요:
  1. subscription.active — Subscription이 활성화됨
  2. subscription.updated — Subscription의 field가 변경됨
  3. subscription.on_hold — renewal 또는 plan-change charge가 실패함
  4. subscription.failed — Subscription 생성에 실패함(최종 상태이며 고객이 다시 subscribe해야 함)
  5. subscription.renewed — recurring charge가 성공함
  6. subscription.past_due — renewal이 실패하고 grace period가 시작됨. 고객은 past_due_ends_at까지 access를 유지함
  7. subscription.plan_changed — Plan이 upgrade, downgrade 또는 변경됨
  8. subscription.cancelled — Subscription이 취소됨
  9. subscription.expired — Subscription이 term 종료에 도달함
이 event가 핵심 event입니다. paused, unpaused, update_payment_method을 포함한 전체 목록은 Subscription Webhooks를 참조하세요.
subscription.updated를 사용하면 모든 subscription 변경에 대한 실시간 알림을 받아 API를 polling하지 않고도 애플리케이션 상태를 동기화할 수 있습니다.

Payment Scenarios

Successful Payment Flow webhook sequence는 subscription에 trial이 있는지에 따라 달라집니다. Immediate billing (0 trial days):
  1. subscription.active: mandate가 인증되고 subscription이 활성화됩니다.
  2. payment.succeeded: 첫 번째 charge를 확인합니다. checkout 후 2~10분 이내에 수신될 것으로 예상하세요.
With a trial period:
  1. trial 시작 시(checkout): payment method가 인증되면 subscription.active가 발생합니다. 아직 recurring charge는 청구되지 않습니다. 첫 번째 실제 charge는 trial 종료 시점까지 연기됩니다.
  2. trial 종료 시: recurring amount가 청구되고 payment.succeeded를 subscription.renewed와 함께 수신합니다.
Every subsequent renewal:
  • subscription.renewed: 각 billing cycle에서 renewal payment가 차감될 때 발생하며, 항상 payment.succeeded와 함께 전송됩니다. 또한 업데이트된 next_billing_date도 포함합니다.
subscription product에 대해 실제로 금액이 차감될 때마다 subscription.renewed 및 payment.succeeded를 수신합니다. 다음 cycle로 access를 연장하는 신호로는 payment.succeeded만 사용하는 대신 subscription.renewed를 사용하세요.
Payment Failure Scenarios
  1. Subscription Failure
  • subscription.failed - mandate 생성에 실패하여 Subscription 생성에 실패했습니다.
  • payment.failed - payment 실패를 나타냅니다.
  1. Subscription On Hold
  • subscription.on_hold - renewal payment 또는 plan change charge 실패로 Subscription이 on hold 상태가 됩니다. 비즈니스에 grace period가 있는 경우, renewal 실패 시 먼저 Subscription이 past_due(subscription.past_due)로 이동하며, grace period가 종료될 때에만 on_hold(또는 grace period 설정에 따라 cancelled)로 이동합니다. Subscription States를 참조하세요.
  • Subscription이 on hold 상태가 되면 payment method가 업데이트될 때까지 자동으로 renewal되지 않습니다.
Best Practice: 구현을 간소화하려면 subscription lifecycle 관리 시 주로 subscription event를 추적하는 것이 좋습니다.
error_code/error_message를 읽고, 재시도 시점을 결정하며, 고객에게 실패를 표시하는 전체 안내는 Handle Payment Failures를 참조하세요.

subscription.failed vs. subscription.on_hold

이 두 event는 혼동하기 쉽지만 처리 방식은 매우 다릅니다:
subscription.failed는 최종 상태입니다. Subscription을 다시 활성화할 수 없습니다. 고객은 새 subscription을 생성해야 합니다. 이 event가 발생하면 절대 entitlement를 부여하지 마세요.

Handling Subscription On Hold

Subscription이 on_hold 상태가 되면 다시 활성화하기 위해 payment method를 업데이트해야 합니다. 이 섹션에서는 subscription이 on hold 상태가 되는 시점과 처리 방법을 설명합니다.

When Subscriptions Go On Hold

다음과 같은 경우 Subscription이 on hold 상태가 됩니다:
  • Renewal payment 실패: 자금 부족, 만료된 카드 또는 bank decline으로 automatic renewal charge가 실패함
  • Plan change charge 실패: plan upgrade/downgrade 중 즉시 charge가 실패함
  • Payment method authorization 실패: recurring charge에 대해 payment method를 인증할 수 없음
on_hold 상태의 Subscription은 자동으로 renewal되지 않습니다. Subscription을 다시 활성화하려면 payment method를 업데이트해야 합니다.

Reactivating Subscriptions from On Hold

on_hold 상태의 Subscription을 다시 활성화하려면 Update Payment Method API를 사용하세요. 이 API는 자동으로 다음을 수행합니다:
  1. 미납 잔액에 대한 charge 생성
  2. charge에 대한 invoice 생성
  3. 새 payment method를 사용하여 payment 처리
  4. payment 성공 시 Subscription을 active 상태로 다시 활성화
1

Handle subscription.on_hold webhook

subscription.on_hold webhook을 수신하면 애플리케이션 상태를 업데이트하고 고객에게 알리세요:
2

Update payment method

고객이 payment method를 업데이트할 준비가 되면 Update Payment Method API를 호출하세요:
고객이 payment method를 저장해 둔 경우 기존 payment method ID를 사용할 수도 있습니다:
3

Monitor webhook events

payment method를 업데이트한 후 다음 webhook event를 모니터링하세요:
  1. payment.succeeded - 미납 잔액에 대한 charge가 성공함
  2. subscription.active - Subscription이 다시 활성화됨

Sample Subscription Event Payload


Changing Subscription Plans

change plan API endpoint를 사용하여 subscription plan을 upgrade 또는 downgrade할 수 있습니다. 이를 통해 subscription의 product와 quantity를 수정하고 proration을 처리할 수 있습니다.

Change Plan API Reference

subscription plan 변경에 대한 자세한 내용은 Change Plan API 문서를 참조하세요.

Proration Options

subscription plan을 변경할 때 즉시 charge 처리 방법으로 네 가지 옵션을 사용할 수 있습니다:

1. prorated_immediately

  • 남은 시간을 기준으로 prorate하여 현재 billing cycle의 사용하지 않은 부분을 credit으로 제공합니다. 이 credit에는 base plan, quantity 및 add-on이 반영됩니다.
  • 그런 다음 새 plan, quantity 및 add-on에 대해 전체 cycle을 청구합니다. charge 자체는 절대 prorate되지 않습니다.
  • 순 즉시 charge = (새 전체 cycle) - (남은 비율 x 기존 전체 cycle). credit이 더 큰 경우 차액은 subscription-scoped credit으로 보관되어 향후 renewal에 사용됩니다.
  • trial period 중에는 사용자가 즉시 새 plan으로 전환되고 고객에게 바로 charge됩니다.

2. full_immediately

  • 이전 cycle에 대한 credit 없이 새 plan의 전체 subscription amount를 고객에게 청구합니다.
  • upgrade와 downgrade 모두 고객은 새 plan의 전체 가격을 처음부터 지불합니다.
  • 기존 plan에 남은 기간과 관계없이 전체 금액을 청구하려는 경우 유용합니다.

3. difference_immediately

  • 고객은 기존 plan 가격과 새 plan 가격의 차액만 지불합니다.
  • 금액은 cycle 중 언제 변경하는지에 따라 달라지지 않습니다. 1일 차와 29일 차의 동일한 upgrade 비용은 같습니다.
  • upgrade 시 고객에게 차액이 즉시 청구됩니다. 예: $30/month → $80/month = 즉시 $50 청구
  • downgrade 시 가격 차액은 subscription-scoped credit으로 저장되어 향후 renewal에 자동 적용됩니다. 예: $50/month → $20/month = $30이 credit으로 저장

4. do_not_bill

  • plan 변경을 즉시 적용하지만 변경 시점에는 아무것도 청구하지 않습니다. 새 plan, quantity 및 add-on을 즉시 사용할 수 있습니다.
  • 현재 청구 cycle의 남은 기간 동안 upgrade된 상위 plan을 무료로 제공하게 됩니다. downgrade는 이미 결제한 cycle의 미사용 부분에 대한 credit 없이 즉시 적용됩니다.
  • do_not_bill를 통해 부여된 add-on은 청구된 적이 없으므로 이후 plan 변경 시 credit되지 않습니다. 이후 변경 시 새 add-on quantity 전체가 청구됩니다.
  • 업데이트된 plan(및 quantity/add-on)은 다음 예정 renewal에 청구되며, 기존 billing date는 유지됩니다.
세 가지 “charge now” mode는 모두 billing cycle을 재설정합니다. prorated_immediately, difference_immediately 및 full_immediately는 Subscription의 next_billing_date를 변경일로 이동합니다. do_not_bill만 기존 renewal date를 유지하지만 즉시 charge는 적용하지 않습니다.

Behavior

  • 이 API를 호출하면 Dodo Payments가 선택한 proration option에 따라 즉시 charge를 시작합니다.
  • prorated_immediately를 사용하면 upgrade 또는 downgrade에 관계없이 변경할 때마다 현재 cycle의 미사용 부분에 대한 credit이 계산됩니다. 이 credit이 새 cycle charge를 초과하면 나머지가 subscription의 credit balance에 추가됩니다. 이 credit은 해당 subscription에만 적용되며 동일한 subscription의 향후 recurring payment를 상쇄하는 데만 사용됩니다.
  • difference_immediately를 사용하면 순액은 항상 정확한 가격 차액입니다. downgrade의 초과분은 prorated_immediately와 동일하게 subscription-scoped credit으로 저장됩니다.
  • full_immediately option은 credit 계산을 건너뛰고 새 plan의 전체 amount를 청구합니다.
  • do_not_bill option은 변경을 즉시 적용하지만 billing을 다음 renewal date까지 연기하며, 해당 date는 유지됩니다.
proration mode 선택:
  • difference_immediately — 고객이 가격 차액을 지불합니다. 가장 예측 가능한 option이며 cycle 중 언제 변경해도 charge가 동일합니다.
  • prorated_immediately — 고객은 현재 cycle에서 사용하지 않은 시간에 대해서만 credit을 받습니다. charge는 cycle 중 변경 시점에 따라 달라집니다.
  • full_immediately — 고객이 새 plan의 전체 amount를 지불합니다. 이전 cycle에 대한 credit은 없습니다.
  • do_not_bill — 지금은 charge하지 않습니다. 새 plan은 다음 renewal에 청구됩니다. 기존 billing date를 유지하는 유일한 mode입니다.

Charge Processing

  • plan 변경 시 시작된 즉시 charge는 일반적으로 2분 이내에 처리가 완료됩니다.
  • 이 즉시 charge가 어떤 이유로든 실패하면 문제가 해결될 때까지 Subscription이 자동으로 on hold 상태가 됩니다.

On-Demand Subscriptions

On-demand subscription을 사용하면 고정된 일정이 아니라 유연한 방식으로 고객에게 charge할 수 있습니다. 이 기능은 모든 account에서 사용할 수 있습니다.
on-demand subscription을 생성하려면: on-demand subscription을 생성하려면 POST /checkouts API endpoint를 사용하고 request body에 subscription_data.on_demand field를 포함하세요. 이를 통해 즉시 charge 없이 payment method를 인증하거나 custom initial price를 설정할 수 있습니다.
POST /subscriptions는 deprecated되었습니다. 기존 integration에서는 계속 작동하지만, 새로운 integration은 subscription_data.on_demand를 포함한 Checkout Session(POST /checkouts)을 통해 on-demand subscription을 생성해야 합니다. 현재 flow는 On-Demand Subscriptions Guide를 참조하세요.
on-demand subscription에 charge하려면: 후속 charge에는 POST /subscriptions//charge endpoint를 사용하고 해당 transaction에서 고객에게 charge할 amount를 지정하세요.
request/response example, 안전한 retry policy 및 webhook 처리를 포함한 단계별 전체 안내는 On-Demand Subscriptions Guide를 참조하세요.

Subscription Billing에 대해 알아야 할 주요 사항

subscription period를 payment frequency보다 길게 설정하세요. subscription period가 payment frequency와 같으면(예: period = 1 month, frequency = 1 month) subscription은 단일 cycle 동안만 유효하고 renewal되지 않은 채 expired로 이동합니다. 지속적인 monthly plan의 경우 긴 subscription period(예: 20 years)와 monthly payment frequency를 설정하세요.
첫 번째 successful charge에서 Currency가 고정됩니다. checkout 생성 시 billing_currency 및 billing_address.country를 항상 명시적으로 전달하세요. 생략하면 고객의 IP(Adaptive Currency)를 기준으로 감지되며, Subscription이 첫 charge를 수행하면 해당 currency가 수명 동안 고정됩니다. 이후 고객이 여행하더라도 변경할 수 없습니다.
trial은 charge가 아닌 $0 authorization을 수행합니다. Subscription에 trial이 있으면 trial 시작 시 카드를 저장하기 위해 $0 mandate authorization이 생성됩니다. 첫 번째 실제 charge는 trial 종료 시 발생합니다. payments list에서 free trial 중인 Subscription에는 total_amount가 0인 payment가 정확히 하나 표시됩니다. paid trial은 대신 trial_amount를 선불로 charge합니다.
Subscription lifecycle: past_due = renewal이 실패하고 grace period가 진행 중이며 고객은 access를 유지합니다. on_hold = renewal이 실패했으며 복구할 수 있습니다. 고객에게 payment method 업데이트를 요청하고 dunning retry가 적용됩니다. expired = term이 renewal 없이 종료되었으며 다시 활성화할 수 없습니다. 고객은 다시 subscribe해야 합니다. cancelled = 고객 또는 merchant가 종료했습니다. 대부분의 renewal 실패는 Dodo 오류가 아니라 issuer 측 decline(자금 부족, 카드 거부)입니다.
Indian card는 RBI e-mandate를 사용합니다. off-session charge(renewal 및 plan-change charge)는 정산까지 최대 약 48시간이 걸릴 수 있으며, ₹15,000 초과 recurring auto-debit에는 새로운 고객 인증이 필요합니다(따라서 이 한도를 초과하는 upgrade는 기존 mandate를 사용할 수 없습니다). 하나의 charge가 아직 processing인 동안 동일한 Subscription에 대한 두 번째 charge는 “Cannot create new charge as previous payment is not successful yet.” 오류와 함께 실패합니다. Non-Indian card는 거의 즉시 확인됩니다.
Subscription은 USD에서 $1.00 minimum을 적용합니다. checkout은 TOTAL_PAYMENT_AMOUNT_BELOW_MINIMUM_AMOUNT와 함께 더 낮은 total을 거부합니다. USD, EUR 및 GBP 이외의 currency도 최소 $1.00의 가치가 있어야 합니다. Minimum Amounts를 참조하세요. product_price on-demand charge가 가장 작은 currency unit 기준 100 미만이면 product_price: value out of range와 함께 거부됩니다. 정확히 $0로 가격이 책정된 subscription product는 허용됩니다. Card-Optional at Zero Price를 참조하세요. 카드에 charge하지 않고 인증하려면 on-demand mandate_only setup을 사용하세요.

Create Subscription (Deprecated)

Subscription을 직접 생성하기 위한 Legacy API입니다. 새로운 integration에는 Checkout Sessions를 사용하세요.

Change Subscription Plan

proration option을 사용하여 subscription plan을 upgrade, downgrade 또는 변경하기 위한 API reference

Update Payment Method

payment method를 업데이트하고 on-hold Subscription을 다시 활성화하기 위한 API reference

Patch Subscription

subscription detail 및 configuration을 업데이트하기 위한 API reference
마지막 수정일 2026년 10월 8일