> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brand-wallet.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Transaction Payload

> Construct a single JSON payload for BrandWallet transactions: campaigns, coupon redemptions, and point spend in one call.

**The BrandWallet API uses a single standard payload structure for all transactions. Whether a customer has a stamp card, a point card, or a multi-tier program, the same body shape on [POST /v1/transactions/process](/api/process-transaction) handles them all.**

A single payload can do any combination of the following in one call:

* **Campaign collection** — applicable campaigns on the selected `card` run; balances update and reward coupons are granted when thresholds are reached.
* **Coupon redemption** — coupons passed in `redeem.coupons` are redeemed; a product coupon can carry the product it was used for (`productOpaqueId`), which is recorded and excluded from earning.
* **Point spend** — `redeem.points` is deducted from the card's point balance; the monetary value is calculated server-side and reflected in the response's `payableAmount`.
* **Order discounts** — `apply_discount` promotions configured by the brand (for example a student discount) reduce the amount to charge; the total comes back in `discountAmount` and is already deducted from `payableAmount`.

Example payload:

```json theme={null}
{
  "customer": "3d8ec956-de2a-4d43-9c1e-74475b153362",
  "card": "41dd8263-288e-4b55-bf2e-6a82995a0441",
  "items": [
    {
      "id": "4221450",
      "name": "Americano",
      "quantity": 4,
      "amount": 140,
      "productPrice": 150
    }
  ],
  "amount": 550,
  "orderId": "ORD-2026-000123",
  "redeem": {
    "coupons": [
      { "id": "906550fd-dcf5-4aed-a80e-03e8939fc2b4", "productOpaqueId": "4221450" }
    ],
    "points": 120
  }
}
```

### Key concepts

* A transaction payload represents a single basket — construct and submit one payload per customer interaction.
* Product, category, user, and branch ids are **opaque ids**, your external system identifiers; BrandWallet resolves them internally. `user` and `branch` default to the authenticated API user and its branch when omitted.
* **`amount` is the single money truth**: the register total with all of your own discounts (commercial + coupon) already deducted; BrandWallet-applied deductions (promotion discounts, points) not deducted — they come back in the response (`discountAmount`, `redeemed.pointsValue`) and are already reflected in `payableAmount`. Never send a discounted amount from a previous response back as `amount`.
* `items[].amount` is the line unit amount and `items[].productPrice` is the product's list price — the latter is used only by [menu sync](/api/process-transaction#menu-synchronization-lazy-sync) to keep your catalog current; neither enters payment math.
* `orderId` is your idempotency key: a completed transaction with the same `orderId` is rejected with `duplicate_transaction`, making retries safe.
* Required fields: `customer` (from [GET /v1/customers/find](/api/find-customer)), `card` (card id from `find` → `cards[].id`, not a campaign id — the campaigns run come from this card), and `amount`. Full field reference: [POST /v1/transactions/process](/api/process-transaction).

### Payload flow

1. **Identify the customer** — call [GET /v1/customers/find](/api/find-customer) with the customer's phone, email, or card barcode. Save the returned `id` (customer id) and `cards[].id` (customerpass id).
2. **Preview the discount (optional)** — call [POST /v1/transactions/validate](/api/validate-transaction) with the basket and `redeem.points` before committing.
3. **Commit the basket** — call [POST /v1/transactions/process](/api/process-transaction) with the same body, optionally echoing the previewed `payableAmount` as `expectedPayableAmount` for a server-side consistency check. BrandWallet returns the updated loyalty state in `executedActions`, the amount to charge in `payableAmount`, and what was redeemed in `redeemed`.

> Use BrandWallet as the single source of truth for all loyalty data. Do not cache points, stamps, or coupon balances locally — fetch fresh state before each transaction.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.