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.

IntervalDescriptionDate CalculationNotes
weeklyEvery 7 daysAdds 7 days to last payment dateWeekends adjusted to Monday
monthlyEvery monthAdds 1 month to last payment dateMaintains same day of month
quarterlyEvery 3 monthsAdds 3 months to last payment dateJanuary → April → July → October
semiannualEvery 6 monthsAdds 6 months to last payment dateTwice yearly
yearlyEvery 12 monthsAdds 12 months to last payment dateAnnual billing

Important Date Rules

RuleDescription
Future Dates OnlyCharge/start dates must be in the future (today is not allowed)
Weekend AdjustmentDates on Saturday/Sunday automatically moved to next Monday
End DateFor recurring debits, end_date must be after next_payment_date
Leap Year HandlingFebruary 29 dates adjusted to February 28 in non-leap years



Order Generation Schedule

Orders are generated automatically when the following conditions are met:

  1. Direct debit status is active
  2. is_fixed_amount is true
  3. next_payment_date ≤ today
  4. is_extended_for_retry is not true
  5. No active orders exist (status: created, pending, or in_process) After order generation, next_payment_date advances by the configured interval.

Santander Processing Schedule

JobScheduleDescription
santander:generate_and_sendWeekdays 19:00Generate orders, build batch file, upload to SFTP
santander:process_responsesWeekdays 18:00Download 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 Monday

Case 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-15

Case 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 Monday

Case 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 debits

Case 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 date

Case 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-01

Case 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:

EventTriggerPayload Includes
direct_debit.createdDirect debit is createddirect_debit_id, reference, status
direct_debit.activatedDirect debit transitions to activedirect_debit_id, status, customer_id
direct_debit.payment_successOrder paid successfullyorder_id, amount, currency, reference
direct_debit.payment_failedOrder failsorder_id, amount, error_code, error_message
direct_debit.cancelledDirect debit is cancelleddirect_debit_id, status, customer_id
direct_debit.completedAll payments processeddirect_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.