Flow · 10 steps

What happens when you get it wrong, or send it twice

What a call does the second time, and what a refusal looks like.

Networks retry and people double-click. This walk sends the same receipt twice and the stock moves once. Then it collects refusals: each is a status and a body whose _tag names it, and none records anything.

Services involved

A filled dot is a read; a ring is a call that changes something.

  • Fulfillment Manager: https://fulfillment.getmanifold.io
  • Inventory Manager: https://inventory.getmanifold.io

Every call carries Authorization: Bearer $MANIFOLD_TOKEN unless its step says otherwise (getting a token). Run a flow in your sandbox, not your live organization: see Before you start.

1 Read the pipeline this organization runs

What the organization chose, or the defaults: payment on account, a manual pick that packs by itself, a manual ship, no invoicing, and an order short of stock that waits.

GET /workflow Fulfillment Manager

What the answer holds: the operation's example.

2 Create a SKU

Untracked, so arrivals are sellable immediately and nothing waits to be named.

POST /items Inventory Manager

Request · application/json
{
  "sku": "WIDGET-PLAIN",
  "name": "Blue widget, 40mm",
  "quantity": 0
}

Answers 201. What the answer holds: the operation's example.

Records inventory.item-created.

3 Receive ten units

reference is the idempotency key — the document this movement came from.

POST /items/WIDGET-PLAIN/receive Inventory Manager

Request · application/json
{
  "quantity": 10,
  "reference": "dock-note-8841"
}

What the answer holds: the operation's example.

Records inventory.stock-received.

4 Send exactly the same receipt again

The retry a flaky network produces. It answers 200 with the current item, appends nothing, and moves no stock: a reference already in the journal is acknowledged, never re-applied.

POST /items/WIDGET-PLAIN/receive Inventory Manager

Request · application/json
{
  "quantity": 10,
  "reference": "dock-note-8841"
}

What the answer holds: the operation's example.

Records nothing.

5 Ten, not twenty

Ten on hand, not twenty. Every write a network can repeat carries a key like this reference, and Manifold applies each key once.

GET /items/WIDGET-PLAIN/stock Inventory Manager

What the answer holds: the operation's example.

6 Try to identify stock that never waited

Untracked units can be sold as soon as they arrive, so none wait to be named. Refused, and nothing is recorded.

POST /items/WIDGET-PLAIN/identify Inventory Manager

Request · application/json
{
  "quantity": 1,
  "serials": [
    "SN-1"
  ],
  "reference": "dock-note-8841-serials"
}
Refused · 409
{
  "_tag": "IdentityTrackingMismatch",
  "sku": "WIDGET-PLAIN",
  "tracking": "none",
  "reason": "untracked stock is sellable on arrival and never waits to be identified"
}

7 Take an order

Made directly as an order — no quote — so it opens and allocates at once.

POST /orders Fulfillment Manager

Request · application/json
{
  "reference": "WEB-10255",
  "lines": [
    {
      "sku": "WIDGET-PLAIN",
      "quantity": 3,
      "unitPriceCents": 2400
    }
  ],
  "customer": {
    "personId": "psn_01a15890-1b2c-7d3e-8f4a-5b6c7d8e9f0a"
  }
}

Answers 201. What the answer holds: the operation's example.

From your answer, later steps send id as {orderId} and lines[0].id as {lineId}.

Records fulfillment.order-created, fulfillment.stock-allocated, fulfillment.shipment-created.

8 Read it back

The whole order: each line with how much is held, picked, packed and shipped, and its parcels, invoices, refunds and any shortfall.

GET /orders/{orderId} Fulfillment Manager

What the answer holds: the operation's example.

9 Try to change a placed order's price

Prices can change only while the quote is a draft. This order was made directly, so its prices were fixed from the start. Refused, and nothing is recorded.

PUT /orders/{orderId}/lines/{lineId}/price Fulfillment Manager

Request · application/json
{
  "unitPriceCents": 1900,
  "reason": "price match"
}
Refused · 409
{
  "_tag": "LineNotRepriceable",
  "orderId": "{orderId}",
  "lineId": "{lineId}",
  "reason": "prices are locked once the order is placed"
}

10 Try to refund more than was ever shipped

Nothing has shipped, so there is nothing to send back. Refused, and no money moves and no stock returns.

POST /orders/{orderId}/refunds Fulfillment Manager

Request · application/json
{
  "refundId": "rfd_01a15853-0c00-7a6b-8c7d-8e9f0a1b2c3d",
  "amountCents": 7200,
  "lines": [
    {
      "lineId": "{lineId}",
      "quantity": 3,
      "restock": true
    }
  ]
}
Refused · 409
{
  "_tag": "OverRefund",
  "orderId": "{orderId}",
  "lineId": "{lineId}",
  "sku": "WIDGET-PLAIN",
  "dispatched": 0,
  "previouslyReturned": 0,
  "requested": 3
}

What a recorded fact is: Facts and the journal. Why a repeated step changes nothing: Idempotency and retries.