Gift Cards API
Create, sell, and redeem digital gift cards.
Overview
GlowScript gift cards provide a flexible way to:
- Sell pre-paid value to clients
- Enable gifting between customers
- Run promotions (sell $100 card for $80)
- Track balances and transaction history
Data Models
Gift Card Template
Templates define purchasable gift card options.
| Field | Type | Description |
|---|---|---|
id | UUID | Unique identifier |
name | String | Display name |
description | String | Optional description |
price | Decimal | Purchase price |
value | Decimal | Card value (can be > price for promos) |
validity_days | Integer | Days until expiration (null = never) |
image_url | String | Card design image |
is_active | Boolean | Available for purchase |
sort_order | Integer | Display order |
Gift Card
A purchased gift card instance.
| Field | Type | Description |
|---|---|---|
id | UUID | Unique identifier |
template_id | UUID | Source template |
code | String | Redemption code (GC-XXXX-XXXX) |
initial_value | Decimal | Original value |
current_balance | Decimal | Remaining balance |
purchased_by_client_id | UUID | Who bought it |
recipient_name | String | Gift recipient name |
recipient_email | String | Recipient email |
recipient_phone | String | Recipient phone |
recipient_message | String | Personal message |
delivery_method | String | How to deliver (email/sms/print) |
delivered_at | DateTime | When delivered |
purchased_at | DateTime | Purchase timestamp |
expires_at | DateTime | Expiration (if applicable) |
is_active | Boolean | Can be redeemed |
Gift Card Transaction
Transaction history for a gift card.
| Field | Type | Description |
|---|---|---|
id | UUID | Unique identifier |
gift_card_id | UUID | Parent gift card |
amount | Decimal | Amount (+purchase, -redemption) |
type | Enum | Transaction type |
balance_after | Decimal | Balance after transaction |
payment_id | UUID | Related payment (if redemption) |
notes | String | Transaction notes |
created_by | UUID | Staff who processed |
created_at | DateTime | Transaction time |
Transaction Types:
purchase— Initial card purchaseredemption— Value used for paymentrefund— Value returned to cardadjustment— Manual balance adjustmentexpiration— Card expired
Templates
Get Templates
import { getGiftCardTemplates } from '@/lib/actions/gift-cards'
const result = await getGiftCardTemplates()
// Include inactive templates
const all = await getGiftCardTemplates(true)Create Template
import { createGiftCardTemplate } from '@/lib/actions/gift-cards'
const result = await createGiftCardTemplate({
name: '$100 Gift Card',
description: 'Perfect for any service',
price: 100.00,
value: 100.00,
validity_days: 365 // optional, null = never expires
})
// Promotional card (sell for less than value)
const promo = await createGiftCardTemplate({
name: 'Holiday Special',
description: 'Buy $80, Get $100!',
price: 80.00,
value: 100.00,
validity_days: 90
})Update Template
import { updateGiftCardTemplate } from '@/lib/actions/gift-cards'
const result = await updateGiftCardTemplate('template-uuid', {
is_active: false // stop selling
})Gift Cards
Get Gift Cards
import { getGiftCards } from '@/lib/actions/gift-cards'
// All active cards
const result = await getGiftCards({ isActive: true })
// Search by code or recipient
const search = await getGiftCards({
search: 'GC-ABC',
limit: 10
})Get Single Gift Card
import { getGiftCard } from '@/lib/actions/gift-cards'
const result = await getGiftCard('gift-card-uuid')
// Includes template, purchaser, redeemer, and transactionsLookup by Code
import { getGiftCardByCode } from '@/lib/actions/gift-cards'
const result = await getGiftCardByCode('GC-ABCD-1234')
if (result.success) {
const card = result.data
console.log(`Balance: $${card.current_balance}`)
if (card.expires_at && new Date(card.expires_at) < new Date()) {
console.log('Card is expired')
}
}Purchase Gift Card
import { purchaseGiftCard } from '@/lib/actions/gift-cards'
// From template
const result = await purchaseGiftCard({
template_id: 'template-uuid',
purchased_by_client_id: 'client-uuid',
recipient_name: 'Jane Doe',
recipient_email: 'jane@example.com',
recipient_message: 'Happy Birthday!',
delivery_method: 'email'
})
// Custom amount (no template)
const custom = await purchaseGiftCard({
custom_value: 250.00,
recipient_name: 'John Smith',
recipient_phone: '+15551234567',
delivery_method: 'sms'
})Response:
{
"success": true,
"data": {
"id": "uuid",
"code": "GC-ABCD-1234",
"initial_value": 100.00,
"current_balance": 100.00,
"expires_at": "2027-02-01T00:00:00Z"
}
}Redemption
Redeem Gift Card
Apply gift card balance to a payment.
import { redeemGiftCard } from '@/lib/actions/gift-cards'
// By card ID
const result = await redeemGiftCard({
gift_card_id: 'card-uuid',
amount: 50.00,
client_id: 'client-uuid',
payment_id: 'payment-uuid',
notes: 'Applied to invoice #1234'
})
// By code (at checkout)
const byCode = await redeemGiftCard({
code: 'GC-ABCD-1234',
amount: 75.00,
client_id: 'client-uuid'
})Response:
{
"success": true,
"data": {
"redeemed": 50.00,
"remaining": 50.00,
"gift_card_id": "uuid"
}
}Error Cases:
{
"success": false,
"error": "Insufficient balance. Available: $25.00"
}
{
"success": false,
"error": "Gift card has expired"
}
{
"success": false,
"error": "Gift card is no longer active"
}Balance Management
Adjust Balance
For refunds, corrections, or manual adjustments.
import { adjustGiftCardBalance } from '@/lib/actions/gift-cards'
// Add value (refund)
const result = await adjustGiftCardBalance({
gift_card_id: 'card-uuid',
amount: 25.00, // positive to add
reason: 'Refund for cancelled appointment'
})
// Remove value (correction)
const correction = await adjustGiftCardBalance({
gift_card_id: 'card-uuid',
amount: -10.00, // negative to subtract
reason: 'Correcting duplicate redemption'
})Deactivate Gift Card
Permanently disable a gift card.
import { deactivateGiftCard } from '@/lib/actions/gift-cards'
const result = await deactivateGiftCard(
'card-uuid',
'Lost card reported by customer' // optional reason
)Transaction History
Get Transactions
import { getGiftCardTransactions } from '@/lib/actions/gift-cards'
const result = await getGiftCardTransactions('card-uuid')Response:
{
"success": true,
"data": [
{
"id": "uuid",
"amount": -50.00,
"type": "redemption",
"balance_after": 50.00,
"notes": "Applied to invoice #1234",
"created_by_profile": { "full_name": "Sarah Staff" },
"created_at": "2026-02-15T14:30:00Z"
},
{
"id": "uuid",
"amount": 100.00,
"type": "purchase",
"balance_after": 100.00,
"created_at": "2026-02-01T10:00:00Z"
}
]
}Checkout Integration
Example: Split Payment with Gift Card
async function processPayment(invoiceTotal: number, giftCardCode: string) {
// 1. Look up gift card
const card = await getGiftCardByCode(giftCardCode)
if (!card.success) {
throw new Error('Invalid gift card code')
}
// 2. Calculate amounts
const giftCardAmount = Math.min(card.data.current_balance, invoiceTotal)
const remainingAmount = invoiceTotal - giftCardAmount
// 3. Redeem gift card
if (giftCardAmount > 0) {
await redeemGiftCard({
code: giftCardCode,
amount: giftCardAmount,
client_id: clientId
})
}
// 4. Charge remaining to credit card
if (remainingAmount > 0) {
await chargeCard(remainingAmount)
}
return { giftCardUsed: giftCardAmount, cardCharged: remainingAmount }
}Best Practices
- Validate before checkout — Check balance and expiration upfront
- Log all transactions — Maintain audit trail
- Send delivery notifications — Email/SMS when purchased as gift
- Set reasonable expiration — 1-2 years is standard
- Track promotion ROI — Compare price vs. value for promos