> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fire.rest/llms.txt
> Use this file to discover all available pages before exploring further.

# Cancel order

> Cancel an aggregator order and, when supported by the payment processor, refund the payment.

Cancels an order previously created through [Inject order](/en/api-reference/orders). Fire looks up the order by `account` and `order_uid`, updates the order to `CANCELED`, and returns the updated order in the standard API envelope.

If the stored payment processor supports refunds (for example, Deuna), Fire attempts the refund and sets `payment_status` to `REFUNDED` on success. For other processors, Fire cancels the payment state and sets `payment_status` to `CANCELED`.

<ParamField header="Authorization" type="string" required>
  Bearer token obtained from [POST /login](/en/api-reference/login). Format: `Bearer <accessToken>`.
</ParamField>

<ParamField header="x-api-key" type="string" required>
  Your Fire API key.
</ParamField>

<ParamField header="x-client-channel" type="string" required>
  Must be `integration`. Identifies the request as coming from an external integration.
</ParamField>

<ParamField header="account" type="string" required>
  Account identifier used to find the order.
</ParamField>

<ParamField header="Content-Type" type="string" default="application/json">
  Use `application/json` for the request body.
</ParamField>

<ParamField path="order_uid" type="string" required>
  UID of the order to cancel.
</ParamField>

<ParamField body="reason" type="string" required>
  Reason for the cancellation or refund request.
</ParamField>

<ParamField body="payment_method_uid" type="string">
  Optional. UID of the payment method used to resolve refund credentials when you need to target a specific method.
</ParamField>

<ParamField body="vendor_uid" type="string" required>
  Vendor UID used to resolve payment credentials.
</ParamField>

<ParamField body="email" type="string">
  Customer email sent to the payment processor when required.
</ParamField>

<ParamField body="customer_uid" type="string">
  Registered customer UID. When present, Fire treats the refund payload as authenticated.
</ParamField>

<ParamField body="anonymous_customer_uid" type="string">
  Anonymous customer UID. Used as the payment user identifier when `customer_uid` is not present.
</ParamField>

<ParamField body="store_uid" type="string">
  Store UID used to resolve store-specific payment credentials.
</ParamField>

<ParamField body="media" type="string">
  Sales medium used to resolve credentials. Supported values: `APP`, `WEB`.
</ParamField>

<ParamField body="cancellation_type" type="string">
  Optional. Cancellation reason ID or code from the catalog. When provided, it is persisted on the order and reported to the payment gateway.
</ParamField>

<RequestExample>
  ```json Minimum cancellation theme={null}
  {
    "reason": "Duplicate charge",
    "vendor_uid": "vendor-uid-abc"
  }
  ```

  ```json Cancellation with type code theme={null}
  {
    "reason": "Customer request",
    "cancellation_type": "101",
    "vendor_uid": "vendor-uid-abc"
  }
  ```

  ```json Cancellation with customer and channel theme={null}
  {
    "reason": "Customer cancellation",
    "cancellation_type": "101",
    "payment_method_uid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
    "vendor_uid": "vendor-uid-abc",
    "store_uid": "store-uid-xyz",
    "media": "WEB",
    "email": "customer@example.com",
    "customer_uid": "customer-uid-123"
  }
  ```
</RequestExample>

<ResponseField name="data" type="object">
  Updated order. Prices in `order_lines`, `totals`, and `payment_methods` are returned as external, unscaled amounts.

  <Expandable title="data">
    <ResponseField name="uid" type="string">Order UID.</ResponseField>
    <ResponseField name="order_code" type="string | null">Human-readable order code.</ResponseField>
    <ResponseField name="account_uid" type="string">Account identifier.</ResponseField>
    <ResponseField name="vendor_uid" type="string | null">Vendor UID.</ResponseField>
    <ResponseField name="store_uid" type="string | null">Store UID.</ResponseField>
    <ResponseField name="status" type="string">Final order status. Successful cancellations return `CANCELED`.</ResponseField>
    <ResponseField name="payment_status" type="string">Final payment status: `REFUNDED` or `CANCELED`.</ResponseField>
    <ResponseField name="cancellation_type" type="string | null">Cancellation reason ID or code as sent in the request, persisted on the order. `null` when not provided.</ResponseField>
    <ResponseField name="order_lines" type="array | null">Order lines with unscaled prices.</ResponseField>
    <ResponseField name="totals" type="array | null">Order totals with unscaled prices.</ResponseField>
    <ResponseField name="payment_methods" type="array | null">Payment methods with unscaled amounts.</ResponseField>
    <ResponseField name="metadata" type="object | null">Order metadata.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="status" type="number">
  HTTP status code from the API envelope.
