अवलोकन
ऑन-डिमांड सब्सक्रिप्शन से आप किसी customer के payment method को एक बार authorize कर सकते हैं और फिर fixed schedule के बजाय, आवश्यकता होने पर variable amounts charge कर सकते हैं। यह सुविधा सभी accounts के लिए उपलब्ध है—किसी approval की आवश्यकता नहीं है। इस गाइड का उपयोग इन कार्यों के लिए करें:- ऑन-डिमांड सब्सक्रिप्शन बनाएँ (optional initial price के साथ mandate authorize करें)
- custom amounts के साथ subsequent charges trigger करें
- webhooks का उपयोग करके outcomes track करें
आवश्यकताएँ
- Dodo Payments merchant account और API key
- Webhook secret configured हो और events प्राप्त करने के लिए एक endpoint हो
- आपके catalog में एक subscription product
ऑन-डिमांड कैसे काम करता है
- आप payment method को authorize करने और optional initial charge collect करने के लिए
on_demandobject के साथ subscription बनाते हैं। - बाद में, dedicated charge endpoint का उपयोग करके उस subscription पर custom amounts के charges बनाते हैं।
- अपने system को update करने के लिए webhooks (जैसे
payment.succeeded,payment.failed) सुनते हैं।
ऑन-डिमांड सब्सक्रिप्शन बनाएँ
Endpoint: POST /checkouts मुख्य request fields (body):इन्हें Create Checkout Session में देखें
ऑन-डिमांड सब्सक्रिप्शन बनाएँ
- Node.js SDK
- Python SDK
- Go SDK
- cURL
Success
ऑन-डिमांड सब्सक्रिप्शन पर charge करें
Mandate authorize होने के बाद, आवश्यकता के अनुसार charges बनाएँ। Endpoint: POST /subscriptions/{subscription_id}/charge मुख्य request fields (body):Charge request body parameters
Charge request body parameters
integer
आवश्यक
Charge की जाने वाली राशि (currency की सबसे छोटी unit में)। उदाहरण: $25.00 charge करने के लिए
2500 pass करें।string
Charge के लिए optional currency override।
string
इस charge के लिए optional description override।
boolean
यदि true है, तो
product_price में Adaptive Currency fees शामिल होती हैं। यदि false है, तो fees अलग से जोड़ी जाती हैं।object
इस charge को settle करने के लिए customer’s wallet balance का उपयोग कैसे किया जाए, यह निर्दिष्ट करें।
object
Payment के लिए अतिरिक्त metadata। यदि इसे छोड़ दिया जाता है, तो subscription metadata का उपयोग किया जाता है।
- Node.js SDK
- Python SDK
- Go SDK
- cURL
Success
विफल charges को संभालना
जब on-demand subscription पर किया गया charge विफल होता है, तो आप तय करते हैं कि आगे क्या होगा। Scheduled subscriptions के विपरीत — जहाँ विफल renewal आगे की automatic billing रोक देता है — on-demand subscriptions विफलता के बाद भी chargeable रहती हैं। आप अपनी retry logic के हिस्से के रूप में charge endpoint को फिर से call कर सकते हैं।विफलता पर क्या होता है
1
Charge attempt fails
POST /subscriptions/{subscription_id}/charge request या तो error response लौटाती है या asynchronously पूरी होती है और decline reason के साथ payment.failed webhook भेजती है।2
Subscription may transition to on_hold
Subscription
on_hold state में जा सकती है और subscription.on_hold webhook भेज सकती है (देखें Subscription States → On Hold)। यह एक signal है — lock नहीं। On-demand subscriptions के लिए, on_hold आपको दोबारा charge करने से नहीं रोकता।3
Retry the charge (your call)
On-demand flows के लिए, Dodo अपने-आप retry नहीं करता। Retry करने के लिए आप किसी भी समय
POST /subscriptions/{subscription_id}/charge को फिर से call कर सकते हैं। नीचे दी गई safe retry policy लागू करें — exponential backoff का उपयोग करें, hard declines को छोड़ दें और burst patterns से बचें — ताकि हमारे fraud और risk systems retries को flag न करें।4
Optionally, ask the customer for a new payment method
यदि payment method के खराब होने के कारण retries लगातार विफल होती रहें (expired card, closed account आदि), तो customer से नया payment method लेने के लिए
POST /subscriptions/{subscription_id}/update-payment-method का उपयोग करें। सफल होने पर subscription active में लौट आती है और payment.succeeded के बाद subscription.active webhooks भेजे जाते हैं।On-demand बनाम scheduled: Scheduled subscriptions के लिए Dodo अपनी renewal retries और dunning चलाता है। On-demand subscriptions के लिए retry policy आपकी जिम्मेदारी है, क्योंकि केवल आप जानते हैं कि अगला charge कब होना चाहिए (यह calendar के बजाय आपके usage events से निर्धारित होता है)।
विफल on-demand charge पर webhook sequence
Events 3 और 4 केवल follow-up charge के सफल होने के बाद भेजे जाते हैं।
Retry की जिम्मेदारी
Subscription Dunning — built-in email recovery sequence — scheduled subscriptions पर विफल renewal payments और customer-initiated cancellations तक सीमित है। इसे on-demand charge failures के लिए डिज़ाइन नहीं किया गया है। जब आपको लगे कि payment method को update करना आवश्यक है, तो customer से सीधे संपर्क करें (जैसे transactional email या in-app prompt)।Payment retries
हमारा fraud detection system aggressive retry patterns को block कर सकता है (और उन्हें संभावित card testing के रूप में flag कर सकता है)। Safe retry policy का पालन करें।Safe retry policies के सिद्धांत
- Backoff mechanism: Retries के बीच exponential backoff का उपयोग करें।
- Retry limits: कुल retries की सीमा तय करें (अधिकतम 3–4 attempts)।
- Intelligent filtering: केवल retryable failures पर retry करें (जैसे network/issuer errors, insufficient funds); hard declines पर कभी retry न करें।
- Card testing prevention:
DO_NOT_HONOR,STOLEN_CARD,LOST_CARD,PICKUP_CARD,FRAUDULENT,AUTHENTICATION_FAILUREजैसी failures पर retry न करें। - Metadata बदलें (वैकल्पिक): यदि आप अपना retry system बनाए रखते हैं, तो metadata के माध्यम से retries को अलग-अलग पहचानें (जैसे
retry_attempt)।
Suggested retry schedule (subscriptions)
- 1st attempt: Charge create करते समय तुरंत
- 2nd attempt: 3 दिनों के बाद
- 3rd attempt: 7 और दिनों के बाद (कुल 10 दिन)
- 4th attempt (final): 7 और दिनों के बाद (कुल 17 दिन)
Burst retries से बचें; authorization time के अनुसार align करें
- अपने पूरे portfolio में “burst” behavior से बचने के लिए retries को original authorization timestamp से anchor करें।
- उदाहरण: यदि customer आज दोपहर 1:10 बजे trial या mandate शुरू करता है, तो अपनी backoff के अनुसार बाद के दिनों में follow-up retries दोपहर 1:10 बजे schedule करें (जैसे, +3 days → दोपहर 1:10 बजे, +7 days → दोपहर 1:10 बजे)।
- वैकल्पिक रूप से, यदि आप last successful payment time
Tstore करते हैं, तो time-of-day alignment बनाए रखने के लिए अगला attemptT + X daysपर schedule करें।
Time-zone और DST: scheduling के लिए consistent time standard का उपयोग करें और intervals बनाए रखने के लिए केवल display हेतु conversion करें।
वे decline codes जिन पर retry नहीं करना चाहिए
STOLEN_CARDDO_NOT_HONORFRAUDULENTPICKUP_CARDAUTHENTICATION_FAILURELOST_CARD
Decline reasons की comprehensive list और यह जानने के लिए कि उन्हें user ठीक कर सकता है या नहीं, Transaction Failures documentation देखें।
Implementation guidelines (no code)
- ऐसा scheduler/queue उपयोग करें जो precise timestamps को persist करे; next attempt को exact time-of-day offset पर calculate करें (जैसे,
T + 3 daysउसी HH:MM पर)। - Next attempt calculate करने के लिए last successful payment timestamp
Tको maintain और reference करें; एक ही समय पर कई subscriptions को bunch न करें। - Last decline reason का हमेशा evaluation करें; ऊपर दी गई skip list में मौजूद hard declines के लिए retries रोक दें।
- आकस्मिक surges रोकने के लिए प्रति customer और प्रति account concurrent retries की सीमा तय करें।
- Proactively communicate करें: अगला scheduled attempt होने से पहले customer को अपना payment method update करने के लिए email/SMS भेजें।
- Metadata का उपयोग केवल observability के लिए करें (जैसे,
retry_attempt); inconsequential fields को rotate करके fraud/risk systems को “evade” करने का कभी प्रयास न करें।
Cancellation
On-demand subscriptions का cancellation flow scheduled subscriptions से अलग होता है, क्योंकि immediate end date को anchor करने के लिए कोई fixed billing cycle नहीं होता।Customer portal behavior
जब कोई customer Customer Portal से on-demand subscription cancel करता है, तो cancellation default रूप से अगली billing date के लिए schedule की जाती है। On-demand subscriptions के लिए Cancel Now option जानबूझकर नहीं दिखाया जाता। कारण यह है: on-demand subscriptions में predictable recurring renewal dates नहीं होतीं — अगला charge time पूरी तरह आपके usage events से निर्धारित होता है। अगली billing date पर cancellation schedule करने से period boundary तक mandate active रहता है, ताकि in-flight usage के charges अभी भी लिए जा सकें और फिर subscription को सही ढंग से समाप्त किया जा सके। Customer द्वारा cancellation की पुष्टि करने के बाद:- Subscription
activeरहती है और scheduled cancellation date तकPOST /subscriptions/{id}/chargeके माध्यम से chargeable रहती है। - Subscription पर
cancel_at_next_billing_dateकोtrueपर set किया जाता है। - Cancellation प्रभावी होने पर
subscription.cancelledwebhook भेजा जाता है।
यदि आपको subscription तुरंत समाप्त करनी हो (उदाहरण के लिए, refund या support request के जवाब में), तो customer portal flow पर निर्भर रहने के बजाय API के माध्यम से इसे programmatically cancel करें।
Programmatically cancel करें
आप किसी भी समय API के माध्यम से on-demand subscription cancel कर सकते हैं। Cancellation immediate होगी या scheduled, यह आप नियंत्रित करते हैं। Endpoint: PATCH /subscriptions/{subscription_id}- Cancel immediately
- Cancel at next billing date
Subscription को तुरंत समाप्त करने के लिए उसका
status, cancelled पर set करें। Mandate revoke हो जाता है और आगे कोई charge create नहीं किया जा सकता।cURL
Cancellation पर webhooks
Webhooks के साथ outcomes track करें
Customer journey track करने के लिए webhook handling implement करें। Implementing Webhooks देखें।- subscription.active: Mandate authorized और subscription activated
- subscription.failed: Creation विफल (जैसे, mandate failure)
- subscription.on_hold: Subscription hold पर रखी गई (जैसे, unpaid state)
- subscription.cancelled: Subscription पूरी तरह cancel हुई (देखें Cancellation)
- payment.succeeded: Charge सफल हुआ
- payment.failed: Charge विफल हुआ
Testing और अगले चरण
1
Create in test mode
Subscription create करने के लिए अपनी test API key का उपयोग करें, फिर लौटाए गए
checkout_url को खोलकर mandate पूरा करें।2
Trigger a charge
एक छोटा
product_price लेकर charge endpoint को call करें (जैसे, 100) और verify करें कि आपको payment.succeeded प्राप्त होता है।3
Go live
Events और internal state updates validate करने के बाद अपनी live API key पर switch करें।
Troubleshooting
- 422 Invalid Request: सुनिश्चित करें कि creation के समय
on_demand.mandate_onlyऔर charges के लिएproduct_priceप्रदान किया गया है। - Currency errors: यदि आप
product_currencyको override करते हैं, तो पुष्टि करें कि यह आपके account और customer के लिए supported है। - No webhooks received: अपनी webhook URL और signature secret configuration verify करें।