---
title: "Cancel a purchase"
method: POST
path: "/v1/sdk/purchases/{purchaseRef}/cancel"
tags: ["Purchases"]
---

# Cancel a purchase

`POST /v1/sdk/purchases/{purchaseRef}/cancel`

## Request

- Base URL: `https://api.solvapay.com`
- URL: `https://api.solvapay.com/v1/sdk/purchases/{purchaseRef}/cancel`
- Auth: HTTP bearer
- TypeScript: <https://skmtc.dev/solvapay/apis/solvapay-rest-api/docs/v1/sdk/purchases/:purchaseRef/cancel/post.ts> (a function with typed inputs; its response is checked against the schema)

Cancels an active purchase. For recurring purchases, cancellation takes effect at the end of the current billing period.

## Path parameters

- `purchaseRef` string, required

## Request body

- CancelPurchaseRequest
  - `reason` string

## Response `200`

Purchase cancelled successfully

- object
  - `purchase` SdkPurchaseResponse
    - `amount` number, required: Amount in USD cents (normalised for aggregation)
    - `autoRenew` boolean: Auto-renew enabled
    - `billingCycle` 'weekly' | 'monthly' | 'quarterly' | 'yearly': Billing cycle
    - `cancellationReason` string: Reason for cancellation
    - `cancelledAt` string: When purchase was cancelled
    - `createdAt` string, required: Created at
    - `currency` string, required: ISO 4217 currency code of the customer-facing charge
    - `customerEmail` string: Customer email
    - `customerRef` string, required: Customer reference
    - `endDate` string: End date of purchase
    - `exchangeRate` number: Exchange rate from original currency to USD
    - `isRecurring` boolean, required: Whether the purchase is recurring
    - `metadata` object: Arbitrary metadata attached to the purchase
    - `nextBillingDate` string: Next billing date
    - `origin` 'paid' | 'free_default' | 'manual' | 'one_time' | 'credit_topup' | 'admin_assignment': How the purchase originated
    - `originalAmount` number: Original amount in the payment currency (minor units)
    - `paidAt` string: Paid at timestamp
    - `planRef` string: Plan reference from the plan snapshot, for reliable plan matching
    - `planSnapshot` SdkPlanSnapshotDto
      - `currency` string, required: Currency code
      - `features` object, nullable: Plan features
      - `isMetered` boolean: Whether the frozen plan counts usage (prices per unit, or has a limit). Shipped clients read this to show an allowance.
      - `name` string: Plan name captured at purchase time
      - `options` object[]: Frozen composable pricing options captured at purchase time
      - `price` number, required: Headline plan price in minor units (e.g. cents)
      - `reference` string: Plan reference
    - `productName` string: Product name
    - `productRef` string: Product reference
    - `reference` string, required: Purchase reference
    - `requiresPayment` boolean: Whether the purchase requires payment
    - `startDate` string, required: Start date
    - `status` string, required: Purchase status
    - `usage` SdkUsagePeriodDto
      - `periodEnd` string: Billing period of the active usage window; counts come from `/v1/sdk/limits`
      - `periodStart` string: Billing period of the active usage window; counts come from `/v1/sdk/limits`
  - `success` boolean

## Other responses

- `404`: Purchase not found

## Changes

- **2026-09-30** `e13ee57d07a6`: 2 info
  - added `#/components/schemas/SdkUsagePeriodDto` to the `purchase/usage` response property `allOf` list for the response status `200`
  - removed `#/components/schemas/UsageBillingDto` from the `purchase/usage` response property `allOf` list for the response status `200`
- **2026-09-18** `aacdf8ae7816`: 2 info
  - added the optional property `purchase/planRef` to the response with the `200` status
  - added the optional property `purchase/planSnapshot/allOf[#/components/schemas/SdkPlanSnapshotDto]/isMetered` to the response with the `200` status
- **2026-08-13** `e356f6586bf2`: 4 warning
  - removed the optional property `purchase/planSnapshot/allOf[#/components/schemas/SdkPlanSnapshotDto]/billingCycle` from the response with the `200` status
  - removed the optional property `purchase/planSnapshot/allOf[#/components/schemas/SdkPlanSnapshotDto]/includedUnits` from the response with the `200` status
  - removed the optional property `purchase/planSnapshot/allOf[#/components/schemas/SdkPlanSnapshotDto]/meterRef` from the response with the `200` status
  - removed the optional property `purchase/planSnapshot/allOf[#/components/schemas/SdkPlanSnapshotDto]/type` from the response with the `200` status
- …earlier changes not shown

[Operation history](https://skmtc.dev/solvapay/apis/solvapay-rest-api/changes/v1/sdk/purchases/:purchaseRef/cancel/post.md)

---

[API](https://skmtc.dev/solvapay/apis/solvapay-rest-api.md) - [All operations](https://skmtc.dev/solvapay/apis/solvapay-rest-api/llms.txt) - [OpenAPI document](https://skmtc.dev/solvapay/apis/solvapay-rest-api/revisions/bd3a1cb8cb52?raw)
