Subscriptions

Subscriptions allow users to set up automatic monthly, quarterly, or yearly contributions to campaigns using saved payment methods.


The Subscription Model

Properties

  • Name
    id
    Type
    integer
    Description

    Unique identifier for the subscription

  • Name
    user_id
    Type
    integer
    Description

    Foreign key to the user who created the subscription

  • Name
    campaign_id
    Type
    integer
    Description

    Foreign key to the campaign receiving donations

  • Name
    payment_method_id
    Type
    integer
    Description

    Foreign key to the saved payment method used for billing

  • Name
    institution_id
    Type
    integer
    Description

    Foreign key to the institution (inherited from campaign)

  • Name
    amount
    Type
    decimal(12,2)
    Description

    Recurring donation amount in PHP

  • Name
    billing_cycle
    Type
    enum
    Description

    Billing frequency: monthly, quarterly, or yearly

  • Name
    status
    Type
    enum
    Description

    Current status: active, paused, cancelled, payment_failed, or expired

  • Name
    next_billing_date
    Type
    date
    Description

    Date of the next scheduled billing

  • Name
    started_at
    Type
    timestamp
    Description

    When the subscription was created

  • Name
    paused_at
    Type
    timestamp | null
    Description

    When the subscription was paused

  • Name
    cancelled_at
    Type
    timestamp | null
    Description

    When the subscription was cancelled

  • Name
    last_charged_at
    Type
    timestamp | null
    Description

    Last successful billing timestamp

  • Name
    failure_count
    Type
    integer
    Description

    Number of consecutive payment failures (0-255)

  • Name
    last_failure_at
    Type
    timestamp | null
    Description

    Most recent payment failure timestamp

  • Name
    last_failure_reason
    Type
    text | null
    Description

    Reason for the last payment failure

  • Name
    cancellation_reason
    Type
    text | null
    Description

    User-provided reason for cancellation

  • Name
    created_at
    Type
    timestamp
    Description

    Record creation timestamp

  • Name
    updated_at
    Type
    timestamp
    Description

    Record last update timestamp

Relationships

  • Name
    user
    Type
    User
    Description

    The user who owns the subscription

  • Name
    campaign
    Type
    Campaign
    Description

    The campaign receiving recurring donations

  • Name
    paymentMethod
    Type
    PaymentMethod
    Description

    The saved payment method used for billing

  • Name
    institution
    Type
    Institution
    Description

    The institution receiving the donations

  • Name
    donations
    Type
    Donation[]
    Description

    All donations created from this subscription

Computed Properties

  • Name
    total_donated
    Type
    decimal
    Description

    Total amount donated through this subscription (completed donations only)


GET/api/v1/subscriptions

List Subscriptions

Retrieves a paginated list of the authenticated user's subscriptions with related campaign and payment method data.

Authentication: Required

Query Parameters

  • Name
    status
    Type
    string
    Description

    Filter by status: active, paused, cancelled

  • Name
    campaign_id
    Type
    integer
    Description

    Filter by specific campaign

  • Name
    page
    Type
    integer
    Description

    Page number for pagination

  • Name
    per_page
    Type
    integer
    Description

    Items per page (default: 15, max: 50)

Request

curl -G https://batchmates-v2.revlv.com/api/v1/subscriptions \
  -H "Authorization: Bearer {token}" \
  -d "status=active" \
  -d "per_page=20"

Response

{
  "success": true,
  "data": {
    "current_page": 1,
    "data": [
      {
        "id": 1,
        "campaign_id": 5,
        "payment_method_id": 2,
        "amount": "500.00",
        "billing_cycle": "monthly",
        "status": "active",
        "next_billing_date": "2024-02-15",
        "started_at": "2024-01-15T10:00:00.000000Z",
        "last_charged_at": "2024-01-15T10:00:00.000000Z",
        "failure_count": 0,
        "campaign": {
          "id": 5,
          "title": "Engineering Scholarship Fund",
          "image": "https://..."
        },
        "paymentMethod": {
          "id": 2,
          "card_last_four": "4242",
          "card_brand": "visa"
        }
      }
    ],
    "per_page": 20,
    "total": 3,
    "last_page": 1
  }
}

