Subscription Events
Breeze sends webhook events of type "SUBSCRIPTION_STATUS_UPDATED" whenever a subscription’s status changes. These events help you track lifecycle transitions like creation, payment success/failure, cancellations, and overdue states.
Each subscription event includes a JSON payload structured in the following manner:
{
"type": "SUBSCRIPTION_STATUS_UPDATED",
"data": {
"id": "subs_abc123xyz",
"status": "INCOMPLETE",
"amount": 199, // in minor unit
"billingCycleConfig": {
"frequency": 1,
"interval": "day"
},
"clientReferenceId": "your-sub-unique-id",
"createdAt": 1755836495645,
"currency": "USD",
"customerId": "cus_asdf1234",
"priceId": "prc_qwert3456",
"productId": "prd_zxcv4567",
"updatedAt": 1755936495645
},
"signature": "webhook_signature"
}{
"type": "SUBSCRIPTION_STATUS_UPDATED",
"data": {
"id": "subs_abc123xyz",
"status": "INCOMPLETE_EXPIRED",
"amount": 199, // in minor unit
"billingCycleConfig": {
"frequency": 1,
"interval": "day"
},
"clientReferenceId": "your-sub-unique-id",
"createdAt": 1755836495645,
"currency": "USD",
"customerId": "cus_asdf1234",
"priceId": "prc_qwert3456",
"productId": "prd_zxcv4567",
"updatedAt": 1755936495645
},
"signature": "webhook_signature"
}{
"type": "SUBSCRIPTION_STATUS_UPDATED",
"data": {
"id": "subs_abc123xyz",
"status": "TRIALING",
"amount": 199, // in minor unit
"billingCycleConfig": {
"frequency": 1,
"interval": "day"
},
"clientReferenceId": "your-sub-unique-id",
"createdAt": 1755836495645,
"currency": "USD",
"customerId": "cus_asdf1234",
"priceId": "prc_qwert3456",
"productId": "prd_zxcv4567",
"updatedAt": 1755936495645
},
"signature": "webhook_signature"
}{
"type": "SUBSCRIPTION_STATUS_UPDATED",
"data": {
"id": "subs_abc123xyz",
"status": "ACTIVE",
"amount": 199, // in minor unit
"billingCycleAnchor": 1755836495645,
"billingCycleConfig": {
"frequency": 1,
"interval": "day"
},
"clientReferenceId": "your-sub-unique-id",
"createdAt": 1755836495645,
"currency": "USD",
"customerId": "cus_asdf1234",
"priceId": "prc_qwert3456",
"productId": "prd_zxcv4567",
"lastInvoiceId": "invc_1234asdf",
"lastSuccessfulInvoiceId": "invc_2345qwert",
"lastSuccessfulPaymentId": "py_3456zxcv",
"updatedAt": 1755936495645
},
"signature": "webhook_signature"
}{
"type": "SUBSCRIPTION_STATUS_UPDATED",
"data": {
"id": "subs_abc123xyz",
"status": "GRACE_PERIOD",
"amount": 199, // in minor unit
"billingCycleConfig": {
"frequency": 1,
"interval": "day"
},
"clientReferenceId": "your-sub-unique-id",
"createdAt": 1755836495645,
"currency": "USD",
"customerId": "cus_asdf1234",
"priceId": "prc_qwert3456",
"productId": "prd_zxcv4567",
"updatedAt": 1755936495645
},
"signature": "webhook_signature"
}{
"type": "SUBSCRIPTION_STATUS_UPDATED",
"data": {
"id": "subs_abc123xyz",
"status": "SUSPENDED",
"amount": 199, // in minor unit
"billingCycleConfig": {
"frequency": 1,
"interval": "day"
},
"clientReferenceId": "your-sub-unique-id",
"createdAt": 1755836495645,
"currency": "USD",
"customerId": "cus_asdf1234",
"priceId": "prc_qwert3456",
"productId": "prd_zxcv4567",
"updatedAt": 1755936495645
},
"signature": "webhook_signature"
}{
"type": "SUBSCRIPTION_STATUS_UPDATED",
"data": {
"id": "subs_abc123xyz",
"status": "CANCELED",
"amount": 199, // in minor unit
"billingCycleConfig": {
"frequency": 1,
"interval": "day"
},
"clientReferenceId": "your-sub-unique-id",
"createdAt": 1755836495645,
"currency": "USD",
"customerId": "cus_asdf1234",
"priceId": "prc_qwert3456",
"productId": "prd_zxcv4567",
"canceledAt": 1755936495645,
"canceledBy": "CUSTOMER",
"updatedAt": 1755936495645
},
"signature": "webhook_signature"
}{
"type": "SUBSCRIPTION_STATUS_UPDATED",
"data": {
"id": "subs_abc123xyz",
"status": "SCHEDULED",
"amount": 199, // in minor unit
"billingCycleConfig": {
"frequency": 1,
"interval": "day"
},
"clientReferenceId": "your-sub-unique-id",
"createdAt": 1755836495645,
"currency": "USD",
"customerId": "cus_asdf1234",
"priceId": "prc_qwert3456",
"productId": "prd_zxcv4567",
"updatedAt": 1755936495645
},
"signature": "webhook_signature"
}{
"type": "SUBSCRIPTION_STATUS_UPDATED",
"data": {
"id": "subs_abc123xyz",
"status": "DISCOUNTED_TRIALING",
"amount": 199, // in minor unit
"billingCycleConfig": {
"frequency": 1,
"interval": "day"
},
"clientReferenceId": "your-sub-unique-id",
"createdAt": 1755836495645,
"currency": "USD",
"customerId": "cus_asdf1234",
"priceId": "prc_qwert3456",
"productId": "prd_zxcv4567",
"updatedAt": 1755936495645,
"discountedTrial": {
"cycleCount": 3,
"billingCycleConfig": {
"interval": "hour",
"frequency": 2
},
"price": {
"amountStr": "1.05",
"currency": "USD"
}
}
},
"signature": "webhook_signature"
}Note that
ACTIVEandCANCELEDstates are the key states that have additional fields in thedataobject.
Use these to update your internal system or notify users.
Webhook payloads always include:
- type – Event type
- data –
Subscriptionobject - signature – HMAC signature for verification
📘 Core Subscription Statuses
| Status | Description |
|---|---|
INCOMPLETE | The subscription was created but no payment has been made yet, or no payment method has been added yet for subscription with trial. |
INCOMPLETE_EXPIRED | The subscription was created but no payment has been made until the expiration time. |
TRIALING | The customer has added their payment method successfully for subscription with trial. First payment will be charged at the end of the trial. |
SCHEDULED | The customer has added their payment method successfully, and the subscription is scheduled to start at a future date. Billing has not yet begun, and no charges yet until the scheduled start time (or the end of a trial if one is configured). |
DISCOUNTED_TRIALING | The customer has successfully added their payment method, and the subscription is currently in a discounted trial period. Breeze will charge the customer the configured discounted trial price for each trial cycle. Once all discounted trial cycles are completed and the next billing event is successfully processed, the subscription will transition to ACTIVE. |
ACTIVE | The customer has made a successful payment. Recurring charges are enabled. |
GRACE_PERIOD | A recurring charge failed. The subscription is in the grace period and awaiting resolution |
SUSPENDED | Grace period expired without successful payment. Merchant should revoke the service access. |
CANCELED | The subscription has been canceled by the customer or merchant |
⚠️ Breeze emits webhook events at each of these state transitions
♻️ Subscription Lifecycle Diagram
stateDiagram-v2
[*] --> INCOMPLETE: Create subscription
INCOMPLETE --> INCOMPLETE_EXPIRED: Customer did not make any successful first payment attempt (default after 60 days)
INCOMPLETE --> TRIALING: Payment method added successfully for free trial only subscription
INCOMPLETE --> ACTIVE: First payment completed successfully
INCOMPLETE --> DISCOUNTED_TRIALING
TRIALING --> CANCELED: Customers cancelled subscription during trial period
TRIALING --> ACTIVE: First payment successfully charged after the trial
TRIALING --> GRACE_PERIOD: First payment failed to be charged after the trial
DISCOUNTED_TRIALING --> CANCELED
DISCOUNTED_TRIALING --> ACTIVE
DISCOUNTED_TRIALING --> GRACE_PERIOD
GRACE_PERIOD --> ACTIVE: Payment successful
GRACE_PERIOD --> SUSPENDED: Grace period expired, no payment
ACTIVE --> GRACE_PERIOD: Payment fails (grace period)
ACTIVE --> CANCELED: Customer cancels
GRACE_PERIOD --> CANCELED: Customer cancels
INCOMPLETE --> SCHEDULED: Payment method added successfully for scheduled subscription
SCHEDULED --> TRIALING: Trial started for a scheduled subscription with free trial
SCHEDULED --> ACTIVE: First payment successfully charged
CANCELED --> [*]
SUSPENDED --> [*]
Sample Scenario
You want to create a a monthly Subscription with a 7 days trial period (merchant grace period config: 3 days), starting July 1st:
- On July 1st, you call
POST /v1/subscriptionwith the customer data and subscription setup and we will return you a checkout_url to redirect the users to proceed with adding their payment method - After user successfully added their payment method, we save the payment method on customer's profile for future payment, and
SubscriptionbecomesTRIALINGand the 7 day trial period starts. - On July 8th, when the trial period end, we automatically charge the customer's saved payment method.
- If the off-session payment on July 8th is successful, the
SubscriptionbecomesACTIVE. The customer receives an email confirming the success payment. The customer is billed subsequently on August 8th, then on September 8th, and so on. - If the off-session payment on July 8th is failed , the
SubscriptionbecomesGRACE_PERIOD- If this off-session payment still failed to be charged on July 11th (e.g. customer did not respond to payment method change request, etc), the
SubscriptionbecomesSUSPENDED
- If this off-session payment still failed to be charged on July 11th (e.g. customer did not respond to payment method change request, etc), the
- If the off-session payment on July 8th is successful, the
- On August 8th, if the
SubscriptionisACTIVE, we will automatically charge the customer's saved payment method. If this attempt to charge fails, customer will receive an email containing a link to complete the payment online, along with the final deadline to retry by August 11th (reflecting a 3-day grace period). During this time, theSubscriptionstatus transitions toGRACE_PERIOD. If no successful payment is made by August 11th, theSubscriptionstatus will automatically transition toSUSPENDED.
sequenceDiagram
participant Merchant
participant BreezeAPI as Breeze Backend
participant PaymentPage as Hosted Payment Page
participant Customer
Note over Merchant, BreezeAPI: Merchant initiates a subscription
Merchant->>BreezeAPI: POST /subscriptions (productId, priceId, customerReference, trialDuration)
BreezeAPI-->>Merchant: checkout_url
Note over Merchant, Customer: Customer completing a subscription
Merchant-->>Customer: Send checkout link
Customer->>PaymentPage: Open hosted payment page
PaymentPage-->>Customer: Render card form
Customer->>PaymentPage: Enter card
PaymentPage->>PaymentPage: Verify payment method
Note over PaymentPage, BreezeAPI: Payment method is saved
PaymentPage->>BreezeAPI: Save Payment Method
BreezeAPI->>BreezeAPI: Mark Subscription as TRIALING
BreezeAPI-->>Merchant: SUBSCRIPTION_STATUS_UPDATED webhook (status=TRIALING)
Note over BreezeAPI: 7 days later (trial ends)
BreezeAPI->>BreezeAPI: Attempt first charge
BreezeAPI-->>BreezeAPI: Payment success or failure
alt Payment Succeeds
BreezeAPI->>BreezeAPI: Mark Subscription as ACTIVE
BreezeAPI-->>Merchant: SUBSCRIPTION_STATUS_UPDATED webhook (status=ACTIVE)
else Payment Fails
BreezeAPI->>BreezeAPI: Mark Subscription as GRACE_PERIOD
BreezeAPI->>Merchant: SUBSCRIPTION_STATUS_UPDATED webhook (status=GRACE_PERIOD)
end
Note over BreezeAPI: 3 days later (grace period duration)
alt A successful payment made within 3 days
BreezeAPI->>BreezeAPI: Mark Subscription as ACTIVE
BreezeAPI-->>Merchant: SUBSCRIPTION_STATUS_UPDATED webhook (status=ACTIVE)
else No successful payment made
BreezeAPI->>BreezeAPI: Mark Subscription as SUSPENDED
BreezeAPI->>Merchant: SUBSCRIPTION_STATUS_UPDATED webhook (status=SUSPENDED)
end
Updated 4 days ago
