Stored-value gift cards, points/rewards loyalty, and “membership” as
loyalty tiers + customer CRM — not a third separate product.
All of it ties into POS tenders and (for loyalty earn) finalize + customer on the cart.
Points program: earn rules, redeem as tender, accounts per customer.
Membership
Not a separate app. UI language for loyalty tiers + being a known customer (CRM). Tier thresholds/perks live under Programs → Loyalty → Tiers.
Membership (how to think about it)
There is no standalone /membership product module
“Members” are customers with a LoyaltyAccount (and optionally a tier name).
Tiers are configured in admin as membership levels (points or spend thresholds, benefits JSON).
Seat/visit theater “member knows their seat” is CRM + loyalty + future visit object — see DocHub 15 identity.
Then finalize like any other tender → Core Invoicing
Mobile POS — no gift card tender UI yet (parity gap; see DocHub 14)
Loyalty
Program configuration (admin)
UI path
Config area
/admin/programs/loyalty · settings
Program on/off, core settings
…/loyalty/rules
Accrual basis, include tax/tip, caps
…/loyalty/earning
Points per dollar / earning rules
…/loyalty/redemption
How points convert to cents, min/step
…/loyalty/tiers
Membership tiers — thresholds & perks
Admin API of record for UI: /api/admin/programs/loyalty and section routes
/loyalty/tiers, /loyalty/earning, /loyalty/rules, /loyalty/redemption, /loyalty/settings
(stored on LoyaltyProgram + metadata JSON).
Accounts & events
LoyaltyAccount — points balance, lifetime, tierName, link to customerId
LoyaltyEvent / POS-written events — earn/redeem history
loyaltyPoints.service.js — calculatePointsEarned, processTransactionLoyalty on finalize
POS integration (money path)
flowchart TD
A[Attach customer on cart] --> B{Tender?}
B -->|Gift code| C[tender/giftcard debit gift_cards balance]
B -->|Loyalty points| D[tender/loyalty debit LoyaltyAccount points]
B -->|Cash/card/crypto| E[other tenders]
C --> F[payments[] on cart]
D --> F
E --> F
F --> G[finalize]
G --> H[Core Invoicing]
G --> I[processTransactionLoyalty earn if customerId + program]
Step
API
Requires
Redeem gift card
POST …/tender/giftcard { code, amountCents? }
Active card, balance
Redeem points
POST …/tender/loyalty { points, … }
Customer + active loyalty account
Earn points
Inside finalize after invoice
customerId on cart; program enabled
Identity link
Loyalty earn/redeem are weak without a customer on the cart.
Gift cards can work anonymously by code; optional customerId on issue for CRM.
Admin Programs hub
/admin/programs — FeatureGate currently keyed on gift_cards for the shell (loyalty pages live under the same layout).
Plan module
In planFeatures
gift_cards
Premium / Enterprise (category premium)
loyalty
Premium / Enterprise
Note: BASIC plan in config may not list them; verify live tenant plan flags before demos.
API map (what’s mounted)
Mount
Role
Notes
/api/admin/programs
Admin gift + loyalty config, batches, check-balance, liability helpers