Gift Cards & Store Credit
Overview
Gift Cards & Store Credit adds a gift card product type to WooCommerce. Buying one issues a card with a code, a balance, a recipient and an optional personal message, delivered by email — immediately or on a date the purchaser chooses.
The card is a real ledger, not a coupon: every redemption writes a transaction recording the amount, the balance before and after, and the order it belonged to. Partial redemption leaves the remainder on the card, and the card carries its own currency with the exchange rate locked at issue, so a card bought in one currency keeps its value when spent in another.
The same table also holds store credit — a card of type store_credit, issued by an administrator rather than purchased.
It is for stores selling gift cards and issuing credit against a customer's account.
Availability
| Item | Value |
|---|---|
| Module key | gift_cards |
| Tier | Premium |
| Entitlement key | 🔴 vouchers — not gift_cards |
| Admin tab | gift-cards |
| Enabled option | aiowc_module_enabled_gift_cards (off until turned on) |
| REST namespace | aiowc/v1 |
| Product type | gift_card |
The entitlement key is vouchers, not the module key. A licence that grants vouchers unlocks this module; a licence naming gift_cards does not. That is worth knowing when reading a licence payload or debugging why the module will not enable.
registerHooks() performs no licence check of its own; the module registry applies the entitlement gate centrally before calling it.
Settings
This module has no DEFAULTS constant. Its settings are read and written through GET/PUT /gift-cards/settings and stored by the module's own settings handling rather than declared as a constant in the module class.
The card
| Field | Meaning |
|---|---|
code | The redemption code, generated by the module. |
type | purchased by default, or store_credit for a card an administrator issued. |
status | active and the other lifecycle states. |
initial_balance, current_balance | What it was worth and what is left, to four decimal places. |
currency_code, locked_exchange_rate | The card's own currency and the rate fixed at issue. |
purchaser_*, recipient_* | Who bought it and who it is for, by user id and email. |
personal_message, sender_name | What the purchaser wrote. |
delivery_date, delivered_at | When it should be sent, and when it was. |
expires_at, reminder_sent_at | When it lapses, and whether the customer has been warned. |
is_transferable | Whether the recipient may pass it on. On by default — except for store credit, which is never transferable. |
is_physical | Whether the card is a physical article rather than an email. |
template_id | The voucher design used for its PDF. |
Redeeming
A customer applies a code at the cart or checkout. Partial redemption is supported: spending less than the balance leaves the remainder, and each movement writes a transaction row carrying the balance before and after, so the ledger reconstructs itself.
Refunds are handled too — the module hooks woocommerce_order_refunded and woocommerce_create_refund, so a refunded order can return value to the card rather than stranding it.
Vouchers, PDFs and QR codes
A card can be rendered as a PDF voucher from a stored design. PDF generation uses Dompdf, which ships with the plugin; TCPDF is used instead when a site happens to have it.
The QR code on the voucher is generated by whichever library is available, in order: chillerlan/php-qrcode, then endroid/qr-code, and if neither is installed it falls back to a Google Charts image URL.
🔴 Neither QR library ships with the plugin, so on a default installation the fallback is what runs. Two consequences follow, and both matter:
- The voucher's QR image is loaded from a third-party Google endpoint, and the redemption URL — which contains the gift card code — is placed in that request's query string. Anyone treating a gift card code as a bearer token should account for that.
- That endpoint is Google's legacy Image Charts service. A store that needs the QR code to be dependable should install one of the two QR libraries, which makes the module generate the image locally.
Multi-currency
The module carries its own currency service and reads the store's currency configuration through the aiowc_get_enabled_currencies and aiowc_get_exchange_rate filters — the same filters Multi-Currency provides. A card records its currency and the rate locked at issue, and a transaction records the original amount and currency alongside the converted one.
Admin screen
The Gift Cards tab lists the cards and issues, edits and deletes them, adjusts a balance, resends a card, and inspects a card's transactions. It also manages voucher templates with a preview, shows statistics across all cards, and carries a diagnostics endpoint for checking the module's own configuration on a given store.
REST API endpoints
All routes are on aiowc/v1 and answer with the { success, data, message } envelope.
Administrator routes — manage_woocommerce
| Method | Path | Purpose |
|---|---|---|
| GET / POST | /gift-cards | List cards; issue one (amount, recipient_email). |
| GET | /gift-cards/{id} | One card. |
| PATCH / PUT /POST | /gift-cards/{id} | Update a card. |
| DELETE | /gift-cards/{id} | Delete a card. |
| POST | /gift-cards/{id}/adjust | Change a balance (amount). |
| POST | /gift-cards/{id}/resend | Send the card again. |
| GET | /gift-cards/{id}/transactions | That card's ledger. |
| GET | /gift-cards/statistics | Totals across all cards. |
| GET | /gift-cards/diagnostics | The module's own health detail. |
| GET / PATCH / PUT / POST | /gift-cards/settings | Read and write the settings. |
| GET / POST | /gift-cards/templates | List and create voucher designs. |
| GET / PATCH / PUT / POST / DELETE | /gift-cards/templates/{id} | Manage one design. |
| GET | /gift-cards/templates/{id}/preview | Render a design for review. |
| GET | /store-credit/customer/{user_id} | A customer's store credit. |
| POST | /store-credit/issue | Issue store credit (user_id, amount). |
Customer routes
| Method | Path | Purpose | Permission |
|---|---|---|---|
| GET | /public/gift-cards/check | Check a code's balance (code). | Public, rate-limited |
| POST | /public/gift-cards/apply | Apply a code to the cart (code). | Nonce, rate-limited |
| DELETE | /public/gift-cards/remove | Remove an applied code (code). | Nonce, rate-limited |
| GET | /public/gift-cards/applied | What is applied to this cart. | Public, rate-limited |
| GET | /public/gift-cards/my-cards | The signed-in customer's cards. | Signed-in user |
| POST | /public/gift-cards/transfer | Pass a card to someone else. | Signed-in user |
Transfer requires a signed-in customer, which is what ties a transfer to an accountable identity.
WooCommerce integration
| Area | Hooks |
|---|---|
| Product type | product_type_selector, woocommerce_product_class, woocommerce_product_data_tabs / _panels, woocommerce_product_options_general_product_data, woocommerce_process_product_meta_gift_card |
| Cart | woocommerce_add_cart_item_data, _get_cart_item_from_session, _get_item_data, _add_to_cart_validation, _after_cart_item_quantity_update, _cart_item_removed, _cart_emptied |
| Totals | woocommerce_before_calculate_totals, _cart_calculate_fees, _cart_totals_before_order_total, _review_order_before_order_total |
| Coupons | woocommerce_applied_coupon, _removed_coupon, _cart_coupon |
| Order | woocommerce_checkout_create_order_line_item, _order_status_processing, _order_status_completed — issuing the card once the order is paid |
| Refunds | woocommerce_create_refund, woocommerce_order_refunded |
| Account | woocommerce_account_menu_items, woocommerce_account_dashboard, and the module's own account endpoint |
| Order display | woocommerce_order_details_after_order_table, woocommerce_admin_order_totals_after_total |
| AJAX | wp_ajax_aiowc_apply_gift_card / _remove_gift_card, and the nopriv pair for signed-out customers |
The module also registers email automation triggers through aiowc_ea_register_triggers, so gift card events can drive the Email Automation module's sequences.
Database schema
| Table | Holds |
|---|---|
{prefix}aiowc_gift_cards | The cards, including store credit, with balances, currency, recipient, delivery and expiry. |
{prefix}aiowc_gift_card_transactions | Every movement: type, amount, balance before and after, currency and the original amount, the order, a related card for a transfer, and a note. |
{prefix}aiowc_gift_card_templates | Voucher designs: name, slug, whether it is the default, the design configuration as JSON, a preview URL. |
These names are this module's. The separate Gift Cards & Vouchers module keeps its own under a gc_ prefix, so the two never share a row.
Background jobs
| Hook | Interval | Work |
|---|---|---|
aiowc_gc_scheduled_delivery | every 15 minutes | Sends cards whose delivery date has arrived. |
aiowc_gc_expiration_check | daily, midnight | Expires cards past their date. |
aiowc_gc_expiration_reminder | daily, 9am | Warns customers whose card is about to lapse. |
aiowc_gc_log_cleanup | weekly | Prunes old log rows. |
All four run on WP-Cron at deliberately chosen times, rather than at whatever time the module happened to be enabled.
Action hooks for integrators
This module has the largest integrator surface in the plugin. The lifecycle events are aiowc_gift_card_created, _delivered, _redeemed, _expiring, _expired, _transferred, _applied_to_cart, _removed_from_cart, _balance_adjusted, _code_generated, and aiowc_store_credit_issued.
The filters are aiowc_gift_card_validation, _pdf_template, _email, _delivery_email, _reminder_email, _redemption_base_url, plus aiowc_get_enabled_currencies and aiowc_get_exchange_rate for currency, and aiowc_ea_fire_trigger for email automation.
Entitlement limits
The vouchers entitlement is an on/off grant with no cap on the number of cards, transactions or templates. The amount limits are store settings.
Health check
The module reports a warning when its tables are missing or WooCommerce is inactive, and otherwise reports that it is functioning normally. The /gift-cards/diagnostics route gives more detail than the health check alone.
Known gaps
- The QR code fallback calls a third-party Google endpoint with the redemption URL in the query string, because no QR library ships with the plugin. Install
chillerlan/php-qrcodeorendroid/qr-codeto generate the image locally. - The entitlement key is
voucherswhile the module key isgift_cards, which is a genuine trap when reading a licence or wiring an integration. - Store credit exists in three unrelated places across the plugin: here as a card of type
store_credit, in the Store Credit module's own ledger, and again in Smart Coupons Advanced, whose table name differs from Store Credit's only by a plural. Nothing reconciles them, so a store should decide which one it is using. - Settings are not declared as defaults on the module, so there is no single place in the code that states what the module's settings are and what they default to.