Pay via BARS
BARS are prepaid barcode vouchers. A platform accepts them at checkout by calling this API from its server: validate a code, deduct an amount, and release the goods. It's code-based, not redirect-based — no bouncing the customer to a gateway.
The recommended flow is two calls:
- 1
POST /v1/verify— is the code valid and in scope? Returns the balance. No money moves. - 2
POST /v1/redeem— atomically deducts the amount and returns the new balance + a rotated remaining code. Success → release the goods.
reverse refunds, and a redemptions/{id} lookup reconciles a lost response. All amounts are in major units (e.g. PKR 5000, not paisa).
Environments & keys
Two isolated environments. The key you use decides which one you touch.
| Env | Base URL | Secret key prefix |
|---|---|---|
| Live | https://api.bars.credit | bars-live-… |
| Sandbox | https://sbx-api.bars.credit | bars-test-… |
merchants.bars.credit.Authentication
Every call carries your secret key as a bearer token. Keep it server-side — never ship it to a browser or app. Your publishable key (bars-live-pub-…) is the only one safe for clients, and it only identifies you.
Authorization: Bearer bars-live-3f9c…
Signing & idempotency
Money-moving calls (redeem, reverse) additionally require an HMAC signature and a mandatory idempotency key.
Idempotency-Key— a unique id per logical payment. Retrying with the same key replays the original result instead of charging twice.X-BARS-Timestamp— unix seconds. Rejected if more than 5 minutes off (replay guard).X-BARS-Signature—HMAC-SHA256(signing_secret, "{timestamp}.{raw_body}"), hex. Sign the exact bytes you send.
X-BARS-Timestamp: 1737480000 X-BARS-Signature: 9a1f… // hex(hmac_sha256(secret, timestamp + "." + rawBody)) Idempotency-Key: 3b1e2a70-…
Verify
Advisory — checks validity/scope and returns the balance. No deduction.
POST https://api.bars.credit/v1/verify
Authorization: Bearer bars-live-…
Content-Type: application/json
{ "code": "BARS-7F3K-9QP2-4M1X-8ZQ0", "currency": "PKR" }200 OK
{
"valid": true,
"livemode": true,
"tier": "gold",
"currency": "PKR",
"balance": 5000,
"face_value": 5000,
"state": "full",
"expires_at": null
}Redeem
Atomic, signed, idempotent. Deducts amount and returns the new balance. On a partial spend the presented code is burned and the leftover rides a new remaining_code (code rotation); null when fully spent. An optional pin is required for PIN-protected bars.
POST https://api.bars.credit/v1/redeem
Authorization: Bearer bars-live-…
Idempotency-Key: 3b1e2a70-…
X-BARS-Timestamp: 1737480000
X-BARS-Signature: 9a1f…
Content-Type: application/json
{ "code": "BARS-7F3K-9QP2-4M1X-8ZQ0", "amount": 1200,
"currency": "PKR", "merchant_reference": "order_123" }200 OK
{
"status": "success",
"livemode": true,
"redeemed": 1200,
"remaining_balance": 3800,
"remaining_code": "BARS-Z8YD-07D6-K3PN-1AA2",
"txn_id": "b7e0…",
"replayed": false
}Reverse (refund)
Credits an amount of a redemption back onto a fresh code. Signed + idempotent. Guards: only the redeeming merchant, only up to what was redeemed.
POST https://api.bars.credit/v1/reverse
Authorization: Bearer bars-live-…
Idempotency-Key: c4d2…
X-BARS-Timestamp: 1737480500
X-BARS-Signature: 51ab…
{ "txn_id": "b7e0…", "amount": 1200 }200 OK
{ "status": "reversed", "livemode": true,
"credited": 1200, "code": "BARS-4KQ9-2M7P-…", "replayed": false }Redemption status
Reconcile a redemption whose response you lost. Scoped to your account + mode.
GET https://api.bars.credit/v1/redemptions/b7e0… Authorization: Bearer bars-live-…
200 OK
{ "txn_id": "b7e0…", "status": "success", "livemode": true,
"redeemed": 1200, "remaining_balance": 3800,
"remaining_code": "BARS-Z8YD-…", "created_at": "2026-07-26T14:00:00.000Z" }Sandbox testing
With a bars-test- key against sbx-api.bars.credit, mint a throwaway bar and run the exact same verify / redeem / reverse flow — no real value at stake.
POST https://sbx-api.bars.credit/v1/test/bars
Authorization: Bearer bars-test-…
{ "amount": 500, "currency": "PKR", "tier": "open" }200 OK
{ "code": "BARS-TEST-…", "tier": "gold", "currency": "PKR",
"amount": 500, "livemode": false }Error codes
| HTTP | error | Meaning |
|---|---|---|
| 401 | unauthorized | Missing or invalid secret key. |
| 401 | signature_missing / signature_mismatch | HMAC signature absent or wrong. |
| 400 | idempotency_key_required | Money-moving call without an Idempotency-Key. |
| 404 | invalid_code | No such bar in this mode/scope. |
| 410 | expired | The bar has passed its expiry. |
| 403 | wrong_merchant / gold_not_accepted | Bar not accepted by this merchant. |
| 402 | insufficient_funds | Amount exceeds the balance. |
| 422 | below_minimum | Remainder would fall below the currency minimum. |
| 401 | pin_required | Bar is PIN-protected; supply pin. |
| 403 | invalid_pin | Wrong PIN. |
| 404 | redemption_not_found | No such txn for this account/mode. |
| 422 | exceeds_redeemed | Reverse amount exceeds what was redeemed. |
| 429 | rate_limited | Too many requests (120/min per IP). |