메인 콘텐츠로 건너뛰기

전제 조건

Dodo Payments API를 통합하려면 다음이 필요합니다:
  • Dodo Payments 상인 계정
  • 대시보드에서 API 자격 증명 (API 키 및 웹훅 비밀 키)
전제 조건에 대한 자세한 가이드는 이 섹션을 확인하세요.

API 통합

체크아웃 세션

안전하게 호스팅된 체크아웃으로 구독 제품을 판매하려면 체크아웃 세션을 사용하세요. 구독 제품을 product_cart에 전달하고 고객을 반환된 checkout_url로 리디렉션하세요.
같은 체크아웃 세션에서 구독 제품과 일회성 제품을 혼합할 수 없습니다.
import DodoPayments from 'dodopayments';

const client = new DodoPayments({
  bearerToken: process.env.DODO_PAYMENTS_API_KEY,
  environment: 'test_mode', // defaults to 'live_mode'
});

async function main() {
  const session = await client.checkoutSessions.create({
    product_cart: [
      { product_id: 'prod_subscription_monthly', quantity: 1 }
    ],
    // Optional: configure trials for subscription products
    subscription_data: { trial_period_days: 14 },
    customer: {
      email: '[email protected]',
      name: 'Jane Doe',
    },
    return_url: 'https://example.com/success',
  });

  console.log(session.checkout_url);
}

main();

API 응답

다음은 응답의 예입니다:
{
  "session_id": "cks_Gi6KGJ2zFJo9rq9Ukifwa",
  "checkout_url": "https://test.checkout.dodopayments.com/session/cks_Gi6KGJ2zFJo9rq9Ukifwa"
}
고객을 checkout_url로 리디렉션하세요.

웹훅

구독을 통합할 때 구독 생애 주기를 추적하기 위해 웹훅을 받게 됩니다. 이러한 웹훅은 구독 상태 및 결제 시나리오를 효과적으로 관리하는 데 도움을 줍니다. 웹훅 엔드포인트를 설정하려면 자세한 통합 가이드를 따르세요.

구독 이벤트 유형

다음 웹훅 이벤트는 구독 상태 변경을 추적합니다:
  1. subscription.active - 구독이 성공적으로 활성화되었습니다.
  2. subscription.updated - 구독 객체가 업데이트되었습니다 (모든 필드 변경 시 발생).
  3. subscription.on_hold - 갱신 실패로 인해 구독이 보류 상태로 전환되었습니다.
  4. subscription.failed - 위임 생성 중 구독 생성에 실패했습니다.
  5. subscription.renewed - 다음 청구 주기를 위해 구독이 갱신되었습니다.
신뢰할 수 있는 구독 생애 주기 관리를 위해 이러한 구독 이벤트를 추적하는 것을 권장합니다.
subscription.updated을 사용하여 구독 변경에 대한 실시간 알림을 받아 애플리케이션 상태를 API를 폴링하지 않고 동기화하세요.

결제 시나리오

성공적인 결제 흐름 결제가 성공하면 다음 웹훅을 받게 됩니다:
  1. subscription.active - 구독 활성화를 나타냅니다.
  2. payment.succeeded - 초기 결제를 확인합니다:
    • 즉시 청구(0일 체험): 2-10분 이내 예상
    • 체험 기간: 종료 시점에
  3. subscription.renewed - 결제 공제 및 다음 주기를 위한 갱신을 나타냅니다. (기본적으로, 구독 제품에 대한 결제가 공제될 때마다 subscription.renewed 웹훅과 함께 payment.succeeded를 받게 됩니다.)
결제 실패 시나리오
  1. 구독 실패
  • subscription.failed - 위임 생성 실패로 인해 구독 생성에 실패했습니다.
  • payment.failed - 결제 실패를 나타냅니다.
  1. 구독 보류
  • subscription.on_hold - 갱신 결제 실패 또는 요금 변경 실패로 인해 구독이 보류 상태로 전환되었습니다.
  • 구독이 보류 상태가 되면 결제 방법이 업데이트될 때까지 자동으로 갱신되지 않습니다.
