> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stateset.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Order Lifecycle

> Order creation through fulfillment and returns, with the reservation semantics that prevent oversells.

# Order Lifecycle

The full path an order takes through the embedded engine, and the calls that move it.

```
create ──▶ reserve inventory ──▶ authorize payment ──▶ confirm reservation
                                                              │
                                                              ▼
                                        ship ──▶ delivered ──▶ returns
```

## Setup

```js theme={null}
import { Commerce } from '@stateset/embedded';

const commerce = new Commerce('./store.db');   // or ':memory:'
```

The engine runs **in-process** — there's no server to start and no network hop.

## 1. Create the order

```js theme={null}
const order = await commerce.orders.create({
  customerId: 'cus_1042',
  lineItems: [{ sku: 'SHOE-RED-10', quantity: 1 }],
});
```

Start minimal, then enrich with payment, shipping, and customer detail as the checkout collects
it.

## 2. Reserve inventory

Reservation is a three-step protocol, not a single write:

```js theme={null}
const reservation = await commerce.inventory.reserve({
  sku: 'SHOE-RED-10',
  quantity: 1,
  orderId: order.id,
});

// after payment authorises
await commerce.inventory.confirmReservation(reservation.id);

// or, if the order falls through
await commerce.inventory.releaseReservation(reservation.id);
```

<Warning>
  **Reserve before authorising payment, confirm after.** Reserving first prevents an oversell in the
  window between the two. Confirming after means a declined card releases the stock instead of
  stranding it.

  A reservation that is neither confirmed nor released holds inventory indefinitely — always pair
  the call with one of the two outcomes, including on your error path.
</Warning>

## 3. Validate and authorise payment

Validate totals, tax, and discounts *before* authorising. For agent-driven flows the action should
be explicit and auditable — see the [decision gate](/next-temporal/policy-engine) for how
consequential actions get approved.

## 4. Fulfil and ship

```js theme={null}
await commerce.orders.updateStatus(order.id, 'processing');
await commerce.orders.ship(order.id, {
  carrier: 'fedex',
  trackingNumber: '794611223344',
});
```

`ship` records the shipment and advances the order; tracking flows back to the customer.

## 5. Cancel, if it comes to that

```js theme={null}
await commerce.orders.cancel(order.id);
```

Cancellation releases reservations and reverses inventory effects. Terminal-state guards apply —
a shipped order cannot be cancelled, it has to be returned.

## 6. Post-purchase

Returns, exchanges, and refunds tie back to the original order and adjust inventory
deterministically. See [Returns Workflow](/stateset-icommerce/stateset-icommerce-returns-workflow).

## Reading state

```js theme={null}
const current = await commerce.orders.get(order.id);
const recent  = await commerce.orders.list({ limit: 50 });
const total   = await commerce.orders.count();
```

List calls are bounded by a server-side limit policy — default 500, maximum 1000 — so an
unbounded scan isn't possible. See
[API hardening](/stateset-icommerce/stateset-icommerce-api-hardening).

## Money

Every monetary value crosses as an **exact decimal string** (`"149.99"`), never a float. Don't
parse into a binary float before doing arithmetic.

## Related

* [Returns Workflow](/stateset-icommerce/stateset-icommerce-returns-workflow)
* [Inventory Lifecycle](/stateset-icommerce/stateset-icommerce-inventory-lifecycle)
* [Scenarios](/stateset-icommerce/stateset-icommerce-scenarios)
