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
  2. Order States
  3. Bag States
  4. State Transition Flow
  5. State Change Triggers
  6. Error States and Recovery
  7. 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 StateTrigger EventNew StateCondition
IN_PROGRESSSubmit API calledPROCESSINGValid cart data
PROCESSINGAt least 1 bag is acceptedNONEStays in PROCESSING until payment is successful
PROCESSINGAny bag rejectedREJECTEDCritical failure after retries
PROCESSINGPayment needs authREQUIRES_ACTION3DS or other authentication
REQUIRES_ACTIONAuth completedPROCESSINGRe-submission initiated
PROCESSINGPayment capturedCOMPLETEDAt least 1 bag was capture AND successful payment
COMPLETEDMerchant cancelsCANCELEDPost-acceptance cancellation
COMPLETEDFull refund processedREFUNDEDAll bags refunded
COMPLETEDPartial refund processedPARTIALLY_REFUNDEDSome bags/SKUs refunded
PARTIALLY_REFUNDEDRemaining items refundedREFUNDEDAll items now refunded

Bag State Triggers

Current StateTrigger EventNew StateCondition
IN_PROGRESSOrder submittedSUBMITTEDRequest sent to merchant
SUBMITTEDMerchant acceptsACCEPTEDPositive API response
SUBMITTEDMerchant rejectsIN_PROGRESSRetryable error
SUBMITTEDMultiple failuresREJECTEDNon-retryable or max retries
ACCEPTEDItems backorderedBACKORDEREDPlatform supports backorders
ACCEPTEDAll items shippedCOMPLETEDFulfillment complete
ACCEPTED/COMPLETEDFull refundREFUNDEDAll items refunded
ACCEPTED/COMPLETEDPartial refundPARTIALLY_REFUNDEDSome items refunded
PARTIALLY_REFUNDEDRemaining refundedREFUNDEDAll items now refunded
Any stateMerchant cancelsCANCELEDCancellation 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.

{
  "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: Last state change
  • 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
    • CANCELED state doesn’t automatically trigger refunds
    • Refunds must be initiated separately by merchant
    • REFUNDED/PARTIALLY_REFUNDED states indicate actual refund processing
  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)

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