Loyalty

The RSA loyalty system tracks points on an immutable transaction ledger — no UPDATE or DELETE operations are ever performed on loyalty transactions.

Point Operations

OperationAPIEndpoint
Earn points (POS)POS APIPOST /pos/api/v1/loyalty/earn
Redeem points (POS)POS APIPOST /pos/api/v1/loyalty/redeem
Redeem points (self-serve)Shopper APIPOST /api/v1/loyalty/redeem
View balanceShopper APIGET /api/v1/loyalty/balance
View transactionsShopper APIGET /api/v1/loyalty/transactions
View balance (POS)POS APIGET /pos/api/v1/members/{id}/balance

Earn Flow (POS)

When a basket is finalized, call the loyalty earn endpoint:

POST/pos/api/v1/loyalty/earn
{
  "memberId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "basketId": "basket-uuid",
  "referenceId": "pos-txn-id-001",
  "points": 125,
  "storeId": "store-uuid"
}

referenceId is the idempotency key — resubmitting the same referenceId returns the original transaction without double-crediting points.

Redeem Flow (Shopper)

Members redeem points via the Shopper API in their app:

POST/api/v1/loyalty/redeem
{
  "points": 500,
  "referenceId": "app-redemption-uuid"
}

Redemptions are validated against the member's current balance. Insufficient balance returns 422 Unprocessable Entity.

Balance

GET /api/v1/loyalty/balance
Authorization: Bearer SHOPPER_JWT
{
  "points": 1250,
  "tier": "Silver",
  "nextTierPoints": 2500,
  "tierExpiresAt": "2026-12-31T00:00:00Z"
}

Immutability

The loyalty ledger is append-only. Corrections are made via reversal transactions, not updates. This provides a full audit trail for compliance and dispute resolution.

Campaigns

Campaign enrollment can award bonus points on completion. See Offers for campaign-offer relationships.