Birthday Offers
Birthday Offers lets managers design automated rewards — a discount, gift voucher, loyalty points, or a free item — that apply automatically around a customer's birthday, with control over the valid window, minimum purchase and reminder settings.
Overview
Each offer is one of four types — Discount, Gift Voucher, Loyalty Points, or Free Item — and only the fields relevant to that type appear in the form; switching type before saving cleans up the unused fields automatically.
Offers can be scoped at Company (applies to every branch), Unit, or Branch level; once an offer is created, its scope level is locked and cannot be changed by editing it.
An offer has its own validity window measured in days before and after the customer's birthday, an optional minimum purchase requirement, an auto-apply switch for checkout, and an optional reminder that fires a set number of days ahead.
Before You Start
- Birthday Offers is a manager/admin-only page — staff without manager rights will not see it in the sidebar at all.
- It requires the
loyaltyfeature at the Advanced plan tier or above. - Free Item offers need at least one product on file, since the free-product picker is populated from your product list.
Step-by-Step Guide
1 Create a new birthday offer
- Click Add Offer in the top-right of the page.
- Enter an Offer Name (required) and an optional Description.
- Choose a Scope Level: Company (all branches), Unit, or Branch — this cannot be changed once the offer is saved.
- Pick an Offer Type: Discount, Gift Voucher, Loyalty Points, or Free Item — the form below adjusts to show only the fields that type needs.
- Fill in the type-specific fields (see field reference below), set the validity window and any minimum purchase amount, then click Create.
2 Configure a Discount offer
- With Offer Type set to Discount, choose Discount Type: Percentage or Fixed Amount.
- Enter the Discount Value (required, e.g. 10 for 10% or a fixed currency amount).
- If Discount Type is Percentage, optionally set a Maximum Discount Amount to cap how much the percentage can ever be worth on a large bill.
3 Configure Gift Voucher, Loyalty Points or Free Item offers
- For Gift Voucher, enter the Voucher Amount the customer receives.
- For Loyalty Points, enter the number of Loyalty Points to award.
- For Free Item, select the Free Product from the dropdown — this list is populated from your first 100 products.
4 Set the validity window, reminders and priority
- Set Days Before Birthday and Days After Birthday to define the window in which the offer is valid and can be applied (defaults to 7 and 7).
- Optionally set a Minimum Purchase Amount the bill must reach before the offer applies.
- Toggle Automatically apply during checkout (Auto-apply) if you want the offer applied without staff having to select it manually.
- Toggle Send birthday reminder and, if enabled, set Send reminder days before to control how far ahead of the birthday the reminder is generated.
- Set a Priority number — when a customer qualifies for more than one active offer, the higher-priority offer is applied first.
- Toggle Active off to temporarily disable an offer without deleting it, then click Create or Save.
5 Edit or remove an offer
- Click the edit (pencil) icon on any offer card to reopen it in the same form, pre-filled — the Scope Level buttons are disabled while editing since scope cannot be changed after creation.
- Click the delete (trash) icon and confirm the prompt to permanently remove an offer.
Every Field & Button, Explained
| Field / Button | What it does |
|---|---|
Add Offer | Opens the create form. |
Offer Name * | Required label shown on the offer card and used to identify it. |
Description | Optional free-text note about the offer. |
Scope Level (Company / Unit / Branch) | Where the offer applies; locked after creation. |
Offer Type (Discount / Gift Voucher / Loyalty Points / Free Item) | Determines which value fields appear below. |
Discount Type & Discount Value | Percentage or Fixed Amount, and the amount/percentage taken off. |
Maximum Discount Amount | Optional cap on a Percentage discount's currency value. |
Loyalty Points | Points awarded for a Loyalty Points-type offer. |
Voucher Amount | Currency value of a Gift Voucher-type offer. |
Free Product | Product given away for a Free Item-type offer, chosen from your product list. |
Days Before Birthday / Days After Birthday | The window (in days) around the birthday during which the offer is valid. |
Minimum Purchase Amount | Bill total that must be reached before the offer can apply. |
Auto-apply | Applies the offer automatically at checkout instead of requiring manual selection. |
Send birthday reminder / Send reminder days before | Enables an automatic reminder a set number of days ahead of the birthday. |
Active | Toggles whether the offer is currently usable, without deleting it. |
Priority | Resolves which offer wins when a customer qualifies for more than one (higher number applies first). |
Edit / Delete icons | Modify or permanently remove an existing offer. |
Tips & Best Practices
- Use Priority to make sure your best birthday offer (not necessarily the first one you created) is the one customers actually get when several qualify.
- Cap Percentage discounts with Maximum Discount Amount if you sell high-ticket items, so a birthday discount cannot unexpectedly wipe out margin on a big sale.
- Turn off Auto-apply for offers you want staff to explain and offer manually (e.g. a Free Item) rather than have silently applied at billing.
Troubleshooting & FAQ
Why can't I find Birthday Offers in the sidebar?
I can't change an offer's Scope Level after creating it.
The Free Product dropdown is empty.
Two birthday offers seem to conflict for the same customer.
🧑💻 Developer Notes
Source component(s):
frontend-app/packages/pos-react-lib/src/pages/BirthdayOffersPage.jsx
Backend endpoints used:
GET /birthday-offersGET /productsPOST /birthday-offersPUT /birthday-offers/:idDELETE /birthday-offers/:id
Related tables (db-core repositories):
BirthdayOfferProduct
Redux slices:
scope (selectCurrentScope / getScopeQueryParams)
Feature flag key: loyalty (requires advanced plan tier or above)
The form strips out fields irrelevant to the chosen offerType before submitting (e.g. discountType/discountValue are deleted from the payload for non-Discount offers), so the API never receives stale values from a previously selected offer type. Scope level is derived read-only from which of storeId/businessUnitId is present on the offer record (getOfferLevel), not stored as its own explicit "level" column.