Billing Cycles#
How recurring schedules are billed: cadence, the payment schedule, skipping and changing cycles.
Overview#
Every subscription (recurring schedule) has a period and a nextPaymentDate. AuxCORE uses them to:
- 📅 Generate a payment schedule - One row per expected payment
- ⏱️ Charge due payments - An hourly scheduler charges every schedule whose
nextPaymentDatehas arrived - ⏭️ Skip a cycle - Move the next charge forward one period
- 🔄 Change the cadence - Update the period or amount; unpaid rows are rebuilt
- 📊 Track each cycle - Paid, failed and upcoming rows with transaction references
All endpoints on this page use admin authentication (Authorization: Bearer YOUR_JWT + X-Tenant-ID, or x-api-key). See Subscriptions.
Billing Cycle Basics#
Start Date and First Charge#
recurringDate1is the first charge date (cannot be in the past).nextPaymentDateis the date the scheduler will charge next. If you do not send it on create, it is set to one period afterrecurringDate1; sendnextPaymentDateequal torecurringDate1to charge on the start date.- One-time scheduled payments (
requestOrigin: "scheduled"ormaximumOccurrence: "1") are charged exactly onrecurringDate1.
Next Billing Date#
Calculated from the period:
| Period | Cycle Length | Example |
|---|---|---|
Weekly |
7 days | 2026-11-01 → 2026-11-08 |
BiWeekly |
14 days | 2026-11-01 → 2026-11-15 |
SemiMonthly |
15 days | 2026-11-01 → 2026-11-16 |
Monthly |
1 month | 2026-11-01 → 2026-12-01 |
Quarterly |
3 months | 2026-11-01 → 2027-02-01 |
Annually |
1 year | 2026-11-01 → 2027-11-01 |
Custom |
1 month (day clamped to month end) | Used for one-time scheduled payments; if it recurs, the next date is the same day next month |
After a successful charge, the next date is calculated from the date the charge was scheduled for (not when it actually ran), so a delayed run does not shift the series. If the result is already in the past (for example after a long pause), it is rolled forward whole periods until it is today or later, so no backlog of catch-up charges is taken. Custom schedules are never rolled forward.
End of Schedule#
| Setting | Number of cycles |
|---|---|
maximumOccurrence: "12" |
12 payments, then the schedule becomes completed |
recurringDate2 (end date) |
Every cycle that falls on or before the end date |
maximumOccurrence: "NoExpire" (or omitted) with no end date |
Runs until cancelled |
Get Payment Schedule#
Returns the cycle rows for a schedule, ordered by payment number.
Endpoint#
curl https://uat.auxcore.net/api/v1/recurring/8d2f1c4b-6a3e-4f7d-b1c9-0e5a7d3f2b61/schedule \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"Response:
{
"success": true,
"data": [
{
"id": "b7e3a1d9-4c2f-4e8a-9d1b-3f6c0a2e5d71",
"recurringMasterId": "8d2f1c4b-6a3e-4f7d-b1c9-0e5a7d3f2b61",
"paymentNumber": 1,
"scheduledDate": "2026-11-01",
"scheduledAmount": 29.99,
"status": "paid",
"actualAmount": 29.99,
"actualDate": "2026-11-01T05:00:12.000Z",
"transactionId": "5b9e2d7a-1c3f-4a8e-b6d0-2f4c8a1e7b93",
"label": "Payment 1"
},
{
"id": "c2d4f6a8-1b3e-4c5d-8e7f-9a0b1c2d3e4f",
"recurringMasterId": "8d2f1c4b-6a3e-4f7d-b1c9-0e5a7d3f2b61",
"paymentNumber": 2,
"scheduledDate": "2026-12-01",
"scheduledAmount": 29.99,
"status": "next_charge",
"label": "Payment 2"
}
]
}Cycle Statuses#
| Status | Description |
|---|---|
waiting |
First payment, not yet charged |
scheduled |
Future payment |
next_charge |
The payment that will be charged next |
paid |
Collected (actualAmount, actualDate, transactionId set) |
failed |
Charge declined |
cancelled |
Schedule was cancelled before this payment |
never_ends |
Placeholder row ("Until cancelled") for open-ended schedules |
Note: For open-ended schedules, the first 24 payments are listed as concrete rows, followed by one
never_endsplaceholder. With an end date, there is one row per cycle up to that date; otherwise the row count equalsmaximumOccurrence(12 if it is not a number).
Skip Next Billing Cycle#
Skip the next charge but keep the schedule active. nextPaymentDate moves forward one period. Only active schedules can skip. No request body.
Endpoint#
curl -X POST https://uat.auxcore.net/api/v1/recurring/8d2f1c4b-6a3e-4f7d-b1c9-0e5a7d3f2b61/skip-next \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"Response:
{
"success": true,
"data": {
"id": "8d2f1c4b-6a3e-4f7d-b1c9-0e5a7d3f2b61",
"status": "active",
"period": "Monthly",
"nextPaymentDate": "2027-01-01"
},
"message": "Next payment skipped successfully"
}Use cases:
- Customer vacations
- Seasonal businesses
- Goodwill gestures
- Service interruptions
Change Cadence or Amount#
Use the update endpoint to change the period, amount or dates of a schedule.
Endpoint#
curl -X PUT https://uat.auxcore.net/api/v1/recurring/8d2f1c4b-6a3e-4f7d-b1c9-0e5a7d3f2b61 \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id" \
-H "Content-Type: application/json" \
-d '{
"period": "Quarterly",
"recurringAmount": 79.99
}'- Changing only
recurringAmountupdates every unpaid row in place. - Changing
perioddeletes the unpaid rows and rebuilds them;paidrows are kept. - Changes take effect from the next charge. There is no proration: the new amount is charged in full on the next cycle.
Billing Time#
Due schedules are charged by a scheduler that runs every hour, so a payment due on a given date is charged early that day. There is no per-schedule billing time or timezone setting.
Note: Proration, extending a cycle, moving the billing day of month, per-schedule timezones and billing-cycle analytics are not available via API.
Cycle Notifications#
AuxCORE does not emit billing-cycle webhook events. Each charged cycle creates an ordinary transaction (requestOrigin: "recurring"), and the customer receives a payment success or failure email when notifications are enabled.
Common Scenarios#
Scenario 1: Annual to Monthly Switch#
# 1. Cancel the annual schedule
curl -X POST https://uat.auxcore.net/api/v1/recurring/8d2f1c4b-6a3e-4f7d-b1c9-0e5a7d3f2b61/cancel \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id" \
-H "Content-Type: application/json" \
-d '{"reason": "Switching to monthly"}'
# 2. Create a new monthly schedule
curl -X POST https://uat.auxcore.net/api/v1/recurring \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id" \
-H "Content-Type: application/json" \
-d '{"recurringAmount": 29.99, "period": "Monthly", "recurringDate1": "2026-11-01", "nextPaymentDate": "2026-11-01", "suggestedMode": "CARD", "customerId": "3f6c2a1e-8b4d-4c7a-9e21-5d0b7f1a2c34", "children": [{"pciToken": "pci_tok_9f8e7d6c5b4a", "isDefault": true}]}'Any refund of unused time must be issued separately as a refund on the original transaction.
Scenario 2: Free Month for Service Issue#
curl -X POST https://uat.auxcore.net/api/v1/recurring/8d2f1c4b-6a3e-4f7d-b1c9-0e5a7d3f2b61/skip-next \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"Best Practices#
✅ DO:#
- Send
nextPaymentDateexplicitly - Avoid surprises about when the first automatic charge runs - Communicate changes - Email the customer before changing amount or period
- Allow skips - Reduces churn
- Check the schedule - Use the schedule endpoint for customer support questions
❌ DON'T:#
- Don't expect proration - Amount changes apply in full from the next cycle
- Don't allow unlimited skips - Set your own limits
- Don't ignore failed cycles - See Dunning
Next Steps#
Need help? Contact support@auxcore.net