Subscriptions
Automate recurring billing for your SaaS, membership, or subscription business. Reevit handles invoice generation, payment collection, retry logic, and dunning—so you can focus on building your product instead of managing billing infrastructure.
Why Automated Subscriptions?
The Challenge
Building subscription billing is complex:
Invoice Generation : Create invoices on schedule (monthly, yearly)
Payment Collection : Charge customers automatically
Retry Logic : Handle failed payments with smart retry strategies
Dunning : Manage customers whose payments fail repeatedly
Proration : Handle upgrades, downgrades, and mid-cycle changes
Multiple Providers : Different PSPs have different subscription APIs
Without Reevit , you’d need to:
Build scheduling infrastructure
Implement retry logic for each provider
Handle dunning manually
Manage subscription state across providers
Write provider-specific code
Result : Months of development, ongoing maintenance, and missed revenue from failed payments.
The Solution
Reevit provides one API for subscription billing that:
Generates invoices automatically on your schedule
Charges customers using their preferred payment method
Retries failed payments with configurable policies
Handles dunning automatically
Works across all providers with unified API
Result : Launch subscriptions faster, reduce failed payments, increase revenue.
How Subscriptions Work
The Subscription Lifecycle
1. Create Subscription → 2. Invoice Generated → 3. Payment Attempted → 4. Success/Failure → 5. Retry (if failed)
Create Subscription : Define customer, plan, amount, and billing interval
Invoice Generated : Reevit creates invoice on schedule (e.g., monthly on the 10th)
Payment Attempted : Reevit charges customer using their payment method
Success/Failure : Payment succeeds or fails
Retry (if failed) : If payment fails, Reevit retries according to your policy
Key Concepts
Subscription : The recurring billing agreement with a customer
Invoice : A billing record for a specific billing period
Payment : The actual charge attempt for an invoice
Retry Policy : Rules for how failed payments are retried
Dunning : Process of managing customers with failed payments
Creating Your First Subscription
Let’s create a subscription for a customer signing up for your premium plan:
curl -X POST https://api.reevit.io/v1/subscriptions \
-H "X-Reevit-Key: pfk_live_xxx.secret" \
-H "X-Org-Id: org_123" \
-H "Idempotency-Key: sub-cust_456-premium" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "cust_456",
"plan_id": "premium",
"amount": 9900,
"currency": "GHS",
"method": "mobile_money",
"interval": "monthly",
"metadata": {
"tier": "premium",
"signup_source": "website"
}
}'
Reevit automatically injects the correlation metadata needed for PSP webhooks. Use metadata for your own fields like plan tier or signup source.
Understanding the Request
Field Description Example Why It Matters customer_idYour customer identifier cust_456Links subscription to your customer plan_idYour plan identifier premiumHelps track which plan customer has amountAmount in minor units 9900 = GHS 99.00The recurring charge amount currencyISO 4217 code GHSCurrency for billing methodPayment method mobile_money, card, bank_transfer (aliases: momo, bank)How customer will be charged intervalBilling frequency monthly, yearlyHow often to charge metadataCustom data {"tier": "premium"}Store additional context
Response
{
"id" : "sub_abc123" ,
"customer_id" : "cust_456" ,
"plan_id" : "premium" ,
"amount" : 9900 ,
"currency" : "GHS" ,
"method" : "mobile_money" ,
"interval" : "monthly" ,
"status" : "active" ,
"next_renewal_at" : "2025-03-10T10:00:00Z" ,
"created_at" : "2025-02-10T10:00:00Z"
}
What Happens Next
Subscription Created : Customer is now subscribed
First Invoice : Invoice created immediately (or on next billing date)
Payment Attempted : Reevit charges customer
Success : Customer gains access, subscription continues
Failure : Retry according to your retry policy
Subscription Statuses
Understanding subscription statuses helps you manage customer access:
Status Description Customer Access What Happens activeSubscription is active and billing Full access Invoices generated, payments attempted pausedBilling paused Access maintained No invoices generated, customer keeps access canceledSubscription ended Access revoked No more invoices, subscription terminated
Status Transitions
Active → Paused :
Customer requests pause
Max retries reached (configurable)
Manual pause via API
Paused → Active :
Customer resumes
Manual resume via API
Active → Canceled :
Customer cancels
Manual cancellation via API
Non-payment after grace period
Managing Subscriptions
List Subscriptions
curl "https://api.reevit.io/v1/subscriptions?status=active" \
-H "X-Reevit-Key: pfk_live_xxx.secret" \
-H "X-Org-Id: org_123"
Use Cases :
Dashboard : Show all active subscriptions
Reporting : Generate subscription reports
Customer lookup : Find customer’s subscription
Query Parameters
Parameter Type Description Example limitinteger Results per page 20offsetinteger Pagination offset 0statusstring Filter by status active, paused, canceledcustomer_idstring Filter by customer cust_456plan_idstring Filter by plan premium
Get Single Subscription
curl https://api.reevit.io/v1/subscriptions/sub_abc123 \
-H "X-Reevit-Key: pfk_live_xxx.secret" \
-H "X-Org-Id: org_123"
Use Cases :
Customer portal : Show subscription details
Support : Look up subscription for support ticket
Billing : Check subscription status before charging
Updating Subscriptions
Change Plan or Amount
curl -X PATCH https://api.reevit.io/v1/subscriptions/sub_abc123 \
-H "X-Reevit-Key: pfk_live_xxx.secret" \
-H "X-Org-Id: org_123" \
-H "Idempotency-Key: sub-update-001" \
-d '{
"amount": 14900,
"plan_id": "enterprise"
}'
What Happens :
Immediate : Subscription updated with new plan/amount
Next Invoice : New amount charged on next billing cycle
Proration : Reevit can handle proration (if supported)
Use Cases :
Upgrades : Customer upgrades to higher tier
Downgrades : Customer downgrades to lower tier
Price changes : Update subscription price
Canceling Subscriptions
Cancel Subscription
curl -X POST https://api.reevit.io/v1/subscriptions/sub_abc123/cancel \
-H "X-Reevit-Key: pfk_live_xxx.secret" \
-H "X-Org-Id: org_123" \
-H "Idempotency-Key: sub-cancel-001"
What Happens :
Status : Subscription status changes to canceled
Access : Revoke customer access immediately or at period end
Invoices : No more invoices generated
Webhook : subscription.canceled event sent
Use Cases :
Customer cancellation : Customer cancels subscription
Non-payment : Cancel after grace period
Policy violation : Cancel due to terms violation
Resuming Subscriptions
Resume a paused subscription:
curl -X POST https://api.reevit.io/v1/subscriptions/sub_abc123/resume \
-H "X-Reevit-Key: pfk_live_xxx.secret" \
-H "X-Org-Id: org_123" \
-H "Idempotency-Key: sub-resume-001"
What Happens :
Status : Subscription status changes to active
Billing : Invoices resume on next billing date
Access : Customer regains full access
Webhook : subscription.resumed event sent
Use Cases :
Customer request : Customer wants to resume
Payment updated : Customer updates payment method
Issue resolved : Problem that caused pause is fixed
Invoices
Invoices are billing records for subscription renewals. Each billing cycle generates a new invoice.
Invoice Lifecycle
Draft → Due → Paid/Failed → Canceled (if needed)
Draft : Invoice created, not yet due
Due : Payment due, Reevit attempts charge
Paid : Payment succeeded
Failed : Payment failed, may retry
Canceled : Invoice canceled (e.g., subscription canceled)
Invoice Statuses
Status Description What Happens Next draftInvoice created, not yet due Waits until due date duePayment pending Reevit attempts charge paidPayment succeeded Invoice complete, subscription continues failedPayment failed Retry according to policy canceledInvoice canceled No payment attempted
Managing Invoices
List Invoices
curl "https://api.reevit.io/v1/invoices?subscription_id=sub_abc123" \
-H "X-Reevit-Key: pfk_live_xxx.secret" \
-H "X-Org-Id: org_123"
Use Cases :
Customer portal : Show billing history
Accounting : Export invoices for accounting
Support : Review invoice history for customer
Query Parameters
Parameter Type Description Example limitinteger Results per page 20offsetinteger Pagination offset 0statusstring Filter by status paid, failedsubscription_idstring Filter by subscription sub_abc123fromdatetime Start date 2025-02-01T00:00:00Ztodatetime End date 2025-02-28T23:59:59Z
Get Single Invoice
curl https://api.reevit.io/v1/invoices/inv_xyz789 \
-H "X-Reevit-Key: pfk_live_xxx.secret" \
-H "X-Org-Id: org_123"
Response:
{
"id" : "inv_xyz789" ,
"subscription_id" : "sub_abc123" ,
"payment_id" : "pay_def456" ,
"amount" : 9900 ,
"currency" : "GHS" ,
"status" : "paid" ,
"due_at" : "2025-02-10T10:00:00Z" ,
"paid_at" : "2025-02-10T10:05:00Z" ,
"retry_count" : 0 ,
"created_at" : "2025-02-10T00:00:00Z"
}
Retrying Failed Invoices
Manual Retry
Manually retry a failed invoice:
curl -X POST https://api.reevit.io/v1/invoices/inv_xyz789/retry \
-H "X-Reevit-Key: pfk_live_xxx.secret" \
-H "X-Org-Id: org_123" \
-H "Idempotency-Key: inv-retry-001"
Use Cases :
Customer updated payment : Retry after customer fixes payment method
Temporary issue resolved : Retry after provider issue resolved
Manual intervention : Support team retries on behalf of customer
Automatic Retries
Reevit automatically retries failed invoices according to your retry policy (see Retry Policies below).
Retry Policies
Retry policies define how failed subscription payments are retried. This is crucial for recovering revenue from failed payments.
Why Retry Policies Matter
Without retry policies :
Failed payment = lost revenue
Customer may not notice payment failed
Manual intervention required
Revenue leakage
With retry policies :
Automatic retries recover most failed payments
Customers notified before final retry
Minimal manual intervention
Higher revenue recovery
Setting Retry Policy
curl -X POST https://api.reevit.io/v1/policies/retry \
-H "X-Reevit-Key: pfk_live_xxx.secret" \
-H "X-Org-Id: org_123" \
-H "Idempotency-Key: retry-policy-001" \
-d '{
"plan_id": "premium",
"delays": ["15m", "1h", "24h"],
"max_retries": 3
}'
Delays specify when to retry after failure:
Format Duration Use Case 15m15 minutes Quick retry for temporary issues 1h1 hour Give customer time to fix payment 24h24 hours Daily retry for persistent issues 7d7 days Weekly retry for long-term issues
Policy Hierarchy
Retry policies are applied in order of specificity:
Plan-level : Specific to a subscription plan (most specific)
Org-level : Default for your organization (empty plan_id)
Global : System default (least specific)
Example :
Premium plan: 4 retries at 15m, 1h, 24h, 72h
Basic plan: 3 retries at 1h, 24h, 7d
Default (no plan): 3 retries at 15m, 1h, 24h
Real-World Example
Scenario : Customer’s card expires
Day 1, 10:00 AM : Invoice due, payment fails (expired card)
Day 1, 10:15 AM : First retry (15m delay) - still fails
Day 1, 11:15 AM : Second retry (1h delay) - still fails
Day 2, 11:15 AM : Third retry (24h delay) - customer updated card, succeeds!
Result : Revenue recovered automatically without manual intervention.
Webhook Events
Subscriptions trigger webhook events you can use to automate your business logic.
Subscription Events
Event When It Fires Use Case subscription.createdNew subscription created Activate access, send welcome email subscription.updatedSubscription modified Update access level, notify customer subscription.canceledSubscription canceled Revoke access, send cancellation email subscription.pausedSubscription paused Suspend access, notify customer subscription.resumedSubscription resumed Reactivate access, notify customer
Invoice Events
Event When It Fires Use Case invoice.createdInvoice generated Notify customer of upcoming charge invoice.paidInvoice payment succeeded Extend access, send receipt invoice.failedInvoice payment failed Notify customer, allow payment update invoice.canceledInvoice canceled Update subscription status
Example: Automating Access
// When subscription is created
if ( event . type === 'subscription.created' ) {
const subscription = event . data ;
await activateAccess ( subscription . customer_id );
await sendWelcomeEmail ( subscription . customer_id );
}
// When invoice is paid
if ( event . type === 'invoice.paid' ) {
const invoice = event . data ;
await extendAccess ( invoice . subscription_id );
await sendReceipt ( invoice );
}
// When subscription is canceled
if ( event . type === 'subscription.canceled' ) {
const subscription = event . data ;
await revokeAccess ( subscription . customer_id );
await sendCancellationEmail ( subscription . customer_id );
}
Business Value
Revenue Recovery
Without Reevit :
10% of subscription payments fail
No automatic retries
Manual intervention required
Result : 10% revenue loss
With Reevit :
10% of payments fail initially
Automatic retries recover 70% of failures
Minimal manual intervention
Result : Only 3% revenue loss
Time Savings
Without Reevit :
Build scheduling infrastructure: 2-4 weeks
Implement retry logic: 1-2 weeks
Handle dunning: 1 week
Ongoing maintenance: Ongoing
With Reevit :
Integrate API: 1-2 days
Configure retry policies: 1 hour
Ongoing maintenance: Minimal
Customer Experience
Without Reevit :
Payment fails → Customer loses access immediately
No notification → Customer confused
Manual retry → Friction
With Reevit :
Payment fails → Retry automatically
Customer notified → Clear communication
Automatic recovery → Seamless experience
Best Practices
1. Set Appropriate Retry Policies
High-value plans : More retries, longer delays
Low-value plans : Fewer retries, shorter delays
Consider customer behavior : When do customers typically fix payments?
2. Notify Customers
Before final retry : Give customers chance to update payment
After failure : Clear instructions on how to fix
After success : Confirm payment and thank customer
3. Handle Cancellations Gracefully
Immediate vs. end of period : Choose based on your business model
Proration : Handle partial refunds if needed
Feedback : Ask why customer canceled
4. Monitor Failed Payments
Track failure rates : Identify patterns
Review retry success : Optimize retry policies
Customer support : Proactive outreach for repeated failures
Store useful information in subscription metadata:
Signup source
Promo code used
Customer tier
Custom flags
Next Steps
Payments See how payment intents, statuses, and refunds work end-to-end.
Webhooks Consume invoice.* and subscription.* events to sync billing state.
Workflows Automate emails, CRM updates, and dunning nudges when renewals fail.
Connections Ensure your PSP connections are healthy for recurring charges.