> ## 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.

# Physical Stock Fulfillment

> Separate shipment status from confirmed reservations and post full-shipment stock once with the 1.39 native binding.

Shipping status and physical inventory posting are separate operations. Creating an order
under `reject_if_insufficient` reserves stock. Shipping confirms its holds; it does not by
itself consume physical on-hand stock. Version 1.39 adds
`commerce.inventory.fulfillOrderStock(orderId)` for a fully shipped/delivered order.

## Verify full shipment and retry

Use a fresh project with `@stateset/embedded@1.39.0`. Save as `stock-fulfillment.mjs`:

```javascript theme={null}
import assert from 'node:assert/strict';
import { Commerce } from '@stateset/embedded';

const commerce = await Commerce.open(':memory:');
try {
  const customer = await commerce.customers.create({
    email: 'warehouse@example.com', firstName: 'Example', lastName: 'Buyer',
  });
  await commerce.inventory.createItem({ sku: 'SHIP-MUG', name: 'Mug', initialQuantity: 5 });
  const order = await commerce.orders.createExact({
    customerId: customer.id, currency: 'USD', stockPolicy: 'reject_if_insufficient',
    items: [{ sku: 'SHIP-MUG', name: 'Mug', quantity: 2, unitPrice: '12.50' }],
  });
  await assert.rejects(() => commerce.inventory.fulfillOrderStock(order.id));
  await commerce.orders.ship(order.id);
  let stock = await commerce.inventory.getStock('SHIP-MUG');
  assert.equal(stock.totalOnHand, '5');
  assert.equal(stock.totalAllocated, '2');
  await commerce.inventory.fulfillOrderStock(order.id);
  await commerce.inventory.fulfillOrderStock(order.id);
  stock = await commerce.inventory.getStock('SHIP-MUG');
  assert.deepEqual(
    [stock.totalOnHand, stock.totalAllocated, stock.totalAvailable],
    ['3', '0', '3'],
  );
  console.log('Physical stock posted once; retry left balances unchanged.');
} finally {
  await commerce.close();
}
```

```bash theme={null}
node stock-fulfillment.mjs
```

The transaction checks reservation transitions, exact balances, inventory ledger rows and
outbox facts before commit. Already fulfilled holds do not post again. This checks local
stock accounting; it does not prove a carrier took custody or an external WMS completed work.

## Choose a partial-shipment contract deliberately

The full-order helper is not a substitute for a line-owned partial shipment. Governed reserved
shipping has its own typed line/quantity and receipt contract. Preserve the order-line and
reservation identities, exact quantities, and original key; inspect actual remaining holds.
Do not release confirmed holds and decrement stock manually to imitate an atomic shipment.

The apply-gated MCP tool is `fulfill_order_stock`. Its availability depends on profile,
strict governed-command coverage and host policy. Check discovery instead of assuming every
native accessor is exposed by a strict endpoint.

For [standalone Warehouse WMS](/stateset-warehouse/overview), physical inventory belongs to
that WMS. Do not maintain an independent embedded stock authority for the same operations
without an explicit integration and reconciliation contract. See [OMS/WMS/TMS](/guides/oms-wms-tms).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.