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

# Cancel Order

> Cancel an order before fulfillment with automatic refund processing

<Warning>
  Orders can only be cancelled if they haven't been shipped. Once shipped, use the return flow instead.
</Warning>

## Overview

The cancel order endpoint allows you to cancel an existing order and automatically process refunds. This is useful for customer-requested cancellations, inventory issues, or fraud prevention.

### Cancellation Rules

<CardGroup cols={2}>
  <Card title="Can Cancel" icon="check-circle">
    * Status: `pending`, `processing`, `paid`
    * No shipments created
    * Within cancellation window
  </Card>

  <Card title="Cannot Cancel" icon="x-circle">
    * Status: `shipped`, `delivered`
    * Partial fulfillment started
    * Past cancellation deadline
  </Card>
</CardGroup>

## Request

### Path Parameters

<ParamField path="order_id" type="string" required>
  The unique identifier of the order to cancel

  **Example**: `ord_1a2b3c4d5e6f`
</ParamField>

### Body Parameters

<ParamField body="reason" type="string" required>
  Reason for cancellation

  **Options**:

  * `customer_request` - Customer initiated cancellation
  * `out_of_stock` - Item(s) no longer available
  * `pricing_error` - Incorrect pricing
  * `fraud_suspected` - Potential fraudulent order
  * `duplicate_order` - Duplicate order placed
  * `other` - Other reason (use notes)
</ParamField>

<ParamField body="refund_amount" type="number">
  Amount to refund. If not specified, full refund is processed

  **Example**: `99.99`
</ParamField>

<ParamField body="notes" type="string">
  Additional notes about the cancellation

  **Example**: `"Customer changed mind about purchase"`
</ParamField>

<ParamField body="notify_customer" type="boolean" default="true">
  Whether to send cancellation email to customer
</ParamField>

<ParamField body="restock_items" type="boolean" default="true">
  Whether to return items to inventory
</ParamField>

## Response

<ResponseField name="order" type="object">
  The cancelled order object

  <Expandable title="properties">
    <ResponseField name="id" type="string">
      Order ID
    </ResponseField>

    <ResponseField name="status" type="string">
      New status: `cancelled`
    </ResponseField>

    <ResponseField name="cancelled_at" type="string">
      ISO 8601 timestamp of cancellation
    </ResponseField>

    <ResponseField name="cancellation_reason" type="string">
      Reason for cancellation
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="refund" type="object">
  Refund details if payment was processed

  <Expandable title="properties">
    <ResponseField name="id" type="string">
      Refund ID
    </ResponseField>

    <ResponseField name="amount" type="number">
      Amount refunded
    </ResponseField>

    <ResponseField name="currency" type="string">
      Currency of refund
    </ResponseField>

    <ResponseField name="status" type="string">
      Refund status: `pending`, `succeeded`, `failed`
    </ResponseField>

    <ResponseField name="estimated_arrival" type="string">
      When customer will receive refund
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="inventory_updates" type="array">
  List of inventory adjustments made
