primeflow

Subscriptions

Manage recurring billing and automated dunning

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.

https://dashboard.reevit.io
Live

Snapshot

Payment overview for the last 30 days

Total Volume

$429.8K

+12.5%from last period

Transactions

2,704

+8.2%from last period

Success Rate

96.8%

+0.3%from last period

Failed

18

transactions failed

Recent Payments

View all
Payment IDAmountStatusProviderMethodFeeAttemptsCreated
pay_1a2b3c4d5e6...GHS 150.00Succeeded
Paystack
CARDGHS 4.651/15 minutes ago
pay_2b3c4d5e6f7...GHS 500.00Pending
Hubtel
MOMOGHS 7.500/115 minutes ago
pay_3c4d5e6f7g8...NGN 250.00Failed
Flutterwave
CARDNGN 0.000/230 minutes ago
pay_4d5e6f7g8h9...NGN 899.00Succeeded
Monnify
CARDNGN 22.471/2about 1 hour ago
pay_5e6f7g8h9i0...NGN 1,200.00Requires Action
Paystack
BANK_TRANSFERNGN 18.000/1about 1 hour ago

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)
  1. Create Subscription: Define customer, plan, amount, and billing interval
  2. Invoice Generated: Reevit creates invoice on schedule (e.g., monthly on the 10th)
  3. Payment Attempted: Reevit charges customer using their payment method
  4. Success/Failure: Payment succeeds or fails
  5. 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.com/v1/subscriptions \
  -H "X-Reevit-Key: pfk_live_xxx" \
  -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": "momo",
    "interval": "monthly",
    "metadata": {
      "tier": "premium",
      "signup_source": "website"
    }
  }'

Understanding the Request

FieldDescriptionExampleWhy It Matters
customer_idYour customer identifiercust_456Links subscription to your customer
plan_idYour plan identifierpremiumHelps track which plan customer has
amountAmount in minor units9900 = GHS 99.00The recurring charge amount
currencyISO 4217 codeGHSCurrency for billing
methodPayment methodmomo, card, bankHow customer will be charged
intervalBilling frequencymonthly, 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": "momo",
  "interval": "monthly",
  "status": "active",
  "next_renewal_at": "2025-03-10T10:00:00Z",
  "created_at": "2025-02-10T10:00:00Z"
}

What Happens Next

  1. Subscription Created: Customer is now subscribed
  2. First Invoice: Invoice created immediately (or on next billing date)
  3. Payment Attempted: Reevit charges customer
  4. Success: Customer gains access, subscription continues
  5. Failure: Retry according to your retry policy

Subscription Statuses

Understanding subscription statuses helps you manage customer access:

StatusDescriptionCustomer AccessWhat Happens
activeSubscription is active and billingFull accessInvoices generated, payments attempted
pausedBilling pausedAccess maintainedNo invoices generated, customer keeps access
canceledSubscription endedAccess revokedNo 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.com/v1/subscriptions?status=active" \
  -H "X-Reevit-Key: pfk_live_xxx" \
  -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

ParameterTypeDescriptionExample
limitintegerResults per page20
offsetintegerPagination offset0
statusstringFilter by statusactive, paused, canceled
customer_idstringFilter by customercust_456
plan_idstringFilter by planpremium

Get Single Subscription

curl https://api.reevit.com/v1/subscriptions/sub_abc123 \
  -H "X-Reevit-Key: pfk_live_xxx" \
  -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.com/v1/subscriptions/sub_abc123 \
  -H "X-Reevit-Key: pfk_live_xxx" \
  -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.com/v1/subscriptions/sub_abc123/cancel \
  -H "X-Reevit-Key: pfk_live_xxx" \
  -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.com/v1/subscriptions/sub_abc123/resume \
  -H "X-Reevit-Key: pfk_live_xxx" \
  -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)
  1. Draft: Invoice created, not yet due
  2. Due: Payment due, Reevit attempts charge
  3. Paid: Payment succeeded
  4. Failed: Payment failed, may retry
  5. Canceled: Invoice canceled (e.g., subscription canceled)

Invoice Statuses

StatusDescriptionWhat Happens Next
draftInvoice created, not yet dueWaits until due date
duePayment pendingReevit attempts charge
paidPayment succeededInvoice complete, subscription continues
failedPayment failedRetry according to policy
canceledInvoice canceledNo payment attempted

Managing Invoices

List Invoices

curl "https://api.reevit.com/v1/invoices?subscription_id=sub_abc123" \
  -H "X-Reevit-Key: pfk_live_xxx" \
  -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

ParameterTypeDescriptionExample
limitintegerResults per page20
offsetintegerPagination offset0
statusstringFilter by statuspaid, failed
subscription_idstringFilter by subscriptionsub_abc123
fromdatetimeStart date2025-02-01T00:00:00Z
todatetimeEnd date2025-02-28T23:59:59Z

Get Single Invoice

curl https://api.reevit.com/v1/invoices/inv_xyz789 \
  -H "X-Reevit-Key: pfk_live_xxx" \
  -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.com/v1/invoices/inv_xyz789/retry \
  -H "X-Reevit-Key: pfk_live_xxx" \
  -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.com/v1/policies/retry \
  -H "X-Reevit-Key: pfk_live_xxx" \
  -H "X-Org-Id: org_123" \
  -H "Idempotency-Key: retry-policy-001" \
  -d '{
    "plan_id": "premium",
    "delays": ["15m", "1h", "24h"],
    "max_retries": 3
  }'

Delay Format

Delays specify when to retry after failure:

FormatDurationUse Case
15m15 minutesQuick retry for temporary issues
1h1 hourGive customer time to fix payment
24h24 hoursDaily retry for persistent issues
7d7 daysWeekly retry for long-term issues

Policy Hierarchy

Retry policies are applied in order of specificity:

  1. Plan-level: Specific to a subscription plan (most specific)
  2. Org-level: Default for your organization (empty plan_id)
  3. 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

  1. Day 1, 10:00 AM: Invoice due, payment fails (expired card)
  2. Day 1, 10:15 AM: First retry (15m delay) - still fails
  3. Day 1, 11:15 AM: Second retry (1h delay) - still fails
  4. 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

EventWhen It FiresUse Case
subscription.createdNew subscription createdActivate access, send welcome email
subscription.updatedSubscription modifiedUpdate access level, notify customer
subscription.canceledSubscription canceledRevoke access, send cancellation email
subscription.pausedSubscription pausedSuspend access, notify customer
subscription.resumedSubscription resumedReactivate access, notify customer

Invoice Events

EventWhen It FiresUse Case
invoice.createdInvoice generatedNotify customer of upcoming charge
invoice.paidInvoice payment succeededExtend access, send receipt
invoice.failedInvoice payment failedNotify customer, allow payment update
invoice.canceledInvoice canceledUpdate 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

5. Use Metadata

Store useful information in subscription metadata:

  • Signup source
  • Promo code used
  • Customer tier
  • Custom flags

Next Steps