# Order pricing & Dash Coins — frontend guide

The backend **persists** the numbers you send on `POST /api/user/v1/orders/create` and uses them for **wallet debit/credit** and **Stripe** (charge amount = amount after Dash Coin discount). **You are responsible** for computing line items, tax, caps, and coin math on the client (or you can add server-side validation later).

---

## APIs to call first

| Purpose | Method & path | Auth |
|--------|----------------|------|
| Commission / platform rules | `GET /api/user/v1/commission/settings` | Bearer **user** JWT |
| Wallet balance | `GET /api/user/v1/wallet` | Bearer **user** JWT |

Example commission response fields (snapshot — see DB for truth):

| Field | Typical use |
|-------|----------------|
| `shipment_threshold_usd` | Compare to **base_rate** (carrier quote) |
| `flat_platform_fee_usd` | Flat fee when base is **below** threshold |
| `percent_platform_fee` | Whole percent (e.g. `8` = 8%) of **base_rate** when at/above threshold |
| `gst_rate` | Whole percent applied to **sub_total** (your product definition) |
| `max_cashback_percent_of_platform_fee` | Max discount % applied to **platform_fee USD** |
| `coins_per_dollar` | Dash Coins per **$1** discount (redeem & display) |
| `delivery_earn_multiplier` | Multiplier for coins **to credit after successful payment** |

---

## Field definitions & formulas

Assume:

- \(R\) = `base_rate` (USD, from carrier/shipment quote)
- Threshold \(T\) = `shipment_threshold_usd`
- Flat fee \(F\) = `flat_platform_fee_usd`
- Percent fee \(p\) = `percent_platform_fee / 100`
- GST \(g\) = `gst_rate / 100`
- Cashback cap % on platform fee \(m\) = `max_cashback_percent_of_platform_fee / 100`
- Coins per dollar \(\gamma\) = `coins_per_dollar`
- Earn multiplier \(\lambda\) = `delivery_earn_multiplier`
- Wallet coins \(W\) from `GET /api/user/v1/wallet` → `dash_coins_balance`

### 1) Platform fee (`platform_fee`)

Use **one** rule consistently:

- If \(R \ge T\): **`platform_fee = R × p`** (percent of base rate)  
- Else: **`platform_fee = F`** (flat)

> Your UI copy must match this exactly (avoid mixing flat on high base rates).

### 2) Subtotal (`sub_total`)

**Standard definition (recommended):**

```text
sub_total = base_rate + platform_fee
```

If you later include **fuel** in the same taxable base:

```text
sub_total = base_rate + platform_fee + fuel_surcharge
```

Pick **one** convention; store it consistently in `sub_total` and use the same base for tax and totals.

### 3) Tax (`tax_amount`)

Common pattern (must match your legal/product rules):

```text
tax_amount = sub_total × gst_rate / 100
```

### 4) Totals before Dash Coins

```text
total_excluding_tax = sub_total   // often aligned with sub_total when tax is separate
total_amount        = sub_total + tax_amount   // add fuel here if not inside sub_total
```

Keep **fuel_surcharge** explicit on the order when you use it.

### 5) Max Dash Coin discount (USD + coins)

Cap is on **platform fee**, not on full shipment:

```text
dash_coins_discount_max = platform_fee × (max_cashback_percent_of_platform_fee / 100)
dash_coins_redeemed_max = dash_coins_discount_max × coins_per_dollar
```

Round money to **2** decimals and coins to a sensible precision (e.g. **4** decimals).

### 6) Actual redemption

User chooses coins to redeem; enforce:

```text
dash_coins_redeemed ≤ min(wallet_balance, dash_coins_redeemed_max)
```

Dollar value of redeemed coins:

```text
dash_coins_discount = dash_coins_redeemed / coins_per_dollar
```

Optionally clamp: `dash_coins_discount ≤ dash_coins_discount_max`.

### 7) Payable amount (Stripe)

What the customer pays after Dash Coins:

```text
payable_amount_after_dashcoin_redemption = total_amount − dash_coins_discount
```

Send this as the amount used for Stripe Checkout / Payment Intent (backend validates against stored order).

### 8) Coins to credit after payment succeeds

Stored on the order for webhook wallet credit:

```text
dash_coins_to_credit_on_payment_success = sub_total × delivery_earn_multiplier
```

---

## Worked example — \(R = 50\) USD base rate

Constants (illustrative): \(T = 44\), \(p = 8\%\), GST \(13\%\), cashback \(30\%\) of platform fee, \(\gamma = 50\), \(\lambda = 2\).

| Step | Calculation | Result |
|------|-------------|--------|
| base_rate | | **50.00** |
| platform_fee | \(50 \ge 44\) → \(50 × 0.08\) | **4.00** |
| sub_total | \(50 + 4\) | **54.00** |
| tax_amount | \(54 × 0.13\) | **7.02** |
| total_amount | \(54 + 7.02\) | **61.02** |
| dash_coins_discount_max | \(0.30 × 4.00\) | **1.20** |
| dash_coins_redeemed_max | \(1.20 × 50\) | **60** coins |
| Suppose user redeems 60 coins | | |
| dash_coins_discount | \(60 / 50\) | **1.20** |
| payable_amount_after_dashcoin_redemption | \(61.02 − 1.20\) | **59.82** |
| dash_coins_to_credit_on_payment_success | \(54 × 2\) | **108** coins |

---

## Order create payload (fields the backend stores)

Send all pricing fields your product needs; required vs optional follows Joi — key persisted fields include:

- Shipment: `pickup_address`, `dropoff_address`, `package_type`, `carrier_name`, dimensions, `declared_value`, etc.
- Pricing: `base_rate`, **`platform_fee`**, **`sub_total`**, `fuel_surcharge`, `total_excluding_tax`, `tax_amount`, **`total_amount`**
- Dash Coins: **`dash_coins_discount_max`**, **`dash_coins_redeemed_max`**, `dash_coins_discount`, `dash_coins_redeemed`, **`payable_amount_after_dashcoin_redemption`**, `dash_coins_to_credit_on_payment_success`

Backend debits **`dash_coins_redeemed`** at order create and credits **`dash_coins_to_credit_on_payment_success`** after Stripe payment succeeds (see wallet services).

---

## Database migration (PostgreSQL)

If tables already exist, add columns (adjust types if needed):

```sql
ALTER TABLE orders ADD COLUMN IF NOT EXISTS platform_fee DECIMAL(12, 2);
ALTER TABLE orders ADD COLUMN IF NOT EXISTS sub_total DECIMAL(12, 2);
ALTER TABLE orders ADD COLUMN IF NOT EXISTS dash_coins_discount_max DECIMAL(12, 4);
ALTER TABLE orders ADD COLUMN IF NOT EXISTS dash_coins_redeemed_max DECIMAL(18, 4);
ALTER TABLE orders ADD COLUMN IF NOT EXISTS payable_amount_after_dashcoin_redemption DECIMAL(12, 2);
```

---

## Stripe amount validation

For checkout session / payment intent, the backend charges **`payable_amount_after_dashcoin_redemption`** when set; otherwise **`total_amount − dash_coins_discount`**, so the client **must** pass an amount consistent with the stored order.