모범 사례: 구현을 단순화하기 위해 구독 생애 주기를 관리하기 위해 주로 구독 이벤트를 추적하는 것을 권장합니다.

구독 보류 처리

구독이 on_hold 상태에 들어가면 결제 방법을 업데이트하여 재활성화해야 합니다. 이 섹션에서는 구독이 보류 상태가 되는 경우와 이를 처리하는 방법을 설명합니다.

구독이 보류 상태가 되는 경우

구독이 보류 상태가 되는 경우는 다음과 같습니다:
  • 갱신 결제 실패: 자동 갱신 요금이 자금 부족, 카드 만료 또는 은행 거부로 인해 실패합니다.
  • 요금 변경 실패: 요금 업그레이드/다운그레이드 중 즉시 요금이 실패합니다.
  • 결제 방법 승인 실패: 결제 방법이 반복 청구를 위해 승인될 수 없습니다.
on_hold 상태의 구독은 자동으로 갱신되지 않습니다. 구독을 재활성화하려면 결제 방법을 업데이트해야 합니다.

보류 상태에서 구독 재활성화

보류 상태에서 구독을 재활성화하려면 결제 방법 업데이트 API를 사용하세요. 이 과정은 자동으로:
  1. 남은 요금에 대한 청구를 생성합니다.
  2. 청구에 대한 송장을 생성합니다.
  3. 새 결제 방법을 사용하여 결제를 처리합니다.
  4. 성공적인 결제 후 구독을 active 상태로 재활성화합니다.
1

subscription.on_hold 웹훅 처리

subscription.on_hold 웹훅을 받으면 애플리케이션 상태를 업데이트하고 고객에게 알리세요:
// Webhook handler
app.post('/webhooks/dodo', async (req, res) => {
  const event = req.body;
  
  if (event.type === 'subscription.on_hold') {
    const subscription = event.data;
    
    // Update subscription status in your database
    await updateSubscriptionStatus(subscription.subscription_id, 'on_hold');
    
    // Notify customer to update payment method
    await sendEmailToCustomer(subscription.customer_id, {
      subject: 'Payment Required - Subscription On Hold',
      message: 'Your subscription is on hold. Please update your payment method to continue service.'
    });
  }
  
  res.json({ received: true });
});
2

결제 방법 업데이트

고객이 결제 방법을 업데이트할 준비가 되면 결제 방법 업데이트 API를 호출하세요:
// Update with new payment method
const response = await client.subscriptions.updatePaymentMethod(subscriptionId, {
  type: 'new',
  return_url: 'https://example.com/return'
});

// For on_hold subscriptions, a charge is automatically created
if (response.payment_id) {
  console.log('Charge created for remaining dues:', response.payment_id);
  // Redirect customer to response.payment_link to complete payment
}
고객이 저장된 결제 방법이 있는 경우 기존 결제 방법 ID를 사용할 수도 있습니다:
await client.subscriptions.updatePaymentMethod(subscriptionId, {
  type: 'existing',
  payment_method_id: 'pm_abc123'
});
3

웹훅 이벤트 모니터링

결제 방법을 업데이트한 후 다음 웹훅 이벤트를 모니터링하세요:
  1. payment.succeeded - 남은 요금에 대한 청구가 성공적이었습니다.
  2. subscription.active - 구독이 재활성화되었습니다.
if (event.type === 'payment.succeeded') {
  const payment = event.data;
  
  // Check if this payment is for an on_hold subscription
  if (payment.subscription_id) {
    // Wait for subscription.active webhook to confirm reactivation
  }
}

if (event.type === 'subscription.active') {
  const subscription = event.data;
  
  // Update subscription status in your database
  await updateSubscriptionStatus(subscription.subscription_id, 'active');
  
  // Restore customer access
  await restoreCustomerAccess(subscription.customer_id);
  
  // Notify customer of successful reactivation
  await sendEmailToCustomer(subscription.customer_id, {
    subject: 'Subscription Reactivated',
    message: 'Your subscription has been reactivated successfully.'
  });
}

샘플 구독 이벤트 페이로드


