Subscriptions
This page describes the complete lifecycle of a Subscription: its status flow, what each status means, the notifications you receive, the structure of the callback payload, and how to query updates.
A Subscription emits two distinct kinds of status update. Keep them separate when building your integration:
- Subscription status update — a change in the state of the recurring agreement itself (e.g.
PENDING → ACTIVE,ACTIVE → SUSPENDED,→ CANCELED). Covered by the Status Map below. - Payment status update (of a Subscription charge) — a change in the state of an individual payment generated by the subscription's billing cycle (e.g.
PROCESSING → PAID). These follow the Payments status flow, not the subscription status flow.
Status Map
The Subscription entity functions as a state machine. Its status transitions are driven by three primary factors:
- Enrollment Events: The authorization process with the Financial Institution (PSP).
- Billing Results: Success or failure of recurring charges (including retries).
- Manual Interventions: Actions triggered by the merchant (e.g., suspension, cancellation) or the payer (e.g., revocation).
The following flowchart illustrates all valid transitions within the subscription lifecycle.
Status Description
Onboarding & Enrollment Phase
Statuses related to the setup of the subscription and the initial authorization with the PSP.
| Status | Description |
|---|---|
| CREATED | The subscription object has been initialized in our system but the enrollment request has not yet been sent to the PSP. |
| PENDING | The enrollment request has been sent and is awaiting Payer authorization (e.g., via Bank App) or PSP confirmation. |
| ACTIVE | The Goal State. The enrollment is authorized, and the subscription is healthy, valid, and ready to process charges according to the schedule. |
| DECLINED | The enrollment request was immediately declined by the PSP (e.g., invalid data or business rules). |
| REJECTED | The payer actively rejected the enrollment request in their banking app, or the PSP rejected it after analysis. |
| EXPIRED | The time window for the payer to authorize the enrollment (QR Code) has elapsed without action. |
| ERROR | A technical error occurred during the setup process preventing the enrollment. |
Operational & Billing Phase
Statuses indicating the ongoing health of an active subscription based on payment performance.
| Status | Description |
|---|---|
| PAST_DUE | A scheduled payment failed, but the Retry Policy is still active. The system will attempt to charge again within the defined window. |
| UNPAID | All retry attempts defined in the policy have failed. The subscription remains valid but is in default. |
| SUSPENDED | The merchant has manually paused the subscription. No new charges will be generated until it is reactivated. |
Terminal States
Final states from which a subscription typically cannot return to ACTIVE (unless a new enrollment is created).
| Status | Description |
|---|---|
| FINISHED | The subscription has reached its natural endDate as defined in the schedule. |
| CANCELED | The subscription was manually terminated by the merchant or the system (e.g., due to long-term default). |
| REVOKED | Critical State. The underlying authorization was revoked by the Payer directly at their bank or by the Financial Institution. No further charges are possible. |
Notification
A subscription integration receives two kinds of notification — keep them separate:
| Kind | What changed | Where the status flow is documented |
|---|---|---|
| Subscription status notification | The recurring agreement itself changed state (e.g. PENDING → ACTIVE, ACTIVE → SUSPENDED, → CANCELED). | The Status Map on this page. |
| Subscription payment notification | An individual charge generated by a billing cycle changed state (e.g. PROCESSING → PAID). | Payments - Status Maps & Updates. |
Configure where each notification is delivered when creating the subscription: subscription-notification-url receives subscription-lifecycle events, while notification-url receives the payment-lifecycle events of each generated charge.
A subscription status notification carries the subscription identifiers:
{
"subscription_id": "SUBSCRIPTION_ID",
"reference_id": "SUBSCRIPTION_REFERENCE_ID"
}
The identifiers returned differ depending on what you query or receive:
| Context | Identifiers returned |
|---|---|
Calling the Subscription endpoint (GET /subscriptions/{id}) | The Subscription id and the Subscription reference_id. |
| Receiving a Subscription payment notification | The Payment reference_id and the Subscription reference_id, so the individual charge can be reconciled against its parent agreement. |
This dual-reference behavior is what lets you tie a single charge to both the payment and the subscription that generated it. See Payments → Notification for the payment-side view.
Update Endpoint
Retrieve the current state of a subscription on demand. Identify the subscription by its id; the response returns the subscription object including its id, reference_id, and status.
GET https://api-sandbox.epag.io/subscriptions/SUBSCRIPTION_ID
| AUTHORIZATION | API Key |
|---|---|
| Key | X-Auth-Token |
| Value | MY_ACCESS_TOKEN |
- 200 - Success
Example Request
curl --location 'https://api-sandbox.epag.io/subscriptions/SUBSCRIPTION_ID' \
--header 'X-Auth-Token: MY_ACCESS_TOKEN'
Example Response
Content-Type: application/json
{
"id": "cc6effd7-2100-47ee-b483-5b4ac719f97d",
"reference_id": "MY_REFERENCE_ID",
"status": "ACTIVE",
"created_at": "2025-10-01T12:34:56.123",
"error_code": null,
"error_description": null,
"start_date": "2025-10-05",
"end_date": null,
"periodicity": "WEEKLY",
"force_work_day": true,
"merchant_initiation": false,
"order_amount": "100.00",
"order_currency": "BRL",
"payment_country": "BR",
"payment_currency": "BRL",
"amount_type": "FIXED",
"scheme": "PIX_AUTOMATICO",
"retry_policy": "NOT_ALLOW",
"minimum_amount": 1
}
To query an individual payment generated by the subscription, use the Payments Update Endpoint.