# Orders

Every order moves through a set of statuses, some of which you set by hand and some of which DZBuild sets for you. This page covers the orders list, the preview popup and detail page, the call-confirm workflow most Algerian merchants run, sending orders to a courier, and the [Advanced Orders](https://dzbuild.com/docs/addons/advanced-orders.md) CRM addon for sub-statuses and call attempts.

## Video

[Orders — how to manage orders in DZBuild](https://www.youtube.com/embed/-_dDZOKzvrU)

## The orders list

Open **Dashboard → Orders** at [`/dashboard/orders`](https://dzbuild.com/dashboard/orders). Each row shows:

* Selection checkbox
* Order number, with a product thumbnail (a **+N** badge when the order has several items), a traffic-source icon and the label you've set, if any
* Customer name and phone — with a fraud-score badge, and a red badge if you've banned that customer
* Total
* Status pill, plus a truck badge once the order has been sent to delivery, a **Return on the way** chip while a courier return has not given its stock back yet, and a **No trace at the courier** chip when the courier keeps answering that it cannot find the parcel (status and stock are left as they are)
* Date and time
* Actions: view, label, edit (printing is in the order preview popup)

Wilaya and commune are **not** columns; they appear in the order preview popup and on the detail page.

Order numbers: the list shows a short per-store number (`#1`, `#2`, …), counted separately for every store. The full system reference used on courier labels, emails and the track-order page is `ORD-<store id>-<YYYYMMDD>-<8 hex characters>` (for example `ORD-11-20260804-3F9A2B1C`), or `LP-<8 hex characters>` for an order taken on a landing page. Numbers are never reused, so a gap after a deleted order is normal.

Filter by:

| Filter           | Use                                                                                                                |
| ---------------- | ------------------------------------------------------------------------------------------------------------------ |
| Status           | Find all `pending` orders to call, or pick **Return on the way** to list returns whose stock has not come back yet |
| Period           | All periods / Today / This week / This month (fixed presets, not a free date range)                                |
| Wilaya           | Plan courier hand-overs by region                                                                                  |
| Delivery type    | `home` / `desk` / `pickup`                                                                                         |
| Sent to delivery | Sent / not sent — how you find the day's un-dispatched orders                                                      |
| Duplicates       | Same phone ordering the same product across more than one order                                                    |

There is no filter by delivery company and no payment filter — storefront orders are cash-on-delivery.

Search by phone, customer name, or order number from the search box at the top. From two characters on, it also matches the order label, the customer and seller notes, and the product name or SKU.

### Live orders

Leave the Orders page open during a campaign: new orders arrive in real time. A toast appears and a short chime plays, no refresh needed. On the first page, with no search and no filter other than the period or not sent, the row is injected at the top of the list with a flash animation and the counters bump. Otherwise a **New orders** button with their count appears; click it to clear the filters and see them.

### Order labels

Each order can carry a short text label of up to 60 characters, a lightweight way to tag orders ("call back tomorrow", "needs address check") straight from the list, without installing the Advanced Orders addon. Click the bookmark icon in the row's actions to add, change or clear it. The chip shows under the order number in both the desktop table and the mobile card, and the search box finds orders by their label.

### Where did this order come from?

Every order carries a small traffic-source icon (Meta, TikTok, Google, Direct, …). DZBuild works it out at checkout time from, in order: click IDs (`fbclid`, `ttclid`, `gclid`), UTM tags, the referring domain, and finally in-app-browser detection (Instagram, Facebook, TikTok, Snapchat, Threads, YouTube, Telegram). An order opened from an in-app browser with no pixel installed often lands as direct/other, and orders placed before this feature shipped have no source at all.

## Order limits per plan

| Plan           | Orders per calendar month |
| -------------- | ------------------------- |
| **Free**       | 30                        |
| **Pro**        | Unlimited                 |
| **Unlimited**  | Unlimited                 |
| **Enterprise** | Unlimited                 |

When a Free-plan store reaches 30 orders in a calendar month, the storefront closes: the **home page, product pages and the checkout page** are replaced by a "store closed" notice, and both storefront and landing-page order submissions are rejected — it is not just the checkout button. Orders already placed are untouched and the dashboard stays fully usable. Manual orders created from the dashboard also count against the limit.

The counter resets automatically on the 1st of the month, or immediately when you upgrade. The orders page shows a live usage card with a progress bar, the remaining count and a days-until-reset countdown, a warning from 80% and a red banner once you hit the limit.

To upgrade, open [`/dashboard/subscribe`](https://dzbuild.com/dashboard/subscribe) and click **▶ How to renew** for the in-app guided tour, or watch the [DZBuild YouTube channel](https://www.youtube.com/@DZBuild-off) tutorials.

## The state machine

```
pending → confirmed → processing → shipped → delivered

                ↓                       ↓

            cancelled             cancelled / returned
```

note

The diagram is the normal path, not an enforced one — the status picker lets you move an order to any of the seven statuses at any time. `processing` is also set automatically the moment you send an order to a courier, and `shipped` / `delivered` / `returned` are set automatically by the courier tracking sync.

| Status       | Description                                                                                                                                                                                                                                                                                                                                                                                                  |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `pending`    | Customer placed the order; you haven't reviewed it yet.                                                                                                                                                                                                                                                                                                                                                      |
| `confirmed`  | You've called and verified. With the default setting, stock is decremented here.                                                                                                                                                                                                                                                                                                                             |
| `processing` | Being packed / prepared, or just sent to a courier.                                                                                                                                                                                                                                                                                                                                                          |
| `shipped`    | Handed to the courier; tracking number issued.                                                                                                                                                                                                                                                                                                                                                               |
| `delivered`  | Customer received it.                                                                                                                                                                                                                                                                                                                                                                                        |
| `cancelled`  | Cancelled before delivery — stock is restored if it had been decremented.                                                                                                                                                                                                                                                                                                                                    |
| `returned`   | The parcel is on its way back to you or already back, set by the courier tracking or by hand. A negative event is recorded against the customer's fraud score. A return you set by hand restores committed stock at once; a return the courier reports gives it back later (see Stock effects below). No refund is logged for a store order; a `refunded` payment state exists only on digital-store orders. |

### Stock effects

* By default, stock is **decremented when the order moves to `confirmed`**, not at `pending`. This protects you from spam orders. To reserve stock as soon as an order arrives instead, open the display settings gear on the Orders page and set **Stock deduction** to **On order receipt**. Only the store owner or a member allowed to edit orders can change it; orders already pending are deducted when confirmed, as before.
* Stock counts as committed while the order is `confirmed`, `processing`, `shipped` or `delivered`, and also while `pending` when the store deducts on receipt.
* Cancelling an order, or setting it to `returned` yourself, **restores stock** at once whenever it had been committed, even if the order was moved back to `pending` in between. Cancelling an order whose stock was never committed changes no stock.
* A return reported by the courier keeps the stock out while the parcel travels back, and the order shows a **Return on the way** chip. The stock comes back when the courier reports the parcel back with you, when you click **Return received** in the order preview popup or on the order page, or on its own 15 days after the courier reported the return (the order page shows that date). To settle several at once, pick **Return on the way** in the status filter, tick the orders and click **Returns received** in the bulk bar.
* Sending a still-`pending` order to a courier moves it to `processing`, which is the moment its stock is deducted.
* **Deleting** an order whose stock had already been committed puts that stock back, a `pending` one included when the store deducts on receipt; under the default setting, deleting a still-`pending` order changes nothing.

## Opening an order

Clicking an order row opens a quick **preview popup** in the list: items, customer, totals, a status changer, a call button, send-to-delivery and print label.

To open the full standalone page at `/dashboard/orders/<id>`, use the eye icon in the Actions column. The pencil icon opens the full edit page at `/dashboard/orders/<id>/edit`.

### The order detail page

* **Status pipeline** — a read-only visual bar showing where the order is now (pending → confirmed → processing → shipped → delivered, with a cancelled/returned branch). It is display-only: change the status from the status picker in the preview popup or on the detail page, not by clicking the pipeline.
* **Items** — what was ordered, with variants, prices, totals.
* **Customer** — name, phone, address. The preview popup also shows a small badge counting how many orders this phone number has placed with you, displayed only when it is more than one. It's an indicator, not a link — to see the customer's other orders, search their phone number in the orders search box or open [Customers](https://dzbuild.com/docs/selling/customers.md).
* **Shipping** — wilaya / commune, courier, tracking number, delivery type (`home` / `desk` / `pickup`).
* **Payment** — cash on delivery, and the amount to collect.
* **Notes** — two separate fields: *Customer notes*, whatever the buyer typed in the checkout form (so this one is customer-supplied, not internal), and *Seller notes*, your own internal notes. Both are editable from the order page. Landing-page custom form fields are appended to the seller notes as `label: value` lines and render as chips.

The core order page keeps no per-change audit log. A full timestamped status history, with the agent who made each change, exists only in the [Advanced Orders](https://dzbuild.com/docs/addons/advanced-orders.md) addon.

### Editing an order

The full edit page at `/dashboard/orders/<id>/edit` lets you:

* Change customer details, wilaya and commune — shipping recalculates live.
* Change the delivery type.
* Add or remove products, change quantities, and edit a line's price.
* Apply a discount.
* Override the shipping price by hand.

note

The **Edit** button in the preview popup opens this same full edit page, so a shipping price you set by hand is kept when you save.

### Deleting an order

There is no delete button on the orders list. The row actions are **view**, **label** and **edit**, and the bulk bar that appears when you tick rows carries the courier picker, **Send to delivery**, **Returns received** (for returns still on the way) and **Clear selection**.

Delete lives on the **order detail page**. Open the order with the eye icon, use the delete action there, and confirm. It is permanent: there is no trash, no archive and no un-delete, so an order removed by mistake has to be re-entered by hand. Deleting an order whose stock had already been committed puts that stock back.

**There is no bulk delete**, and none is available yet on any plan. To clear a batch of fake or spam orders today, open them one at a time, or leave them as `cancelled`, which keeps them out of your working filters while the record survives.

### Create an order by hand

Taking orders by phone, Instagram DM or WhatsApp? Add them from the orders page: search a product, pick variants and quantity, then fill in the customer's details and their wilaya / commune — shipping is priced from your store's rate table.

Manual orders start as `pending`, are cash-on-delivery like any other order, and **do count** against the Free plan's 30-per-month limit. Creating one needs the `orders.edit` permission.

## The call-confirm workflow

Most Algerian merchants run a phone-confirm flow:

1. Order arrives as `pending`.
2. You call the customer to confirm the order is real and still wanted.
3. Mark as `confirmed` if real → stock decrements, ready to ship.
4. Mark as `cancelled` if fake or customer-cancelled → no stock used.

A green **Call** button in the order preview popup (and in the Advanced Orders table) turns the customer's number into a `tel:` link, so the call is one tap away on mobile. It lives in the list's preview popup, not on the standalone order detail page.

For a dedicated CRM-style page with sub-statuses, call-attempt tracking and a full per-order timeline, install [Advanced Orders](https://dzbuild.com/docs/addons/advanced-orders.md).

## Spotting bad orders

* **Fraud score** — every order shows a badge for that phone number, built from its cancellation, return and successful-delivery history. Moving an order to `cancelled`, `returned` or `delivered` feeds that history.
* **Ban a customer**: from an order (the preview popup or the order page), pick a reason and confirm. By default the ban blocks new orders from the browser that order was placed from; tick the box that also bans the phone number to block the number too, which is what a ban on the [Customers](https://dzbuild.com/docs/selling/customers.md) page does. When DZBuild has no browser on record for the order, it bans the phone number instead. A red badge marks orders from banned phone numbers. Banning needs the `customers.edit` permission.
* **Duplicates filter** — surfaces the same phone number ordering the same product across more than one order, which is the usual shape of a double-submit or a prank.

## Sending an order to a courier

Link a courier first at [`/dashboard/link-shipping`](https://dzbuild.com/dashboard/link-shipping) — see [Shipping](https://dzbuild.com/docs/selling/shipping.md). Once one is linked, the preview popup and the order detail page both show a **Send to delivery** button:

1. Pick a delivery provider from the dropdown (shown only if you have several linked; your default is marked with a ⭐).
2. Click **Send**. DZBuild calls the courier's API, gets back a tracking number and stores it on the order along with the courier's name, flags the order as sent, and moves the status from `pending` / `confirmed` to **`processing`** — not `shipped`. An order already in any other status keeps that status. If the order was still `pending`, this is the moment stock is deducted.

The order then moves to `shipped` / `delivered` / `returned` on its own as the tracking sync reads the courier's status. If you set a sent order to `cancelled`, DZBuild first checks the parcel at the courier: with Noest, Maystro, Ecom Delivery and Elogistia, a parcel that has not moved yet can be cancelled there too with **Cancel at the courier and here**. Otherwise choose **Cancel here only** and also cancel the parcel in the courier's own space, or the driver may still come.

The send dialog lets you choose the **courier**; for Noest and Zimou Express it also carries a **The customer can open the parcel before paying** box, ticked by default. Home vs desk vs pickup is a property of the order itself, set by the customer at checkout. To change it, edit the order (the **Edit** button in the preview popup, or `/dashboard/orders/<id>/edit`), which also recalculates the shipping cost.

A desk send is refused **by DZBuild**, before any API call, when the synced courier data says that wilaya has no desk. If the courier's API refuses the send or is down, DZBuild shows the error and the order stays unsent. If the courier does not answer in time, the parcel may already exist on its side: the message names the order reference, so look it up in the courier's space before you send again.

## Tracking after the hand-off

Once the order has a tracking number, DZBuild re-checks the courier automatically and maps the courier's current status onto the order status (`shipped`, `delivered`, `returned`, `cancelled`). A parcel the courier starts sending back shows as `returned` straight away; see Stock effects above for when its stock comes back. A change on the courier's side can take a little while to show up on the order. The order page and the preview popup show the resulting order status as a single line, with a **Refresh** button for an on-demand check.

There is no per-event courier history — only the latest status is stored. An unrecognised courier status is ignored rather than guessed, so a rare status can leave the order where it is until you set it by hand.

## The buyer's tracking page

Every storefront has a public order tracking page at `/track-order` (`/track` opens it too). When a buyer asks where their order is, send them there: they need no account, only the order number, typed or pasted, with or without a leading `#`. Your storefront's navbar links to the page on every theme, and two buttons open it with the number already filled in and the order on screen: the track-order button on the confirmation page shown after checkout, and the **Track my order** button in [WhatsApp Sender](https://dzbuild.com/docs/addons/whatsapp-sender.md) messages.

The page searches by the full reference (`ORD-…` or `LP-…`), not by the short `#1`, `#2` number from your orders list, and it only finds orders of your own store; a number it cannot match gets a not-found message. When a buyer has only the short number, open the order detail page, where the full reference is printed in small type next to it. To send a buyer a direct link, add the reference to the address: `https://<your-store-address>/track-order?order=<reference>`.

What the buyer sees, in your store's language (Arabic or French), on every theme except Digital:

* The order number, the order date and a status badge.
* A five-step progress bar: `pending`, `confirmed`, `processing`, `shipped`, `delivered`. A cancelled order shows a cancelled badge and no progress.
* Each product with its picture, quantity and line total, then the subtotal, the shipping cost when there is one, and the total.

The status comes straight from the order, so when the courier tracking sync moves it to `shipped` or `delivered`, the buyer sees that too. The page never shows the buyer's name, phone or address, the courier or the tracking number. On the [Digital theme](https://dzbuild.com/docs/storefront/digital-theme.md) the page has three steps, `pending`, `confirmed` and `delivered`, and shows only the total; for a confirmed or delivered order it also asks for the last 4 digits of the phone number used on the order before it shows files, codes or accounts. See [Digital delivery](https://dzbuild.com/docs/selling/digital-delivery.md).

## Printing a label

The **Print** button in the order preview popup prints the order's label.

* If the order has already been sent to an Ecotrack-powered courier or Elogistia **and has a tracking number**, you get that courier's own PDF bordereau.
* For every other courier, and for orders not yet dispatched, DZBuild prints its own sheet: store name and phone, customer name, phone and address, the item list with quantities and prices, subtotal / shipping / total, the tracking number when there is one, and a QR code that reopens the order in your dashboard.

On mobile — and on desktop when the popup is blocked — the sheet renders inline instead of opening a print window. For per-product label customisation, see [Custom Delivery Label](https://dzbuild.com/docs/addons/custom-delivery-label.md).

## Bulk actions

Ticking order checkboxes (or the header select-all) reveals the bulk bar: **Send to delivery**, with a courier dropdown when more than one courier is linked, and **Returns received**, which gives back the stock of the ticked returns that are still on the way (shown to members who can edit orders). The bulk bar only exists when at least one courier is linked. Orders already sent have their checkbox disabled, except returns still on the way, which you can tick for **Returns received**.

Maximum **50 orders per operation**. Results come back in a modal split into sent / failed / skipped.

There is no bulk delete, no bulk status change, no bulk label generation, and no CSV or Excel export of orders in the dashboard. Deleting is one order at a time from its detail page, as described under [Deleting an order](#deleting-an-order). The closest thing to an export is the **Google Sheets** addon, which pushes orders out to a spreadsheet.

## Who can do what

Orders are permission-gated at three levels — **view**, **edit** and **delete** (a fourth **export** checkbox exists in the team screen but is not wired to anything today) — so a call-centre worker can be given view + edit without the ability to delete orders. Note that confirming an order, editing it, creating one by hand and sending it to a courier all share the same `orders.edit` permission; they can't be granted separately.

## Notifications

When a new order arrives:

* **On the Orders page** — the row is injected live at the top of the list with a flash, a toast appears and a short chime plays. There is no notification-bell centre in the dashboard and no on/off switch for the chime; it plays only on the Orders page.
* **Email** to the store owner.
* **Push** — turn the Push switch on at [`/dashboard/notifications`](https://dzbuild.com/dashboard/notifications) and accept the browser prompt. This works in any browser that supports Web Push; installing the dashboard as a PWA is not required (though on iOS it is, which is why the page shows an iOS hint). In the DZBuild mobile app the same row is labelled "app notifications".
* **Telegram** — connect one or more accounts; each team member gets their own seat with independent new-order and status-change toggles.
* **Discord** — same per-channel new-order and status-change toggles.

The channels you can toggle at `/dashboard/notifications` are Push, Email, Telegram and Discord.

### Webhooks

Two separate paths:

1. Install the **Webhooks (n8n / Make / Zapier)** addon from [`/dashboard/addons`](https://dzbuild.com/dashboard/addons) — it requires the Unlimited plan — then add your automation URL at `/dashboard/webhooks`. DZBuild posts an HMAC-signed payload the moment an order is created or its status changes.
2. If you're building against the public API, register webhooks with your API key instead — see [Webhooks (API)](https://dzbuild.com/api-docs/webhooks/overview.md).

## Advanced Orders (addon — Unlimited plan)

The CRM-style page at [`/dashboard/orders/advanced`](https://dzbuild.com/dashboard/orders/advanced) adds:

* **12 sub-statuses** on top of the standard ones: `no answer`, `busy line`, `postponed`, `waiting customer call`, `confirmed`, `cancelled`, `fake`, `duplicate`, `customer cancelled`, `at courier`, `returned`, `completed`.
* **Call-attempt tracking** — each attempt is logged with one of five outcomes (no answer, busy, answered, wrong number, callback requested) plus a note, and a red call-count chip shows on the row.
* **Full status timeline** per order, with the agent who made each change.
* **Team stats** — per-agent activity across the call queue.
* **Filter and search** by sub-status.

The CRM page does not replace the standard orders page, but it is not read-only either. Eight of the twelve sub-statuses are mapped onto the core order status — confirmed → `confirmed`; cancelled, fake, duplicate and customer cancelled → `cancelled`; at courier → `shipped`; returned → `returned`; completed → `delivered`. Setting one of those also changes the status on the standard orders page, moves stock, updates the customer's fraud score, and fires the normal status-change notifications. The four pre-confirmation states (no answer, busy line, postponed, waiting customer call) have no core equivalent and leave the order status untouched.

Activate from [`/dashboard/addons`](https://dzbuild.com/dashboard/addons) (requires the Unlimited plan).

## Tips

* **Confirm by phone within 1 hour of the order** when you can — the longer the delay, the more cancellations.
* **Don't move orders to `confirmed` unless you've actually verified.** It decrements stock and creates a real shipping intent.
* **Use sub-statuses** if your team handles ≥ 50 orders/day — `no answer` callbacks need their own queue.
* **Clear out old `pending` orders** weekly. They're usually fake or spam and clutter the list — cancel them one by one from the list, or work through them in the Advanced Orders queue.
* **Bind the order detail to a single screen** during call sessions — open it on tablet, dial on phone.
* **Send to courier in batches** at the same hour each day so the courier expects a pickup window — up to 50 orders per batch.

## What's next

* [Customers](https://dzbuild.com/docs/selling/customers.md)
* [Shipping & couriers](https://dzbuild.com/docs/selling/shipping.md)
* [Advanced Orders addon](https://dzbuild.com/docs/addons/advanced-orders.md)
* [Custom Delivery Label addon](https://dzbuild.com/docs/addons/custom-delivery-label.md)
* [Webhooks](https://dzbuild.com/api-docs/webhooks/overview.md)
