Home / Help Center / pos-app / Sell / Billing / Gift Cards
🎁 Sell / Billing

Gift Cards

Gift Cards lets you sell prepaid store credit as physical or digital gift cards — issue a card with a starting balance and optional expiry, track its remaining balance, top it up any time, and let customers redeem it against future purchases at billing.

📍 Menu path: Sell / Billing → Gift Cards
👤 Who uses it: All Billing-access roles can view gift cards; issuing a new card and topping up a balance require Create/Edit permission on this page

Overview

Every gift card is a code (auto-generated or one you type yourself) tied to a starting balance and, optionally, an expiry date and a linked customer.

A card's status is calculated automatically from three things: whether it is switched Active, whether today's date is past its expiry date, and whether its balance has been spent down to zero — that gives you Active, Expired, Used Up or Inactive.

The stats row at the top of the page rolls up three numbers so you always know your exposure: Total Issued, Active, and Total Value — the combined remaining balance of every card that is active, not expired, and still has money on it.

Before You Start

Step-by-Step Guide

1 Issue a new gift card

  1. Click Issue Gift Card in the top-right of the page (only visible if you have Create permission).
  2. Enter the starting Amount — this is required and must be a positive number; the form blocks submission with "Amount must be positive" if you leave it blank or enter zero/negative.
  3. Optionally type a Code (e.g. GIFT-2025); leave it blank to let the system generate one. Whatever you type is automatically uppercased and trimmed before saving.
  4. Optionally set an Expires On date, and optionally pick a Customer from the dropdown to link the card to their profile.
  5. Click the submit button (reads "Issue Gift Card", or "Saving…" while in flight) — the modal closes and the new card appears at the top of the list, sorted by Issued On (newest first) by default.
💡 If the code you typed is already in use, or any other validation fails on the server, the exact error message from the server is shown in a toast instead of a generic failure.

2 Top up an existing card's balance

  1. Find the card in the table or grid view and click Top Up — this only appears on cards that are still Active, and only for users with Edit permission.
  2. An inline amount box appears under the card's action row; type a positive top-up amount.
  3. Click Save to add the amount to the card's balance — a success toast shows the new balance, or click the ✕ to cancel without saving.
  4. The card list refreshes automatically after a successful top-up.
💡 Top-up amounts must be greater than zero — the form shows "Enter a positive amount" otherwise.

3 Look up, search and export cards

  1. Use the search box ("Search code or customer...") to filter the list by gift card code or the linked customer's name.
  2. Click any column header (Code, Balance/Initial, Customer, Expires, Issued On) to sort — Issued On sorts newest-first by default.
  3. Switch between table and card/grid layouts using the view toggle in the data grid toolbar.
  4. Click Export to download the current list (respecting your search/sort) — the export includes Code, Balance/Initial, Customer, Expires, Status and Issued On.
  5. Click the copy icon next to any code to copy it to the clipboard for quick sharing with a customer.

Every Field & Button, Explained

Field / ButtonWhat it does
Issue Gift CardOpens the modal to create a new prepaid card; only visible with Create permission.
Amount *Starting balance for the card; required, must be a positive number.
CodeOptional custom code; auto-uppercased and trimmed, left blank to auto-generate one.
Expires OnOptional expiry date; past-dated cards are automatically shown as Expired regardless of remaining balance.
CustomerOptional link to an existing customer record, chosen from a searchable dropdown of up to 500 customers.
Top UpPer-card action (Active cards only, Edit permission required) that opens an inline amount box to add funds to the balance.
Copy iconCopies the gift card's code to the clipboard.
Status badgeActive (green), Used Up (yellow — balance reached zero), Expired (red — past Expires On), or Inactive (grey — manually deactivated).
Total Issued / Active / Total ValueHeader stats — count of all cards, count of usable cards, and combined remaining balance of usable cards.
Search boxFilters the list by gift card code or customer name.

Tips & Best Practices

Troubleshooting & FAQ

Why can't I see the Issue Gift Card button?
That button only renders for users with Create permission on the Gift Cards page. Ask your Admin to grant it under Settings → Staff Permissions.
A card shows as Expired even though it still has balance.
Status is calculated purely from the Expires On date versus today — once that date has passed, the card is marked Expired regardless of remaining balance, and can no longer be topped up or redeemed.
Why is Gift Cards missing from my sidebar entirely?
Gift Cards requires the Advanced plan tier or above. Check your current plan under Settings → Billing/Subscription, or ask an Admin to upgrade.
I issued a card with a duplicate code — what happens?
The server rejects the request and the exact validation error is shown in a toast (e.g. code already in use); try again with a different code or leave it blank to auto-generate.

🧑‍💻 Developer Notes

Source component(s):

  • frontend-app/packages/pos-react-lib/src/pages/GiftCardsPage.jsx

Backend endpoints used:

  • GET /giftcards
  • GET /customers
  • POST /giftcards
  • POST /giftcards/:id/topup

Related tables (db-core repositories):

  • GiftCard
  • Customer

Redux slices:

  • scope (selectCurrentScope / getScopeQueryParams)

Feature flag key: gift_cards (requires advanced plan tier or above)

Status (Active/Expired/Used Up/Inactive) is derived client-side from isActive, expiresAt and balance rather than stored as its own column. The customer dropdown loads a flat GET /customers?limit=500 rather than paginating, so very large customer bases only show the first 500 in the picker.