# Direct Order Submission

Direct order submission enables channels who calculate their own tax and shipping rates to submit fully composed orders in a single request. For most commerce platforms, the prices you provide in the order submission request will override the built-in pricing engine of the platform. This ensure’s that the merchants system of record and automated customer communication (ex. order confirmation emails) remain accurate.

This guide goes through the steps needed to compose an Order and directly submit it to the merchant through Violet.

## **Retrieve SKUs from the Violet Catalog**

Retrieve SKUs you are able to sell through the [Violet Catalog APIs](https://app.gitbook.com/s/8lXIp71Ct5qCUhXjko2q/catalog/offers/get-all-merchant-offers)

### Offer Publishing Status

The parent Offer of each SKU in the Order must be published to your app at the time of Order creation. This can be determined by examining the `publishing_status` on an Offer and ensuring that it has a value of `PUBLISHED`.\
If the Offer is not published to your app at the time of Order creation the following exception will be returned:

```json
{
  "message": "Sku identified by %s is currently not available for purchase due to offer not published.",
  "error": "offer_not_published",
  "code": 2011
}
```

## Capture Shopper Information

Capture Shopper information through your UI elements. At a minimum, you will need the following:

1. First Name
2. Last Name
3. Email
4. Shipping Address

You will need to submit this information as a part of the Create Order endpoint. Optionally, if "Billing Address" is different to the "Shipping Address", those details can also be added to the request body.

## Estimate Cart Prices

Estimate Cart prices using the [Estimate Cart](https://app.gitbook.com/s/8lXIp71Ct5qCUhXjko2q/orders-and-checkout/cart-pricing/estimate-cart) endpoint. You will need to input the information that was previously collected from the Shopper.

{% hint style="info" %}
You can also include **discounts** in your Estimate Cart request to see their impact on pricing before creating an order. See the [Discounts section](#discounts) below for details.
{% endhint %}

<details>

<summary>Sample Request</summary>

```jsx
POST /carts/estimate

{
  "base_currency": "USD",
  "skus": [
    {
      "quantity": 2,
      "sku_id": 123
    }
  ],
  "shipping_address": {
    "city": "Seattle",
    "state": "WA",
    "postal_code": "<string>",
    "country": "US",
    "address_1": "<string>",
    "address_2": "<string>"
  }
```

</details>

<details>

<summary>Sample Response</summary>

```jsx
{
  "estimated_carts": [
    {
      "merchant_id": 123,
      "platform": "SHOPIFY",
      "base_currency": "USD",
      "sub_total": 1,
      "shipping_total": 1,
      "discount_total": 1,
      "total": 1,
      "skus": [
        {
          "quantity": 1,
          "sku_id": 80455,
          "name": "Lunar Lemonade - 10 oz.",
          "price": 9999,
          "merchant_id": 10064,
          "external_id": "42519630413999",
          "available": true,
          "requires_shipping": true,
          "product_type": "PHYSICAL",
        }
      ],
      "available_shipping_methods": [
        {
          "carrier": "OTHER",
          "label": "Teleportation",
          "price": 10000
        }
      ],
      "has_shipping_methods": true,
      "external_error_messages": [
        "<string>"
      ]
    }
  ]
}
```

</details>

## Discounts

Direct Order Submission supports **two different discount mechanisms** to give you maximum flexibility in your Checkout strategy:

1. **Synced Discounts (Promo Codes)** — Honor merchant-managed promo codes validated against their ecommerce platform
2. **Custom Discounts** — Create your own channel-defined discounts with full control over amounts and targeting

### Key Features

* **Target different parts of the Order**: Apply discounts at order level, shipping level, or SKU level
* **Apply amount or percentage-based Discounts**: Pass in fixed amount discounts (in fractional currency unit, e.g. cents) or percentage-based discounts (e.g. 15% off)
* **Preview Discounts using Estimate Cart**: Use Estimate Cart to evaluate discount impact before creating orders

### Quick Example

Apply a custom 15% discount to an entire order:

```json
{
  "base_currency": "USD",
  "skus": [
    { "quantity": 1, "sku_id": 1, "price": 5000 }
  ],
  "discounts": [
    {
      "merchant_id": 11111,
      "type": "CUSTOM",
      "target_type": "ORDER", 
      "percentage": 15.0
    }
  ],
  "shipping_address": {
    "country": "US"
  }
}
```

### Complete Guide

For comprehensive documentation including request/response examples, field explanations, error handling, and best practices, see our dedicated guide:

[**Direct Order Submission with Discounts**](https://docs.violet.io/prism/checkout-guides/guides/direct-order-submission-with-discounts)

This guide covers:

* Synced vs Custom discount types
* Estimate Cart and Create Order usage
* All targeting options (ORDER/SKU/SHIPPING)
* BagDiscount field reference
* Validation rules and error scenarios
* Supported platforms

## Adding a Payment Method

{% hint style="info" %}
If you are bypassing payments (i.e. not using Violet to orchestrate payments and payouts), you do not need to include a payment method. When creating an Order in the next step, simply leave out the `payment_method` in the request.
{% endhint %}

Violet supports accepting two forms of payment method when creating Orders.

1. Single-use Card Tokens
2. Pre-authorized Stripe Payment Intents

### Creating a Single-use Card Token

Capture Shopper Credit Card information using Stripe JS Elements and create a Stripe Token:

* <https://docs.stripe.com/js/tokens/create\\_token?type=cardElement>

Alternatively, if you're using a different user input form to collect and store shopper credit card information, you can call the Stripe API directly to create a token

* <https://docs.stripe.com/api/tokens/create\\_card?lang=curl>

For the token to be accepted during Checkout, you'll need to ensure that its created using the Stripe Public Key that is associated with the same Stripe account being used for payment orchestration. If this is Violet's Account, please reach out to us for this key.

### Using a pre-authorized Payment Intent

{% hint style="info" %}
This payment method can only be used if you've connected your pre-existing Stripe Platform account to Violet. Learn more about this [here](https://docs.violet.io/prism/payments).
{% endhint %}

{% stepper %}
{% step %}
**Create a payment intent with Stripe**

Start with creating a payment intent in Stripe using the [Payment Intents API](https://docs.stripe.com/api/payment_intents/create). This must be done on the same account you used to onboard with Violet Payments. Ensure that the amount and currency, match that of the Order you will be creating. Additionally, Violet requires that the payment intent is marked for manual capture. For example:

```
 curl https://api.stripe.com/v1/payment_intents \
     -u "sk_test_<REDACTED>:" \
     -d amount=120000 \
     -d currency=usd \
     -d capture_method=manual
```

Store the payment intent ID that Stripe returns in the response.
{% endstep %}

{% step %}
**Add a payment method to the Payment Intent**

A payment method must be added to the payment intent prior to it being used when creating an Order. To do this, you can use Stripe.js Elements, or the update [Payment Intents API](https://docs.stripe.com/api/payment_intents/update).

Alternatively, you can modify the call in the previous step to include a payment method on payment intent create. For example:

```bash
 curl https://api.stripe.com/v1/payment_intents \
     -u "sk_test_<REDACTED>:" \
     -d amount=120000 \
     -d currency=usd \
     -d payment_method=pm_card_visa \
     -d capture_method=manual
```

{% endstep %}

{% step %}
**Authorize the payment intent**

Authorize the payment intent by calling the [Confirm Payment Intent API](https://docs.stripe.com/api/payment_intents/confirm). This ensures that this is not a fraudulent payment method and that there are sufficient funds for this purchase. Alternatively, if Stripe.js Elements were used to capture the shopper payment method, Stripe may have automatically authorized the shopper payment method. Once a payment intent is authorized, its amount cannot change.
{% endstep %}

{% step %}
**Include the payment intent when calling Create Order**

When creating an Order using the API below, include the payment intent as a payment method. For example:

```json
"payment_method": {
    "type": "PAYMENT_INTENT",
    "payment_provider": "STRIPE",
    "token": "pi_123kj123k12j31k2j"
}
```

{% endstep %}
{% endstepper %}

### Line Item Tax and Duty Support

Line item taxes are required when Tax Remittance is enabled for your app. These can be passed using the `rates` object on each SKU in the Order. If only tax\_total is provided at the Bag level, Violet will automatically allocate it across the SKUs in the Bag based on their relative line prices. Our recommendation, however, is to always include it at the SKU level.

Each SKU within a Bag must include one or more `rates` objects containing:

| Field    | Type    | Required                  | Description                                                                           |
| -------- | ------- | ------------------------- | ------------------------------------------------------------------------------------- |
| `name`   | string  | Yes                       | Display name for the rate                                                             |
| `type`   | string  | Yes                       | `TAX` for sales tax, VAT, or GST. `DUTY` for import duties, tariffs, or customs fees. |
| `amount` | integer | Either `amount` or `rate` | Fixed amount in cents                                                                 |
| `rate`   | number  | Either `amount` or `rate` | Percentage rate                                                                       |

{% hint style="info" %}
If both `amount` and `rate` are provided, Violet uses `amount` for calculations but persists both values.
{% endhint %}

#### Tax Examples

The following examples show each option for submitting taxes:

<details>

<summary>Option 1: Rate</summary>

```json
"rates": [
  {
    "name": "WA Sales Tax",
    "type": "TAX",
    "rate": 10.0
  }
]
```

</details>

<details>

<summary>Option 2: Amount</summary>

```json
"rates": [
  {
    "name": "WA Sales Tax",
    "type": "TAX",
    "amount": 10000
  }
]
```

</details>

<details>

<summary>Option 3: Rate + Amount</summary>

```json
"rates": [
  {
    "name": "WA Sales Tax",
    "type": "TAX",
    "rate": 10.0,
    "amount": 10000
  }
]
```

{% hint style="info" %}
Violet prioritizes amount in calculations but persists both values.
{% endhint %}

</details>

A complete Create Order request, with line-item taxes, is shown below:

<details>

<summary>Sample Create Order request with line-item taxes</summary>

```json
{
  "payment_method": {
    "type": "SINGLE_USE_CARD_TOKEN",
    "payment_provider": "STRIPE",
    "token": "tok_amex"
  },
  "order": {
    "app_order_id": "ishan-dos-sandbox",
    "customer": {
      "first_name": "Ishan",
      "last_name": "Guru",
      "email": "ishan.guru+line_item_taxes@violet.io"
    },
    "bags": [
      {
        "skus": [
          {
            "sku_id": 80445,
            "price": 100000,
            "quantity": 2,
            "rates": [
              {
                "name": "Washington (WA) Sales Tax",
                "type": "TAX",
                "amount": 10000
              }
            ]
          }
        ],
        "shipping_method": {
          "label": "Teleportation2",
          "price": 10000
        }
      }
    ],
    "shipping_address": {
      "address_1": "2815 Elliott Ave",
      "address_2": "Unit 100",
      "city": "Seattle",
      "state": "WA",
      "country": "US",
      "postal_code": "98121"
    },
    "currency": "USD"
  }
}
```

</details>

<details>

<summary>Sample Response</summary>

```json
{
    "id": 99400,
    "token": "1a028df30d444a78992a52d117297c65",
    "errors": [],
    "app_id": 10193,
    "developer_id": 10122,
    "customer": {
        "first_name": "Ishan",
        "last_name": "Guru",
        "email": "ishan.guru+dos_testing@violet.io",
        "name": "Ishan Guru"
    },
    "bags": [
        {
            "id": 118380,
            "order_id": 99400,
            "merchant_id": 10064,
            "app_id": 10193,
            "external_id": "6277080055983",
            "status": "ACCEPTED",
            "fulfillment_status": "PROCESSING",
            "financial_status": "PAID",
            "dispute_status": "UNDISPUTED",
            "skus": [
                {
                    "id": 112067,
                    "merchant_id": 10064,
                    "app_id": 10193,
                    "product_id": "815b064726de41d9a21de4bfc029416f",
                    "sku_id": 80445,
                    "external_id": "42519630413999",
                    "name": "Lunar Lemonade - 10 oz.",
                    "brand": "Space Drinks",
                    "thumbnail": "https://cdn.shopify.com/s/files/1/0621/1849/4383/files/wealthy_lunar_lemonade_4a9c0731-8758-4847-91e1-d6d37d6ace22.png",
                    "quantity": 2,
                    "price": 100000,
                    "weight": 3.0,
                    "available": true,
                    "status": "PROCESSING",
                    "product_type": "PHYSICAL",
                    "rates": [
                        {
                            "order_sku_id": 112067,
                            "amount": 10000,
                            "rate": 10.0,
                            "type": "TAX",
                            "name": "Sales Tax",
                            "dollar_amount": 100.0,
                            "decimal_rate": 0.1
                        }
                    ],
                    "line_price": 200000
                }
            ],
            "shipping_method": {
                "type": "FLAT_RATE_PRICE",
                "label": "Teleportation2",
                "price": 10000,
                "custom": false,
                "id": 97302,
                "merchant_id": 10064
            },
            "taxes": [
                {
                    "order_id": 99400,
                    "merchant_id": 10064,
                    "state": "WA",
                    "rate": 5.0,
                    "amount": 10000
                }
            ],
            "sub_total": 200000,
            "shipping_total": 10000,
            "tax_total": 10000,
            "total": 220000,
            "taxes_included": false,
            "external_checkout": false,
            "commission_rate": 25.0,
            "date_created": "2024-12-13T00:08:58+0000",
            "date_last_modified": "2024-12-13T00:08:58.000+00:00",
            "remorse_period_ends": "2025-01-12T00:08:58+0000",
            "currency": "USD",
            "external_currency": "USD",
            "channel": "MARKETPLACE",
            "app_order_id": "ishan-dos-sandbox",
            "platform": "SHOPIFY",
            "fulfillments": [],
            "discounts": [],
            "wallet_based_checkout": false,
            "bag_status": "ACCEPTED",
            "bag_id": 118380,
            "merchant_name": "Space Drinks"
        }
    ],
    "shipping_address": { ... },
    "billing_address": { ... },
    "sub_total": 200000,
    "shipping_total": 10000,
    "tax_total": 10000,
    "total": 220000,
    "app_order_id": "ishan-dos-sandbox",
    "status": "COMPLETED",
    "is_guest": true,
    "date_created": "2024-12-13T00:08:56+0000",
    "date_last_modified": "2024-12-13T00:09:01+0000",
    "payment_transactions": [ ... ],
    "order_status": "COMPLETED",
    "order_id": 99400
}
```

</details>

#### Duties

For cross-border orders, you can submit import duties using `type: "DUTY"` in the `rates` array. You can calculate duties using HS codes from the product catalog with a third-party service, or apply a fixed rate or amount from the merchant.

```json
"rates": [
  {
    "name": "Import Duty (IT→US)",
    "type": "DUTY",
    "amount": 3268
  }
]
```

Duties and taxes can be combined on the same SKU when both apply:

```json
"rates": [
  {
    "name": "NY Sales Tax",
    "type": "TAX",
    "amount": 1527
  },
  {
    "name": "Import Duty (IT→US)",
    "type": "DUTY",
    "amount": 3268
  }
]
```

Duty amounts are handled at the line item level, bag total, and order total — including in distributions and settlement.

{% hint style="info" %}
Violet does not calculate duties. Channels are responsible for determining duty amounts — either from merchant-provided rates or by using trade compliance data with a third-party calculation service. See the [Cross-Border Duties guide](https://docs.violet.io/prism/checkout-guides/guides/cross-border-duties) for a complete walkthrough.
{% endhint %}

### Creating the Order

Call the Violet [Create Order](https://app.gitbook.com/s/8lXIp71Ct5qCUhXjko2q/orders-and-checkout/orders/create-order) endpoint with the information collected above to create an Order:

{% hint style="warning" %}
The following information must be included to create an Order:

1. First Name
2. Last Name
3. Email
4. Shipping Address
5. Bag(s)

For a multi-merchant Order, multiple bags must be created in the Order payload. Each Bag must contain items from only one merchant and have its own shipping method.
{% endhint %}

{% hint style="info" %}
**Discounts** can be included at the bag level when creating orders. See the [Discounts section](#discounts) above for full implementation details.
{% endhint %}

<details>

<summary>Sample Request</summary>

```jsx
POST /orders

{
 "payment_method": {
   "type": "SINGLE_USE_CARD_TOKEN",
   "payment_provider": "STRIPE",
   "token": "tok_1289y1ishakj12h31kj212kh"
 },
  "order": {
    "app_order_id": "mario-test-1",
    "customer": {
      "first_name": "Ultra",
      "last_name": "Violet",
      "email": "super@mar.io"
    },
    "bags": [
      {
        "skus": [
          {
            "sku_id": 80455,
            "price": 100000
          }
        ],
        "shipping_method": {
          "carrier": "OTHER",
          "label": "Teleportation",
          "price": 10000
        },
        "tax_total": 10000
      }
    ],
    "shipping_address": {
      "address_1": "2815 Elliott Ave",
      "address_2": "Unit 100",
      "city": "Seattle",
      "state": "WA",
      "country": "US",
      "postal_code": "98121"
    },
    "billing_address": {
      "address_1": "200 West Street",
      "city": "New York",
      "state": "NY",
      "country": "US",
      "postal_code": "10282"
    },
    "currency": "USD"
  }
}
```

</details>

{% hint style="info" %}
`billing_address` is optional in the request above. If left out, the `shipping_address` will be used as the `billing_address` for the Order.
{% endhint %}

If Order submission succeeds, Violet will respond with a completed Cart.

<details>

<summary>Sample Response</summary>

```jsx
{
    "id": 54609,
    "token": "f9bd116404dc4441838a94f31a942d5f",
    "errors": [],
    "app_id": 10193,
    "developer_id": 10122,
    "customer": {
        "first_name": "Ultra",
        "last_name": "Violet",
        "email": "super@mar.io",
        "name": "Ultra Violet"
    },
    "bags": [
        {
            "id": 64579,
            "order_id": 54609,
            "merchant_id": 10064,
            "status": "ACCEPTED",
            "fulfillment_status": "PROCESSING",
            "financial_status": "PAID",
            "skus": [
                {
                    "id": 60509,
                    "merchant_id": 10064,
                    "app_id": 10193,
                    "product_id": "815b064726de41d9a21de4bfc029416f",
                    "sku_id": 80445,
                    "external_id": "42519630413999",
                    "name": "Lunar Lemonade - 10 oz.",
                    "brand": "Space Drinks",
                    "thumbnail": "https://cdn.shopify.com/s/files/1/0621/1849/4383/files/wealthy_lunar_lemonade_4a9c0731-8758-4847-91e1-d6d37d6ace22.png",
                    "quantity": 1,
                    "price": 100000,
                    "weight": 3.0,
                    "available": true,
                    "status": "PROCESSING",
                    "product_type": "PHYSICAL",
                    "line_price": 100000
                }
            ],
            "shipping_method": {
                "type": "FLAT_RATE_PRICE",
                "carrier": "OTHER",
                "label": "Teleportation",
                "price": 10000,
                "custom": false,
                "id": 21839,
                "merchant_id": 10064
            },
            "taxes": [
                {
                    "order_id": 54609,
                    "merchant_id": 10064,
                    "state": "WA",
                    "rate": 10.0,
                    "amount": 10000
                }
            ],
            "sub_total": 100000,
            "shipping_total": 10000,
            "tax_total": 10000,
            "total": 120000,
            "taxes_included": false,
            "transactions": [],
            "external_checkout": false,
            "commission_rate": 0.0,
            "date_created": "2024-06-28T20:31:56+0000",
            "date_last_modified": "2024-06-28T20:31:56.000+00:00",
            "remorse_period_ends": "2024-07-28T20:31:56+0000",
            "currency": "USD",
            "external_currency": "USD",
            "channel": "MARKETPLACE",
            "app_order_id": "ishan-test-1",
            "platform": "SHOPIFY",
            "fulfillments": [],
            "discounts": [],
            "wallet_based_checkout": false,
            "bag_id": 64579,
            "bag_status": "ACCEPTED",
            "merchant_name": "Space Drinks"
        }
    ],
    "shipping_address": {
        "name": "Ultra Violet",
        "city": "Seattle",
        "state": "WA",
        "country": "US",
        "postal_code": "98121",
        "type": "BILLING",
        "address_1": "2815 Elliott Ave",
        "address_2": "Unit 100",
        "first_name": "Ultra",
        "last_name": "Violet"
    },
    "billing_address":{
        "name": "Ultra Violet",
        "city": "New York",
        "state": "NY",
        "country": "US",
        "postal_code": "10282",
        "type": "BILLING",
        "address_1": "200 West Street",
        "first_name": "Ultra",
        "last_name": "Violet"
    },
    "payment_transactions": [
        {
            "id": 31464,
            "order_id": 54627,
            "payment_provider": "STRIPE",
            "payment_provider_transaction_id": "pi_3PXoWvK29KDiBVld1n7ym4B0",
            "payment_method_id": 10630,
            "payment_provider_payment_method_id": "pm_1PXoWvK29KDiBVldLNqe04Oi",
            "payment_intent_client_secret": "pi_3PXoWvK29KDiBVld1n7ym4B0_secret_tB77zb3BoTCKigUe5R38hrCKS",
            "amount": 120000,
            "metadata": {
                "payment_intent_client_secret": "pi_3PXoWvK29KDiBVld1n7ym4B0_secret_tB77zb3BoTCKigUe5R38hrCKS",
                "payment_intent_id": "pi_3PXoWvK29KDiBVld1n7ym4B0"
            },
            "currency": "USD",
            "status": "CAPTURED",
            "errors": [],
            "date_created": "2024-07-01T18:00:45+0000",
            "date_last_modified": "2024-07-01T18:00:48+0000"
        }
    ],
    "sub_total": 0,
    "shipping_total": 0,
    "tax_total": 0,
    "total": 0,
    "app_order_id": "mario-test-1",
    "status": "COMPLETED",
    "is_guest": true,
    "date_created": "2024-06-28T20:31:56+0000",
    "date_last_modified": "2024-06-28T20:31:56+0000",
    "priced": true,
    "wallet_based_checkout": false,
    "currency": "USD",
    "channel": "MARKETPLACE",
    "currency_symbol": "$",
    "intent_based_checkout": true,
    "order_status": "COMPLETED",
    "order_id": 54609,
    "guest": true
}
```

</details>

If there are any issues with submission, they will be returned to instead of the Order above. A new payment token will need to be sent with each Create Order request.

### Submission Date

At the time of order submission a `date_submitted` property on the Order and Bag objects will be populated with [**ISO 8601**](https://en.wikipedia.org/wiki/ISO_8601) datetime values that reflect the submission time. On the Order object this value will capture the last time the Order was submitted to Violet. Each Bag object within the Order object will reflect the last time an attempt was made to submit the Bag to the external commerce platform.

## Zero-Dollar ($0) Orders

Violet fully supports $0 orders through Direct Order Submission, enabling scenarios such as fully discounted orders, promotional campaigns, loyalty rewards, or free product samples where products may have zero monetary value while still requiring order processing and fulfillment tracking.

### When $0 Orders Occur

A $0 order can occur when:

* All SKUs in the order have a price of $0 (e.g., free promotional items)
* Discounts fully offset the order subtotal (e.g., 100% discount code)
* A combination of discounts brings the total to $0

### How Violet Handles $0 Orders

#### Payment Processing

When the order total equals $0:

* **No payment method is required** — You can omit `payment_method` from your Create Order request
* **Payment authorization is skipped** — Violet does not attempt to charge the shopper
* The `PaymentTransaction` will have:
  * `capture_status`: `NOT_REQUIRED`
  * `payment_provider`: Your app name (not a payment provider like Stripe)

{% hint style="info" %}
If you include a payment method on a $0 order, Violet will accept the request but will not process any payment. The payment method is essentially ignored.
{% endhint %}

<details>

<summary>Sample $0 Order Request (No Payment Method)</summary>

```json
POST /orders

{
  "order": {
    "app_order_id": "promo-order-001",
    "customer": {
      "first_name": "Jane",
      "last_name": "Doe",
      "email": "jane@example.com"
    },
    "bags": [
      {
        "skus": [
          {
            "sku_id": 12345,
            "price": 0,
            "quantity": 1
          }
        ],
        "shipping_method": {
          "label": "Free Shipping",
          "price": 0
        },
        "tax_total": 0
      }
    ],
    "shipping_address": {
      "address_1": "123 Main St",
      "city": "Seattle",
      "state": "WA",
      "country": "US",
      "postal_code": "98101"
    },
    "currency": "USD"
  }
}
```

</details>

#### Tax Handling

For $0 orders, tax is calculated as follows:

* **$0 price SKUs** — Tax amount and tax rate are automatically set to $0
* **Zero bag subtotal** — When the bag subtotal is $0 (even if individual SKU prices were reduced by discounts), no tax liability exists

This is consistent with standard tax treatment: when the taxable base is $0, there is no tax to collect.

{% hint style="warning" %}
If you are responsible for tax calculation and remittance, ensure your tax provider is configured to handle $0 taxable amounts. Most tax providers will return $0 tax for a $0 taxable base, but verify this behavior in your integration.
{% endhint %}

#### Commission Handling

Violet does not apply commission on $0 orders:

* When order total is $0 or negative, commission calculation is skipped
* No distribution records are created for commission amounts
* This prevents negative commission scenarios

### Discounts and $0 Orders

Discounts can reduce an order to $0. When using [Custom Discounts](https://docs.violet.io/prism/checkout-guides/guides/direct-order-submission-with-discounts):

* A discount cannot exceed the bag subtotal (you'll receive a validation error)
* When a discount equals the subtotal exactly, the order becomes a $0 order
* All $0 order behaviors described above apply when discounts bring the total to $0

<details>

<summary>Sample Request: Discount Bringing Order to $0</summary>

```json
POST /orders

{
  "order": {
    "app_order_id": "full-discount-001",
    "customer": {
      "first_name": "John",
      "last_name": "Smith",
      "email": "john@example.com"
    },
    "bags": [
      {
        "skus": [
          {
            "sku_id": 12345,
            "price": 5000,
            "quantity": 1
          }
        ],
        "discounts": [
          {
            "type": "CUSTOM",
            "target_type": "ORDER",
            "amount": 5000,
            "code": "FREEGIFT"
          }
        ],
        "shipping_method": {
          "label": "Free Shipping",
          "price": 0
        },
        "tax_total": 0
      }
    ],
    "shipping_address": {
      "address_1": "456 Oak Ave",
      "city": "Portland",
      "state": "OR",
      "country": "US",
      "postal_code": "97201"
    },
    "currency": "USD"
  }
}
```

</details>

### Order Lifecycle for $0 Orders

$0 orders follow the same lifecycle as regular orders:

1. **Order Status** — Progresses through `PROCESSING` → `COMPLETED` as normal
2. **Bag Status** — Moves through `ACCEPTED` → fulfillment states as the merchant processes the order
3. **Fulfillment** — Merchants still receive and fulfill $0 orders through their commerce platform
4. **Webhooks** — All standard order webhooks are emitted (ORDER\_COMPLETED, BAG\_FULFILLED, etc.)

### Refunds on $0 Orders

If a merchant initiates a refund on a $0 order:

* Violet creates a refund record with `status`: `EXTERNAL`
* No funds are moved since no payment was captured
* The `ORDER_REFUNDED` webhook is still emitted
* Your system should update order status accordingly but no financial reversal is needed

### Best Practices for $0 Orders

1. **Validate pricing upstream** — Ensure your pricing logic is correct before submitting to Violet
2. **Track promotional orders** — Use `app_order_id` to identify promotional or $0 orders in your system
3. **Set appropriate fulfillment expectations** — Merchants will still see and fulfill these orders
4. **Monitor for abuse** — Implement rate limiting or other controls to prevent abuse of $0 order functionality
