# Orders

Submit order data to ChargebackStop for chargeback prevention and dispute resolution. This API powers integrations with Mastercard Consumer Clarity, Visa Order Insight, and chargeback alert matching.

**Base URL:** `https://api.chargebackstop.com/v1/orders/`

**Authentication:** Bearer token via API key. Required abilities vary by endpoint (all newly created API keys include these Orders abilities by default):

* `orders:read` for GET endpoints
* `orders:write` for POST endpoints
* `orders:update` for PATCH endpoints

**Rate limits:**

* **100 requests per minute** per endpoint, per organisation/partner group
* Each endpoint has an independent rate limit pool (e.g., hitting the list limit doesn't affect create)
* Rate limits are applied by owner (organisation or partner group), not by API key
* Exceeding the limit returns `429 Too Many Requests`

**Batch Limit:** Maximum 100 orders per request (POST only).

***

## GET /v1/orders - List Orders

Retrieve a paginated list of orders with optional filtering and sorting.

**Authentication:** Bearer token via API key with `orders:read` ability.

### Query parameters

| Parameter         | Type     | Description                                                                                                         |
| ----------------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
| `organisation_id` | string   | Filter by organisation ID                                                                                           |
| `integration_id`  | string   | Filter by integration ID                                                                                            |
| `reference_id`    | string   | Filter by exact reference\_id                                                                                       |
| `type`            | string   | Filter by order type: `COMPLETE` or `PARTIAL`                                                                       |
| `order_status`    | string   | Filter by status: `OPEN_PENDING`, `OPEN_PENDING_RETURN`, `CLOSED_COMPLETE`, `CLOSED_CANCELLED`, `OTHER`             |
| `created_at_gte`  | datetime | Orders created on or after this timestamp (ISO 8601)                                                                |
| `created_at_lte`  | datetime | Orders created on or before this timestamp (ISO 8601)                                                               |
| `sort`            | string   | Sort field: `created_at` (oldest first), `-created_at` (newest first, default), `order_datetime`, `-order_datetime` |
| `limit`           | integer  | Number of results per page (default: 100)                                                                           |
| `offset`          | integer  | Number of results to skip for pagination                                                                            |

### Example request

```bash
curl -X GET "https://api.chargebackstop.com/v1/orders/?reference_id=order-2024-001&sort=-created_at&limit=10" \
  -H "Authorization: Bearer <api_key>"
```

### Example response

```json
{
  "items": [
    {
      "id": "ord_abc123",
      "reference_id": "order-2024-001",
      "type": "COMPLETE",
      "organisation_id": "org_xyz",
      "integration_id": "int_123",
      "created_at": "2024-01-15T10:30:00Z",
      "order_datetime": "2024-01-15T10:30:00Z",
      "order_number": "ORD-2024-001",
      "order_status": "CLOSED_COMPLETE",
      "order_currency": "USD",
      "order_total_amount_in_cents": 9720,
      "transactions": [...],
      "deliveries": [...],
      "items": [...],
      "refunds": [...],
      "subscriptions": [...],
      "disputes": [...],
      "links": [
        {
          "rel": "self",
          "uri": "/v1/orders/ord_abc123"
        }
      ]
    }
  ],
  "count": 1
}
```

***

## GET /v1/orders/{order\_id} - Get Order by ID

Retrieve a single order by its internal `id` (the `id` field returned in JSON responses), not by `reference_id`.

To retrieve an order by `reference_id`, use the list endpoint: `GET /v1/orders?reference_id=<your_reference_id>`.

**Authentication:** Bearer token via API key with `orders:read` ability.

### URL parameters

| Parameter  | Type   | Description                                |
| ---------- | ------ | ------------------------------------------ |
| `order_id` | string | The internal order ID (e.g., `ord_abc123`) |

### Example request

```bash
curl -X GET "https://api.chargebackstop.com/v1/orders/ord_abc123" \
  -H "Authorization: Bearer <api_key>"
```

### Example response

Returns the full order object with all nested relations (transactions, deliveries, items, refunds, subscriptions, disputes).

```json
{
  "id": "ord_abc123",
  "reference_id": "order-2024-001",
  "type": "COMPLETE",
  "organisation_id": "org_xyz",
  "integration_id": "int_123",
  "created_at": "2024-01-15T10:30:00Z",
  "order_datetime": "2024-01-15T10:30:00Z",
  "order_number": "ORD-2024-001",
  "order_status": "CLOSED_COMPLETE",
  "order_currency": "USD",
  "order_total_amount_in_cents": 9720,
  "customer_email": "john.doe@example.com",
  "transactions": [...],
  "deliveries": [...],
  "items": [...],
  "refunds": [...],
  "subscriptions": [...],
  "disputes": [...],
  "links": [
    {
      "rel": "self",
      "uri": "/v1/orders/ord_abc123"
    }
  ]
}
```

### Error responses

**404 Not Found** - Order does not exist or is not accessible:

```json
{
  "errors": [
    {
      "code": "NOT_FOUND",
      "message": "Not found"
    }
  ]
}
```

***

## POST /v1/orders - Create Orders

Submit order data to ChargebackStop for chargeback prevention and dispute resolution.

**Authentication:** Bearer token via API key with `orders:write` ability.

**Rate Limit:** 100 requests per minute per organisation/partner group.

**Batch Limit:** Maximum 100 orders per request.

**Request Body:** JSON array of order objects (even when submitting a single order).

> **Schema validation before partial success:** Partial success applies after request schema validation. If the top-level request is invalid (for example, body is not an array or fields have invalid types), the API returns a full-request `422` and no orders are processed.

***

## Which mode should I use?

| Mode         | Use Case                                                                                                                                                              | Integration Type                   |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| **PARTIAL**  | You have an existing payment processor integration (Stripe, Adyen, etc.) and want to submit enrichment data linked to those processor transactions                    | Any non-CUSTOM\_ORDERS integration |
| **COMPLETE** | You do not have an existing payment processor integration to enrich and want to submit full order data directly (for digital receipts, deflection, or alert matching) | CUSTOM\_ORDERS integration only    |

> **Important: Order type and integration type must match**
>
> * **COMPLETE orders** can ONLY be created with `CUSTOM_ORDERS` integrations. Attempting to create a COMPLETE order on a Stripe, Adyen, or other payment processor integration will return `INVALID_ORDER_TYPE`.
> * **PARTIAL orders** can ONLY be created with non-CUSTOM\_ORDERS integrations (Stripe, Adyen, Shopify, etc.) and require orders enrichment to be enabled by ChargebackStop support. Attempting to create a PARTIAL order on a CUSTOM\_ORDERS integration will return `INVALID_ORDER_TYPE`.

***

## PARTIAL mode - enrichment for existing integrations

Use PARTIAL mode when you already have a payment processor integration (Stripe, Adyen, Shopify, etc.) connected to ChargebackStop and want to enrich your orders with additional data.

### Getting started

**Prerequisites:**

* An existing integration (Stripe, Adyen, etc.) with orders enrichment enabled by the ChargebackStop team
* API key with `orders:write` ability

**Minimal required fields:**

| Field                 | Description                                          |
| --------------------- | ---------------------------------------------------- |
| `type`                | Must be `"PARTIAL"`                                  |
| `organisation_id`     | Your organisation ID                                 |
| `integration_id`      | Your integration ID                                  |
| `reference_id`        | Unique order identifier                              |
| `order_email`         | Email associated with the order                      |
| `customer_account_id` | Customer identifier (email, username, or account ID) |

> **Device identifier required:** PARTIAL orders must include at least one of: `device_ip_address`, `device_id`, or `device_fingerprint`. This is used for fraud prevention and dispute evidence.

**Example 1: Basic PARTIAL Order**

```json
[
  {
    "type": "PARTIAL",
    "organisation_id": "org_abc123",
    "integration_id": "int_stripe456",
    "reference_id": "order-2024-001",
    "order_email": "customer@example.com",
    "customer_account_id": "customer@example.com",
    "device_ip_address": "216.24.60.17"
  }
]
```

***

## Digital receipts and deflection field sets

These field sets are required for PARTIAL mode, and are required for all order modes when digital receipts or deflection is enabled.

Examples below use PARTIAL payloads, but the same field sets can be included in COMPLETE orders.

### Mastercard Consumer Clarity

Consumer Clarity helps reduce chargebacks by providing cardholders with detailed purchase information in their banking app, making transactions more recognisable.

**Required fields for Consumer Clarity:**

| Field                            | Description                          |
| -------------------------------- | ------------------------------------ |
| `order_datetime`                 | When the order was placed (ISO 8601) |
| `order_number`                   | Customer-facing order number         |
| `order_subtotal_amount_in_cents` | Subtotal before tax                  |
| `order_currency`                 | Currency code (ISO 4217)             |
| `order_total_amount_in_cents`    | Total amount including tax           |

**Example 2: Consumer Clarity (Mastercard)**

```json
[
  {
    "type": "PARTIAL",
    "organisation_id": "org_abc123",
    "integration_id": "int_stripe456",
    "reference_id": "order-2024-001",
    "order_email": "customer@example.com",
    "customer_account_id": "cust-12345",
    "device_ip_address": "216.24.60.83",

    "order_datetime": "2024-01-15T10:30:00Z",
    "order_number": "ORD-2024-001",
    "order_subtotal_amount_in_cents": 4500,
    "order_currency": "USD",
    "order_total_amount_in_cents": 4950
  }
]
```

***

### Visa Order Insight

Order Insight provides Visa cardholders with purchase details directly in their banking app, helping them recognise legitimate transactions.

**Required fields for Order Insight:**

| Field   | Description                                    |
| ------- | ---------------------------------------------- |
| `items` | Array with at least one item containing `name` |

**Example 3: Order Insight (Visa)**

```json
[
  {
    "type": "PARTIAL",
    "organisation_id": "org_abc123",
    "integration_id": "int_stripe456",
    "reference_id": "order-2024-001",
    "order_email": "customer@example.com",
    "customer_account_id": "cust-12345",
    "device_ip_address": "216.24.60.142",

    "items": [
      {
        "reference_id": "item-001",
        "name": "Widget Pro",
        "price_in_cents": 4500,
        "quantity": 1
      }
    ]
  }
]
```

***

### Product and merchant information

Some merchants (particularly Merchant of Record platforms) may need to include product and merchant information with each order if default settings are not configured in the platform.

> **Note:** If product and merchant information varies per order, include it in each order submission. If the values are stable across all orders, you can set defaults in the ChargebackStop platform instead.

**Product information fields:**

| Field                    | Description      |
| ------------------------ | ---------------- |
| `items[].name`           | Product name     |
| `items[].price_in_cents` | Item price       |
| `items[].quantity`       | Quantity ordered |

**Merchant information fields:**

| Field                    | Description                           |
| ------------------------ | ------------------------------------- |
| `merchant_name`          | Corporate/parent company name         |
| `merchant_contact_phone` | Customer service phone (E.164 format) |
| `merchant_store_name`    | Store name recognisable to customer   |
| `merchant_url`           | Merchant website URL                  |

**Example 4: Product and merchant information**

```json
[
  {
    "type": "PARTIAL",
    "organisation_id": "org_abc123",
    "integration_id": "int_stripe456",
    "reference_id": "order-2024-001",
    "order_email": "customer@example.com",
    "customer_account_id": "cust-12345",
    "device_ip_address": "216.24.60.201",

    "merchant_name": "Example Corporation",
    "merchant_contact_phone": "+14155551234",
    "merchant_store_name": "Example Store",
    "merchant_url": "https://example.com",

    "items": [
      {
        "reference_id": "item-001",
        "name": "Widget Pro",
        "price_in_cents": 4500,
        "quantity": 1
      }
    ]
  }
]
```

***

### First-Party Trust (FPT) - Mastercard

First-Party Trust is a Mastercard programme that helps identify legitimate transactions by linking customer identity data (email, device) across purchases. This strengthens fraud prevention and reduces first-party fraud chargebacks.

**Required fields for FPT:**

| Field             | Description                                                                |
| ----------------- | -------------------------------------------------------------------------- |
| `customer_email`  | Customer's email address                                                   |
| `order_email`     | Email associated with the order                                            |
| Device identifier | At least one of: `device_ip_address`, `device_id`, or `device_fingerprint` |

**Example 5: First-Party Trust (Mastercard)**

```json
[
  {
    "type": "PARTIAL",
    "organisation_id": "org_abc123",
    "integration_id": "int_stripe456",
    "reference_id": "order-2024-001",

    "customer_email": "john.doe@example.com",
    "order_email": "john.doe@example.com",
    "customer_account_id": "cust-12345",

    "device_ip_address": "216.24.60.58",
    "device_id": "device-abc123",
    "device_fingerprint": "fp-xyz789"
  }
]
```

***

### Compelling Evidence 3.0 (CE3.0) - Visa

Compelling Evidence 3.0 is a Visa programme that helps merchants win disputes by proving the cardholder has a history of legitimate purchases. By submitting customer and device data with each order, you build evidence that can be used in dispute responses.

**Required fields for CE3.0:**

| Field             | Description                                                                |
| ----------------- | -------------------------------------------------------------------------- |
| `customer_email`  | Customer's email address                                                   |
| Device identifier | At least one of: `device_ip_address`, `device_id`, or `device_fingerprint` |

**Example 6: Compelling Evidence 3.0 (Visa)**

```json
[
  {
    "type": "PARTIAL",
    "organisation_id": "org_abc123",
    "integration_id": "int_stripe456",
    "reference_id": "order-2024-001",

    "customer_email": "john.doe@example.com",
    "order_email": "john.doe@example.com",
    "customer_account_id": "cust-12345",

    "device_ip_address": "216.24.60.229",
    "device_fingerprint": "fp-xyz789"
  }
]
```

***

## COMPLETE mode

Use COMPLETE mode when you do not have an existing payment processor integration to enrich and want to submit full order data directly to ChargebackStop. This mode supports digital receipts, deflection, and alert matching, and is for merchants using the `CUSTOM_ORDERS` integration type.

### Getting started

**Prerequisites:**

* A `CUSTOM_ORDERS` integration
* API key with `orders:write` ability

**Required fields for COMPLETE orders:**

| Field                            | Description                        |
| -------------------------------- | ---------------------------------- |
| `type`                           | Must be `"COMPLETE"`               |
| `organisation_id`                | Your organisation ID               |
| `integration_id`                 | Your CUSTOM\_ORDERS integration ID |
| `reference_id`                   | Unique order identifier            |
| `order_datetime`                 | When the order was placed          |
| `order_number`                   | Customer-facing order number       |
| `order_subtotal_amount_in_cents` | Subtotal before tax                |
| `order_currency`                 | Currency code (ISO 4217)           |
| `order_total_amount_in_cents`    | Total amount                       |
| `order_status`                   | Order status                       |

***

### Alert matching

To match orders with chargeback alerts, you must include at least one transaction with specific fields that enable accurate matching. The richer the data set you provide, the better the matching accuracy will be — we recommend including as many transaction fields as possible.

**Required transaction fields:**

| Field                  | Description                   |
| ---------------------- | ----------------------------- |
| `amount_in_cents`      | Transaction amount            |
| `currency`             | Currency code                 |
| `authorised_at`        | When authorisation occurred   |
| `payment_method_type`  | Payment method (e.g., `CARD`) |
| `authorisation_status` | Status (e.g., `SETTLED`)      |

**Additional required fields for card payments:**

| Field                        | Description               |
| ---------------------------- | ------------------------- |
| `payment_method_card_last_4` | Last 4 digits of card     |
| `payment_method_card_brand`  | Card brand (e.g., `VISA`) |

**Matching identifiers (send all three whenever possible):**

| Identifier                  | Recommendation          | Notes                                                                                     |
| --------------------------- | ----------------------- | ----------------------------------------------------------------------------------------- |
| `acquirer_reference_number` | Send whenever available | Most reliable; directly links to the network transaction                                  |
| `authorisation_code`        | Send whenever available | Improves matching when paired with card details (especially `payment_method_card_last_4`) |
| `payment_method_card_bin`   | Send whenever available | Improves matching when combined with card details and amount/currency                     |

For card payments, at least one matching identifier is required. Best practice is to send all three identifiers whenever available, or as many as possible.

**Why these fields matter:**

* **ARN (Acquirer Reference Number):** The most reliable identifier for matching - directly links to the network transaction
* **Authorisation Code:** The 6-digit code from the issuer, used with card last 4 when ARN is not available
* **Card BIN:** The first 6-8 digits of the card, helps narrow down matches when combined with other card details and amount

> **Note:** It is worth sending any related refunds and disputes for the order. Including these records helps us detect invalid alerts more accurately.

**Example 7: Alert matching (COMPLETE)**

```json
[
  {
    "type": "COMPLETE",
    "organisation_id": "org_abc123",
    "integration_id": "int_custom789",
    "reference_id": "order-2024-001",

    "order_datetime": "2024-01-15T10:30:00Z",
    "order_number": "ORD-2024-001",
    "order_subtotal_amount_in_cents": 9000,
    "order_currency": "USD",
    "order_tax_amount_in_cents": 720,
    "order_total_amount_in_cents": 9720,
    "order_status": "CLOSED_COMPLETE",

    "customer_email": "john.doe@example.com",
    "customer_first_name": "John",
    "customer_last_name": "Doe",

    "transactions": [
      {
        "reference_id": "txn-001",
        "amount_in_cents": 9720,
        "currency": "USD",
        "payment_method_type": "CARD",
        "authorisation_status": "SETTLED",
        "payment_method_reference_id": "pm_card_abc123",
        "authorised_at": "2024-01-15T10:30:05Z",
        "descriptor": "EXAMPLE STORE",
        "descriptor_prefix": "EXAMPLE",
        "descriptor_suffix": "STORE",
        "settlement_datetime": "2024-01-16T00:00:00Z",
        "cvc_verified": true,
        "three_d_secure_verified": true,

        "acquirer_reference_number": "74027012345678901234567",
        "authorisation_code": "123456",
        "network_id": "network-txn-123",

        "payment_method_card_brand": "VISA",
        "payment_method_card_last_4": "4242",
        "payment_method_card_bin": "424242",
        "payment_method_card_exp_month": 12,
        "payment_method_card_exp_year": 2026,
        "payment_method_card_wallet_type": "APPLE_PAY",
        "payment_method_card_issuer": "Chase Bank",
        "billing_address": {
          "line_1": "123 Main St",
          "line_2": "Apt 4B",
          "city": "New York",
          "country_subdivision": "NY",
          "postal_code": "10001",
          "country": "US"
        }
      }
    ],

    "refunds": [
      {
        "reference_id": "refund-001",
        "amount_in_cents": 4500,
        "currency": "USD",
        "status": "SUCCEEDED",
        "original_transaction_reference_id": "txn-001",
        "refund_datetime": "2024-01-17T12:00:00Z"
      }
    ],

    "disputes": [
      {
        "reference_id": "dispute-001",
        "amount_in_cents": 4500,
        "currency": "USD",
        "stage": "1ST_CHARGEBACK",
        "status": "OPEN",
        "type": "CHARGEBACK",
        "network_reason_code": "10.4",
        "is_rapid_dispute_resolution": false,
        "evidence_due_by": "2024-02-15T23:59:59Z",
        "payment_method_type": "CARD",
        "card_brand": "VISA"
      }
    ]
  }
]
```

***

## Example 8: Full COMPLETE Order

This example includes all available fields for a COMPLETE order.

```json
[
  {
    "type": "COMPLETE",
    "organisation_id": "org_abc123",
    "integration_id": "int_custom789",
    "reference_id": "order-2024-001",

    "order_datetime": "2024-01-15T10:30:00Z",
    "order_number": "ORD-2024-001",
    "order_subtotal_amount_in_cents": 9000,
    "order_currency": "USD",
    "order_tax_amount_in_cents": 720,
    "order_total_amount_in_cents": 9720,
    "order_status": "CLOSED_COMPLETE",
    "order_phone": "+14155551234",
    "order_is_adult_content": false,

    "order_request_refund_url": "https://example.com/orders/ORD-2024-001/refund",
    "order_buy_again_url": "https://example.com/orders/ORD-2024-001/reorder",
    "order_write_review_url": "https://example.com/orders/ORD-2024-001/review",
    "order_view_url": "https://example.com/orders/ORD-2024-001",

    "order_proof_of_consent": "Customer agreed to Terms of Service on 2024-01-15 via checkout checkbox",
    "order_communications": "Order confirmation email sent 2024-01-15. Shipping notification sent 2024-01-16.",

    "customer_email": "john.doe@example.com",
    "customer_first_name": "John",
    "customer_last_name": "Doe",
    "customer_account_id": "john.doe@example.com",
    "order_email": "john.doe@example.com",

    "device_ip_address": "216.24.60.94",
    "device_id": "device-abc123",
    "device_fingerprint": "fp-xyz789",

    "merchant_reference_id": "merchant-001",
    "merchant_name": "Example Corporation",
    "merchant_store_name": "Example Store",
    "merchant_store_description": "Your one-stop shop for widgets and gadgets",
    "merchant_contact_email": "receipts@example.com",
    "merchant_customer_service_email": "support@example.com",
    "merchant_contact_phone": "+14155559876",
    "merchant_address": {
      "line_1": "100 Commerce St",
      "line_2": "Suite 500",
      "line_3": "Building A",
      "city": "San Francisco",
      "country_subdivision": "CA",
      "postal_code": "94105",
      "country": "US"
    },
    "merchant_store_url": "https://store.example.com",
    "merchant_url": "https://example.com",
    "merchant_terms_and_conditions_url": "https://example.com/terms",
    "merchant_logo_url": "https://example.com/logo.png",
    "merchant_refund_policy_url": "https://example.com/refund-policy",

    "transactions": [
      {
        "reference_id": "txn-001",
        "amount_in_cents": 9720,
        "currency": "USD",
        "payment_method_type": "CARD",
        "authorisation_status": "SETTLED",
        "payment_method_reference_id": "pm_card_abc123",
        "authorised_at": "2024-01-15T10:30:05Z",
        "descriptor": "EXAMPLE STORE",
        "descriptor_prefix": "EXAMPLE",
        "descriptor_suffix": "STORE",
        "authorisation_code": "123456",
        "acquirer_reference_number": "74027012345678901234567",
        "network_id": "network-txn-123",
        "settlement_datetime": "2024-01-16T00:00:00Z",
        "cvc_verified": true,
        "three_d_secure_verified": true,
        "payment_method_card_brand": "VISA",
        "payment_method_card_last_4": "4242",
        "payment_method_card_exp_month": 12,
        "payment_method_card_exp_year": 2026,
        "payment_method_card_bin": "424242",
        "payment_method_card_wallet_type": "APPLE_PAY",
        "payment_method_card_issuer": "Chase Bank",
        "billing_address": {
          "line_1": "123 Main St",
          "line_2": "Apt 4B",
          "city": "New York",
          "country_subdivision": "NY",
          "postal_code": "10001",
          "country": "US"
        }
      }
    ],

    "deliveries": [
      {
        "reference_id": "dlv-physical-001",
        "type": "PHYSICAL",
        "physical_shipping_carrier": "UPS",
        "physical_shipping_tracking_number": "1Z999AA10123456784",
        "physical_shipping_status": "DELIVERED",
        "physical_shipping_datetime_shipped": "2024-01-16T08:00:00Z",
        "physical_shipping_datetime_delivered": "2024-01-18T14:30:00Z",
        "physical_shipping_address": {
          "line_1": "123 Main St",
          "line_2": "Apt 4B",
          "city": "New York",
          "country_subdivision": "NY",
          "postal_code": "10001",
          "country": "US"
        }
      },
      {
        "reference_id": "dlv-digital-001",
        "type": "DIGITAL",
        "digital_delivery_datetime": "2024-01-15T10:35:00Z",
        "digital_download_start_datetime": "2024-01-15T10:36:00Z",
        "digital_download_end_datetime": "2024-01-15T10:37:00Z",
        "digital_delivery_ip_address": "216.24.60.175",
        "digital_notification_sent": true,
        "digital_notification_sent_datetime": "2024-01-15T10:35:00Z",
        "digital_notification_method": "EMAIL"
      }
    ],

    "items": [
      {
        "reference_id": "item-001",
        "name": "Widget Pro",
        "price_in_cents": 4500,
        "quantity": 2,
        "product_url": "https://example.com/products/widget-pro",
        "product_reference_id": "prod-widget-pro",
        "sku": "WIDGET-PRO-001",
        "delivery_reference_id": "dlv-physical-001"
      },
      {
        "reference_id": "item-002",
        "name": "Digital License Key",
        "price_in_cents": 0,
        "quantity": 1,
        "product_url": "https://example.com/products/license",
        "product_reference_id": "prod-license",
        "sku": "LICENSE-001",
        "delivery_reference_id": "dlv-digital-001",
        "subscription_reference_id": "sub-001"
      }
    ],

    "refunds": [
      {
        "reference_id": "refund-001",
        "amount_in_cents": 4500,
        "currency": "USD",
        "status": "SUCCEEDED",
        "original_transaction_reference_id": "txn-001",
        "refund_datetime": "2024-01-17T12:00:00Z"
      }
    ],

    "subscriptions": [
      {
        "reference_id": "sub-001",
        "interval": "MONTH",
        "interval_price_in_cents": 2999,
        "interval_currency": "USD",
        "status": "ACTIVE",
        "display_name": "Pro Plan Monthly",
        "trial_start_date": "2024-01-01T00:00:00Z",
        "trial_end_date": "2024-01-14T23:59:59Z",
        "trial_price_in_cents": 0,
        "trial_currency": "USD",
        "start_date": "2024-01-15T00:00:00Z",
        "next_charge_date": "2024-02-15T00:00:00Z"
      }
    ],

    "disputes": [
      {
        "reference_id": "dispute-001",
        "amount_in_cents": 4500,
        "currency": "USD",
        "stage": "1ST_CHARGEBACK",
        "status": "OPEN",
        "type": "CHARGEBACK",
        "network_reason_code": "10.4",
        "is_rapid_dispute_resolution": false,
        "evidence_due_by": "2024-02-15T23:59:59Z",
        "payment_method_type": "CARD",
        "card_brand": "VISA"
      }
    ]
  }
]
```

***

## API reference

**Required column abbreviations:**

| Abbreviation | Feature                        |
| ------------ | ------------------------------ |
| CC           | Consumer Clarity (Mastercard)  |
| FPT          | First Party Trust (Mastercard) |
| OI           | Order Insight (Visa)           |
| CE3.0        | Compelling Evidence 3.0 (Visa) |

**Validation wording note:**

* `Required` means the field must be present in the request payload. It does not, by itself, imply a non-empty string value.
* `1-255 chars` means the API enforces a non-empty string.
* `Up to 255 chars` means the API enforces only a maximum length, and an empty string may still be accepted when the field is otherwise optional.

***

### Order fields

#### Core fields

| Field             | Type   | Required | Validation              | Description              |
| ----------------- | ------ | -------- | ----------------------- | ------------------------ |
| `type`            | string | Yes      | `COMPLETE` or `PARTIAL` | Order type discriminator |
| `organisation_id` | string | Yes      | Valid org ID            | Your organisation ID     |
| `integration_id`  | string | Yes      | Valid integration ID    | Integration ID           |
| `reference_id`    | string | Yes      | 1-255 chars             | Unique order identifier  |

#### Order details

| Field                            | Type     | Required                                   | Validation                                                                            | Description                      |
| -------------------------------- | -------- | ------------------------------------------ | ------------------------------------------------------------------------------------- | -------------------------------- |
| `order_datetime`                 | datetime | `COMPLETE` orders, and for CC when enabled | ISO 8601                                                                              | When the order was placed        |
| `order_number`                   | string   | `COMPLETE` orders, and for CC when enabled | Up to 255 chars                                                                       | Customer-facing order number     |
| `order_subtotal_amount_in_cents` | integer  | `COMPLETE` orders, and for CC when enabled | >= 0                                                                                  | Subtotal before tax              |
| `order_currency`                 | string   | `COMPLETE` orders, and for CC when enabled | ISO 4217                                                                              | Currency code                    |
| `order_tax_amount_in_cents`      | integer  | No                                         | >= 0                                                                                  | Tax amount                       |
| `order_total_amount_in_cents`    | integer  | `COMPLETE` orders, and for CC when enabled | >= 0                                                                                  | Total amount                     |
| `order_status`                   | enum     | `COMPLETE` orders                          | `OPEN_PENDING`, `OPEN_PENDING_RETURN`, `CLOSED_COMPLETE`, `CLOSED_CANCELLED`, `OTHER` | Order status                     |
| `order_status_other_description` | string   | If `order_status` is `OTHER`               | 1-255 chars                                                                           | Description when status is OTHER |
| `order_phone`                    | string   | No                                         | E.164 format                                                                          | Order contact phone              |
| `order_is_adult_content`         | boolean  | No                                         | -                                                                                     | Adult content flag               |

#### Order URLs

| Field                      | Type   | Required | Validation                 | Description        |
| -------------------------- | ------ | -------- | -------------------------- | ------------------ |
| `order_request_refund_url` | string | No       | Valid URL, up to 255 chars | Refund request URL |
| `order_buy_again_url`      | string | No       | Valid URL, up to 255 chars | Reorder URL        |
| `order_write_review_url`   | string | No       | Valid URL, up to 255 chars | Review URL         |
| `order_view_url`           | string | No       | Valid URL, up to 255 chars | Order view URL     |

#### Order evidence

| Field                    | Type   | Required | Validation       | Description               |
| ------------------------ | ------ | -------- | ---------------- | ------------------------- |
| `order_proof_of_consent` | string | No       | Up to 500 chars  | Proof of customer consent |
| `order_communications`   | string | No       | Up to 1000 chars | Communications history    |

***

### Customer fields

| Field                 | Type   | Required                                   | Validation      | Description         |
| --------------------- | ------ | ------------------------------------------ | --------------- | ------------------- |
| `customer_email`      | string | For FPT, CE3.0                             | Valid email     | Customer's email    |
| `customer_first_name` | string | No                                         | Up to 255 chars | First name          |
| `customer_last_name`  | string | No                                         | Up to 255 chars | Last name           |
| `customer_account_id` | string | `PARTIAL` orders                           | Up to 255 chars | Customer identifier |
| `order_email`         | string | `PARTIAL` orders, and for FPT when enabled | Valid email     | Order email         |

***

### Device fields

| Field                | Type   | Required                                                        | Validation      | Description        |
| -------------------- | ------ | --------------------------------------------------------------- | --------------- | ------------------ |
| `device_ip_address`  | string | `PARTIAL` orders, and for FPT/CE3.0 when enabled (at least one) | IPv4/IPv6       | Customer's IP      |
| `device_id`          | string | `PARTIAL` orders, and for FPT/CE3.0 when enabled (at least one) | Up to 255 chars | Device ID          |
| `device_fingerprint` | string | `PARTIAL` orders, and for FPT/CE3.0 when enabled (at least one) | Up to 255 chars | Device fingerprint |

At least one device identifier is required for `PARTIAL` orders, and for FPT/CE3.0 when enabled.

***

### Merchant fields

| Field                               | Type   | Required                             | Validation      | Description                 |
| ----------------------------------- | ------ | ------------------------------------ | --------------- | --------------------------- |
| `merchant_reference_id`             | string | No                                   | Up to 255 chars | Internal merchant reference |
| `merchant_name`                     | string | When default merchant not configured | Up to 255 chars | Corporate name              |
| `merchant_store_name`               | string | When default merchant not configured | Up to 255 chars | Store name                  |
| `merchant_store_description`        | string | No                                   | Up to 255 chars | Store description           |
| `merchant_contact_email`            | string | No                                   | Valid email     | Receipt email               |
| `merchant_customer_service_email`   | string | No                                   | Valid email     | Support email               |
| `merchant_contact_phone`            | string | When default merchant not configured | E.164           | Support phone               |
| `merchant_url`                      | string | When default merchant not configured | URL             | Merchant URL                |
| `merchant_store_url`                | string | No                                   | URL             | Store URL                   |
| `merchant_terms_and_conditions_url` | string | No                                   | URL             | T\&C URL                    |
| `merchant_logo_url`                 | string | No                                   | URL             | Logo URL                    |
| `merchant_refund_policy_url`        | string | No                                   | URL             | Refund policy URL           |

#### Merchant address

| Field                                  | Type   | Required                                                       | Description    |
| -------------------------------------- | ------ | -------------------------------------------------------------- | -------------- |
| `merchant_address.line_1`              | string | At least one line required when `merchant_address` is provided | Address line 1 |
| `merchant_address.line_2`              | string | At least one line required when `merchant_address` is provided | Address line 2 |
| `merchant_address.line_3`              | string | At least one line required when `merchant_address` is provided | Address line 3 |
| `merchant_address.city`                | string | Required when `merchant_address` is provided                   | City           |
| `merchant_address.country_subdivision` | string | Required when `merchant_address` is provided                   | State/province |
| `merchant_address.postal_code`         | string | Required when `merchant_address` is provided                   | Postal code    |
| `merchant_address.country`             | string | Required when `merchant_address` is provided                   | Country code   |

> **Request/response shape:** Both requests and responses use nested `merchant_address`.

***

### Transactions

**Limit:** Maximum 10 transactions per order.

At least one transaction is required for Alert Matching.

| Field                         | Type     | Required                                | Validation                                      | Description                                    |
| ----------------------------- | -------- | --------------------------------------- | ----------------------------------------------- | ---------------------------------------------- |
| `reference_id`                | string   | Always                                  | 1-255 chars                                     | Transaction ID (unique within the integration) |
| `amount_in_cents`             | integer  | Always                                  | >= 0                                            | Amount                                         |
| `currency`                    | string   | Always                                  | ISO 4217                                        | Currency                                       |
| `payment_method_type`         | enum     | Always                                  | `CARD`, `STRIPE_LINK`, `BANK_ACCOUNT`, `OTHER`  | Payment method                                 |
| `authorisation_status`        | enum     | Always                                  | `AUTHORISED`, `CAPTURED`, `SETTLED`, `REVERTED` | Auth status                                    |
| `payment_method_reference_id` | string   | Always                                  | Up to 255 chars                                 | Payment method ID                              |
| `authorised_at`               | datetime | For Alert Matching                      | ISO 8601                                        | Auth timestamp                                 |
| `descriptor`                  | string   | No                                      | Up to 255 chars                                 | Billing descriptor                             |
| `descriptor_prefix`           | string   | No                                      | Up to 255 chars                                 | Descriptor prefix                              |
| `descriptor_suffix`           | string   | No                                      | Up to 255 chars                                 | Descriptor suffix                              |
| `authorisation_code`          | string   | For Alert Matching (CARD, at least one) | Up to 6 chars                                   | Auth code                                      |
| `acquirer_reference_number`   | string   | For Alert Matching (CARD, at least one) | 50 chars                                        | ARN                                            |
| `network_id`                  | string   | No                                      | 50 chars                                        | Network transaction identifier                 |
| `settlement_datetime`         | datetime | No                                      | ISO 8601                                        | Settlement time                                |
| `cvc_verified`                | boolean  | No                                      | -                                               | CVC verified                                   |
| `three_d_secure_verified`     | boolean  | No                                      | -                                               | 3DS verified                                   |

#### Card payment fields

When `payment_method_type` is `CARD`, the following fields are required:

| Field                             | Type    | Required                                     | Description                                                                                                                      |
| --------------------------------- | ------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `payment_method_card_brand`       | enum    | If `payment_method_type` is `CARD`           | `AMEX`, `DINERS`, `DISCOVER`, `EFTPOS_AU`, `JCB`, `MASTERCARD`, `UNIONPAY`, `VISA`, `CARTES_BANCAIRES`, `OTHER`                  |
| `payment_method_card_last_4`      | string  | If `payment_method_type` is `CARD`           | Last 4 digits                                                                                                                    |
| `payment_method_card_exp_month`   | integer | No                                           | Exp month                                                                                                                        |
| `payment_method_card_exp_year`    | integer | No                                           | Exp year                                                                                                                         |
| `payment_method_card_bin`         | string  | For Alert Matching (at least one identifier) | Card BIN                                                                                                                         |
| `payment_method_card_wallet_type` | enum    | No                                           | `AMEX_EXPRESS_CHECKOUT`, `APPLE_PAY`, `GOOGLE_PAY`, `LINK`, `MASTERPASS`, `SAMSUNG_PAY`, `VISA_CHECKOUT`, `REVOLUT_PAY`, `OTHER` |
| `payment_method_card_issuer`      | string  | No                                           | Card issuer                                                                                                                      |

> **Note:** For alert matching with card payments, send all three identifiers whenever available (`acquirer_reference_number`, `authorisation_code`, and `payment_method_card_bin`). If you cannot provide all three, provide at least one of the following combinations:
>
> * `acquirer_reference_number` (works on its own)
> * `authorisation_code` + `payment_method_card_last_4`
> * `payment_method_card_bin` + `payment_method_card_last_4` + `payment_method_card_brand` + `amount_in_cents` + `currency`

#### Billing address

| Field                                 | Type   | Required                                                      | Description    |
| ------------------------------------- | ------ | ------------------------------------------------------------- | -------------- |
| `billing_address.line_1`              | string | At least one line required when `billing_address` is provided | Address line 1 |
| `billing_address.line_2`              | string | At least one line required when `billing_address` is provided | Address line 2 |
| `billing_address.line_3`              | string | At least one line required when `billing_address` is provided | Address line 3 |
| `billing_address.city`                | string | Required when `billing_address` is provided                   | City           |
| `billing_address.country_subdivision` | string | Required when `billing_address` is provided                   | State/province |
| `billing_address.postal_code`         | string | Required when `billing_address` is provided                   | Postal code    |
| `billing_address.country`             | string | Required when `billing_address` is provided                   | Country code   |

***

### Deliveries

**Limit:** Maximum 10 deliveries per order.

| Field          | Type   | Required | Description                                 |
| -------------- | ------ | -------- | ------------------------------------------- |
| `reference_id` | string | Always   | Delivery ID (unique within the integration) |
| `type`         | enum   | No       | `DIGITAL` or `PHYSICAL`                     |

> **Create uniqueness scope:** On POST, deliveries are unique per integration by `reference_id`. Reusing a delivery `reference_id` for the same integration returns `DUPLICATE_DELIVERY`.

#### Digital delivery fields

| Field                                | Type     | Required | Description                     |
| ------------------------------------ | -------- | -------- | ------------------------------- |
| `digital_delivery_datetime`          | datetime | No       | Delivery time                   |
| `digital_download_start_datetime`    | datetime | No       | Download start                  |
| `digital_download_end_datetime`      | datetime | No       | Download end                    |
| `digital_delivery_ip_address`        | string   | No       | Download IP                     |
| `digital_notification_sent`          | boolean  | No       | Notification sent               |
| `digital_notification_sent_datetime` | datetime | No       | Notification time               |
| `digital_notification_method`        | enum     | No       | `EMAIL`, `SMS`, `PUSH`, `OTHER` |

#### Physical delivery fields

When `type` is `PHYSICAL`, the following fields are required:

| Field                                        | Type     | Required                                 | Description                                                                                                                                                |
| -------------------------------------------- | -------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `physical_shipping_carrier`                  | string   | No                                       | Carrier name                                                                                                                                               |
| `physical_shipping_tracking_number`          | string   | No                                       | Tracking number                                                                                                                                            |
| `physical_shipping_status`                   | enum     | If `type` is `PHYSICAL`                  | `NOT_SHIPPED`, `BACKORDERED`, `IN_TRANSIT`, `PARTIAL_SHIPPED`, `SHIPPED`, `CANCELLED`, `SHIPPING_EXCEPTION`, `PICKED_UP_BY_CUSTOMER`, `DELIVERED`, `OTHER` |
| `physical_shipping_status_other_description` | string   | If `physical_shipping_status` is `OTHER` | Description when status is OTHER                                                                                                                           |
| `physical_shipping_datetime_shipped`         | datetime | If `type` is `PHYSICAL`                  | Ship date                                                                                                                                                  |
| `physical_shipping_datetime_delivered`       | datetime | No                                       | Delivery date                                                                                                                                              |

#### Physical shipping address

| Field                                           | Type   | Required                                                                | Description    |
| ----------------------------------------------- | ------ | ----------------------------------------------------------------------- | -------------- |
| `physical_shipping_address.line_1`              | string | At least one line required when `physical_shipping_address` is provided | Address line 1 |
| `physical_shipping_address.line_2`              | string | At least one line required when `physical_shipping_address` is provided | Address line 2 |
| `physical_shipping_address.line_3`              | string | At least one line required when `physical_shipping_address` is provided | Address line 3 |
| `physical_shipping_address.city`                | string | Required when `physical_shipping_address` is provided                   | City           |
| `physical_shipping_address.country_subdivision` | string | Required when `physical_shipping_address` is provided                   | State/province |
| `physical_shipping_address.postal_code`         | string | Required when `physical_shipping_address` is provided                   | Postal code    |
| `physical_shipping_address.country`             | string | Required when `physical_shipping_address` is provided                   | Country code   |

***

### Items

**Limit:** Maximum 10 items per order.

| Field                       | Type    | Required | Description                                                               |
| --------------------------- | ------- | -------- | ------------------------------------------------------------------------- |
| `reference_id`              | string  | Yes      | Item ID (unique within the integration)                                   |
| `name`                      | string  | Yes      | Product name                                                              |
| `price_in_cents`            | integer | Yes      | Price in cents (≥ 0)                                                      |
| `quantity`                  | integer | Yes      | Quantity (≥ 1)                                                            |
| `product_url`               | string  | No       | Product URL                                                               |
| `product_reference_id`      | string  | No       | Internal product ID                                                       |
| `sku`                       | string  | No       | SKU                                                                       |
| `delivery_reference_id`     | string  | No       | Links to delivery (must reference a delivery in the same request)         |
| `subscription_reference_id` | string  | No       | Links to subscription (must reference a subscription in the same request) |

***

### Refunds

**Limit:** Maximum 10 refunds per order.

| Field                               | Type     | Required            | Description                               |
| ----------------------------------- | -------- | ------------------- | ----------------------------------------- |
| `reference_id`                      | string   | Always              | Refund ID (unique within the integration) |
| `amount_in_cents`                   | integer  | Always              | Refund amount                             |
| `currency`                          | string   | Always              | Currency                                  |
| `status`                            | enum     | Always              | `PENDING`, `SUCCEEDED`, `FAILED`          |
| `original_transaction_reference_id` | string   | No                  | Links to transaction                      |
| `refund_datetime`                   | datetime | For CC when enabled | When the refund was processed (ISO 8601)  |

> **Create uniqueness scope:** On POST, refunds are unique per integration by `reference_id`. Reusing a refund `reference_id` for the same integration returns `DUPLICATE_REFUND`.

***

### Subscriptions

**Limit:** Maximum 10 subscriptions per order.

> **Upsert behaviour**: Subscriptions are identified by `reference_id` per integration. If a subscription with the same `reference_id` already exists, it will be **updated** with the new values. The subscription will be linked to the new order while maintaining links to previous orders. This allows the same subscription to span multiple orders (e.g., monthly renewals).
>
> **Warning: Full replace semantics** - When updating a subscription, ALL optional fields are replaced, not merged. If you omit a field in a subsequent request, it will be set to NULL. For example, if Order 1 creates a subscription with `display_name: "Pro Plan"` and Order 2 references the same subscription without `display_name`, the display name will be cleared.

| Field                     | Type     | Required | Description                                   |
| ------------------------- | -------- | -------- | --------------------------------------------- |
| `reference_id`            | string   | Always   | Subscription ID (unique per integration)      |
| `interval`                | enum     | Always   | `DAY`, `WEEK`, `MONTH`, `YEAR`                |
| `interval_price_in_cents` | integer  | Always   | Price per interval                            |
| `interval_currency`       | string   | Always   | Currency                                      |
| `status`                  | enum     | No       | `ACTIVE`, `CANCELLED`, `TRIALING`, `PAST_DUE` |
| `display_name`            | string   | No       | Display name (up to 255 chars)                |
| `trial_start_date`        | datetime | No       | Trial start                                   |
| `trial_end_date`          | datetime | No       | Trial end                                     |
| `trial_price_in_cents`    | integer  | No       | Trial price                                   |
| `trial_currency`          | string   | No       | Trial currency                                |
| `start_date`              | datetime | No       | Subscription start                            |
| `cancellation_date`       | datetime | No       | Cancellation date                             |
| `next_charge_date`        | datetime | No       | Next billing date                             |

***

### Disputes

**Limit:** Maximum 10 disputes per order.

| Field                         | Type     | Required                           | Description                                                                                                     |
| ----------------------------- | -------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `reference_id`                | string   | Always                             | Dispute ID (unique within the integration)                                                                      |
| `amount_in_cents`             | integer  | Always                             | Dispute amount                                                                                                  |
| `currency`                    | string   | Always                             | Currency                                                                                                        |
| `stage`                       | enum     | Always                             | `1ST_CHARGEBACK`, `2ND_CHARGEBACK`                                                                              |
| `status`                      | enum     | Always                             | `OPEN`, `UNDER_REVIEW`, `WON`, `LOST`                                                                           |
| `type`                        | enum     | Always                             | `INQUIRY`, `CHARGEBACK`                                                                                         |
| `network_reason_code`         | string   | No                                 | Network reason code                                                                                             |
| `is_rapid_dispute_resolution` | boolean  | No                                 | RDR flag                                                                                                        |
| `evidence_due_by`             | datetime | No                                 | Evidence deadline                                                                                               |
| `payment_method_type`         | enum     | No                                 | `CARD`, `KLARNA`, `PAYPAL`                                                                                      |
| `card_brand`                  | enum     | If `payment_method_type` is `CARD` | `AMEX`, `DINERS`, `DISCOVER`, `EFTPOS_AU`, `JCB`, `MASTERCARD`, `UNIONPAY`, `VISA`, `CARTES_BANCAIRES`, `OTHER` |

> **Create uniqueness scope:** On POST, disputes are unique per integration by `reference_id`. Reusing a dispute `reference_id` for the same integration returns `DUPLICATE_DISPUTE`.

***

### Address schema

All address objects (billing, shipping, merchant) use this structure:

| Field                 | Type   | Required                   | Validation                        |
| --------------------- | ------ | -------------------------- | --------------------------------- |
| `line_1`              | string | At least one line required | Up to 255 chars                   |
| `line_2`              | string | At least one line required | Up to 255 chars                   |
| `line_3`              | string | At least one line required | Up to 255 chars                   |
| `city`                | string | Always                     | 1-255 chars                       |
| `country_subdivision` | string | Always                     | 1-255 chars                       |
| `postal_code`         | string | Always                     | 1-255 chars                       |
| `country`             | string | Always                     | ISO 3166-1 alpha-2 uppercase code |

> **Note:** When providing an address, include at least one of `line_1`, `line_2`, or `line_3`, plus `city`, `country_subdivision`, `postal_code`, and `country`.

***

## Field validation

### Currency codes

All currency fields must be valid **ISO 4217** codes. Common examples: `USD`, `EUR`, `GBP`, `CAD`, `AUD`, `JPY`. See the [ISO 4217 standard](https://en.wikipedia.org/wiki/ISO_4217) for the full list.

### Phone numbers

Phone fields must be in **E.164 format**:

* Start with `+`
* Followed by 1-15 digits
* No spaces or special characters

**Valid:** `+14155551234`, `+442071234567` **Invalid:** `415-555-1234`, `(415) 555-1234`

### Email addresses

All email fields are validated for proper email format.

### Amounts

All `*_in_cents` fields must be non-negative integers (>= 0).

***

## Error codes

| Code                               | Description                                                                                                                                         |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `RATE_LIMITED`                     | Rate limit exceeded (100 requests/min per endpoint)                                                                                                 |
| `BATCH_SIZE_EXCEEDED`              | More than 100 orders in request                                                                                                                     |
| `DUPLICATE_DELIVERY`               | Delivery with same `reference_id` already exists for this integration                                                                               |
| `DUPLICATE_DELIVERY_REFERENCE`     | Duplicate `reference_id` in deliveries array (within same request)                                                                                  |
| `DUPLICATE_DISPUTE`                | Dispute with same `reference_id` already exists for this integration                                                                                |
| `DUPLICATE_DISPUTE_REFERENCE`      | Duplicate `reference_id` in disputes array (within same request)                                                                                    |
| `DUPLICATE_ITEM`                   | Item with same `reference_id` already exists for this integration                                                                                   |
| `DUPLICATE_ITEM_REFERENCE`         | Duplicate `reference_id` in items array (within same request)                                                                                       |
| `DUPLICATE_ORDER`                  | Order with same `reference_id` already exists for this integration                                                                                  |
| `DUPLICATE_REFERENCE_ID`           | Fallback error when a duplicate `reference_id` is detected                                                                                          |
| `DUPLICATE_REFUND`                 | Refund with same `reference_id` already exists for this integration                                                                                 |
| `DUPLICATE_REFUND_REFERENCE`       | Duplicate `reference_id` in refunds array (within same request)                                                                                     |
| `DUPLICATE_SUBSCRIPTION_REFERENCE` | Duplicate `reference_id` in subscriptions array (within same request)                                                                               |
| `DUPLICATE_TRANSACTION`            | Transaction with same `reference_id` already exists for this integration                                                                            |
| `DUPLICATE_TRANSACTION_REFERENCE`  | Duplicate `reference_id` in transactions array (within same request)                                                                                |
| `ENRICHMENT_NOT_ENABLED`           | Orders enrichment is not enabled for a non-`CUSTOM_ORDERS` integration when submitting a `PARTIAL` order                                            |
| `INTERNAL_ERROR`                   | Internal server error                                                                                                                               |
| `INVALID_DELIVERY_REFERENCE`       | Item references a non-existent delivery                                                                                                             |
| `INVALID_INTEGRATION`              | Integration not found or not accessible                                                                                                             |
| `INVALID_ORDER_TYPE`               | Order type doesn't match integration type                                                                                                           |
| `INVALID_SUBSCRIPTION_REFERENCE`   | Item references a non-existent subscription                                                                                                         |
| `MISSING_FIELD`                    | Required field is missing for the configured integration                                                                                            |
| `DELIVERY_NOT_FOUND`               | Referenced delivery not found in order (PATCH only)                                                                                                 |
| `IMMUTABLE_FIELD`                  | Attempting to modify immutable fields on existing refund/dispute records (`amount_in_cents`, `currency`, and for disputes also `type`) (PATCH only) |
| `INVALID_FIELD_FOR_TYPE`           | Updating wrong type fields on delivery (PATCH only)                                                                                                 |
| `SUBSCRIPTION_NOT_FOUND`           | Referenced subscription not found (PATCH only)                                                                                                      |
| `TOO_MANY_DELIVERIES`              | Maximum 10 deliveries allowed per order                                                                                                             |
| `TOO_MANY_DISPUTES`                | Maximum 10 disputes allowed per order                                                                                                               |
| `TOO_MANY_ITEMS`                   | Maximum 10 items allowed per order                                                                                                                  |
| `TOO_MANY_REFUNDS`                 | Maximum 10 refunds allowed per order                                                                                                                |
| `TOO_MANY_SUBSCRIPTIONS`           | Maximum 10 subscriptions allowed per order                                                                                                          |
| `TOO_MANY_TRANSACTIONS`            | Maximum 10 transactions allowed per order                                                                                                           |

***

## Response format

The API uses **partial success** semantics for per-order processing: valid orders are created even if other orders in the same batch fail. Each order is processed independently, and failures do not cause a rollback of successfully created orders.

This behaviour applies after request schema validation. Schema-level validation failures return a full-request `422` response and skip per-order processing.

The response includes:

* `created`: Number of orders successfully created
* `failed`: Number of orders that failed validation
* `results`: Array of successfully created orders
* `errors`: Array of error details for failed orders

### Success response

```json
{
  "created": 2,
  "failed": 0,
  "results": [
    {
      "id": "ord_abc123",
      "reference_id": "order-001",
      "type": "COMPLETE",
      "organisation_id": "org_xyz",
      "integration_id": "int_123",
      "created_at": "2024-01-15T10:30:00Z",
      "transactions": [...],
      "items": [...],
      ...,
      "links": [
        {
          "rel": "self",
          "uri": "/v1/orders/ord_abc123"
        }
      ]
    }
  ],
  "errors": []
}
```

### Error response

```json
{
  "created": 1,
  "failed": 1,
  "results": [...],
  "errors": [
    {
      "index": 1,
      "reference_id": "order-002",
      "code": "DUPLICATE_ORDER",
      "message": "Order with reference_id 'order-002' already exists for this integration",
      "field": "reference_id"
    }
  ]
}
```

### Rate-limited response (429)

Returned when you exceed 100 requests per minute for the endpoint.

```json
{
  "errors": [
    {
      "code": "RATE_LIMITED",
      "message": "Too many requests"
    }
  ]
}
```

### Canonical order object

Successful `GET /v1/orders`, `GET /v1/orders/{order_id}`, `POST /v1/orders`, and `PATCH /v1/orders/{order_id}` responses all use the same canonical order object shape.

Each order object includes:

* Core fields: `id`, `reference_id`, `type`, `organisation_id`, `integration_id`, `created_at`
* Any documented order, customer, device, and merchant fields that are present for that order
* Nested arrays: `transactions`, `deliveries`, `items`, `refunds`, `subscriptions`, `disputes`

Each nested object includes its own server-generated `id` plus the documented fields for that resource.

***

## PATCH /v1/orders/{order\_id} - Update an Order

Partially update an existing order and its nested objects.

**Authentication:** Bearer token via API key with `orders:update` ability.

**URL parameters:**

* `order_id` (required): The order ID to update

***

### Request body

All fields are optional. Only provided fields will be updated.

| Field                            | Type   | Description                                |
| -------------------------------- | ------ | ------------------------------------------ |
| `order_status`                   | enum   | New order status                           |
| `order_status_other_description` | string | Required when `order_status` is `OTHER`    |
| `order_communications`           | string | Updated communications history             |
| `deliveries`                     | array  | Deliveries to update (by reference\_id)    |
| `subscriptions`                  | array  | Subscriptions to update (by reference\_id) |
| `refunds`                        | array  | Refunds to create/update                   |
| `disputes`                       | array  | Disputes to create/update                  |

***

### Delivery updates

Update deliveries that belong to the order. Each delivery is identified by `reference_id`.

**Important:**

* Only deliveries belonging to this order can be updated
* Delivery type (`DIGITAL` or `PHYSICAL`) cannot be changed after creation
* Fields are type-constrained: digital fields only work on `DIGITAL` deliveries, physical fields only work on `PHYSICAL` deliveries

| Field                       | Type    | Description                                                                  |
| --------------------------- | ------- | ---------------------------------------------------------------------------- |
| `reference_id`              | string  | **Required.** Delivery to update                                             |
| `digital_*` fields          | various | For DIGITAL deliveries only                                                  |
| `physical_*` fields         | various | For PHYSICAL deliveries only                                                 |
| `physical_shipping_address` | object  | Full address object. If provided, it must satisfy the shared address schema. |

If you include `physical_shipping_address` in a PATCH request, send a complete valid address object rather than a partial address fragment.

**Example 9: Update physical delivery status**

```json
{
  "deliveries": [
    {
      "reference_id": "dlv-001",
      "physical_shipping_status": "DELIVERED",
      "physical_shipping_datetime_delivered": "2024-01-18T14:30:00Z"
    }
  ]
}
```

***

### Subscription updates

Update existing subscriptions by `reference_id`. Only subscriptions that already exist can be updated - to create new subscriptions, use the POST endpoint when creating an order.

| Field                     | Type    | Required | Description                                   |
| ------------------------- | ------- | -------- | --------------------------------------------- |
| `reference_id`            | string  | Yes      | Subscription identifier                       |
| `interval`                | enum    | No       | `DAY`, `WEEK`, `MONTH`, `YEAR`                |
| `interval_price_in_cents` | integer | No       | Price per interval                            |
| `interval_currency`       | string  | No       | ISO 4217 currency code                        |
| `status`                  | enum    | No       | `ACTIVE`, `CANCELLED`, `TRIALING`, `PAST_DUE` |
| `display_name`            | string  | No       | Display name (up to 255 chars)                |
| Other fields              | various | No       | See subscription fields in POST documentation |

**Example 10: Update subscription status**

```json
{
  "subscriptions": [
    {
      "reference_id": "sub-001",
      "status": "CANCELLED"
    }
  ]
}
```

***

### Refund updates

Create new refunds or update existing refunds. For existing refunds, `amount_in_cents` and `currency` are immutable, while `status`, `original_transaction_reference_id`, and `refund_datetime` can be updated.

| Field                               | Type     | Required | Description                              |
| ----------------------------------- | -------- | -------- | ---------------------------------------- |
| `reference_id`                      | string   | Yes      | Refund identifier                        |
| `amount_in_cents`                   | integer  | New only | Refund amount (immutable on existing)    |
| `currency`                          | string   | New only | Currency code (immutable on existing)    |
| `status`                            | enum     | Yes      | `PENDING`, `SUCCEEDED`, `FAILED`         |
| `original_transaction_reference_id` | string   | No       | Related transaction                      |
| `refund_datetime`                   | datetime | No       | When the refund was processed (ISO 8601) |

**Example 11: Create new refund**

```json
{
  "refunds": [
    {
      "reference_id": "ref-001",
      "amount_in_cents": 5000,
      "currency": "USD",
      "status": "SUCCEEDED"
    }
  ]
}
```

**Example 12: Update existing refund status**

```json
{
  "refunds": [
    {
      "reference_id": "ref-001",
      "status": "SUCCEEDED"
    }
  ]
}
```

***

### Dispute updates

Create new disputes or update existing disputes. For existing disputes, `amount_in_cents`, `currency`, and `type` are immutable, while `stage`, `status`, `network_reason_code`, `is_rapid_dispute_resolution`, `evidence_due_by`, `payment_method_type`, and `card_brand` can be updated.

| Field             | Type    | Required | Description                                     |
| ----------------- | ------- | -------- | ----------------------------------------------- |
| `reference_id`    | string  | Yes      | Dispute identifier                              |
| `amount_in_cents` | integer | New only | Dispute amount (immutable on existing)          |
| `currency`        | string  | New only | Currency code (immutable on existing)           |
| `type`            | enum    | New only | `INQUIRY`, `CHARGEBACK` (immutable on existing) |
| `stage`           | enum    | Yes      | `1ST_CHARGEBACK`, `2ND_CHARGEBACK`              |
| `status`          | enum    | Yes      | `OPEN`, `UNDER_REVIEW`, `WON`, `LOST`           |
| Other fields      | various | No       | See dispute fields in POST documentation        |

**Example 13: Update dispute status**

```json
{
  "disputes": [
    {
      "reference_id": "disp-001",
      "stage": "1ST_CHARGEBACK",
      "status": "WON"
    }
  ]
}
```

***

### PATCH error codes

| Code                               | Description                                                                                                                            |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `DELIVERY_NOT_FOUND`               | Referenced delivery not found in this order                                                                                            |
| `DUPLICATE_DELIVERY_REFERENCE`     | Duplicate `reference_id` in deliveries array                                                                                           |
| `DUPLICATE_DISPUTE_REFERENCE`      | Duplicate `reference_id` in disputes array                                                                                             |
| `DUPLICATE_REFUND_REFERENCE`       | Duplicate `reference_id` in refunds array                                                                                              |
| `DUPLICATE_SUBSCRIPTION_REFERENCE` | Duplicate `reference_id` in subscriptions array                                                                                        |
| `IMMUTABLE_FIELD`                  | Attempting to modify immutable fields on existing refund/dispute records (`amount_in_cents`, `currency`, and for disputes also `type`) |
| `INVALID_FIELD_FOR_TYPE`           | Updating wrong type fields on delivery (e.g., physical fields on digital delivery)                                                     |
| `MISSING_FIELD`                    | New refund/dispute missing required fields                                                                                             |
| `SUBSCRIPTION_NOT_FOUND`           | Referenced subscription not found                                                                                                      |
| `TOO_MANY_DELIVERIES`              | Maximum 10 deliveries allowed per order                                                                                                |
| `TOO_MANY_DISPUTES`                | Maximum 10 disputes allowed per order (including existing + new)                                                                       |
| `TOO_MANY_REFUNDS`                 | Maximum 10 refunds allowed per order (including existing + new)                                                                        |
| `TOO_MANY_SUBSCRIPTIONS`           | Maximum 10 subscriptions allowed per order                                                                                             |

***

### PATCH response

Returns the updated order with all nested objects.

**Success Response (200)**

```json
{
  "id": "ord_abc123",
  "reference_id": "order-001",
  "type": "COMPLETE",
  "organisation_id": "org_xyz",
  "integration_id": "int_123",
  "created_at": "2024-01-15T10:30:00Z",
  "order_status": "CLOSED_COMPLETE",
  "transactions": [...],
  "deliveries": [...],
  "items": [...],
  "refunds": [...],
  "subscriptions": [...],
  "disputes": [...],
  "links": [
    {
      "rel": "self",
      "uri": "/v1/orders/ord_abc123"
    }
  ]
}
```

**Error Response (422)**

```json
{
  "errors": [
    {
      "code": "IMMUTABLE_FIELD",
      "message": "Cannot modify amount_in_cents on existing refund"
    }
  ]
}
```

**Not Found Response (404)**

```json
{
  "detail": "Order with ID ord_nonexistent not found"
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.chargebackstop.com/developer/api-documentation/orders.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
