Exploring Commerce Layer gift cards.
Gift cards might not be the flashiest feature on your roadmap, but they’re one of the most versatile tools in a merchant’s toolbox. They bridge the gap between flexibility and intent — offering customers a simple way to give, and merchants a strategic lever to drive growth.
According to Capital One Shopping, the global gift card market was valued at $1.24 trillion in 2024 and is projected to reach $2.31 trillion by 2030, underscoring the scale and sustained growth of the sector. While Adobe doesn’t publish a gift card-specific breakdown, their 2024 holiday report shows that U.S. consumers spent over $222 billion online during the holiday season, with gift cards continuing to play a key role in last-minute purchases. Gift cards aren’t just convenient — they drive results. Industry data suggests that gift card recipients often spend more than the card’s value and exhibit higher conversion rates and lower return rates, making them a valuable tool for customer acquisition and retention (as stated by the Report Pundit on Shopify Gift Card Trends).
For merchants, this means more than just incremental sales. Gift cards can increase average order value, introduce your brand to new customers, and support loyalty and retention programs — all while reducing friction at checkout. When implemented through an API-first, headless platform like Commerce Layer, they become fully customizable, scalable across markets, and easy to integrate into any frontend experience.
In this article, we’ll look at how Commerce Layer helps brands issue, redeem, and manage gift cards with complete flexibility — turning a simple feature into a powerful commerce enabler.
How gift cards work in Commerce Layer
Commerce Layer offers a fully-fledged gift card service that’s deeply integrated with its core order and inventory infrastructure, while remaining flexible enough to support external integrations. Whether you’re launching a new program or connecting an existing gift card system, Commerce Layer allows you to issue, redeem, and manage gift cards across any touchpoint — without compromising on scalability or control.
Core concepts and features
Gift cards are a unique type of payment method: customers can purchase gift cards and use them to pay for an order. But gift cards are way more than this.
A gift card represents a “credit” a customer owns: this means that gift cards can also be used by customer service teams to refund or gift customers in a simple yet effective way.
There are two types of gift cards:
- Rechargeable (digital wallet) — card balance can be used and reloaded at any time.
- Non-rechargeable (standard) – — card balance cannot be reloaded.
Both types can be further split into:
- Single-use — card can only be used once disregarding the balance.
- Multiple-use — card can be reused until balance is positive.
Gift cards can be assigned either to a market or to a currency (in the latter case, it’s essential that the gift card currency aligns with the currency of the active market selected by the customer).
The brand new Gift cards app
The Gift cards app in the Dashboard is the easiest way to visually create and manage gift cards.
Located under the Marketing section in the left sidebar of the Dashboard the Gift cards app opens showing all the currently existing gift cards:
From the app you can create a new gift card and namely:
- Create a code (this will be the unique identifier of the gift card, if not provided it will be automatically generated).
- Assign the gift card to a market or a currency.
- Set the initial balance and the max balance (useful in case of rechargeable gift cards).
- Add an expiration date.
- Set the recipient email (we’ll dig further on this later).
- Add an image (that can be used to display the gift card in the checkout for instance).
- Specify all the configurable options (rechargeability, single usage, behaviour when calculating taxes, etc.).
Once the gift card is created is possible to manage existing gift card using the Gift card app detail view. Here we can see the status, the balance, we can deactivate the gift card end edit it (screenshot of the editing view further below):
The Gift card app is also the go-to place for customer service operators as they can view all the details (including also the card recipient) in one single comprehensive view:
The gift card resource and API endpoint
Commerce Layer is an API-first platform, and gift cards are no exception.
The full API reference is available here.
Using the /api/gift_cards
endpoint, you can create, read, update, and delete a gift_card
resource. Write operations (create, update, and delete) can be executed using an integration token, while read operations will soon be available using a customer token (they're also readable using an integration token).
It's important to note that gift cards can also be used by external systems as long as an integration token is created and used to access the gift card endpoint.
Gift cards are omnichannel by nature, as they can be purchased online and used offline (and vice versa). Commerce Layer supports such use cases by exposing attributes and triggers like:
_balance_change_cents
— to update the balance of a gift card (after in-store usage, for instance).._activate
— to allow in-store activation..balance_cents
— to verify if the card has a positive balance.
This makes our gift card a viable solution even for brands that want to make their gift cards available to affiliates.
Gift card lifecycle
To better understand how gift cards work in Commerce Layer let’s give a look at the lifecycle of a gift card. For each action we’ll highlight details and main concepts and we’ll also share some best practices to make the most out of this great feature.
The diagram below shows the lifecycle of each type of gift card supported by Commerce Layer:
Creation
Gift cards can be created with this command:
cl create gift_card -a balance_cents=10000 rechargeable=false single_use=false currency_code=USD
{
id: 'rnEdUmJpyb',
type: 'gift_cards',
status: 'draft',
code: 'e6cc1eb1-9b0e-4123-8858-836fbed990ec',
currency_code: 'USD',
initial_balance_cents: 10000,
initial_balance_float: 100,
formatted_initial_balance: '$100.00',
balance_cents: 10000,
balance_float: 100,
formatted_balance: '$100.00',
balance_max_cents: null,
balance_max_float: null,
formatted_balance_max: null,
balance_log: [ { datetime: '2025-06-26T10:04:13.410Z', balance_change_cents: 10000 } ],
usage_log: {},
single_use: false,
rechargeable: false,
distribute_discount: true,
image_url: null,
expires_at: null,
recipient_email: null,
created_at: '2025-06-26T10:04:13.410Z',
updated_at: '2025-06-26T10:04:13.410Z',
reference: null,
reference_origin: null,
metadata: {}
}
Successfully created new resource of type gift_cards with id rnEdUmJpyb
This corresponds to the following API call:
curl -g -X POST \
'https://yourdomain.commercelayer.io/api/gift_cards' \
-H 'Accept: application/vnd.api+json' \
-H 'Authorization: Bearer your-access-token' \
-H 'Content-Type: application/vnd.api+json' \
-d '{
"data": {
"type": "gift_cards",
"attributes": {
"currency_code": "USD",
"balance_cents": 10000,
"rechargeable": false,
"single_use": false,
}
}
}'
Gift cards can be created either using a sales channel or an integration token, the former for standard website use, the latter could be a solution if you have a BFF.
Gift cards can be created in advance or on the fly (that is, when the customer wants to purchase one). The first option requires a BFF as you can't list gift cards with a sales channel token. The second is probably the best choice as it's more straightforward.
When you create a gift card, you can assign it to a recipient (i.e. the person that will receive the gift). To do so you can either add the gift_card.recipient_email
attribute when creating the resource or patch the resource once created. The platform will automatically create a gift_card_recipient
object and attach it to the gift card. If the customer email matches an existing customer the gift_card_recipient
will have the relationship with the customer
set.
Setting recipient_email
on the gift_card
resource is actually a shortcut to creating a gift_card_recipient
resource and attaching it to the gift_card
(if you do so you will see that gift_card.recipient_email
will be populated with the email specified in the gift_card_recipient
object).
A separate mention goes to physical gift cards: the best approach in this case is to import batches of gift card codes, along with balance and additional settings using imports. This is also the suggested approach to import third party generated gift cards.
Purchase
There are two scenarios related to gift card purchase whether you are purchasing a digital or a physical gift card.
Purchasing a digital gift card
Purchasing a digital gift card can be done contextually to the creation of the line item of an order. Let’s see the operations involved.
The first step is creating a gift card (if we don’t have pre-generated cards), this can be done as explained in the previous section.
Now that we have our gift card ( rMnaUzZRnX
would be the ID in our case) we have to create a line item for it. So let’s create an order:
~ % cl create order
{
id: 'gojhLRvrLL',
type: 'orders',
number: 84019271,
affiliate_code: null,
...
created_at: '2025-06-26T14:57:23.901Z',
updated_at: '2025-06-26T14:57:23.901Z',
reference: null,
reference_origin: null,
metadata: {}
}
Now let’s create a line item of type gift_cards
and attach it to the order:
~ % cl create line_item -a quantity=1 -r item=gift_cards/rMnaUzZRnX -r order=orders/gojhLRvrLL
{
id: 'nEatKjbKGr',
type: 'line_items',
sku_code: null,
bundle_code: null,
quantity: 1,
_external_price: null,
currency_code: 'USD',
unit_amount_cents: 10000,
unit_amount_float: 100,
formatted_unit_amount: '$100.00',
compare_at_amount_cents: 10000,
compare_at_amount_float: 100,
formatted_compare_at_amount: '$100.00',
options_amount_cents: 0,
options_amount_float: 0,
formatted_options_amount: '$0.00',
discount_cents: 0,
discount_float: 0,
formatted_discount: '$0.00',
total_amount_cents: 10000,
total_amount_float: 100,
formatted_total_amount: '$100.00',
tax_amount_cents: 0,
tax_amount_float: 0,
formatted_tax_amount: '$0.00',
name: 'Gift card: $100.00',
image_url: null,
discount_breakdown: {},
tax_rate: 0,
tax_breakdown: {},
item_type: 'gift_cards',
frequency: null,
coupon_code: null,
rule_outcomes: [],
circuit_state: null,
circuit_failure_count: null,
created_at: '2025-06-30T08:55:00.000Z',
updated_at: '2025-06-30T08:55:00.000Z',
reference: null,
reference_origin: null,
metadata: {},
order: {
id: 'gojhLRvrLL',
type: 'orders',
number: 84019271,
...
circuit_state: null,
circuit_failure_count: null,
created_at: '2025-06-26T14:57:23.901Z',
updated_at: '2025-06-30T08:55:00.012Z',
reference: null,
reference_origin: null,
metadata: {}
},
item: {
id: 'rMnaUzZRnX',
type: 'gift_cards',
status: 'draft',
code: 'f6c6a15b-c0a6-4f4d-b9d3-c2ddcff7fd4f',
currency_code: 'USD',
initial_balance_cents: 10000,
initial_balance_float: 100,
formatted_initial_balance: '$100.00',
balance_cents: 10000,
balance_float: 100,
formatted_balance: '$100.00',
balance_max_cents: null,
balance_max_float: null,
formatted_balance_max: null,
balance_log: [ { datetime: '2025-06-30T08:46:14.023Z', balance_change_cents: 10000 } ],
usage_log: {},
single_use: false,
rechargeable: false,
distribute_discount: true,
image_url: null,
expires_at: null,
recipient_email: null,
created_at: '2025-06-30T08:46:14.023Z',
updated_at: '2025-06-30T08:46:14.023Z',
reference: null,
reference_origin: null,
metadata: {}
}
}
Successfully created new resource of type line_items with id nEatKjbKGr
So let’s review what we’ve done. We created a line_item
resource in the same way we would have added a SKU, with the only difference of setting the item_type
of the line_item
to gift_cards
(this is done implicitly when setting the relationship to the gift_card
resource). No other operation is needed.
Purchasing a physical gift card
Purchasing digital gift cards is a slightly different matter as in this case we need a shipment for the physical card. There’s no out-of-the-box feature for physical gift card, but that’s not an issue, thanks to the flexibility of Commerce Layer we can easily code our way around this.
First of all we should create a sku
for the gift card. The SKU should be mapped to the balance of the actual gift_card
, so we’ll have SKUs matching the combination of balance and currencies (i.e. GIFT_CARD_50_USD
, GIFT_CARD_100_EUR
, and so on).
Here an example showing the sku for a 50 EUR gift card:
~ % cl get skus/nRwRSggKRE -i prices
{
id: 'nRwRSggKRE',
type: 'skus',
code: 'GIFT_CARD_50_USD',
name: 'Commerce Layer GIFT CARD USD 50 ',
description: '',
image_url: '',
pieces_per_pack: null,
weight: null,
unit_of_weight: null,
hs_tariff_number: '',
do_not_ship: false,
do_not_track: false,
inventory: { available: true, quantity: 100, levels: [ { quantity: 100, delivery_lead_times: [] } ] },
created_at: '2025-06-30T09:32:47.556Z',
updated_at: '2025-06-30T09:40:51.856Z',
reference: null,
reference_origin: null,
jwt_custom_claim: null,
metadata: {},
prices: [
{
id: 'NzPUDxeOob',
type: 'prices',
currency_code: 'USD',
sku_code: 'GIFT_CARD_50_USD',
amount_cents: 5000,
amount_float: 50,
formatted_amount: '$50.00',
original_amount_cents: 5000,
formatted_original_amount: '$50.00',
compare_at_amount_cents: 5000,
compare_at_amount_float: 50,
formatted_compare_at_amount: '$50.00',
rule_outcomes: [],
processed_at: '2025-06-30T09:41:33.170Z',
created_at: '2025-06-30T09:35:21.359Z',
updated_at: '2025-06-30T09:35:21.359Z',
reference: null,
reference_origin: null,
rules: {},
resource_payload: {},
jwt_custom_claim: null,
metadata: {}
}
]
}
You can see in the inventory
attribute that we have 100 pieces of the card available: as the gift card has to be batch-printed is very likely that we want to check the stock, otherwise (print on demand) we can simply flag them as “do not track stock”.
Now to purchase the physical card we have to do two things:
- Create
gift_card
resource with amount corresponding to the price of the SKU (skus.prices.amount_cents
). - Create a
line_item
resource with the SKU representing the desired gift card and attach the digital gift card to it.
The first is easily done:
~ % cl create gift_card -a currency_code=USD balance_cents=5000 rechargeable=false single_use=false
{
id: 'lmqEUBqLbP',
type: 'gift_cards',
status: 'draft',
code: '4716e53f-6d78-4068-8a45-913924582c9f',
currency_code: 'USD',
initial_balance_cents: 5000,
initial_balance_float: 50,
formatted_initial_balance: '$50.00',
balance_cents: 5000,
balance_float: 50,
formatted_balance: '$50.00',
balance_max_cents: null,
balance_max_float: null,
formatted_balance_max: null,
balance_log: [ { datetime: '2025-06-30T09:56:54.908Z', balance_change_cents: 5000 } ],
usage_log: {},
single_use: false,
rechargeable: false,
distribute_discount: true,
image_url: null,
expires_at: null,
recipient_email: null,
created_at: '2025-06-30T09:56:54.908Z',
updated_at: '2025-06-30T09:56:54.908Z',
reference: null,
reference_origin: null,
metadata: {}
}
Successfully created new resource of type gift_cards with id lmqEUBqLbP
For the second step let’s create a “standard” line item of type skus
and add as metadata the ID of the gift card previously created:
~ % cl create line_item -a quantity=1 -r item=skus/nRwRSggKRE -r order=orders/gojhLRvrLL -m gift_card_id=lmqEUBqLbP
{
id: 'ZYjteXWWxR',
type: 'line_items',
sku_code: 'GIFT_CARD_50_USD',
...
created_at: '2025-06-30T09:57:44.638Z',
updated_at: '2025-06-30T09:57:44.638Z',
reference: null,
reference_origin: null,
metadata: { gift_card_id: 'lmqEUBqLbP' },
order: {
id: 'gojhLRvrLL',
type: 'orders',
number: 84019271,
...
created_at: '2025-06-26T14:57:23.901Z',
updated_at: '2025-06-30T09:57:44.662Z',
reference: null,
reference_origin: null,
metadata: {}
},
item: {
id: 'nRwRSggKRE',
type: 'skus',
code: 'GIFT_CARD_50_USD',
name: 'Commerce Layer GIFT CARD USD 50 ',
description: '',
image_url: '',
pieces_per_pack: null,
weight: null,
unit_of_weight: null,
hs_tariff_number: '',
do_not_ship: false,
do_not_track: false,
created_at: '2025-06-30T09:32:47.556Z',
updated_at: '2025-06-30T09:40:51.856Z',
reference: null,
reference_origin: null,
jwt_custom_claim: null,
metadata: {}
}
}
Successfully created new resource of type line_items with id ZYjteXWWxR
We now have a shippable gift card associated to a digital gift_card
resource!
Our philosophy is to give you building blocks rather than opinionated solutions and this is just an example (yet quite solid) of how to implement such use case. Another approach could be to rely on imports. In this case the approach would be:
- A batch of gift cards is printed.
- Generated codes, along with gift cards data are imported in Commerce Layer using (imports).
- When a card is added to an order no association is done contextually (just the generic
GIFT_CARD_50_EUR
is added). - During fullfilment, the warehouse operator picks a card form the batch of newly printed cards and adds it to the parcel along with other products.
- When the customer receives the box the gift card is ready to be used as is already imported in Commerce Layer (or can be used offline).
As shown in the state diagram at the beginning of this chapter, whether the gift card is physical or digital, its initial state after purchase is inactive. Let’s take a look at how to activate it — and how it can be used as a payment method.
Activation
Activating a gift card is as easy as going to the Gift cards app of the Dashboard and click the related button:
The above corresponds to hitting the /api/gift_cards
endpoint and patching the card as active or, using the CLI, issuing the command below:
~ % cl update gift_cards/VPyxUYnoPK -a _activate=true
{
id: 'VPyxUYnoPK',
type: 'gift_cards',
status: 'active',
code: '773434e1-d962-452a-a455-665a62daf463',
currency_code: 'USD',
initial_balance_cents: 1000,
initial_balance_float: 10,
formatted_initial_balance: '$10.00',
balance_cents: 10000,
balance_float: 100,
formatted_balance: '$100.00',
balance_max_cents: null,
balance_max_float: null,
formatted_balance_max: null,
balance_log: [
{ datetime: '2025-06-12T10:36:38.754Z', balance_change_cents: 1000 },
],
usage_log: {},
single_use: false,
rechargeable: false,
distribute_discount: true,
image_url: null,
expires_at: null,
recipient_email: null,
created_at: '2025-06-12T10:36:38.754Z',
updated_at: '2025-06-30T10:21:46.154Z',
reference: null,
reference_origin: null,
metadata: {}
}
Successfully updated resource of type gift_cards with id VPyxUYnoPK
This flow is of course pretty simple (and manual). As usual here we leave space to your creativity without forcing any way of activating a gift card, but we still want to give some advice on how a solid activation process could look like.
You can create a webhook for order.place
event and deploy a callback that, upon order placement will:
- Get the line item containing the gift card and extract the
gift_card_id
(depending on how the gift card is being purchased this can be in theline_item
linked resource or stored as a metadata). - Send an email to the customer that informs about the gift card and shows an activation link.
- When the customer clicks on the link, some logic will patch the corresponding
gift_card
resource setting_activate=true
The gift card is now active and can be used to pay for an order.
Redemption
Not much to say indeed on redemption. Once you have an active gift card this can be used as a way to pay for an order, also in combination with a credit card or a wire transfer.
Commerce Layer hosted cart and checkout MFEs natively supports gift cards:
According to the status diagram in the beginning, if the balance is zero and the card is not rechargeable the gift card will enter the redeemed status.
Conclusion
Gift cards may seem like a simple feature on the surface, but Commerce Layer turns them into a flexible and powerful tool for modern commerce. With full API support, market-aware configuration, and a dedicated app for easy management, brands can issue, activate, and redeem gift cards across any channel — physical or digital, online or in-store.
Whether you’re launching a new gift card program or integrating an existing one, Commerce Layer provides the building blocks you need to tailor the experience to your business model. From refunds and customer rewards to promotional gifting and affiliate-ready setups, the possibilities are broad — and entirely under your control.
By thinking of gift cards not just as a payment method but as a strategic asset, you can unlock new value at every stage of the customer journey — while keeping your operations clean, global, and API-first.