Complete subscription lifecycle with native proration.
7 states, 4 cycles, 3 billing methods. Trial, upgrade/downgrade, pause, scheduled cancellation. Historical versioning on every change.
Feature

7
subscription states
4
billing cycles
24/7
automatic processing
100%
versioned changes
States modeled in SubscriptionStatus
Each transition is recorded as SubscriptionVersion (hybrid SCD type-2) for complete audit.
Draft
Created via dashboard but not yet confirmed. No billing.
- Transitions: → confirmed (manual confirmation)
Confirmed
Ready to start. Awaiting trial start or first billing.
- Transitions: → trialing (with trial) | → active (without trial)
Trialing
Free period before first billing. Trial without card supported.
- Transitions: → active (trial ends) | → canceled (cancellation during trial)
Active
Active recurring billing. Subscription-renewal worker (daily 00:00 UTC) renews the cycle.
- Transitions: → past_due (payment fails) | → paused | → canceled
Past Due
Payment failed. Payment-retry worker tries every 6h. Suspension-check worker suspends after grace period.
- Transitions: → active (payment OK) | → canceled (all attempts failed)
Paused
Customer pause (pauseCollection stores reason and timestamp). No billing until resumed.
- Transitions: → active (customer resumes)
Canceled
Terminated. cancelAtPeriodEnd allows scheduled cancellation at end of cycle.
- Final state
What you can do
Billing Cycles
Define the cycle per plan or per subscription. billing_cycle_anchor anchors the renewal date.
- Monthly, quarterly, semi-annual, annual
- Configurable anchor (doesn't need to start on day 1)
- current_period_start and current_period_end calculated
Flexible Trial
Trial in days, with or without card. Automatic notification before end via trial-ending worker (daily 09:00 UTC).
- trial_period_days per plan or override per subscription
- Automatic conversion to active
- Cancellation during trial without billing
Upgrade/Downgrade with Proration
3 behaviors: create_prorations (default), none, always_invoice. Formula: (plan_value / days_in_cycle) × days_remaining.
- Preview before confirming (no side effect)
- Immediate upgrade, end-of-period downgrade (configurable)
- Credit generated on downgrade (creditOnDowngrade)
Item Changes (PlanChange)
Plan changes are tracked as PlanChange + SubscriptionItemChange. Idempotency via Idempotency-Key header.
- Complete versioning
- Rules per plan pair (PlanChangeRule)
- Scheduled → done promotion by dedicated worker
Pause and Resume
pauseCollection JSON stores reason, date, resume rule. allowPause configurable per subscription.
- Indefinite or date-limited pause
- Complete history in customer portal
- Webhook subscription.paused / subscription.resumed
Billing Methods
CollectionMethod controls invoice generation and billing.
- charge_automatically: all automatic (card)
- manual_charge: automatic invoice, manual billing (boleto/PIX)
- manual_invoice: all manual (one-off)
Smart Cancellation
cancel_at_period_end schedules cancellation for end of cycle. canceled_at + cancellationReason recorded.
- Immediate or scheduled cancellation
- Free reason for churn analysis
- Webhook + AuditLog
Automatic Renewal
renewalSettings JSON controls auto-renew, end_of_commitment or prompt. Subscription-renewal worker processes daily.
- 100% automated renewal
- Commitment support (12 months, 24 months)
- Idempotency by subscription + period
Create subscription via API
bash
curl -X POST https://api.billing.kobana.com.br/v1/subscriptions \
-H "Authorization: Bearer sk_live_..." \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"billing_account_id": "ba_abc123",
"plan_id": "plan_growth_monthly",
"trial_period_days": 14,
"collection_method": "charge_automatically",
"metadata": { "source": "checkout", "campaign": "q3-2026" }
}'response
{
"id": "sub_xyz789",
"status": "trialing",
"billing_cycle": "monthly",
"trial_end": "2026-06-20T00:00:00Z",
"current_period_start": "2026-06-06T00:00:00Z",
"current_period_end": "2026-07-06T00:00:00Z",
"recurring_amount_cents": 29900,
"items": [
{ "id": "si_1", "product_id": "prod_platform", "quantity": 1 }
]
}