CRM · Customer loyalty — cards & stamps
Shows the customer’s loyalty cards per campaign with their stamp counts, and lets staff manually add stamps or exchange a completed card.
| Area | CRM |
| Routes | crm.users.edit |
| Centre modules | loyalty-cards |
| Staff levels | root · admin · manager · crmmanager · crmoperator · weboperator |
| Models | campaign · loyalty-card · ticket |
| UI label | ticket.loyalty-card |
| Coverage | 3 use cases · 2 happy · 3 failure |
How it works
createStamps is guarded by validateStampNumber(amount, campaign), which refuses an amount larger than the campaign’s stamp quota. createStampsModalCampaigns narrows the picker to campaigns that can still take stamps. exchangeStamps consumes a completed card. Unredeemed stamps are surfaced separately (loyalty-cards.unredeemed-stamps).
Use cases
Why someone opens this (3)
- Compensating a customer whose stamp was not registered at the till.
- Redeeming a completed card for its reward at the desk.
- Explaining to a customer how many stamps they still need.
Path map
flowchart LR F(["Customer loyalty — cards and stamps"]):::feat F --> H1["Stamps granted manually"]:::ok F --> H2["Completed card exchanged"]:::ok F -.-> X1["Too many stamps requested"]:::bad F -.-> X2["Card generation fails"]:::bad F -.-> X3["Exchange fails"]:::bad classDef feat fill:#157068,stroke:#157068,color:#ffffff,font-weight:bold classDef ok fill:#e3f1ea,stroke:#0d6b42,color:#0d4a2e classDef bad fill:#f7e6e2,stroke:#9a2d1c,color:#6e1f13
Happy paths
Stamps granted manually
- Operator opens the loyalty-cards step and selects a campaign.
- Opens the create-stamps modal and enters an amount within the campaign’s quota.
validateStampNumberpasses and the stamps are created.loyalty-cards.generate-success-messageconfirms and the card’s count updates.
Completed card exchanged
- Operator opens the exchange-stamps modal for a full card.
- Confirms; the stamps are consumed and the card moves to its exchanged state.
Failure paths
Too many stamps requested
Cause — Amount exceeds the campaign’s stamp quantity.
What happens —
loyalty-cards.error-stamp-number(‘Number of stamps is greater than the quantity of stamps in the campaign’); nothing is created.
Card generation fails
Cause — API error while creating cards/stamps.
What happens —
loyalty-cards.generate-error-messagestates explicitly that nothing was created and to contact support.
Exchange fails
Cause — API error or already-exchanged card.
What happens — Caught in
try/catch; the modal closes without a specific message.
QA checklist
Tick these off while regression-testing this feature. The boxes are plain Markdown, so progress is visible in git diffs.
- ✅ Stamps granted manually
- ✅ Completed card exchanged
- ⛔ Too many stamps requested
- ⛔ Card generation fails
- ⛔ Exchange fails
Implementation
Translation keys (8)
Key English ticket.loyalty-cardLoyalty Card loyalty-cardsLoyalty Cards loyalty-card.campaignActivity loyalty-card.stamps.valueValue loyalty-cards.unredeemed-stampsUnredeemed stamps loyalty-cards.generate-success-messageThe loyalty cards has been generated correctly. loyalty-cards.generate-error-messageThere was a problem when generating the loyalty cards and they haven’t been created. Please, contact with the support team. loyalty-cards.error-stamp-numberNumber of stamps is greater than the quantity of stamps in the campaign
Related
- Same area — Customer list & filtering · Customer create & edit · Customer deletion with unsubscribe notice · Customer CSV export with column picker · Customer CSV import · Children CSV import · AI natural-language customer filter · Save current filters as a segment · Segment list, refresh & export · Segment builder with automatic tag actions · Segment categories · User tags (user types) · Customer receipts tab & ticket-stamp generation · Customer loyalty — raffle tickets · Customer loyalty — rewards · Customer loyalty — coupon exchanges · Customer children (dependants) · Receipt verification queue · Store list, filters & exports · Store create & edit · Store CSV import · Store labels (store types) · Customer action log (dormant)
- Shares data with — Activity editor (loyalty mechanics, rules & targeting) · Activity list & duplication · Activity report & PDF · Activity campaigns (programme grouping) · Proposal editor (content, coupon, push, AI images) · Push notification editor (scheduling, geofencing, deep links) · App button manager (MOFs)
- Behind the same module — Customer receipts tab & ticket-stamp generation · Activity editor (loyalty mechanics, rules & targeting)
Generated from doc/feature-inventory.json · id crm-customer-loyalty-cards · commit 276788ca6