# Order and Bag States

## **Purpose**

This document articulates the states and state changes within the Direct Order Submission checkout flow for both Orders and Bags, providing a comprehensive understanding of how entities transition through the checkout process.

## **Table of Contents**

1. [Overview](#overview)
2. [Order States](#order-states)
3. [Bag States](#bag-states)
4. [State Transition Flow](#state-transition-flow)
5. [State Change Triggers](#state-change-triggers)
6. [Error States and Recovery](#error-states-and-recovery)
7. [State Synchronization](#state-synchronization)

***

## **Overview**

In Violet's Direct Order Submission flow, the checkout process involves two primary entities:

* **Order**: The top-level entity representing the entire purchase
* **Bag**: A merchant-specific subset of the order containing SKUs from a single merchant

Each entity progresses through specific states during the checkout process, with state transitions triggered by system events and external responses. Violet doesn't use a traditional "pending" concept - orders transition quickly through states.

***

## **Order States**

### **1. `IN_PROGRESS`**

* **Description**: Order has not yet been submitted to ecom platform
* **Entry Condition**: Order/Cart creation
* **Duration**: Until submission is initiated
* **Next States**: `PROCESSING`

### **2. `PROCESSING`**

* **Description**: Brief millisecond status while being submitted to the merchant's e-commerce platform
* **Entry Condition**: Submit endpoint called
* **Duration**: Milliseconds
* **Next States**: `REQUIRES_ACTION`, or error

### **3. `ACCEPTED`**

* **Description**: Merchant's system successfully accepted the order
* **Entry Condition**: All bags accepted by merchants
* **Duration**: Brief transitional state
* **Next States**: `COMPLETED`, `CANCELED`

### **4. `REJECTED`**

* **Description**: Merchant's system failed to process the order
* **Entry Condition**: Critical failure during submission
* **Duration**: Terminal state
* **Next States**: None (terminal)

### **5. `COMPLETED`**

* **Description**: Violet has submitted the order as a whole
* **Entry Condition**: Order successfully processed and payment captured
* **Duration**: Terminal state (with exceptions)
* **Next States**: `CANCELED`

### **6. `CANCELED`**

* **Description**: Merchant chose to cancel after initially accepting
* **Entry Condition**: Cancellation request from merchant or channel
* **Duration**: Terminal state
* **Next States**: None (terminal)

### **7. `REQUIRES_ACTION`**

* **Description**: Order-level status requiring intervention (e.g., 3D Secure authentication)
* **Entry Condition**: Payment requires additional authentication
* **Duration**: Until shopper completes action
* **Next States**: `PROCESSING`, `CANCELED`

***

## **Bag States**

Individual bags within an order can have different statuses:

### **1. `IN_PROGRESS`**

* **Description**: Initial state upon creation until submission
* **Entry Condition**: Bag entity created when items added to cart
* **Duration**: Until order submission
* **Next States**: `SUBMITTED`

### **2. `SUBMITTED`**

* **Description**: Brief transitional state when submitted to merchant (usually moves quickly to ACCEPTED)
* **Entry Condition**: Order submission initiated
* **Duration**: Milliseconds to seconds
* **Next States**: `ACCEPTED`, `REJECTED`, `IN_PROGRESS` (on retryable failure)
* **Note**: For platforms without external carts, bags remain in this state longer to prevent duplicate submissions

### **3. `ACCEPTED`**

* **Description**: Successfully received by the e-commerce platform and visible in merchant's dashboard
* **Entry Condition**: Positive merchant response with external order ID
* **Duration**: Until fulfillment or post-submission changes
* **Next States**: `COMPLETED`, `CANCELED`, `REFUNDED`, `PARTIALLY_REFUNDED`

### **4. `COMPLETED`**

* **Description**: All fulfillments have been shipped; bag is finished except for potential refunds/returns
* **Entry Condition**: All items fulfilled by merchant
* **Duration**: Terminal state (with exceptions)
* **Next States**: `REFUNDED`, `PARTIALLY_REFUNDED`

### **5. `REFUNDED`**

* **Description**: All items returned and fully refunded
* **Entry Condition**: Full refund processed by merchant
* **Duration**: Terminal state
* **Next States**: None (terminal)

### **6. `PARTIALLY_REFUNDED`**

* **Description**: Some items returned and partially refunded
* **Entry Condition**: Partial refund processed by merchant
* **Duration**: Can be terminal or transition to REFUNDED
* **Next States**: `REFUNDED` (if remaining items refunded)

### **7. `CANCELED`**

* **Description**: Order canceled by merchant (doesn't trigger automatic refund)
* **Entry Condition**: Merchant-initiated cancellation
* **Duration**: Terminal state
* **Next States**: None (terminal)

### **8. `REJECTED`**

* **Description**: E-commerce platform rejected the bag (Violet retries before accepting this state)
* **Entry Condition**: Multiple failed submission attempts
* **Duration**: Terminal state
* **Next States**: None (terminal)

***

## **State Transition Flow**

### **Direct Order Submission Flow Sequence**

```
1. Order Created → Order: IN_PROGRESS
                → Bags: IN_PROGRESS (auto-created)
   ↓
2. Submit Order → Order: PROCESSING (milliseconds)
                → Bags: SUBMITTED (brief transition)
   ↓
3. Merchant Response:
   - Success → Bags: ACCEPTED
             → Order: PROCESSING
   - Failure → Bags: REJECTED (after retries)
             → Order: REJECTED
   - Retry → Bags: IN_PROGRESS (retryable failures)
   ↓
4. Payment Processing:
   - Requires 3DS → Order: REQUIRES_ACTION
   - Direct capture → Continue
   ↓
5. All Bags Accepted + Payment Success → Order: COMPLETED
                                      → Bags remain ACCEPTED
   ↓
6. Post-Submission States:
   - Fulfillment → Bags: COMPLETED
   - Full Refund → Bags: REFUNDED
   - Partial Refund → Bags: PARTIALLY_REFUNDED
   - Cancellation → Order: CANCELED
				      → Bags: CANCELED
```

### **Key State Relationships**

1. **During Submission**:
   * Order moves through `PROCESSING` very quickly (milliseconds)
   * Bags transition through `SUBMITTED` briefly
   * Order cannot be `COMPLETED` unless at least one bag is `ACCEPTED`
2. **Post-Submission**:
   * Bag states are managed by merchant platforms
   * Violet syncs state changes via webhooks and reconciliation.
   * Bags can have different states within the same order

***

## **State Change Triggers**

### **Order State Triggers**

| Current State        | Trigger Event              | New State            | Condition                                         |
| -------------------- | -------------------------- | -------------------- | ------------------------------------------------- |
| `IN_PROGRESS`        | Submit API called          | `PROCESSING`         | Valid cart data                                   |
| `PROCESSING`         | At least 1 bag is accepted | NONE                 | Stays in PROCESSING until payment is successful   |
| `PROCESSING`         | Any bag rejected           | `REJECTED`           | Critical failure after retries                    |
| `PROCESSING`         | Payment needs auth         | `REQUIRES_ACTION`    | 3DS or other authentication                       |
| `REQUIRES_ACTION`    | Auth completed             | `PROCESSING`         | Re-submission initiated                           |
| `PROCESSING`         | Payment captured           | `COMPLETED`          | At least 1 bag was capture AND successful payment |
| `COMPLETED`          | Merchant cancels           | `CANCELED`           | Post-acceptance cancellation                      |
| `COMPLETED`          | Full refund processed      | `REFUNDED`           | All bags refunded                                 |
| `COMPLETED`          | Partial refund processed   | `PARTIALLY_REFUNDED` | Some bags/SKUs refunded                           |
| `PARTIALLY_REFUNDED` | Remaining items refunded   | `REFUNDED`           | All items now refunded                            |

### **Bag State Triggers**

| Current State          | Trigger Event      | New State            | Condition                    |
| ---------------------- | ------------------ | -------------------- | ---------------------------- |
| `IN_PROGRESS`          | Order submitted    | `SUBMITTED`          | Request sent to merchant     |
| `SUBMITTED`            | Merchant accepts   | `ACCEPTED`           | Positive API response        |
| `SUBMITTED`            | Merchant rejects   | `IN_PROGRESS`        | Retryable error              |
| `SUBMITTED`            | Multiple failures  | `REJECTED`           | Non-retryable or max retries |
| `ACCEPTED`             | Items backordered  | `BACKORDERED`        | Platform supports backorders |
| `ACCEPTED`             | All items shipped  | `COMPLETED`          | Fulfillment complete         |
| `ACCEPTED`/`COMPLETED` | Full refund        | `REFUNDED`           | All items refunded           |
| `ACCEPTED`/`COMPLETED` | Partial refund     | `PARTIALLY_REFUNDED` | Some items refunded          |
| `PARTIALLY_REFUNDED`   | Remaining refunded | `REFUNDED`           | All items now refunded       |
| Any state              | Merchant cancels   | `CANCELED`           | Cancellation request         |

***

## **Error States and Recovery**

### **Error Handling in Order States**

1. **PROCESSING Failures**:
   * Violet automatically retries retryable failures
   * Bags return to `IN_PROGRESS` for retry attempts
   * After max retries, bags move to `REJECTED`
2. **REQUIRES\_ACTION Recovery**:
   * Re-render payment sheet with same `payment_intent_client_secret`
   * Resubmit order after action completed

### **Nested Error Object Structure when at least one Bag succeeds and a least one Bag fails.**

```json
{
  "errors": [
    {
      "id": 10153,
      "order_id": 10634,
      "bag_id": 10645,
      "entity_type": "BAG",
      "entity_id": "10645",
      "type": "EXTERNAL_SUBMISSION_FAILED",
      "message": "Merchant API returned error: Invalid shipping method",
      "external_platform": "SHOPIFY",
      "date_created": "2025-06-16T14:21:24+0000"
    }
  ]
}
```

### **Important: Always Check Errors Array**

A cart response can come back with status code 200 and still have errors in the errors field. This happens when some bags succeed while others fail.

***

## **State Synchronization**

### **Post-Submission Synchronization**

Once bags are accepted by merchants, state management is handled by the merchant platform. Violet tracks these changes and updates the bag in our system.

### **Key Synchronization Mechanisms**

1. **Webhooks**: Primary method for real-time updates
   * Order lifecycle events (fulfillment, refund, cancellation)
   * Merchant-initiated changes
   * State transitions
2. **Order Reconciliation**: For platforms with limited webhook support
   * Periodic status checks for bags in `ACCEPTED`, `COMPLETED`, `PARTIALLY_REFUNDED` state
   * Ensures no missed events
3. **Platform-Specific Handling**:
   * **Cartless Platforms**: Bags remain in `SUBMITTED` state longer to prevent duplicate submissions
   * Poll Get Cart by ID endpoint until status changes

### **Date Tracking**

* `date_created`: When order/bag was created
* `date_submitted`: When validation passed and submission began
* `date_last_modified`: On an Order, this timestamp is updated only when a property of the Order itself is modified. Some, but not all, Bag status updates will also modify the parent Order. To ensure you have the latest status, check the `date_last_modified` of the associated Bag entities if the Order's timestamp has not changed.
* `date_last_consolidated`: Last sync with merchant platform

### **State Consistency Rules**

1. **Order-Bag Consistency**
   * Order reflects aggregate bag states
   * Mixed bag states possible (some `ACCEPTED`, some `REJECTED`)
2. **Refund vs Cancellation vs Returns**
   * `CANCELED` state doesn't always automatically trigger refunds - refunds may need to be initiated separately by merchant
   * `REFUNDED`/`PARTIALLY_REFUNDED` states indicate actual refund processing has occurred
   * Returns can happen with or without refunds:
     * **Return + Refund**: `fulfillment_status` of `RETURNED` with `financial_status` of `REFUNDED`/`PARTIALLY_REFUNDED`
     * **Return Only**: `fulfillment_status` of `RETURNED` with `financial_status` remaining `PAID`
   * Use `fulfillment_status` to track physical item movement, `financial_status` to track monetary transactions
3. **Retry Logic**
   * Violet handles automatic retries for transient failures
   * Bags remains in `SUBMITTED` during retry attempts
   * Final `REJECTED` state only after all retries exhausted

***

## **Best Practices**

### **State Management**

1. **Handle Brief Transitional States**:
   * `PROCESSING` and `SUBMITTED` are millisecond states
   * Don't rely on catching these states in polling
2. **Error Handling**:
   * Always check `errors` array regardless of HTTP status
   * For single bag order failures check the exception message.
   * Implement appropriate retry logic for your use case
3. **Cancellation vs Refund**:
   * Understand that `CANCELED` doesn't mean refunded
   * Track refund states separately (`REFUNDED`, `PARTIALLY_REFUNDED`)
4. **Return and Refund Tracking:**
   * Check both `fulfillment_status` and `financial_status` to understand complete bag state
   * Don't assume `RETURNED` fulfillment means money was refunded
   * For exchange scenarios, look for `RETURNED` + `PAID` combination

### **Monitoring Recommendations**

1. **Track State Durations**:
   * Alert on bags stuck in `SUBMITTED`
   * Monitor for orders in `REQUIRES_ACTION`
2. **Handle Mixed States**:
   * Orders can have bags in different states
   * Implement UI to show per-merchant status
3. **Webhook Best Practices**:
   * Subscribe to all relevant webhooks
   * Implement webhook retry logic
   * Use reconciliation as backup for missed webhooks


---

# 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.violet.io/prism/checkout-guides/guides/order-and-bag-states.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.
