Billing Cycles
Manage subscription billing cycles, proration, and schedule changes.
Overview
Billing cycles control when and how subscriptions are charged:
- 📅 Billing dates - When charges occur
- 💵 Proration - Partial charges for mid-cycle changes
- 🔄 Cycle management - Skip, extend, or modify cycles
- 📊 Cycle history - Track all billing events
- ⏰ Timezone handling - Bill at correct local time
Billing Cycle Basics
Cycle Start Date
The date when the subscription begins:
{
"subscriptionId": "sub_abc123",
"startDate": "2026-01-01",
"currentCycle": {
"cycleNumber": 1,
"startDate": "2026-01-01",
"endDate": "2026-01-31",
"billingDate": "2026-01-31"
}
}
Next Billing Date
Automatically calculated based on frequency:
| Frequency | Cycle Length | Example |
|---|---|---|
| Daily | 1 day | 2026-01-01 → 2026-01-02 |
| Weekly | 7 days | 2026-01-01 → 2026-01-08 |
| Monthly | 1 month | 2026-01-01 → 2026-02-01 |
| Annually | 1 year | 2026-01-01 → 2027-01-01 |
Get Billing Cycles
Endpoint
GET /api/v1/recurring/:subscriptionId/billing-cycles
curl https://dev.auxcore.net/api/v1/recurring/sub_abc123/billing-cycles \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"
Response:
{
"success": true,
"data": {
"subscriptionId": "sub_abc123",
"cycles": [
{
"cycleNumber": 1,
"startDate": "2026-01-01",
"endDate": "2026-01-31",
"billingDate": "2026-01-31",
"amount": 99.00,
"status": "completed",
"transactionId": "txn_123"
},
{
"cycleNumber": 2,
"startDate": "2026-02-01",
"endDate": "2026-02-28",
"billingDate": "2026-02-28",
"amount": 99.00,
"status": "upcoming"
}
]
}
}
Proration
Upgrade Mid-Cycle
When upgrading from $29/month to $99/month on day 15:
curl -X PUT https://dev.auxcore.net/api/v1/recurring/sub_abc123 \
-d '{
"planId": "plan_pro_99",
"prorate": true
}'
Calculation:
Days remaining: 15 days
Old plan: $29/month (daily: $0.97)
New plan: $99/month (daily: $3.30)
Credits: 15 days × $0.97 = -$14.55
New charges: 15 days × $3.30 = +$49.50
Immediate charge: $49.50 - $14.55 = $34.95
Response:
{
"success": true,
"data": {
"subscriptionId": "sub_abc123",
"immediateCharge": 34.95,
"prorationDetails": {
"unusedCredit": 14.55,
"newCharges": 49.50,
"daysRemaining": 15
},
"nextBillingDate": "2026-02-15",
"nextBillingAmount": 99.00
}
}
Downgrade Mid-Cycle
When downgrading from $99/month to $29/month:
curl -X PUT https://dev.auxcore.net/api/v1/recurring/sub_abc123 \
-d '{
"planId": "plan_basic_29",
"prorate": true
}'
Options:
- Immediate credit: Apply credit to next bill
- End of cycle: Change at cycle end (no proration)
{
"prorate": true,
"prorationBehavior": "credit" // or "next_cycle"
}
Skip Next Billing Cycle
Skip the next charge but keep subscription active:
Endpoint
POST /api/v1/recurring/:subscriptionId/skip-next
curl -X POST https://dev.auxcore.net/api/v1/recurring/sub_abc123/skip-next \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id" \
-d '{
"reason": "Customer vacation"
}'
Response:
{
"success": true,
"data": {
"subscriptionId": "sub_abc123",
"skippedCycle": {
"cycleNumber": 3,
"originalBillingDate": "2026-03-01",
"newBillingDate": "2026-04-01"
},
"message": "Billing cycle skipped"
}
}
Use cases:
- Customer vacations
- Seasonal businesses
- Goodwill gestures
- Service interruptions
Extend Billing Cycle
Add days to current cycle:
Endpoint
POST /api/v1/recurring/:subscriptionId/extend-cycle
curl -X POST https://dev.auxcore.net/api/v1/recurring/sub_abc123/extend-cycle \
-d '{
"days": 7,
"reason": "Service downtime compensation"
}'
Response:
{
"success": true,
"data": {
"subscriptionId": "sub_abc123",
"originalEndDate": "2026-01-31",
"newEndDate": "2026-02-07",
"daysAdded": 7
}
}
Change Billing Date
Move billing to a specific day of month:
Endpoint
PUT /api/v1/recurring/:subscriptionId/billing-date
curl -X PUT https://dev.auxcore.net/api/v1/recurring/sub_abc123/billing-date \
-d '{
"billingDayOfMonth": 1,
"prorate": true
}'
Before:
- Started: Jan 15
- Bills on: 15th of each month
After:
- New billing day: 1st of month
- Next bill: Feb 1 (prorated for 16 days)
Billing Timezone
Set billing time and timezone:
{
"billingTime": "09:00:00",
"timezone": "America/New_York"
}
Benefits:
- Bill during business hours
- Avoid midnight charges
- Respect customer timezone
Cycle Webhooks
billing_cycle.started
{
"type": "billing_cycle.started",
"data": {
"subscriptionId": "sub_abc123",
"cycleNumber": 3,
"startDate": "2026-03-01",
"endDate": "2026-03-31",
"amount": 99.00
}
}
billing_cycle.ending_soon
{
"type": "billing_cycle.ending_soon",
"data": {
"subscriptionId": "sub_abc123",
"cycleNumber": 3,
"endDate": "2026-03-31",
"nextBillingDate": "2026-03-31",
"amount": 99.00,
"daysUntilBilling": 3
}
}
billing_cycle.completed
{
"type": "billing_cycle.completed",
"data": {
"subscriptionId": "sub_abc123",
"cycleNumber": 3,
"transactionId": "txn_456",
"amount": 99.00,
"billedAt": "2026-03-31T09:00:00Z"
}
}
Common Scenarios
Scenario 1: Annual to Monthly Switch
Customer wants to switch from annual to monthly billing:
# 1. Get remaining value
curl /api/v1/recurring/sub_abc123
# Response shows 8 months remaining on annual plan
# 2. Cancel annual subscription
curl -X POST /api/v1/recurring/sub_abc123/cancel \
-d '{"refundUnused": true}'
# 3. Create new monthly subscription
curl -X POST /api/v1/recurring \
-d '{
"planId": "plan_monthly_29",
"customerId": "cust_123"
}'
Scenario 2: Free Month for Service Issue
# Skip next billing cycle
curl -X POST /api/v1/recurring/sub_abc123/skip-next \
-d '{"reason": "Service downtime compensation"}'
Scenario 3: Align All Subscriptions
Customer has 3 subscriptions on different dates, wants all on 1st:
for sub in sub_1 sub_2 sub_3; do
curl -X PUT /api/v1/recurring/$sub/billing-date \
-d '{"billingDayOfMonth": 1, "prorate": true}'
done
Best Practices
✅ DO:
- Enable proration - Fair for customers
- Communicate changes - Email before billing date changes
- Allow skips - Reduces churn
- Respect timezones - Bill at reasonable hours
- Track cycle history - For customer support
- Test scenarios - Verify proration calculations
❌ DON'T:
- Don't surprise customers - Warn before changes
- Don't skip proration - Customers expect fair billing
- Don't allow unlimited skips - Set reasonable limits
- Don't forget webhooks - Automate cycle notifications
- Don't ignore failed cycles - Track and resolve
Analytics
Track billing cycle performance:
curl "https://dev.auxcore.net/api/v1/analytics/billing-cycles?period=90d" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Tenant-ID: your-tenant-id"
Response:
{
"success": true,
"data": {
"totalCycles": 5000,
"successfulCycles": 4750,
"failedCycles": 250,
"successRate": 0.95,
"averageCycleValue": 87.50,
"prorationRevenue": 12500.00,
"skippedCycles": 45
}
}
Testing
Test Proration
# 1. Create subscription on day 1
curl -X POST https://dev.auxcore.net/api/v1/recurring \
-d '{
"planId": "plan_basic_29",
"customerId": "cust_test_123",
"startDate": "2026-01-01"
}'
# 2. Upgrade on day 15 with proration
curl -X PUT https://dev.auxcore.net/api/v1/recurring/sub_test_123 \
-d '{
"planId": "plan_pro_99",
"prorate": true
}'
# 3. Verify proration amount
Next Steps
Need help? Contact support@auxvault.com