Skip to Content

Cancel Subscription Checkout

PATCH/subscription-checkouts/:id/cancel

Description

Cancel a pending subscription checkout intent before the customer signs. Use this when the customer abandons the checkout, the order is voided merchant-side, or the intent should no longer be honored.

This endpoint cancels the intent. To cancel an active on-chain subscription, use POST /subscriptions/:id/cancel instead.

⚠️

Cancelling a pending intent does NOT abort an in-flight on-chain subscribeAndCharge transaction. If the customer’s transaction is in the mempool when you cancel and confirms after, the indexer flips the intent back to completed and you receive a subscription_checkout.completed webhook. Merchants must handle this case. The latest webhook is authoritative.

Headers

HeaderDescriptionRequired
AuthorizationBearer token with your API keyyes
Content-Typeapplication/jsonno

Path Parameters

NameTypeDescriptionRequired
idstringThe subscription checkout ID (e.g. `schk_1234567890abcdef`).yes

Body Parameters

NameTypeDescriptionRequired
cancellation_reasonstringOptional reason for cancellation: `merchant_initiated` or `subscriber_declined`.no

Example Request

cancel-subscription-checkout.js
const response = await fetch(
  'https://checkout-api.exodus-int.com/subscription-checkouts/schk_1234567890abcdef/cancel',
  {
    method: 'PATCH',
    headers: {
      Authorization: 'Bearer sk_live_xxxxxxxxxxxxxxxx',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      cancellation_reason: 'merchant_initiated',
    }),
  },
);
 
const intent = await response.json();
console.log(intent.status); // "cancelled"

Response

SUCCESSFUL RESPONSE
{
  "object": "subscription_checkout",
  "id": "schk_1234567890abcdef",
  "status": "cancelled",
  "onchain_id": "0x9f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0d1e2f3a",
  "business_name": "Acme Inc",
  "subscriber": null,
  "external_customer_id": "cus_42",
  "supported_chains": ["eip155:1", "eip155:137"],
  "token_symbol": "USDC",
  "price": "9990000",
  "price_currency": null,
  "period_duration": 2592000,
  "recommended_cap": "120000000",
  "checkout_url": "https://checkout.exodus-int.com/subscribe/schk_1234567890abcdef",
  "metadata": { "external_plan_ref": "pro_monthly" },
  "cancellation_reason": "merchant_initiated",
  "expires_at": "2026-05-19T12:05:00Z",
  "created_at": "2026-05-19T12:00:00Z",
  "updated_at": "2026-05-19T12:03:11Z",
  "cancelled_at": "2026-05-19T12:03:11Z"
}

Cancel by current state

Current statusResponseNotes
pending200status: cancelledFires subscription_checkout.cancelled webhook.
cancelled200 — existing recordIdempotent no-op. Webhook does not re-fire.
completed400 invalid_requestCancel the materialized subscription via POST /subscriptions/:id/cancel.
expired400 invalid_requestIntent has expired; nothing to cancel.

Errors

StatusCodeDescription
400invalid_requestThe intent can’t be cancelled because its status is completed or expired.
404not_foundIntent ID does not exist.
403forbiddenIntent belongs to another merchant.

Webhook Fired

subscription_checkout.cancelled — fires once on the pending → cancelled transition. Re-cancels do not re-fire.

Start building

XO

Request Demo

Schedule a call with our team

Select a product
Arrow right

Start building
Grateful

Contact Us

We're here to help