속성유형필수설명
business_idstring비즈니스를 위한 고유 식별자
timestampstring이벤트가 발생한 시간의 타임스탬프 (반드시 전달된 시간과 같지 않을 수 있음)
typestring이벤트 유형. 이벤트 유형을 참조하세요.
dataobject주요 데이터 페이로드. 데이터 객체를 참조하세요.

구독 요금 변경

구독 요금을 변경 API 엔드포인트를 사용하여 구독 요금을 업그레이드하거나 다운그레이드할 수 있습니다. 이를 통해 구독의 제품, 수량을 수정하고 비례 배분을 처리할 수 있습니다.

요금 변경 API 참조

구독 요금 변경에 대한 자세한 정보는 요금 변경 API 문서를 참조하세요.

비례 배분 옵션

구독 요금을 변경할 때 즉시 요금을 처리하는 두 가지 옵션이 있습니다:

1. prorated_immediately

  • 현재 청구 주기에서 남은 시간을 기준으로 비례 배분 금액을 계산합니다.
  • 고객에게 이전 요금과 새로운 요금의 차이만 청구합니다.
  • 체험 기간 동안, 사용자를 즉시 새로운 요금으로 전환하고 고객에게 즉시 청구합니다.

2. full_immediately

  • 고객에게 새로운 요금의 전체 구독 금액을 청구합니다.
  • 이전 요금의 남은 시간이나 크레딧은 무시합니다.
  • 청구 주기를 재설정하거나 비례 배분과 관계없이 전체 금액을 청구하고자 할 때 유용합니다.

3. difference_immediately

  • 업그레이드 시, 고객은 두 요금의 차액을 즉시 청구받습니다.
  • 예를 들어, 현재 요금이 30달러이고 고객이 80달러로 업그레이드하면 즉시 50달러가 청구됩니다.
  • 다운그레이드 시, 현재 요금의 사용되지 않은 금액이 내부 크레딧으로 추가되어 향후 구독 갱신에 자동으로 적용됩니다.
  • 예를 들어, 현재 요금이 50달러이고 고객이 20달러 요금으로 전환하면 남은 30달러가 크레딧으로 추가되어 다음 청구 주기에 사용됩니다.

동작

  • 이 API를 호출하면 Dodo Payments는 선택한 비례 배분 옵션에 따라 즉시 청구를 시작합니다.
  • 요금 변경이 다운그레이드이고 prorated_immediately를 사용하는 경우, 크레딧이 자동으로 계산되어 구독의 크레딧 잔액에 추가됩니다. 이러한 크레딧은 해당 구독에만 적용되며 동일한 구독의 향후 반복 결제를 상쇄하는 데만 사용됩니다.
  • full_immediately 옵션은 크레딧 계산을 우회하고 전체 새로운 요금 금액을 청구합니다.
비례 배분 옵션을 신중하게 선택하세요: 사용되지 않은 시간을 고려한 공정한 청구를 위해 prorated_immediately를 사용하거나, 현재 청구 주기와 관계없이 전체 새로운 요금 금액을 청구하고자 할 때 full_immediately를 사용하세요.

청구 처리

  • 요금 변경 시 즉시 시작된 청구는 보통 2분 이내에 처리됩니다.
  • 이 즉시 청구가 어떤 이유로든 실패하면 구독은 문제가 해결될 때까지 자동으로 보류 상태로 전환됩니다.

주문형 구독

주문형 구독은 고객에게 고정된 일정이 아닌 유연하게 요금을 청구할 수 있게 해줍니다. 이 기능을 활성화하려면 지원팀에 문의하세요.
주문형 구독을 생성하려면: 주문형 구독을 생성하려면 POST /subscriptions API 엔드포인트를 사용하고 요청 본문에 on_demand 필드를 포함하세요. 이를 통해 즉시 청구 없이 결제 방법을 승인하거나 사용자 정의 초기 가격을 설정할 수 있습니다. 주문형 구독에 요금을 청구하려면: 후속 요금 청구를 위해 POST /subscriptions/charge 엔드포인트를 사용하고 해당 거래에 대해 고객에게 청구할 금액을 지정하세요.
완전한 단계별 가이드를 보려면—요청/응답 예제, 안전한 재시도 정책 및 웹훅 처리 포함—주문형 구독 가이드를 참조하세요.