> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.paymentkit.com/guides/billing/subscriptions/cancel-a-subscription/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.paymentkit.com/_mcp/server. # Cancel a subscription # Cancel immediately Immediate cancellation terminates the subscription right away. No further invoices are generated. #### Dashboard 1. Go to **Billing > Subscriptions** in the sidebar 2. Select the subscription to cancel 3. Click **Cancel subscription** 4. Choose **Cancel immediately** 5. Select a refund option 6. Confirm the action #### API ```bash curl -X POST https://app.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/cancel \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "refund_option": "prorated" }' ``` The subscription transitions to **Cancelled** state. This is a terminal state and cannot be reversed. # Cancel at period end Schedule the subscription to cancel at the end of the current billing period. The customer continues to have access until the period expires. #### API ```bash curl -X PATCH https://app.paymentkit.com/api/{account_id}/subscriptions/{subscription_id} \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "cancel_at_period_end": true }' ``` #### Python SDK ```python subscription = client.subscriptions.update( account_id="acc_abc123", subscription_id="sub_abc123", cancel_at_period_end=True ) ``` The subscription remains **Active** until the current period ends, then automatically transitions to **Cancelled**. # Cancel on a specific date Schedule the subscription to cancel on a custom date. Use this for contract end dates or customer-requested future cancellations. ```bash curl -X POST https://app.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/schedule-cancellation \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "cancel_at": "2026-06-01T00:00:00Z", "refund_option": "none" }' ``` The subscription continues billing normally until the scheduled date, then cancels automatically. # Refund options When cancelling, choose how to handle the customer's payments: | Option | Behavior | | --------------- | ----------------------------------------------------------------------------------- | | `none` | Cancel with no refund. The default. | | `full` | Refund the full paid amount for the current billing period. | | `prorated` | Refund only the unused portion of the current period, calculated by remaining time. | | `cancel_unpaid` | Void all open and draft invoices instead of refunding paid ones. | > **Note** > > Only invoices with licensed (non-metered) prices are eligible for refunds. Metered usage that has already been consumed is not refundable. ## Preview a cancellation Before confirming, preview the refund amount without applying any changes: ```bash curl -X POST https://app.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/cancel \ -H "Authorization: Bearer sk_live_..." \ -H "Content-Type: application/json" \ -d '{ "refund_option": "prorated", "is_preview": true }' ``` The response includes the calculated refund amount. No database changes or payment operations are performed. # Undo a scheduled cancellation Remove a scheduled cancellation before it takes effect. This clears both `cancel_at_period_end` and `cancel_at` flags. ```bash curl -X DELETE https://app.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/scheduled-cancellation \ -H "Authorization: Bearer sk_live_..." ``` The subscription continues renewing as normal. > **Note** > > Returns `400 Bad Request` if no scheduled cancellation exists. Check `cancel_at_period_end` or `cancel_at` on the subscription before calling. # Cancel a pending plan change If a subscription has a pending plan change scheduled for period end (via `effective_at: "period_end"` on the change-plan endpoint), cancel it before it applies. ```bash curl -X DELETE https://app.paymentkit.com/api/{account_id}/subscriptions/{subscription_id}/pending-change \ -H "Authorization: Bearer sk_live_..." ``` **Response:** ```json { "status": "cancelled", "cancelled_items": [ { "action": "update", "subscription_item_id": "si_abc123", "new_price_id": "prc_xyz789" } ] } ``` If no pending change exists, the response returns `status: "not_found"` with an empty `cancelled_items` array. # When to use each approach | Approach | Use case | | ------------------------ | ---------------------------------------------------------------------------------------------------------------- | | **Cancel immediately** | Customer requests immediate termination. Pair with a refund option. | | **Cancel at period end** | Customer wants to stop renewing but use the service through the paid period. Most common for self-service flows. | | **Cancel on date** | Contract has a defined end date, or customer requests cancellation on a future date. | > **Warning** > > Cancellation is irreversible. To restart billing for a cancelled customer, create a new subscription. # Webhook events | Event | Trigger | | ------------------------ | --------------------------------------------------------------------------- | | `subscription.cancelled` | Subscription was cancelled (immediate, at period end, or on scheduled date) | > End a subscription immediately, at period end, or on a scheduled date. Choose a refund strategy that fits your use case.