MekanteMekante Developers
Getting started
Till API
Webhooks
llms.txt
  • Türkçe
  • English
Getting started
Till API
Webhooks
llms.txt
  • Türkçe
  • English
  • Getting started

    • Mekante Developers
    • Getting started
    • Authentication
  • Till API

    • Till flow
    • Endpoints
    • Errors
    • Limits
  • Webhooks

    • Webhooks
    • Signature verification

Till flow

The customer opens their loyalty card in the Mekante Wallet app on their phone and presents a QR code. Your POS reads that code and follows the steps below.

Scan QR ──► POST /scan ──► (preview points) ──► POST /earn      award points/stamps
                       └──────────────────────► POST /redeem    redeem reward

Earning points or stamps

  1. Scan the QR code. The QR payload is an opaque token string. Send it to POST /scan. The response includes scanId and member details (name, masked phone, balances, tier) that you can display on the cashier screen.
  2. Preview (optional). Call POST /earn/preview to calculate how many points and stamps a purchase amount will award without writing to the ledger.
  3. Commit the earn. Call POST /earn with scanId and the purchase amount (or stamp count). The Idempotency-Key header is required.

Redeeming a reward

There are two ways to redeem a reward:

  1. Cashier chooses. Scan the customer's standard QR code with POST /scan. The response's rewards array lists all rewards the member can (or cannot, with reason and missing) redeem. After the cashier picks one, send scanId and the chosen rewardId to POST /redeem.
  2. Customer chooses. The customer selects a reward in the Wallet app and generates a dedicated redeem QR code for that reward. Scan it with POST /scan: the response has intent: "redeem" and populates reward. You do not need to pass rewardId to POST /redeem; if you do, it must match the scanned reward (400 REWARD_MISMATCH).

The response returns a 6-character confirmation code. The customer receives an instant push notification that their reward was redeemed, and the cashier/API key is recorded on the ledger entry. A cashier or API key can redeem at most the daily limit configured by the business (429 CASHIER_DAILY_LIMIT).

Important rules

QR codes expire after 30 seconds. An expired code returns 400 QR_EXPIRED. Ask the customer to refresh their screen.

Each QR code can only be scanned once. A second scan returns 409 QR_ALREADY_USED. This prevents replay via screenshots or photos.

A scan is valid for 5 minutes. After POST /scan succeeds, you have 5 minutes to call POST /earn or POST /redeem with that scanId. Once consumed or expired, it returns 409 SCAN_INVALID and you must scan a fresh QR code. If your POS UI reloads, you can re-fetch an active scan with GET /scans/:id.

Amounts are integer kuruş. 15000 = 150 TL. Decimal, zero, or negative values are rejected. The hard ceiling is 100000000 kuruş; the business's own per-transaction limit is usually lower (Limits).

Idempotency-Key: never double-count a sale

If the network drops mid-request, you won't know whether the server committed the transaction. Retrying the same request with the same Idempotency-Key guarantees points are not awarded twice; the server replays the original response with "replayed": true.

  • Generate one key per sale and tie it to the sale (for example from the receipt ID: pos-2026-000123).
  • Must be between 8 and 100 characters long.
  • Reusing the same key for a different operation or payload returns 409 DUPLICATE_REQUEST.
  • Passing receiptNo adds a second layer of protection: the same receipt number cannot be recorded twice (409 DUPLICATE_RECEIPT).
First request  → 201 Created      "replayed": false
Retry          → 200 OK           "replayed": true  (same entry, no duplicate points)

Voiding a mistaken entry

POST /ledger/:id/void reverses an earn or redeem ledger entry. Because an API key operates with cashier privileges, it can only void its own entries and only within 15 minutes of creation. If earned points have already been spent in the meantime, the entry cannot be voided (409 POINTS_ALREADY_SPENT).

Next
Endpoints