Skip to content

Order Workflow

The order workflow implements a complex state machine using XState to manage the order lifecycle from payment through completion or cancellation.

Overview

Key features: - State machine with 11 states using XState - Event-driven transitions - Role-based guards (seller/customer/admin) - Automatic actions (notifications, refunds, payouts) - Dispute resolution for problematic orders - Correction requests for quality issues - Cancellation workflow with escalation

Order States

type OrderState =
  | 'paid'                  // Payment completed, awaiting seller acceptance
  | 'rejected'              // Seller declined order
  | 'inprogress'           // Seller working on order
  | 'cancel_requested'     // Customer requested cancellation
  | 'disputing'            // Under admin review
  | 'delivered'            // Awaiting customer approval
  | 'correction_requested' // Customer wants changes
  | 'completed'            // Finished successfully
  | 'cancelled'            // Cancelled with refund

State Machine

Implemented with XState:

const orderMachine = createMachine({
  initial: 'paid',
  states: {
    paid: {
      on: {
        'order.rejected': {
          target: 'rejected',
          guard: 'isSeller',
          actions: ['sendDeclinedOrderMessage', 'createRefund']
        },
        'order.accepted': {
          target: 'inprogress',
          guard: 'isSeller',
          actions: 'sendAcceptedOrderMessage'
        }
      }
    },
    inprogress: {
      on: {
        'order.delivered': {
          target: 'delivered',
          guard: 'isSeller'
        },
        'order.cancel_requested': [
          {
            target: 'cancelled',
            guard: 'isSeller', // Seller can immediately cancel
            actions: 'sendOrderCancelledMessage'
          },
          {
            target: 'cancel_requested',
            actions: 'sendCancellationRequestedMessage'
          }
        ]
      }
    },
    delivered: {
      on: {
        'order.completed': {
          target: 'completed',
          guard: 'isCustomer',
          actions: ['releasePayment', 'sendCompletedOrderMessage']
        },
        'order.requires_correction': {
          target: 'correction_requested',
          guard: 'isCustomer'
        }
      }
    }
    // ... more states
  }
});

Key Workflows

Happy Path

paid → inprogress → delivered → completed

Cancellation Flow

inprogress → cancel_requested → cancelled (if seller accepts)
inprogress → cancel_requested → disputing (after 3 requests)

Correction Flow

delivered → correction_requested → inprogress → delivered → completed

API Endpoints

/** * Advances an order through its workflow state machine by processing a workflow event.

POST /orders/:id/advance

Advances an order through its workflow state machine by processing a workflow event.

This endpoint allows authorized users (customers, sellers, or staff) to trigger state transitions in an order's lifecycle. The system validates permissions and processes the state change through the XState workflow engine.

Parameters: - id (path) - Order ID to advance - event (body) - Workflow event type - Additional event-specific data

Authorization: - Order customers and sellers can advance their orders
- Staff members can advance any order - Returns 403 for unauthorized users

Example:

POST /orders/ord_123456/advance
{
  "event": "order.accepted",
  "notes": "Ready to start work on logo design"
}

Business Rules

  1. Role-based transitions – Guards check user role
  2. Automatic refunds – On rejection/cancellation
  3. Payment release – On order completion
  4. Dispute after 3 cancellations – Escalate to admin
  5. Event logging – All transitions recorded
  6. Delivery deadline tracking – isLate() detection

Best Practices

✅ Do

  • Log all state transitions
  • Send notifications on state changes
  • Use guards to enforce role permissions
  • Record timestamps for all events
  • Allow corrections before completion

❌ Don't

  • Don't skip state machine transitions
  • Don't allow invalid transitions
  • Don't forget to issue refunds
  • Don't release payment before completion
  • Don't bypass dispute resolution