Billing Cycles

Billing cycles determine when recurring donations are charged. Batchmates supports monthly, quarterly, and yearly billing frequencies.


Supported Cycles

Monthly

Charges occur once per month on the same day. Most popular option for regular supporters.

Example: Created on January 15

  • First charge: January 15
  • Next charge: February 15
  • Following: March 15

Quarterly

Charges occur every 3 months. Good for larger donations spread throughout the year.

Example: Created on January 15

  • First charge: January 15
  • Next charge: April 15
  • Following: July 15

Yearly

Charges occur once per year. Ideal for significant annual contributions.

Example: Created on January 15, 2024

  • First charge: January 15, 2024
  • Next charge: January 15, 2025
  • Following: January 15, 2026

Monthly Subscription

{
  "campaign_id": 5,
  "amount": 500,
  "billing_cycle": "monthly",
  "payment_method_id": 2
}

Quarterly Subscription

{
  "campaign_id": 5,
  "amount": 1500,
  "billing_cycle": "quarterly",
  "payment_method_id": 2
}

Yearly Subscription

{
  "campaign_id": 5,
  "amount": 6000,
  "billing_cycle": "yearly",
  "payment_method_id": 2
}

Next Billing Date

The next_billing_date field indicates when the next charge will occur:

{
  "id": 1,
  "billing_cycle": "monthly",
  "next_billing_date": "2024-02-15",
  "last_charged_at": "2024-01-15T10:00:00.000000Z"
}

Calculation Logic

After each successful payment, the system automatically calculates the next billing date:

  • Monthly: Adds 1 month to current billing date
  • Quarterly: Adds 3 months to current billing date
  • Yearly: Adds 1 year to current billing date

Edge Cases

End of Month: If created on January 31, monthly billing adjusts to the last day of shorter months:

  • January 31 → February 28/29 → March 31 → April 30

Leap Years: Yearly subscriptions created on February 29 will bill on February 28 in non-leap years.


Billing Process

The automated billing process runs daily and processes subscriptions due for billing:

  1. Identify Due Subscriptions

    • Query subscriptions where status = 'active'
    • Filter by next_billing_date <= today
  2. Attempt Payment

    • Use saved payment method
    • Create donation record with donation_type = 'recurring'
    • Process through payment gateway
  3. Handle Result

    Success:

    • Mark donation as completed
    • Update campaign balance
    • Reset failure_count to 0
    • Calculate next billing date

    Failure:

    • Mark donation as failed
    • Increment failure_count
    • Record last_failure_reason
    • If failure_count >= 3, set status to payment_failed

Payment Retry Logic

Failed payments are automatically retried:

  • Name
    First Failure
    Description

    Retry after 3 days

  • Name
    Second Failure
    Description

    Retry after 7 days

  • Name
    Third Failure
    Description

    Status changes to payment_failed, no more retries

After Third Failure

{
  "id": 1,
  "status": "payment_failed",
  "failure_count": 3,
  "last_failure_at": "2024-01-22T10:00:00.000000Z",
  "last_failure_reason": "Insufficient funds"
}

Pausing & Resuming

Pausing

When a subscription is paused:

  • No billing attempts occur
  • next_billing_date remains unchanged
  • Status changes to paused
  • paused_at timestamp is recorded

Paused Subscription

{
  "id": 1,
  "status": "paused",
  "paused_at": "2024-01-20T14:30:00.000000Z",
  "next_billing_date": "2024-02-15"
}

Resuming

When resumed:

  • Status returns to active
  • paused_at is cleared
  • Billing resumes on next_billing_date
  • If billing date has passed, charges immediately

Changing Billing Cycles

Currently, changing billing cycles requires:

  1. Cancelling existing subscription
  2. Creating new subscription with desired cycle

Note: Future updates may support cycle changes without cancellation.


Minimum Amounts

Campaigns can set minimum recurring amounts:

Campaign Settings

{
  "allow_recurring": true,
  "min_recurring_amount": "100.00"
}

If user attempts to subscribe below minimum:

Error Response

{
  "success": false,
  "message": "Minimum recurring amount is ₱100"
}

Billing Notifications

Users receive notifications for:

  • ✅ Successful recurring payment
  • ⚠️ Failed payment attempt (with retry date)
  • ❌ Payment failed after 3 attempts
  • 📅 Upcoming billing reminder (3 days before)

Email Notifications

Subject: Recurring Donation Successful - Engineering Scholarship Fund

Thank you for your recurring donation of ₱500.00 to 
Engineering Scholarship Fund.

Next billing date: February 15, 2024

View your subscription: https://app.batchmates-v2.revlv.com/subscriptions/1

Campaign End Handling

When a campaign ends while subscriptions are active:

  1. Existing subscriptions status → expired
  2. No more billing attempts
  3. Users notified of campaign completion
  4. Subscription remains in history

Expired Subscription

{
  "id": 1,
  "status": "expired",
  "campaign": {
    "id": 5,
    "status": "completed",
    "title": "Engineering Scholarship Fund"
  }
}

Best Practices

For Users

  • Ensure payment method is valid and has sufficient funds
  • Keep card expiration dates updated
  • Review monthly commitment vs. budget
  • Monitor email for payment notifications

For Campaigns

  • Set reasonable minimum amounts (₱50-100 for monthly)
  • Communicate impact of recurring support
  • Update donors on how funds are used
  • Thank recurring supporters regularly

Subscription Lifecycle

Create → Active → (Optional Pause) → Active → Cancel
                ↓
         Payment Failed → Update Payment → Active

Key States:

  • active - Currently billing on schedule
  • paused - Temporarily stopped by user
  • payment_failed - Requires payment method update
  • cancelled - Permanently ended
  • expired - Campaign ended

Statistics

Track your recurring donation impact:

Subscription Stats

{
  "total_subscriptions": 5,
  "active_count": 3,
  "paused_count": 1,
  "monthly_commitment": "1500.00",
  "total_donated": "18000.00"
}

monthly_commitment - Total amount of active monthly subscriptions (quarterly and yearly converted to monthly equivalent)

total_donated - Sum of all completed donations from recurring subscriptions

Was this page helpful?