</ResponseField>

<ResponseField name="traceId" type="string">
  Trace identifier for support and debugging.
</ResponseField>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": {
      "uid": "550e8400-e29b-41d4-a716-446655440000",
      "order_code": "ORD-2026-001234",
      "account_uid": "acc-uid-12345",
      "vendor_uid": "vendor-uid-abc",
      "store_uid": "store-uid-xyz",
      "status": "CANCELED",
      "payment_status": "REFUNDED",
      "cancellation_type": "101",
      "order_lines": [],
      "totals": [],
      "payment_methods": [],
      "metadata": {},
      "created_at": "2026-03-30T12:00:00.000Z",
      "updated_at": "2026-03-30T12:05:00.000Z",
      "deleted_at": null
    },
    "status": 200,
    "method": "POST",
    "pathname": "/api/v4/integrations/sales/aggregator/orders/550e8400-e29b-41d4-a716-446655440000/refund",
    "duration": 120,
    "traceId": "abc123",
    "isArray": false
  }
  ```

  ```json 422 theme={null}
  {
    "status": 422,
    "errors": {
      "status": "422",
      "code": "invalid_type",
      "title": "Validation error",
      "detail": "reason is required"
    }
  }
  ```

  ```json 404 theme={null}
  {
    "status": 404,
    "errors": {
      "status": "404",
      "code": "not_found",
      "title": "Not found",
      "detail": "Order not found"
    }
  }
  ```

  ```json 400 theme={null}
  {
    "status": 400,
    "errors": {
      "status": "400",
      "code": "custom",
      "title": "Error",
      "detail": "Payment methods not found"
    },
    "message": "Payment methods not found",
    "code": 0,
    "moreInfo": "https://docs.artisn.io/api/errors"
  }
  ```
</ResponseExample>

## Processing rules

* When provided, `payment_method_uid` helps resolve credentials, but Fire evaluates the payment methods stored on the order.
* For Deuna refunds, the order must include `metadata.order_token`; otherwise Fire returns `400`.
* After saving the updated order, Fire returns prices transformed for external consumption.
* Fire notifies the cancellation downstream after the order is saved.

## Post-cancellation behavior

<Warning>
  A `200` means **the order** was cancelled. It does **not** mean the fiscal document is already voided: that part is asynchronous and may still be in flight — or fail — after we responded.
</Warning>

### Fiscal voiding is asynchronous

When the order had a fiscal document issued, Fire requests its cancellation from the provider and leaves the document in `cancelling`. The final state arrives **via a provider webhook**, not in this endpoint's response.

| Document status | What it means                                                        |
| --------------- | -------------------------------------------------------------------- |
| `cancelling`    | Void requested, awaiting provider confirmation. **Transient** state. |
| `cancelled`     | Voided and confirmed. Chain complete.                                |
| `rejected`      | The tax authority refused the void. The document is still valid.     |

If the provider webhook never arrives, the document **stays in `cancelling` indefinitely** — no automatic retry unblocks it. If you need fiscal certainty, waiting for this endpoint's `200` is not enough; check the document status afterwards.

### Amounts are not zeroed

A cancelled order **keeps its totals and its payment methods with the original amounts**. `order_lines`, `totals` and `payment_methods` come back with the same values they had before the cancellation; what changes is `status` and `payment_status`.

This is deliberate: the order records what happened, not what remains in force. If you reconcile amounts against cancelled orders you will find they **match perfectly** — because exactly what was sold was charged, before the void. The right reconciliation for a cancelled order is not "do the amounts match?" but "was every link reversed?".

### Cancellation is all-or-nothing

There is no per-line or partial-amount void: the whole order is cancelled or nothing is. That is why the request carries no amounts and no item list. To reverse only part of an order, cancel it and inject a new one.

### What to verify on the client side

* **Do not assume the fiscal document is voided** because you got a `200`. Check its status if you need certainty.
* **`payment_status` distinguishes two different outcomes**: `REFUNDED` (the processor returned the money) and `CANCELED` (the charge was voided without a refund). They are not equivalent for reconciliation.
* **The downstream event fires after the order is saved**, not after the fiscal void is confirmed. It arrives before the chain is closed.
