Gift cards in Shop Rentals are simple: issue a card with a balance, share the code with the recipient, redeem against any reservation in your shop. Everything is ledger-tracked for accounting integrity.
Where to find it
/dashboard/shop-rentals/gift-cards
Issuing a gift card
Click + Issue gift card:
- Amount (USD) — initial balance, e.g., $50
- Recipient name (optional) — for your records and the gift card message
- Recipient email (optional) — for sending the code via email
- Message (optional) — gift message included on any printed certificate
- Custom code (optional) — most shops let the system auto-generate
a code like
GC-1A2B-3C4D-5E6F
Click Save. The card appears in the table with status "Active" and balance equal to the initial amount.
A gift card transaction is automatically logged:
gift_card_transactions row:
amount_cents: +5000 ← initial issuance (positive = balance loaded)
description: "Initial issuance"
Sharing the code
Click the code in the table to copy. Share via:
- Email the customer — paste the code in your email reply
- Print on a gift certificate — generate a PDF or use a template with the code visible
- Verbal pickup at the counter — for in-shop gifts
The code is case-insensitive for redemption — most shops uppercase it for legibility.
Redeeming at checkout
The walk-in wizard and public booking flow don't yet have a built-in "Apply gift card" field — gift card redemption is currently API-driven.
To redeem programmatically:
POST /api/shop-rentals/gift-cards/[code]/redeem
{
"reservationUuid": "...",
"amountCents": 2500
}
Response:
{
"ok": true,
"gift_card_balance_cents": 2500,
"reservation_balance_due_cents": 0,
"reservation_amount_paid_cents": 5000
}
This:
- Verifies the gift card is active and has sufficient balance
- Verifies the reservation belongs to your subaccount
- Inserts a
gift_card_transactionsrow with negative amount = redemption - Decrements
gift_cards.current_balance_cents - Increments
reservations.amount_paid_centsby the redemption - Recomputes
balance_due_cents
The reservation now shows the customer paid via gift card; the gift card's remaining balance is reduced.
A "Redeem gift card" button on the booking detail page is on the roadmap.
Partial redemption
Gift cards support partial redemption. A $50 card used for a $20 booking leaves $30 on the card. The customer can use the remaining balance on a future booking.
Track this via:
SELECT code, initial_balance_cents, current_balance_cents
FROM gift_cards
WHERE current_balance_cents > 0;
Refunds back to a gift card
If you refund a reservation that was paid (in part) by a gift card, you can credit the gift card balance back. Currently this is manual:
UPDATE gift_cards
SET current_balance_cents = current_balance_cents + 2500
WHERE id = '<gift-card-id>';
INSERT INTO gift_card_transactions (gift_card_id, amount_cents, description)
VALUES ('<gift-card-id>', 2500, 'Refund from cancelled reservation');
A native "refund to gift card" destination on the refund modal is on the roadmap.
Expiration
By default, gift cards don't expire. To set an expiration:
UPDATE gift_cards
SET expires_at = '2027-12-31'
WHERE id = '<gift-card-id>';
The redeem endpoint checks expires_at < now() and rejects expired
cards. Most US states have minimum legal validity periods (typically
5+ years) — set expirations carefully and disclose at issuance.
Status states
| Status | Meaning |
|---|---|
| Active | Card is usable, has balance |
| Used | Balance is $0 — fully redeemed |
| Inactive | Manually deactivated; can't be redeemed even with balance |
To deactivate a card (e.g., reported lost):
UPDATE gift_cards
SET is_active = false
WHERE id = '<gift-card-id>';
The customer can no longer redeem, even if there's a balance left. To re-activate, set back to true.
Reporting
SELECT
date_trunc('month', purchased_at) AS month,
count(*) AS cards_issued,
sum(initial_balance_cents) / 100.0 AS revenue_loaded,
sum(initial_balance_cents - current_balance_cents) / 100.0 AS redeemed
FROM gift_cards
WHERE subaccount_id = '<your-subaccount-id>'
GROUP BY 1
ORDER BY 1 DESC;
Gift cards are excellent revenue — money loaded today, redeemed over weeks/months. The gap between "loaded" and "redeemed" is your active gift card liability — important for accounting.
Liability accounting
Gift card liability is the unredeemed balance — money you've collected but haven't delivered service for yet. Treat as a liability on your books until redemption.
The gift_card_transactions ledger gives you a clean audit trail:
- Positive amount = liability incurred (issuance) or refund-to-card
- Negative amount = liability discharged (redemption)
- Sum across all transactions for a card = current balance
This matches GAAP-friendly gift card accounting.
Common scenarios
Customer lost the gift card code
Look up by recipient email or name in the gift cards table. Re-share the code. No re-issuance needed.
Customer wants to combine two gift cards on one reservation
Redeem each separately:
POST /api/shop-rentals/gift-cards/CODE1/redeem
{ "reservationUuid": "...", "amountCents": 2000 }
POST /api/shop-rentals/gift-cards/CODE2/redeem
{ "reservationUuid": "...", "amountCents": 1500 }
Both transactions land on the same reservation; the customer pays the remaining balance (if any) via card.
Bulk issuance for a corporate gift program
Run a script that calls the issue endpoint N times. Or insert directly via SQL with custom codes. The endpoint is idempotency-safe via custom codes — calling with the same code twice errors instead of double-issuing.
Gift card resale / chargeback
If a gift card is purchased fraudulently and the original card is charged back, deactivate the gift card immediately and adjust the recipient's customer record if they've redeemed any of it. This should be exceedingly rare.