Cancel a subscription
In certain cases, a subscription may be cancelled.
Cancellation scenarios
The outcome of a cancellation depends on the subscription's lifecycle stage.
1. Withdrawal — free cancellation (under 24 hours)
If fewer than 24 hours have passed since the subscription was confirmed, the cancellation is treated as a withdrawal. No penalty applies and any amount already paid is refunded to the customer.
This applies when the subscription status is draft, sent, in_progress, or waiting_for_payment — i.e. before the first charge settles.
No summary is required in this case. Only reason is accepted.
2. Pre-activation cancellation (over 24 hours, not yet active)
If the subscription was confirmed more than 24 hours ago but items have not yet been activated, a penalisation may apply. The operator confirms the agreed penalty with the customer before proceeding.
Submit the agreed purchase_fee and total_to_pay in the summary object.
3. Active or activating subscription
Once the subscription is active or activating, cancellation requires the customer to either keep or return each product. Before proceeding, retrieve the suggested costs for each option by calling GET /api/public/v1/subscriptions/:id — the response already includes pre-calculated cancellation_cost_kept and cancellation_cost_returned per item (see Getting the cancellation cost below). Present these to the operator and customer, then submit the agreed breakdown in the summary object.
Submit the full summary including which items are kept, which are returned, and the totals.
Getting the cancellation cost
To get the suggested cancellation cost for each item, call GET /api/public/v1/subscriptions/:id. Each item in last_persisted_cart.cart_items exposes two pre-calculated cost fields that seQura computes server-side based on the remaining subscription months:
| Field | Description |
|---|---|
cancellation_cost_kept | Cost if the customer keeps the item: subscription_price × remaining_months |
cancellation_cost_returned | Cost if the customer returns the item: subscription_price × remaining_months × 50% |
Both fields are null when the subscription is not active or activating.
Formula
remaining_months = max(total_months - current_month, 0)
cancellation_cost_kept = item.subscription_price × remaining_months
cancellation_cost_returned = item.subscription_price × remaining_months × 0.5
Example response (excerpt)
{
"id": 123,
"status": "active",
"current_month": 6,
"total_months": 24,
"last_persisted_cart": {
"cart_items": [
{
"reference": "FRAME-001",
"name": "Designer Frame",
"subscription_price": { "value": 1500, "string": "15,00 €" },
"cancellation_cost_kept": { "value": 27000, "string": "270,00 €" },
"cancellation_cost_returned": { "value": 13500, "string": "135,00 €" }
},
{
"reference": "LENS-001",
"name": "Progressive Lenses",
"subscription_price": { "value": 2000, "string": "20,00 €" },
"cancellation_cost_kept": { "value": 36000, "string": "360,00 €" },
"cancellation_cost_returned": { "value": 18000, "string": "180,00 €" }
}
]
}
}In this example: 24 − 6 = 18 remaining months. The frame costs €15/month × 18 = €270 to keep, or €135 to return.
API Endpoint
Endpoint: /api/public/v1/subscriptions/:subscription_id/cancel
Method POST
Swagger https://docs.sequra.com/update/reference/post_api-public-v1-subscriptions-id-cancel#/
Request parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
reason | string | No | Human-readable cancellation reason. |
explanation | string | No | Additional free-text explanation of the reason. |
summary | object | No | Cancellation cost breakdown. See below. |
summary object
summary object| Field | Type | Description |
|---|---|---|
kept_items | array of objects | Cart items the customer keeps, each with their cancellation cost. |
returned_items | array of objects | Cart items the customer returns, each with their cancellation cost. |
purchase_fee | integer | Optional extra fee charged to the customer (cents). Used when the customer buys out products outside the subscription. |
total_to_pay | integer | Total amount the customer owes for this cancellation (cents). Sum of all item costs + purchase_fee. |
Each item in kept_items and returned_items is an object:
| Field | Type | Description |
|---|---|---|
id | string | Cart item ID. |
price | integer | Cancellation cost for this item (cents). |
Important: The entire summary object — including all item costs, purchase_fee, and total_to_pay — is stored for informational purposes only. seQura does not use these values to process any charges or validate the cancellation. The subscription will be cancelled regardless of whether summary is provided or what values it contains. The data is recorded in the cancellation event for your own reporting and audit trail.
Request example — active subscription, customer returns one item and keeps another
{
"reason": "Customer request",
"explanation": "Customer no longer needs the subscription",
"summary": {
"kept_items": [{ "id": "frame-cart-item-id", "price": 45000 }],
"returned_items": [{ "id": "lens-cart-item-id", "price": 22500 }],
"purchase_fee": 0,
"total_to_pay": 67500
}
}Request example — pre-activation cancellation with purchase fee
{
"reason": "Customer request",
"summary": {
"kept_items": [],
"returned_items": [],
"purchase_fee": 5000,
"total_to_pay": 5000
}
}Response
{
"success": true,
"message": "Subscription cancelled successfully"
}Error responses
| HTTP status | Reason |
|---|---|
| 422 | Subscription is already cancelled or in an error state |
| 401 | API account not authorised for this subscription |
| 404 | Subscription not found |
Updated 3 days ago