POST/api/v1/subscriptions

Create Subscription

Creates a new recurring donation subscription. The campaign must allow recurring donations and the payment method must belong to the authenticated user.

Authentication: Required

Request Body

  • Name
    campaign_id
    Type
    integer
    Description

    ID of the campaign to support

  • Name
    payment_method_id
    Type
    integer
    Description

    ID of the saved payment method to use

  • Name
    amount
    Type
    number
    Description

    Recurring donation amount in PHP (minimum: 1)

  • Name
    billing_cycle
    Type
    string
    Description

    Billing frequency: monthly, quarterly, or yearly

Request

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

Response

{
  "success": true,
  "data": {
    "id": 1,
    "user_id": 10,
    "campaign_id": 5,
    "payment_method_id": 2,
    "institution_id": 3,
    "amount": "500.00",
    "billing_cycle": "monthly",
    "status": "active",
    "next_billing_date": "2024-02-15",
    "started_at": "2024-01-15T10:00:00.000000Z",
    "campaign": {
      "id": 5,
      "title": "Engineering Scholarship Fund",
      "image": "https://..."
    },
    "paymentMethod": {
      "id": 2,
      "card_last_four": "4242",
      "card_brand": "visa"
    }
  },
  "message": "Subscription created successfully"
}

Error (Campaign Not Accepting Subscriptions)

{
  "success": false,
  "message": "This campaign does not accept recurring donations"
}

Error (Below Minimum Amount)

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

GET/api/v1/subscriptions/{id}

Get Subscription

Retrieves detailed information about a subscription, including the campaign, institution, payment method, and recent donations.

Authentication: Required

Path Parameters

  • Name
    id
    Type
    integer
    Description

    The subscription ID

Request

curl https://batchmates-v2.revlv.com/api/v1/subscriptions/1 \
  -H "Authorization: Bearer {token}"

Response

{
  "success": true,
  "data": {
    "subscription": {
      "id": 1,
      "amount": "500.00",
      "billing_cycle": "monthly",
      "status": "active",
      "next_billing_date": "2024-02-15",
      "failure_count": 0,
      "campaign": {
        "id": 5,
        "title": "Engineering Scholarship Fund",
        "description": "Supporting bright students...",
        "image": "https://...",
        "status": "active",
        "institution": {
          "id": 3,
          "name": "University of the Philippines",
          "logo": "https://..."
        }
      },
      "paymentMethod": {
        "id": 2,
        "card_last_four": "4242",
        "card_brand": "visa",
        "payment_gateway": "maya"
      },
      "donations": [
        {
          "id": 45,
          "subscription_id": 1,
          "amount": "500.00",
          "status": "completed",
          "paid_at": "2024-01-15T10:00:00.000000Z"
        }
      ]
    },
    "total_donated": "1500.00"
  }
}

POST/api/v1/subscriptions/{id}/pause

Pause Subscription

Pauses an active subscription. No charges will occur while paused. Only active subscriptions can be paused.

Authentication: Required

Path Parameters

  • Name
    id
    Type
    integer
    Description

    The subscription ID to pause

Request

curl -X POST https://batchmates-v2.revlv.com/api/v1/subscriptions/1/pause \
  -H "Authorization: Bearer {token}"

Response

{
  "success": true,
  "message": "Subscription paused"
}

Error (Invalid Status)

{
  "success": false,
  "message": "Can only pause active subscriptions"
}

POST/api/v1/subscriptions/{id}/resume

Resume Subscription

Resumes a paused subscription. Billing will continue from the next scheduled date. Only paused subscriptions can be resumed.

Authentication: Required

Path Parameters

  • Name
    id
    Type
    integer
    Description

    The subscription ID to resume

Request

