17 — Gift Cards
CEO Summary
Gift cards are a revenue driver and customer retention tool. Create, activate, reload, redeem. Used as POS tender. Business value: Upfront cash, repeat visits. Key metrics: Outstanding liability, redemption rate, batch utilization. If this breaks: POS cannot accept gift card payments; customers cannot redeem.
Architecture
Overview
Gift cards are stored-value instruments. Customers purchase, reload, or receive them; they redeem at POS. All amounts in cents.
- Base path: /api/giftcards, /api/gift-card-management
- Auth: requireSessionAuth, tenantResolver
- Feature gate: checkFeatureAccess('gift_cards')
File Structure
backend/
├── routes/
│ ├── giftcards.routes.js # Public API: create, balance, redeem, reload
│ ├── giftCard.routes.js # Alternate routes
│ ├── giftCardManagement.routes.js # Admin: batches, CRUD
│ └── admin.programs.routes.js # Admin programs (gift card overlap)
├── services/
│ ├── giftCard.service.js
│ └── giftCardManagement.service.js
├── models/
│ ├── giftCardTxn.model.js
│ ├── giftCardTransaction.model.js
│ └── (gift_cards table in tenant DB)
└── jobs/
└── giftcards.expirer.js # Expire cards past expiresAt
API Endpoints
| Method | Path | Purpose |
|---|---|---|
| POST | /api/giftcards | Create gift card (initialValueCents, code, activate, customerId, expiresAt, mode, reloadable, batchId) |
| GET | /api/giftcards/:id | Get by ID |
| GET | /api/giftcards/code/:code | Lookup by code |
| POST | /api/giftcards/:id/reload | Reload (add value) |
| POST | /api/giftcards/:id/redeem | Redeem (deduct) |
| POST | /api/giftcards/balance | Check balance by code |
| POST | /api/pos/carts/:id/tender/giftcard | POS tender: apply gift card payment |
Database Schema
Table: gift_cards (tenant main DB)
| Column | Purpose |
|---|---|
| id | UUID |
| orgId | Organization |
| code | Human-readable code (e.g. XXXX-XXXX-XXXX-XXXX) |
| mode | retail |
| reloadable | true/false |
| status | active, inactive, expired |
| initialValueCents | Original value |
| balanceCents | Current balance |
| currency | USD |
| batchId | Optional batch |
| customerId | Optional customer |
| activatedAt | Activation timestamp |
| expiresAt | Expiration |
Gift Card Lifecycle
- Create — POST /api/giftcards with initialValueCents, code (or auto-gen), activate
- Activate — Set activatedAt on create
- Reload — POST /api/giftcards/:id/reload (add value)
- Redeem — POST /api/giftcards/:id/redeem or POS tender
- Expire — giftcards.expirer job marks cards past expiresAt
POS Integration
POS tender: gift card payment. Route: POST /api/pos/carts/:id/tender/giftcard. Deducts balance, adds to cart payments. See 06 — POS & Invoicing.
Batches
giftCardManagement.routes — Create batches, bulk issue. GiftCardBatches table. Used for reporting and liability.
Audit
giftCard.service creates AuditEvent for giftcard.issue, giftcard.reload, giftcard.redeem. See 20 — Audit.
Integration Points
| System | Connection |
|---|---|
| POS | Tender type: giftcard |
| Payments | Payment hub — giftcard in availableMethods |
| Audit | AuditEvent for issue/reload/redeem |
| Admin Liability | admin.liability.routes — gift card liability |
Key Paths
| Path | Purpose |
|---|---|
backend/routes/giftcards.routes.js | Main gift card API |
backend/services/giftCard.service.js | Business logic |
backend/jobs/giftcards.expirer.js | Expiration job |