Cancel an order or subscription
Cancels one order or a sequential batch of up to 100 account-owned IDs. Every ordinary API order is still eligible only during its own 15-second pre-dispatch grace window; eligible subscriptions may settle asynchronously.
https://notpanel.com/api/v3action=cancelapplication/x-www-form-urlencodedorder ID or comma-separated orders IDs, up to 100. Older UUID and sub_ references remain accepted. Bulk mode never extends an order's cancellation window.Parameters
| Name | Type | Description |
|---|---|---|
| keyRequired | string | Your API key. |
| actionRequired | string | Must be the literal string "cancel". |
| orderConditional | string | One numeric ordinary-order or eligible upstream-managed subscription ID returned by action=add. |
| ordersConditional | string (CSV) | Comma-separated ordinary-order or eligible subscription IDs, maximum 100. The response preserves input order and returns success or error per item. |
Example request
Replace YOUR_API_KEY with the key generated under your dashboard’s API page.
curl -X POST https://notpanel.com/api/v3 \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "key=YOUR_API_KEY&action=cancel&order=7001"const res = await fetch("https://notpanel.com/api/v3", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
key: "YOUR_API_KEY",
action: "cancel",
order: "7001",
}),
});
const data = await res.json();
console.log(data);import requests
res = requests.post(
"https://notpanel.com/api/v3",
data={
"key": "YOUR_API_KEY",
"action": "cancel",
"order": "7001",
},
)
print(res.json())<?php
$body = http_build_query([
'key' => 'YOUR_API_KEY',
'action' => 'cancel',
'order' => '7001',
]);
$response = file_get_contents('https://notpanel.com/api/v3', false, stream_context_create([
'http' => [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
'content' => $body,
'ignore_errors' => true,
],
]));
print_r(json_decode($response, true));
Example response
{
"order": 7001,
"status": "Canceled",
"status_key": "cancelled",
"cancel": 1,
"refund": "0.50",
"refund_pending": 0
}Common errors
| Status | Body | Cause |
|---|---|---|
| 400 | {"error":"Invalid subscription order reference"} | This error is returned only when a legacy sub_ reference is malformed. A well-formed but unknown subscription reference returns 404 Subscription not found. |
| 409 | {"error":"Cancellation window has ended or the order has already started"} | The ordinary order has left its 15-second cancellation window or is no longer pending. The single request returns 409. |
| 409 | {"error":"Order is already completed"} | The item is already in a non-cancellable terminal state. A retry of an earlier successful cancellation returns that same successful result instead. |
| 409 | {"error":"Order is already refunded"} | The item is already in a non-cancellable terminal state. A retry of an earlier successful cancellation returns that same successful result instead. |
| 404 | {"error":"Order not found"} | No order or eligible subscription with that identifier belongs to this account. A single request returns 404. |
| 409 | {"error":"Subscription is currently executing; retry cancellation shortly","error_code":"CANCELLATION_IN_PROGRESS","retryable":true} | The subscription is currently executing. The subscription cancellation request returns 409 with Retry-After: 2; retry shortly. |
| 400 | {"error":"Subscription cancellation is not allowed","error_code":"CANCELLATION_NOT_ALLOWED_SUBSCRIPTION"} | The subscription is already terminal and cannot be cancelled. The response is 400. |
| 404 | {"error":"Subscription not found"} | No eligible account-owned subscription exists for that reference, or it uses the wrong management mode. The response is 404. |
| 429 | {"error":"Rate limit exceeded for cancel"} | The cancellation action limit was reached. Retry after the reported delay; the response is 429. |