Skip to content

Discount Codes

Discount codes are admin-issued promo codes that deduct a flat amount or a percentage from a customer’s order subtotal. They are validated and consumed atomically inside the order transaction — no separate “apply coupon” step is needed.


How it works

Admin creates code Customer validates Customer places order
POST /admin/discounts → GET /discounts/validate → POST /orders
{ code: "SAVE20", ?code=SAVE20 { …, discount_code: "SAVE20" }
discount_type: "percentage", &subtotal=500
discount_value: 20 }
← { discount_amount: 100,
final_total: 400 }
← order.discount_code = "SAVE20"
order.discount_amount = 100
order.total_amount = 400
  1. Validate before showing the customer a total. Call GET /api/v1/discounts/validate with the cart subtotal whenever the user types a code in the checkout form.
  2. Include the code in the order body. Pass discount_code in POST /api/v1/orders. The server re-validates and atomically increments the code’s used_count — preventing race conditions where two customers claim the last use simultaneously.

Validate a discount code

GET /api/v1/discounts/validate?code=SAVE20&subtotal=500
Authorization: Bearer $TOKEN
{
"success": true,
"data": {
"code": "SAVE20",
"discount_type": "percentage",
"discount_value": 20,
"discount_amount": 100,
"final_total": 400,
"description": "20% off your order — Eid Special"
}
}
FieldTypeDescription
codestringThe normalised (uppercased) discount code.
discount_type"percentage" | "flat"How the discount is computed.
discount_valuenumberThe raw value — percentage points or BDT flat amount.
discount_amountnumberComputed reduction for this subtotal, in BDT.
final_totalnumberSubtotal minus discount (never below 0).
descriptionstring | nullAdmin-set description shown to the customer.

Validation errors

HTTPMessageCause
400"Discount code "X" is not valid or has been deactivated."Code doesn’t exist or is_active=false.
400"Discount code "X" is not active yet."Current date is before start_date.
400"Discount code "X" has expired."Current date is after end_date.
400"Discount code "X" has reached its usage limit."used_count ≥ usage_limit.
400"Your subtotal (X BDT) is below the minimum purchase (Y BDT)…"Cart subtotal too low for this code.

Apply at checkout

Add discount_code to POST /api/v1/orders:

POST /api/v1/orders
Authorization: Bearer $TOKEN
Content-Type: application/json
{
"items": [
{ "variant_id": 22406, "quantity": 1 }
],
"payment_method": "bkash",
"discount_code": "SAVE20"
}

The order response now includes:

{
"success": true,
"data": {
"id": 101,
"order_number": "87654321",
"total_amount": 400,
"discount_code": "SAVE20",
"discount_amount": 100,
"status": "INITIATED",
"…": ""
}
}
FieldDescription
total_amountFinal charged amount after discount.
discount_codeThe code that was applied. null if no code used.
discount_amountBDT amount deducted. null if no code used.

Admin management

Discount codes are created and managed via the admin API (/admin/discounts). Each code supports:

PropertyDescription
codeHuman-readable promo code (auto-uppercased, e.g. SAVE20).
discount_type"percentage" or "flat".
discount_valuePercentage points (0–100) or flat BDT amount.
min_purchaseMinimum subtotal required to redeem. Defaults to 0.
max_discountCap for percentage discounts (e.g. max 200 BDT off).
start_date / end_dateOptional validity window.
usage_limitMaximum total redemptions. null = unlimited.
used_countAuto-incremented; read-only from the client side.
is_activeToggle to disable without deleting.