> For the complete documentation index, see [llms.txt](https://tyrix.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://tyrix.gitbook.io/docs/script-resources/tyrix-droply/customer-app.md).

# Customer App

Droply installs itself onto LB Phone as a normal app. Everything below happens inside the phone — there is no separate NUI, no command, and no interaction point.

## Signup

A customer must create a Droply account once before they can order. The signup screen asks for a **display name** (`minDisplayName`–`maxDisplayName`, default 2–48 characters); the phone number is pulled from lb-phone automatically and just confirmed.

If a customer somehow reaches checkout without an account, the server rejects the order and pushes them back to the signup screen. Signups are logged to the `signup` Discord channel.

## Browse

The store list shows every storefront with at least one priced, visible item.

Each card carries the logo, display name, description, delivery fee, item count, star rating with review count, and an open/closed badge. Customers can sort by:

* **Closest** — resolved client-side from the customer's own coordinates against each store's first assigned station.
* **Rating** — highest average stars first.
* **Name** — alphabetical.

Closed stores stay listed but greyed out. Stores that have **blocked** this customer are marked and cannot be ordered from.

## Store page & menu

Opening a store shows the banner, description, address, phone number, and rating, with the menu grouped into the boss's categories. Each row carries the item label, boss-written description, and unit price.

Customers can browse the full menu, the about section, and the reviews of a **closed** store — only the order button is gated.

## Cart & checkout

Items are added with a quantity up to `maxQtyPerItem` (default 25), across at most `maxDistinctItems` distinct items (default 12).

At checkout the customer picks:

**Delivery location**

| Mode              | Behaviour                                                                                         |
| ----------------- | ------------------------------------------------------------------------------------------------- |
| **Live location** | The server reads the customer's ped coordinates at the moment the order is placed.                |
| **Map pin**       | The customer drops a GTA waypoint (Esc → M → right-click → reopen phone) and taps the pin button. |

Pin coordinates are validated against world bounds (±5000 on X/Y, −200 to 1000 on Z) before the order is accepted.

**Tip** — any amount up to `maxTip`. The tip goes to the driver in full.

**Promo code** — validated live as it is typed. Validation is strictly read-only; the code is only consumed when the order is actually placed. See [Promotions](/docs/script-resources/tyrix-droply/promotions.md).

The order total is:

```
total = max(0, subtotal − discount) + delivery fee + tip
```

Every line price, the subtotal, and the discount are **recomputed server-side** from the live menu. Nothing the client sends about price is trusted.

Funds are checked at this point but **not taken**. See [Order Lifecycle → Money](/docs/script-resources/tyrix-droply/order-lifecycle.md#money).

## Tracking

Once a driver marks the order out for delivery, the customer gets:

* A **world blip** for the driver, with a route drawn to it, plus a red flag blip on the drop-off.
* An **in-app mini-map** showing the driver moving in real time.
* An **ETA**, derived from the remaining distance and `Config.Droply.avgSpeedMps`.
* A one-shot **"your driver is approaching"** notification when the driver comes within `approachNotifyMeters` (default 150 m).

Blips and routes are cleared automatically when the order is delivered, cancelled, or the resource stops.

## Order chat

Every order carries a private customer ↔ driver chat, opened from the order details screen. Messages are capped at 500 characters and stored per order, so history survives a reconnect. The chat becomes available once a driver has accepted the order.

The customer also sees the driver's name and phone number once the order is accepted, so they can call through the normal phone if they prefer.

## Order history & reorder

The history screen lists the customer's last 50 orders with status, itemisation, and totals.

**Reorder** re-projects a past order's items against the store's *current* menu. Items that are no longer sold, or that lost their price, are dropped silently and the customer is told how many were removed. Prices always come from the live menu, never from the historical order — an old order cannot lock in an old price.

Reorder requires the store to be currently open.

## Reviews

After a delivery the customer can leave a star rating and up to 500 characters of feedback — one review per order. See [Reviews](/docs/script-resources/tyrix-droply/reviews.md).

## Profile & favourites

The profile screen holds the display name, avatar URL, banner URL, and phone number, plus a **favourites** list toggled from any store page. Favourites are stored per character identifier.

## Cancelling

Customers can cancel from the order details screen while the order is `pending`, `accepted`, or `preparing`.

* Cancelling while **`pending`** (no driver yet) is always free.
* Cancelling once a driver is **`preparing`** may incur a cancellation fee — see [Anti Abuse](/docs/script-resources/tyrix-droply/anti-abuse.md#cancellation-fees).

Once the order is `enroute`, the customer can no longer cancel; the driver is already on the way.
