Recurring Payments
Orchestrate billing cycles, recover failed renewals, and monitor subscription lifecycles.
Recurring Payments API
The Recurring Payments API provides the operational infrastructure for managing subscription-based revenue models. Failed renewals enter a three-day recovery lifecycle before cancellation, while expired subscriptions can be explicitly reactivated through the customer lifecycle API.
While a subscription is past_due, an operator can queue one immediate retry with PUT /customers/{customerId}/subscriptions/{subscriptionId}/lifecycle/retry-renewal.json. The manual retry preserves the original renewal boundary and is limited to one idempotent charge per cycle and calendar day.
Operational Configuration
Audit Recurring Settings
Retrieve the global operational parameters governing recurring billing. This includes the current retry logic for failed payments and the timing offsets for subsequent billing cycles.
recurring_settings:readQuery Parameters
No query parameters required.
Responses
Operational settings successfully retrieved.
{
"status": "success",
"settings": {
"retry_policy": "daily_recovery_window",
"max_attempts": 3,
"next_attempt_offset": "24 hours",
"dunning_notifications": true
}
}Technical Implementation
curl --location --request GET \
'https://api.hub.donutwork.com/2026-02-01/recurring-payments/settings.json' \
--header 'Authorization: Bearer YOUR_API_TOKEN'try {
const config = await sdk.recurringPayments.getSettings();
console.log(`Billing Policy: ${config.settings.retry_policy} (Max Retries: ${config.settings.max_retries})`);
} catch (error) {
console.error(`Fetch Failed: ${error.message}`);
}Subscription Lifecycle Monitoring
Audit Active Subscriptions
Retrieve a comprehensive inventory of all subscriptions currently managed by the recurring payment engine. This endpoint provides crucial visibility into renewal dates, customer associations, and current billing health.
recurring_subscriptions:readQuery Parameters
sizeintegerpageintegerResponses
Subscription inventory retrieved.
{
"type": "RecurringSubscriptions",
"count": 1250,
"per_page": 100,
"elements": [
{
"id": "67bdf...",
"customerId": "66a15...",
"subscription_reference": "sub_premium_9921",
"status": "active",
"next_renewal_date": "2026-04-01T00:00:00Z",
"last_payment_status": "success"
}
]
}Implementation
const filters = { page: 1, size: 50 };
try {
const activeSubs = await sdk.recurringPayments.listSubscriptions(filters);
activeSubs.elements.forEach(sub => {
console.log(`Subscription ${sub.id}: Renewal due on ${sub.next_renewal_date}`);
});
} catch (error) {
console.error(`Telemetry Error: ${error.message}`);
}