Gift Cards¶
BadgerCommerce provides a complete gift card system supporting both external providers (Savvy) and a built-in internal provider (Badger), with PIN encryption, virtual gift card fulfillment, and checkout redemption via the PaymentV2 system.
Key Features¶
Gift Card Providers¶
- Badger Internal Provider: Fully internal card creation, balance management, and transaction processing with no external API dependencies
- Savvy External Provider: Integration with the Savvy gift card platform for physical card programs
- Configurable per Site: Switch providers via the
giftCardServicesite config key - Auto-Discovery: Providers register automatically via Spring component scanning — no manual wiring required
Card Management¶
- Registration: Register existing cards by card number + PIN
- Balance Tracking: Real-time balance updates with full transaction history
- Top-Up: Add value to existing cards
- Charge/Refund/Reverse: Full transaction lifecycle support
- User Association: Link cards to customer accounts for easy access
PIN Security¶
- AES-256-GCM Encryption: PINs for Badger-issued cards are encrypted at rest using AES-256-GCM
- Per-Site Encryption Keys: Each site uses its own encryption key, auto-generated on first use
- Backward Compatibility: Legacy plaintext PINs (e.g. Savvy-issued cards) continue to work
- Admin Reveal: SUPERADMIN users can reveal encrypted PINs via a secure AJAX endpoint
Virtual Gift Card Sales¶
- Product Type Decorator: Products marked with the
virtualGiftCarddecorator can be sold as virtual gift cards - Recipient Details: Buyer provides recipient email (required), name (optional), and personal message (optional)
- Automatic Fulfillment: Pipeline processor creates the card and emails delivery details on order completion
- Email Delivery: HTML and plain text email templates with card number, PIN, balance, and personal message
Checkout Redemption¶
- PaymentV2 Integration: Gift cards are a first-class payment method in the PaymentV2 checkout system
- Split Payments: Use a gift card to cover part of an order, with the remainder charged to another payment method (e.g. Stripe)
- Two-Phase Flow: Balance is reserved during authorisation, then confirmed on capture or released on failure
- Real-Time Validation: Card number + PIN verified at checkout with immediate balance display
Multi-Tenancy¶
The gift card system is fully multi-tenant:
Per-Site Isolation¶
- Gift cards are scoped by
siteId - Each site can use a different gift card provider
- Encryption keys are per-site
- Card lookups are always filtered by site
Provider Configuration¶
The active provider is determined by the giftCardService config key:
- "savvyGiftCardService" — Savvy external provider (default)
- "badgerGiftCardService" — Badger internal provider
Technical Implementation¶
Data Model¶
GiftCard (common/.../giftcard/beans/GiftCard.java)
- id: MongoDB document ID
- siteId: Tenant identifier
- cardNumber: Full card number (Badger cards use 6040 prefix + 12 random digits)
- cardBalance: Current balance in minor currency units (e.g. pence)
- currencyCode: ISO currency code
- cardStatus: Card lifecycle status
- pinCode: Legacy plaintext PIN (Savvy cards)
- pinCodeEncrypted: AES-256-GCM encrypted PIN (Badger cards)
- nonce: Security nonce for anonymous card lookups
- transactions: Embedded list of GiftCardTransaction records
Provider Interface¶
GiftCardEventProcessor (common/.../giftcard/service/GiftCardEventProcessor.java)
All providers implement this interface with a unique getServiceName():
| Method | Purpose |
|---|---|
processCreateNew() |
Generate a new card with number, PIN, and initial balance |
processCharge() |
Debit an amount from the card |
processTopUp() |
Credit an amount to the card |
processRefund() |
Refund a previous charge |
processReverse() |
Reverse a recent transaction |
processBalanceCheck() |
Query the current balance |
Providers are auto-discovered via List<GiftCardEventProcessor> autowiring and mapped by service name at startup.
Badger Internal Provider¶
BadgerGiftCardEventProcessorImpl (common/.../giftcard/service/BadgerGiftCardEventProcessorImpl.java)
- Service name:
"badgerGiftCardService" - Generates 16-digit card numbers:
6040prefix + 12SecureRandomdigits - Generates 4-digit zero-padded PINs via
SecureRandom - Encrypts PINs using
GiftCardPinEncryptionServicebefore returning in the response - All operations are local — reads from
GiftCardRepository, returns results for the event listener to persist
PIN Encryption¶
GiftCardPinEncryptionService (common/.../giftcard/service/GiftCardPinEncryptionService.java)
- Algorithm: AES/GCM/NoPadding (AES-256-GCM)
- IV: 12 bytes, randomly generated per encryption
- GCM tag length: 128 bits
- Key: 32-byte AES key from
gift-card-pin-encryption-keysite config (auto-generated on first use) - Output: Base64-encoded (IV + ciphertext)
- PIN verification: decrypt and compare, with fallback to plaintext for legacy cards
Checkout Payment Flow¶
GiftCardPaymentMethodProcessor (common/.../payment/giftcard/GiftCardPaymentMethodProcessor.java)
Extends PaymentMethodProcessor<GiftCardPaymentMethod> for PaymentV2 integration:
- Apply: Customer enters card number + PIN → validates card → reserves balance via
GiftCardService.reserveBalance() - Authorise: Balance already reserved during apply step → returns success
- Capture: Confirms the reservation via
GiftCardService.confirmReservation() - Cancel/Fail: Releases the reservation via
GiftCardService.releaseReservation() - Refund: Credits the amount back to the gift card
The two-phase reserve/confirm pattern ensures balance is held during checkout without permanent deduction until payment is captured.
Virtual Gift Card Fulfillment¶
VirtualGiftCardFulfilmentProcessor (commerce-core/.../pipeline/impl/VirtualGiftCardFulfilmentProcessor.java)
Pipeline processor that runs after order submission:
- Scans order line items for the
virtualGiftCardproduct type decorator - Skips items already fulfilled (have
giftCardIdattribute) - Calls
GiftCardService.createNewGiftCardSync()for each unfulfilled item - Stores the created
giftCardIdon the line item - Sends delivery email to the recipient via
EmailService - Returns
"virtualGiftCardOk"or"virtualGiftCardError"
Must be added to the site's submitOrder pipeline configuration to activate.
VirtualGiftCardAddToBasketExtension (commerce-core/.../extensions/products/VirtualGiftCardAddToBasketExtension.java)
Product page extension that renders recipient input fields. Must be added to virtual gift card product pages via the admin extension manager. Templates available for both bootstrap and nova themes.
Event Processing (Async)¶
GiftCardEventListener (worker/.../giftcards/GiftCardEventListener.java)
RabbitMQ listener that handles asynchronous gift card operations:
- Receives GiftCardMessage from the GIFTCARD_SERVICE_QUEUE
- Dispatches to the configured GiftCardEventProcessor by service name
- Persists results back to MongoDB
- Handles encrypted PIN storage: if pinCodeEncrypted is present in the response, stores the encrypted value and clears the plaintext
Admin Interface¶
Gift Card List (/admin/giftcards)¶
- Shows all gift cards for the site
- Displays: card number (masked), balance, status, currency
Gift Card Detail (/admin/giftcards/card/{id})¶
- Card Details: Full card number, balance, currency, status, expiry
- PIN Display: Masked by default (
****), with "Reveal PIN" button (SUPERADMIN only) - Transaction History: All charges, top-ups, refunds with timestamps and amounts
- Balance Refresh: Request updated balance from the provider
Reveal PIN Endpoint¶
GET /admin/giftcards/card/{id}/reveal-pin- Requires
SUPERADMINrole - Decrypts
pinCodeEncryptedif present, otherwise returns plaintextpinCode - Returns JSON
{ "pin": "1234" }
Configuration¶
| Config Key | Default | Category | Purpose |
|---|---|---|---|
giftCardService |
savvyGiftCardService |
payment-config | Active gift card provider |
gift-card-pin-encryption-key |
Auto-generated | payment-config | AES-256 encryption key for PINs |
Key Classes¶
| Class | Location | Purpose |
|---|---|---|
GiftCard |
common | Gift card entity (MongoDB) |
GiftCardEventProcessor |
common | Provider interface |
BadgerGiftCardEventProcessorImpl |
common | Internal provider |
SavvyGiftCardEventProcessorImpl |
worker | External Savvy provider |
GiftCardService / GiftCardServiceImpl |
common | Business logic and two-phase payments |
GiftCardPinEncryptionService |
common | AES-256-GCM PIN encryption |
GiftCardPaymentMethodProcessor |
common | PaymentV2 checkout integration |
GiftCardPaymentMethod |
common | Payment method data model |
GiftCardEventListener |
worker | Async RabbitMQ event handler |
VirtualGiftCardFulfilmentProcessor |
commerce-core | Order pipeline — card creation + email |
VirtualGiftCardAddToBasketExtension |
commerce-core | Product page recipient fields |
NewGiftCardResult |
common | Sync creation result (card + plaintext PIN) |
GiftCardAdminController |
web-admin | Admin UI + reveal-pin endpoint |
Integration Points¶
The gift card system integrates with: - PaymentV2: Checkout redemption as a first-class payment method - Order Pipeline: Virtual gift card fulfillment on order submission - Email Service: Delivery emails for virtual gift cards - Extension System: Product page UI for recipient details - Admin UI: Card management, balance refresh, PIN reveal - RabbitMQ: Async event processing for balance checks, charges, etc. - Site Configuration: Provider selection, encryption keys