Number ranges
Three things in the orders app carry a number a human reads: the order, the delivery note, and the return. Each is drawn from a counter the merchant shapes.
Base path: https://api.revenexx.com/v1/orders/number-ranges.
The three seeded ranges
curl -X POST https://api.revenexx.com/v1/orders/number-ranges/defaults \
-H "X-Revenexx-Tenant: <TENANT_SLUG>" \
-H "X-Revenexx-Api-Key: rvxk_..." \
-H "Content-Type: application/json" \
-d '{}'
| Code | Numbers | Seeded as |
|---|---|---|
order | Orders | ORD- + six digits, step 1 |
delivery | Delivery notes, drawn by POST /v1/orders/{id}/ship | DEL- + six digits, step 1 |
return | Returns, drawn by POST /v1/orders/{id}/return | RET- + six digits, step 1 |
The app runs this on install, so a fresh tenant needs nothing. Call it by hand after a range was deleted, or to see what a tenant has.
Idempotent: a code that already exists comes back under existing and is left exactly as it is, counter included, so a merchant who changed the prefix keeps their change. It answers 200, never 201 — it is a reconcile, not a create — and it never repairs or renames a range that is already there.
The shape of a number
{prefix}{counter padded to `padding`}{suffix}
| Field | Meaning |
|---|---|
code | Which counter this is. Unique per tenant, and the value the settings point at. |
prefix | Literal text in front. ORD- turns counter 123 into ORD-000123. Empty by default. |
suffix | Literal text after — a market or year marker. Empty by default, which is what most merchants use. |
padding | How wide the counter is written, zero-padded. 6 makes 123 into 000123; 0 writes the bare number. Widening it later does not renumber what was already drawn. |
step | How far the counter moves per draw. 1 is consecutive; a larger step is what a merchant chooses who does not want their order volume readable off an invoice. |
counter | The last number drawn — state, not configuration. |
position_step | The gap between the position numbers of a new order: 10 numbers the lines 10, 20, 30, leaving room to slot one in later. Read from the order range only. |
channel_id | A label. It does not select the range. |
metadata | Free-form. The app stores it and reads nothing out of it. |
counter is state
The next draw is counter + step, and it writes the new value back.
counter forward skips numbers. Moving it back re-issues them, and the unique index on the order number then answers 409. Setting it is a repair, not a configuration.Because a draw writes the counter, updated_at on a range changes on every single order.
channel_id does not select the range
A draw finds the range by code alone, and the unique index on (tenant, code) means one code is one range per tenant. So an order on another channel draws from the same range this one names. channel_id is a label on the row, nothing more.
Adding a range
curl -X POST https://api.revenexx.com/v1/orders/number-ranges \
-H "X-Revenexx-Tenant: <TENANT_SLUG>" \
-H "X-Revenexx-Api-Key: rvxk_..." \
-H "Content-Type: application/json" \
-d '{"code":"order_at","prefix":"AT-","padding":6,"step":1}'
A code that is taken answers 409 rather than creating a second counter under the same name. Creating a range renumbers nothing that already exists.
Pointing a setting at it
A new range is only used once a setting names it:
| Setting | Drawn by |
|---|---|
order_number_range_code | POST /v1/orders/place |
delivery_number_range_code | POST /v1/orders/{id}/ship |
return_number_range_code | POST /v1/orders/{id}/return |
422. Create the range first, then point the setting at it.Settings resolve per market, so a per-market number range is a per-market setting pointing at a second range — not a channel_id on the range. See Settings.