curl -X POST https://batchmates-v2.revlv.com/api/v1/subscriptions/1/resume \
  -H "Authorization: Bearer {token}"

Response

{
  "success": true,
  "message": "Subscription resumed"
}

Error (Invalid Status)

{
  "success": false,
  "message": "Can only resume paused subscriptions"
}

POST/api/v1/subscriptions/{id}/cancel

Cancel Subscription

Permanently cancels a subscription. Users can optionally provide a reason for cancellation. This action cannot be undone.

Authentication: Required

Path Parameters

  • Name
    id
    Type
    integer
    Description

    The subscription ID to cancel

Request Body

  • Name
    reason
    Type
    string
    Description

    Optional cancellation reason (max 500 characters)

Request

{
  "reason": "Financial constraints"
}

Request (No Reason)

curl -X POST https://batchmates-v2.revlv.com/api/v1/subscriptions/1/cancel \
  -H "Authorization: Bearer {token}"

Response

{
  "success": true,
  "message": "Subscription cancelled"
}

PATCH/api/v1/subscriptions/{id}/payment-method

Update Payment Method

Updates the payment method for a subscription. The new payment method must belong to the authenticated user. This also resets the failure count.

Authentication: Required

Path Parameters

  • Name
    id
    Type
    integer
    Description

    The subscription ID

Request Body

  • Name
    payment_method_id
    Type
    integer
    Description

    ID of the new payment method to use

Request

{
  "payment_method_id": 3
}

Response

{
  "success": true,
  "message": "Payment method updated"
}

Error (Invalid Payment Method)

{
  "message": "The given data was invalid.",
  "errors": {
    "payment_method_id": [
      "The selected payment method id is invalid."
    ]
  }
}

GET/api/v1/subscriptions/stats

Get Subscription Stats

Retrieves subscription statistics for the authenticated user, including counts, monthly commitment, and total donated through recurring donations.

Authentication: Required

Request

curl https://batchmates-v2.revlv.com/api/v1/subscriptions/stats \
  -H "Authorization: Bearer {token}"

Response

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

Billing Cycles

Subscriptions support three billing frequencies:

  • Name
    monthly
    Description

    Charges occur once per month

  • Name
    quarterly
    Description

    Charges occur every 3 months

  • Name
    yearly
    Description

    Charges occur once per year

The next_billing_date is automatically calculated based on the billing cycle when a payment succeeds.


Subscription Status Flow

Active → Paused

User manually pauses their subscription. Can be resumed at any time.

Active → Payment Failed

After 3 consecutive payment failures, status changes to payment_failed. User should update payment method.

Active/Paused → Cancelled

User cancels subscription permanently. Cannot be resumed.

Active → Expired

Campaign ends or is deleted while subscription is active.


Payment Failure Handling

The system tracks payment failures:

  • First Failure: failure_count = 1, status remains active, retry scheduled
  • Second Failure: failure_count = 2, status remains active, retry scheduled
  • Third Failure: failure_count = 3, status changes to payment_failed

When status is payment_failed:

  • No more automatic billing attempts
  • User must update payment method to resume
  • Updating payment method resets failure_count to 0

Campaign Requirements

To accept subscriptions, campaigns must:

  1. Set allow_recurring = true
  2. Optionally set a min_recurring_amount
  3. Be in active status

Campaign Not Accepting Subscriptions

{
  "success": false,
  "message": "This campaign does not accept recurring donations"
}

Below Minimum Amount

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

Error Responses

  • Name
    422 Validation Error
    Description

    Invalid input data or business rule violation

  • Name
    403 Unauthorized
    Description

    User attempting to access another user's subscription

  • Name
    404 Not Found
    Description

    Subscription not found

Validation Error

{
  "message": "The given data was invalid.",
  "errors": {
    "campaign_id": ["The selected campaign id is invalid."],
    "amount": ["The amount must be at least 1."],
    "billing_cycle": ["The selected billing cycle is invalid."]
  }
}

Was this page helpful?