Loyalty Audit & Correction Workflow
When a member’s points/XP need manual verification (e.g., wrong tier at signup, missed multiplier), use the Payload REST API on prod (https://dungeon.club).
Auth
Use PAYLOAD_API_KEY from .env with header: Authorization: users API-Key <key>
Steps
- Fetch member:
GET /api/members/{id}— note loyaltyPoints, xp, tier, earnMultiplier - Fetch loyalty transactions:
GET /api/loyalty-transactions?where[member][equals]={id}&sort=-createdAt&limit=100 - Fetch purchases:
GET /api/purchases?where[member][equals]={id}&sort=purchasedAt&limit=100 - Fetch check-ins:
GET /api/check-ins?where[member][equals]={id}&sort=-createdAt&limit=100 - Verify each transaction’s math (see formulas below)
- Sum all transaction points and XP — compare against member record totals
- Patch corrections:
- Transaction:
PATCH /api/loyalty-transactions/{id}with correctedxp,metadata - Member:
PATCH /api/members/{id}with correctedxpand/orloyaltyPoints
- Transaction:
Points & XP formulas
| Source | Points | XP |
|---|---|---|
| Purchase | floor(totalMoney × tier.earnMultiplier) | floor(points × buffMultiplier) |
| Check-in | 100 (fixed, no tier multiplier) | floor(100 × buffMultiplier) |
| Event | as awarded (no tier multiplier) | floor(points × buffMultiplier) |
| Backfill | 1x multiplier (pre-membership) | same as points |
Common gotchas
- Buff applies to tier-adjusted points, not raw cents. E.g., $3.00 at 1.5x Bronze = 450 pts. With 3x buff, XP = 1,350 (not 900).
- Backfilled purchases intentionally use 1x — they predate membership.
- Member totals don’t auto-recalculate after editing a transaction — update them manually.
- Transaction metadata goes stale after manual edits — update
earnMultiplier,buffApplied.baseXp,buffApplied.buffedXptoo. - URL brackets need percent-encoding in curl (
[→%5B,]→%5D).