Skip to content

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 giftCardService site 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 virtualGiftCard decorator 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: 6040 prefix + 12 SecureRandom digits
  • Generates 4-digit zero-padded PINs via SecureRandom
  • Encrypts PINs using GiftCardPinEncryptionService before 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-key site 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:

  1. Apply: Customer enters card number + PIN → validates card → reserves balance via GiftCardService.reserveBalance()
  2. Authorise: Balance already reserved during apply step → returns success
  3. Capture: Confirms the reservation via GiftCardService.confirmReservation()
  4. Cancel/Fail: Releases the reservation via GiftCardService.releaseReservation()
  5. 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:

  1. Scans order line items for the virtualGiftCard product type decorator
  2. Skips items already fulfilled (have giftCardId attribute)
  3. Calls GiftCardService.createNewGiftCardSync() for each unfulfilled item
  4. Stores the created giftCardId on the line item
  5. Sends delivery email to the recipient via EmailService
  6. 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 SUPERADMIN role
  • Decrypts pinCodeEncrypted if present, otherwise returns plaintext pinCode
  • 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