</ResponseField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.stateset.network/v1/orders/ord_1a2b3c4d5e6f/cancel \
    -H "Authorization: Bearer sk_test_..." \
    -H "Content-Type: application/json" \
    -d '{
      "reason": "customer_request",
      "notes": "Customer found a better price elsewhere",
      "notify_customer": true,
      "restock_items": true
    }'
  ```

  ```javascript Node.js theme={null}
  const cancellation = await stateset.orders.cancel('ord_1a2b3c4d5e6f', {
    reason: 'customer_request',
    notes: 'Customer found a better price elsewhere',
    notify_customer: true,
    restock_items: true
  });

  console.log('Order cancelled:', cancellation.order.id);
  console.log('Refund status:', cancellation.refund.status);
  ```

  ```python Python theme={null}
  cancellation = stateset.orders.cancel(
      'ord_1a2b3c4d5e6f',
      reason='customer_request',
      notes='Customer found a better price elsewhere',
      notify_customer=True,
      restock_items=True
  )

  print(f"Order cancelled: {cancellation.order.id}")
  print(f"Refund amount: {cancellation.refund.amount}")
  ```

  ```php PHP theme={null}
  $cancellation = $stateset->orders->cancel('ord_1a2b3c4d5e6f', [
      'reason' => 'customer_request',
      'notes' => 'Customer found a better price elsewhere',
      'notify_customer' => true,
      'restock_items' => true
  ]);

  echo "Order status: " . $cancellation->order->status;
  ```
</RequestExample>

<ResponseExample>
  ```json Success Response theme={null}
  {
    "order": {
      "id": "ord_1a2b3c4d5e6f",
      "status": "cancelled",
      "amount": 149.99,
      "currency": "ssusd",
      "cancelled_at": "2024-01-15T10:30:00Z",
      "cancellation_reason": "customer_request",
      "cancellation_notes": "Customer found a better price elsewhere",
      "items": [
        {
          "id": "item_abc123",
          "product_id": "prod_widget_001",
          "quantity": 2,
          "price": 74.99
        }
      ]
    },
    "refund": {
      "id": "ref_xyz789",
      "amount": 149.99,
      "currency": "ssusd",
      "status": "succeeded",
      "payment_method": "original_payment_method",
      "estimated_arrival": "2024-01-17T10:30:00Z",
      "transaction_hash": "0xabc..."
    },
    "inventory_updates": [
      {
        "product_id": "prod_widget_001",
        "quantity_returned": 2,
        "new_available": 152
      }
    ],
    "notifications_sent": {
      "customer_email": true,
      "admin_alert": true,
      "webhook": true
    }
  }
  ```

  ```json Error Response theme={null}
  {
    "error": {
      "type": "invalid_request_error",
      "code": "order_not_cancellable",
      "message": "Order cannot be cancelled because it has already been shipped",
      "order_status": "shipped",
      "shipped_at": "2024-01-14T15:00:00Z"
    }
  }
  ```
</ResponseExample>

## Webhooks

This endpoint triggers the following webhook events:

* `order.cancelled` - When order is successfully cancelled
* `refund.created` - When refund is initiated
* `inventory.updated` - When items are restocked

## Best Practices

<AccordionGroup>
  <Accordion title="Implement Cancellation Windows">
    Set clear cancellation deadlines based on your fulfillment process:

    ```javascript theme={null}
    // Check if order can be cancelled
    const canCancel = (order) => {
      const hoursSinceOrder = (Date.now() - order.created_at) / (1000 * 60 * 60);
      return order.status !== 'shipped' && hoursSinceOrder < 24;
    };
    ```
  </Accordion>

  <Accordion title="Handle Partial Payments">
    For orders with multiple payment methods or partial payments:

    ```javascript theme={null}
    // Calculate refund for partial payments
    const calculateRefund = (order, cancellationFees = 0) => {
      const paidAmount = order.payments
        .filter(p => p.status === 'succeeded')
        .reduce((sum, p) => sum + p.amount, 0);
      
      return Math.max(0, paidAmount - cancellationFees);
    };
    ```
  </Accordion>

  <Accordion title="Customer Communication">
    Always provide clear communication about cancellations:

    ```javascript theme={null}
    // Custom cancellation email
    await stateset.emails.send({
      to: order.customer.email,
      template: 'order_cancelled',
      data: {
        order_number: order.number,
        refund_amount: refund.amount,
        refund_timeline: '3-5 business days',
        reason: cancellation.reason
      }
    });
    ```
  </Accordion>
</AccordionGroup>

## Related Endpoints

<CardGroup cols={2}>
  <Card title="Create Refund" icon="money-bill-wave" href="/orders/refund">
    Process partial refunds without cancelling
  </Card>

  <Card title="Return Order" icon="box-open" href="/orders/return">
    Handle returns for delivered orders
  </Card>

  <Card title="Update Order" icon="edit" href="/orders/update">
    Modify order details before fulfillment
  </Card>

  <Card title="List Orders" icon="list" href="/orders/list">
    Query orders by status or customer
  </Card>
</CardGroup>
