Billing Cycles & Use Cases
Overview of recurrence logic and practical use cases. Review the supported billing intervals and the specific data structures required to automate your customer's payment schedule across daily, weekly, monthly, or yearly cycles.
Billing Cycles
The system calculates next_payment_date automatically based on the interval and initial next_payment_date provided at creation. After each successful payment, the next date advances by the configured interval. Dates falling on weekends (Saturday/Sunday) are automatically adjusted to the next Monday.
| Interval | Description | Date Calculation | Notes |
|---|---|---|---|
| weekly | Every 7 days | Adds 7 days to last payment date | Weekends adjusted to Monday |
| monthly | Every month | Adds 1 month to last payment date | Maintains same day of month |
| quarterly | Every 3 months | Adds 3 months to last payment date | January → April → July → October |
| semiannual | Every 6 months | Adds 6 months to last payment date | Twice yearly |
| yearly | Every 12 months | Adds 12 months to last payment date | Annual billing |
Important Date Rules
| Rule | Description |
|---|---|
| Future Dates Only | Charge/start dates must be in the future (today is not allowed) |
| Weekend Adjustment | Dates on Saturday/Sunday automatically moved to next Monday |
| End Date | For recurring debits, end_date must be after next_payment_date |
| Leap Year Handling | February 29 dates adjusted to February 28 in non-leap years |
Order Generation Schedule
Orders are generated automatically when the following conditions are met:
- Direct debit status is
active is_fixed_amountistruenext_payment_date≤ todayis_extended_for_retryis nottrue- No active orders exist (status:
created,pending, orin_process) After order generation,next_payment_dateadvances by the configured interval.
Santander Processing Schedule
| Job | Schedule | Description |
|---|---|---|
santander:generate_and_send | Weekdays 19:00 | Generate orders, build batch file, upload to SFTP |
santander:process_responses | Weekdays 18:00 | Download response files, process results |
Practical Use Cases
Below are common scenarios demonstrating how to configure the API for different business models. See our Direct Debit Management page for further details on how to use each endpoint.
Case 1: Monthly Subscription
Scenario: A gym charges $500 MXN monthly on the 1st of each month.
// Create the direct debit
POST /api/direct-debits
{
"customer_id": "6944a4946afaf625504595e3",
"is_fixed_amount": true,
"is_recurring": true,
"amount": 500.00,
"currency": "MXN",
"interval": "monthly",
"next_payment_date": "2026-04-01",
"end_date": "2027-04-01",
"concept": "Gym Membership"
}
// System calculates next dates: 2026-04-01, 2026-05-01, 2026-06-01...
// Weekends automatically adjusted to MondayCase 2: Quarterly Payment
Scenario: A software company charges $3,000 MXN each quarter on the 15th.
POST /api/direct-debits
{
"customer_id": "6944a4946afaf625504595e4",
"is_fixed_amount": true,
"is_recurring": true,
"amount": 3000.00,
"currency": "MXN",
"interval": "quarterly",
"next_payment_date": "2026-01-15",
"end_date": "2027-01-15",
"concept": "Software License"
}
// System calculates next dates: 2026-01-15, 2026-04-15, 2026-07-15, 2026-10-15Case 3: Weekly Payment
Scenario: A streaming service charges $99 MXN every week on Fridays.
POST /api/direct-debits
{
"customer_id": "6944a4946afaf625504595e5",
"is_fixed_amount": true,
"is_recurring": true,
"amount": 99.00,
"currency": "MXN",
"interval": "weekly",
"next_payment_date": "2026-04-03", // Friday
"end_date": "2026-12-31",
"concept": "Streaming Premium"
}
// System calculates next dates: 2026-04-03, 2026-04-10, 2026-04-17...
// If date falls on weekend, automatically moved to MondayCase 4: Scheduled One-Time Charge
Scenario: A one-time charge of $10,000 MXN scheduled for March 31, 2026.
POST /api/direct-debits
{
"customer_id": "6944a4946afaf625504595e6",
"is_fixed_amount": true,
"is_recurring": false,
"amount": 10000.00,
"currency": "MXN",
"next_payment_date": "2026-03-31",
"concept": "Payment for professional services"
}
// Single charge only. After payment, status changes to 'completed'
// No end_date needed for non-recurring debitsCase 5: Variable Amount Charge
Scenario: A utility company charges varying amounts each month based on consumption.
// Step 1: Create variable direct debit (no fixed amount)
POST /api/direct-debits
{
"customer_id": "6944a4946afaf625504595e7",
"is_fixed_amount": false,
"currency": "MXN",
"concept": "Electric Utility"
}
// Step 2: After activation, create individual charges
POST /api/direct-debits/6944a5366afaf625504595ea/charges
{
"amount": 1250.00,
"scheduled_date": "2026-04-15"
}
// Step 3: Next month's charge
POST /api/direct-debits/6944a5366afaf625504595ea/charges
{
"amount": 1480.00,
"scheduled_date": "2026-05-15"
}
// Each charge is an independent order with its own amount and dateCase 6: Semiannual Insurance Payment
Scenario: An insurance company charges $5,000 MXN twice a year.
POST /api/direct-debits
{
"customer_id": "6944a4946afaf625504595e8",
"is_fixed_amount": true,
"is_recurring": true,
"amount": 5000.00,
"currency": "MXN",
"interval": "semiannual",
"next_payment_date": "2026-01-01",
"end_date": "2028-01-01",
"concept": "Insurance Premium"
}
// System calculates next dates: 2026-01-01, 2026-07-01, 2027-01-01, 2027-07-01Case 7: Annual Membership
Scenario: A professional association charges $1,200 MXN yearly.
POST /api/direct-debits
{
"customer_id": "6944a4946afaf625504595e9",
"is_fixed_amount": true,
"is_recurring": true,
"amount": 1200.00,
"currency": "MXN",
"interval": "yearly",
"next_payment_date": "2026-01-01",
"concept": "Annual Membership Dues"
}
// System calculates next dates: 2026-01-01, 2027-01-01, 2028-01-01...Webhook Events
Events dispatched through the notification system during billing cycles:
| Event | Trigger | Payload Includes |
|---|---|---|
direct_debit.created | Direct debit is created | direct_debit_id, reference, status |
direct_debit.activated | Direct debit transitions to active | direct_debit_id, status, customer_id |
direct_debit.payment_success | Order paid successfully | order_id, amount, currency, reference |
direct_debit.payment_failed | Order fails | order_id, amount, error_code, error_message |
direct_debit.cancelled | Direct debit is cancelled | direct_debit_id, status, customer_id |
direct_debit.completed | All payments processed | direct_debit_id, status, total_payments |
Webhook Payload Example
{
"message": "Direct debit payment processed successfully.",
"direct_debit_id": "6944a5366afaf625504595ea",
"reference": 1234567,
"order_id": "6944a53b6afaf625504595ef",
"amount": 500.00,
"currency": "MXN",
"is_recurring": true,
"status": "paid"
}Retry and Extension Scenarios
Single Charge Retry
When a one-time scheduled charge fails:
// After max attempts reached, status becomes 'pending'
// Merchant retries:
POST /api/direct-debits/6944a5366afaf625504595ea/retry
// Response: Status returns to 'active' with new next_payment_date
{
"status": "active",
"next_payment_date": "2026-04-05T12:00:00.000Z",
"is_extended_for_retry": true
}Variable Charge Retry
When a variable charge fails:
// Retry failed charge
POST /api/direct-debits/6944a5366afaf625504595ea/charges/6944a53a6afaf625504595ee/retry
{
"scheduled_date": "2026-04-20"
}
// Response: Order reset to 'created' status
{
"status": "created",
"attempts": 0,
"is_retry_order": true,
"scheduled_date": "2026-04-20T12:00:00.000Z"
}Extended for Retry Flag
The is_extended_for_retry flag prevents duplicate order generation when retrying recurring debits near cycle boundaries. This ensures only one order exists per billing cycle during retry scenarios.
Updated 12 days ago