Get Started with Aeion Gift Cards
Set up your stored-value engine in 5 steps. Purchase flow, PIN verification, split-payment redemption, auto-reload triggers, and bulk promotional generation — all at 0% transaction fees, included natively in Aeion OS.
Issue Your First Gift Card (Purchase Flow)
Go to Commerce → Gift Cards → Issue Gift Card or use the API.
Purchase Gift Card (API):
bash
POST /giftcards/purchase
{
"amount": 50.00,
"currency": "USD",
"quantity": 1,
"senderName": "John Smith",
"senderEmail": "john@example.com",
"recipientName": "Jane Doe",
"recipientEmail": "jane@example.com",
"personalMessage": "Happy birthday! Enjoy the coffee.",
"deliveryMethod": "email",
"expirationMonths": 12
}
Response:
typescript
{
"cards": [
{
"id": "gc-xxx",
"code": "GC-9G4F-X2P1-MQRB",
"amount": 50.00,
"formattedAmount": "$50.00",
"currency": "USD",
"expiresAt": "2027-05-11T00:00:00Z"
}
],
"totalAmount": 50.00,
"formattedTotal": "$50.00",
"status": "pending_payment",
"message": "Complete payment to activate gift cards"
}
Code Format: A short prefix followed by grouped alphanumeric characters, e.g. GC-9G4F-X2P1-MQRB
PIN: 4-digit numeric, AES-256-GCM encrypted at rest
Status: pending → after payment → active
Generate Bulk Codes (API):
bash
POST /giftcards/bulk-generate
{
"quantity": 1000,
"amount": 5.00,
"currency": "USD",
"batchPrefix": "PR",
"source": "holiday_promo_2026",
"templateId": "template-xxx",
"expirationMonths": 1
}
Response:
typescript
{
"batchId": "batch_01HV3M7K9X...",
"quantity": 1000,
"amount": 5.00,
"totalValue": 5000.00,
"cards": [
{ "id": "gc-xxx", "code": "PR-9G4F-X2P1-MQRB" },
{ "id": "gc-yyy", "code": "PR-N7K2-H5W8-TXLC" }
// ... 998 more
]
}
Promotional Prefix: PR for bulk promo codes, GC for standard, SC for store credit wallets
Activate After Payment
After payment is confirmed, activate the gift card.
Activate (API):
bash
POST /giftcards/{cardId}/activate
{
"paymentTransactionId": "txn_stripe_xxx",
"orderId": "order-xxx"
}
Response:
typescript
{
"status": "active",
"code": "GC-9G4F-X2P1-MQRB"
}
Activation Process:
- Status transitions from
pendingtoactive - An activation timestamp is recorded
- An activation transaction is logged with a unique idempotency key
- A delivery event fires for scheduled or immediate recipient notification
Scheduled Delivery:
bash
POST /giftcards/purchase
{
"amount": 75.00,
"recipientEmail": "jane@example.com",
"deliveryMethod": "email",
"scheduledDelivery": "2026-06-15T09:00:00Z" // Birthday gift
}
A background job engine processes scheduled deliveries automatically once the scheduled time arrives.
Check Balance & Redeem (Split Payment)
| Scenario | Card Balance | Order Total | Charged | Remaining |
|---|---|---|---|---|
| Full coverage | $100 | $80 | $80 | $0 |
| Partial | $30 | $100 | $30 | $70 → Stripe |
| Overpay | $150 | $100 | $100 | $0, card = $50 |
| Exact | $100 | $100 | $100 | $0 |
Reload & Transfer
Reload Balance (API):
bash
POST /giftcards/reload
{
"code": "GC-9G4F-X2P1-MQRB",
"pin": "1234",
"amount": 25.00,
"paymentMethodId": "pm_stripe_xxx"
}
Response:
typescript
{
"previousBalance": 20.00,
"addedAmount": 25.00,
"newBalance": 45.00,
"formattedBalance": "$45.00"
}
Concurrency-Safe: Reloads are applied atomically, with checks that block canceled/expired/non-reloadable cards and enforce any configured maximum balance cap. A confirmed final balance is always returned, even under concurrent requests.
Auto-Reload Configuration:
typescript
// Configure on card record
{
"autoReloadEnabled": true,
"autoReloadAmount": 25.00, // Reload $25
"autoReloadThreshold": 10.00, // Trigger when balance ≤ $10
"autoReloadPaymentMethodId": "pm_xxx"
}
Triggered automatically when the card balance drops to or below the configured threshold — the balance is topped up and a transaction is logged.
Transfer to Another Person (API):
bash
POST /giftcards/transfer
{
"code": "GC-9G4F-X2P1-MQRB",
"pin": "1234",
"recipientEmail": "bob@example.com",
"recipientName": "Bob Smith",
"message": "Here's a gift card for you!"
}
Response:
typescript
{
"message": "Gift card transferred to bob@example.com",
"newCode": "GC-N7K2-H5W8-TXLC",
"balance": 45.00
}
Transfer Process:
- Old code (
GC-9G4F-X2P1-MQRB) invalidated - New code (
GC-N7K2-H5W8-TXLC) generated for recipient - Transaction logged with sender/recipient details
- Email sent to new recipient with new code and balance
Issue Store Credit & Review Analytics
Issue Store Credit (API):
bash
POST /giftcards/issue-store-credit
{
"customerId": "user-xxx",
"amount": 75.00,
"currency": "USD",
"reason": "Return - Item not as described",
"orderId": "order-return-xxx",
"notes": "Ticket #8492 - Customer Support Resolution"
}
Response:
typescript
{
"data": {
"wallet": {
"id": "gc-yyy",
"code": "SC-N7K2-H5W8-TXLC",
"balance": 75.00,
"currency": "USD"
}
}
}
Wallet Behavior:
- If customer already has a store-credit wallet → increment existing balance atomically
- If no wallet → create new one with prefix
SC - Transaction logged with reason and originating order for audit purposes
Review Analytics (Admin):
bash
GET /giftcards/analytics
Response:
typescript
{
"stats": {
"totalCards": 5420,
"activeCards": 3100,
"emptyCards": 1200,
"expiredCards": 120,
"totalIssued": 270000.00,
"totalRedeemed": 189000.00,
"outstandingBalance": 81000.00,
"averageCardValue": 49.82,
"formattedTotalIssued": "$270,000.00",
"formattedTotalRedeemed": "$189,000.00",
"formattedOutstandingBalance": "$81,000.00",
"redemptionRate": 70
},
"recentTransactions": [...]
}
Redemption Rate: total redeemed ÷ total issued × 100
Liability Report:
- Outstanding Balance = total unredeemed value (liability)
- Purchase type (digital / promotional / store credit) distinguishes liability from breakage for CFO reporting
Transaction History (API):
bash
GET /giftcards/{cardId}/transactions?limit=50&offset=0
Response:
typescript
{
"transactions": [
{ "type": "purchase", "amount": 50.00, "balanceAfter": 50.00, "createdAt": "2026-05-01T10:00:00Z" },
{ "type": "redemption", "amount": -30.00, "balanceAfter": 20.00, "createdAt": "2026-05-05T14:30:00Z" },
{ "type": "reload", "amount": 25.00, "balanceAfter": 45.00, "createdAt": "2026-05-10T09:00:00Z" }
]
}
Quick Reference
Purchase API:
```bash # Buy gift card(s) POST /giftcards/purchase
# Bulk generate promo codes (admin) POST /giftcards/bulk-generate
# Activate after payment POST /giftcards/{id}/activate ```
Redemption API:
```bash # Check balance POST /giftcards/balance?code=XXX&pin=XXX
# Redeem (split payment) POST /giftcards/redeem { "code": "GC-XXX", "pin": "1234", "amount": 100.00, "orderId": "xxx" }
# Reload balance POST /giftcards/reload { "code": "GC-XXX", "pin": "1234", "amount": 25.00 } ```
Wallet API:
```bash # Issue store credit (refund to wallet) POST /giftcards/issue-store-credit
# Claim unlinked card to account POST /giftcards/claim
# Get my linked cards GET /giftcards/my-cards ```
Transfer API:
bash
# Transfer to another person
POST /giftcards/transfer
{ "code": "GC-XXX", "pin": "1234", "recipientEmail": "bob@example.com" }
Analytics API:
```bash # Admin dashboard GET /giftcards/analytics
# Transaction history GET /giftcards/{id}/transactions
# History by code POST /giftcards/history { "code": "GC-XXX", "pin": "1234" } ```
Admin API:
```bash # Manual balance adjustment POST /giftcards/adjust { "code": "GC-XXX", "amount": -5.00, "reason": "Fraud refund" }
# Disable/cancel card POST /giftcards/{id}/disable { "reason": "Suspected fraud" }
# Get templates GET /giftcards/templates?category=seasonal&featured=true ```
Event Subscriptions:
```bash # Scheduled delivery — runs automatically once the scheduled time arrives
# Expiration check — runs daily (7-day warning + auto-expire)
# Auto-reload trigger — fires automatically on low balance, logs a reload transaction ```
FAQ
`POST /giftcards/redeem` returns `{ chargedAmount, remainingOrderAmount, isPartial }`. If a card has $30 and the order is $100, `chargedAmount = 30`, `remainingOrderAmount = 70`. Stripe/Adyen charges the remainder. A unique idempotency key prevents double-redemption on retry.
Balance changes (reloads, redemptions, auto-reload) are applied atomically with built-in guardrails — for example, a reload only applies while the card is reloadable and not canceled or expired. If two requests race, one succeeds and the other returns a clear conflict response instead of corrupting the balance.
PINs are AES-256-GCM encrypted before storage and verified against the encrypted value — the plaintext PIN is never stored or logged.
`POST /giftcards/purchase` with a `scheduledDelivery` timestamp. A background job engine delivers the card automatically once that time arrives and emits a delivery event.
Runs daily. (1) 7-day warning: notifies cards where `expiresAt` is within 7 days, status `active`, no prior reminder sent. (2) Auto-expire: sets `status: "expired"` for cards past `expiresAt`.
When the balance drops to or below the configured threshold, the balance is topped up automatically by the configured reload amount and a transaction is logged. Configure via `autoReloadEnabled`, `autoReloadAmount`, `autoReloadThreshold`.
A short prefix followed by grouped alphanumeric characters drawn from a set that avoids ambiguous characters (no `0`/`O`, `1`/`I`/`L`). Example: `GC-9G4F-X2P1-MQRB`, `SC-N7K2-H5W8-TXLC`, `PR-HJKM-8RX2-PQWT`.
Store credit wallets are tracked as their own purchase type, separate from purchased or promotional cards, and use the `SC` prefix. This distinction is critical for CFO liability reporting (promotional credits ≠ financial liability).
Old code invalidated, new code generated for recipient. Transaction logged with sender/recipient metadata. An event fires for delivery email.
`purchase`, `activation`, `redemption`, `partial_redemption`, `reload`, `transfer_in`, `transfer_out`, `adjustment`, `refund`, `void`, `expiration`, `cancellation`, `issuance`. Each carries its own unique idempotency key.
`POST /giftcards/claim` links an unclaimed card (no linked customer) to the authenticated user's account. This is concurrency-safe — if two requests try to claim the same card, only one succeeds.
`pending` (awaiting payment), `active` (usable), `empty` (balance = 0), `expired` (past expiration date), `disabled` (admin action), `canceled`.
`POST /giftcards/bulk-generate` (admin only) generates the requested quantity of cards in a single batch, each tagged with a shared batch ID. Cards default to `purchaseType: "promotional"` and `status: "active"`.
Native platform feature. No transaction fees are added or deducted. Balance deducted = amount requested. Card balance = balance before - redemption amount.
`POST /giftcards/adjust` (admin only) applies an atomic increment/decrement and logs the adjustment with the performing admin, reason, and notes. Balance cannot go negative.