Skip to content
Saleor
Esc
↑↓navigate↵open⌘Jpreview
On this page

Gift Cards

Gift cards in Saleor are digital codes that customers can redeem during checkout to reduce the total order amount. In Saleor, they can be created by staff or purchased directly at checkout.

Gift cards are not assigned to any channel and can be used in any channel whose currency matches the gift card’s currency.

Creating and Managing Gift Cards

Staff users with the MANAGE_GIFT_CARD permission can create gift cards directly in Saleor and send them to customers. Gift cards can be created individually or in bulk, and can have an expiry date set or be non-expiring.

Creating Gift Cards

Single Gift Card Creation

The following example shows how to create a single gift card. Once you provide the userEmail and configure the email plugin for the given channel, the gift card is sent to the customer, and the SENT_TO_CUSTOMER event is created. In this example, providing the expiryDate value will set the expiry date. If you want to create a non-expiring card, do not provide the expiryDate value.

mutation giftCardCreate($input: GiftCardCreateInput!) {
  giftCardCreate(input: $input) {
    giftCard {
      id
      code
      last4CodeChars
      isActive
      expiryDate
      initialBalance {
        currency
        amount
      }
      currentBalance {
        currency
        amount
      }
      events {
        type
      }
    }
  }
}
{
  "input": {
    "balance": {
      "amount": 100,
      "currency": "USD"
    },
    "userEmail": "test@example.com",
    "channel": "channel-USD",
    "expiryDate": "2050-10-10",
    "isActive": true
  }
}
{
  "data": {
    "giftCardCreate": {
      "giftCard": {
        "id": "R2lmdENhcmQ6MjQ1",
        "code": "0A65-0A28-1347",
        "last4CodeChars": "1347",
        "isActive": true,
        "expiryDate": "2050-10-10",
        "initialBalance": {
          "currency": "USD",
          "amount": 100
        },
        "currentBalance": {
          "currency": "USD",
          "amount": 100
        },
        "events": [
          {
            "type": "ISSUED"
          }
        ]
      }
    }
  }
}

Bulk Gift Card Creation

Creating gift cards in bulk is similar, but you need to specify the number of gift cards to create and the tag value which will be assigned to all created gift cards.

mutation giftCardBulkCreate($input: GiftCardBulkCreateInput!) {
  giftCardBulkCreate(input: $input) {
    giftCards {
      id
      code
      isActive
    }
  }
}
{
  "input": {
    "count": 5,
    "tags": ["example-tag"],
    "isActive": true,
    "balance": {
      "amount": 200,
      "currency": "USD"
    }
  }
}
{
  "data": {
    "giftCardBulkCreate": {
      "giftCards": [
        {
          "id": "R2lmdENhcmQ6MjQ2",
          "code": "F5A2-81C9-E289",
          "isActive": true
        },
        {
          "id": "R2lmdENhcmQ6MjQ3",
          "code": "FA61-39FC-03DE",
          "isActive": true
        },
        {
          "id": "R2lmdENhcmQ6MjQ4",
          "code": "0A7B-2E6F-06A8",
          "isActive": true
        },
        {
          "id": "R2lmdENhcmQ6MjQ5",
          "code": "F7C9-7479-8AE6",
          "isActive": true
        },
        {
          "id": "R2lmdENhcmQ6MjUw",
          "code": "60C5-10B9-DF19",
          "isActive": true
        }
      ]
    }
  }
}

After creation, you can export the gift card codes to CSV. Read more about exporting gift cards.

Managing Gift Cards

Resending Gift Cards

You can resend the gift card to the customer at any time after creation. If the userEmail is not provided, the card is sent to the customer who already used the card. If the card hasn’t been used yet, it is sent to the customer who created it.

mutation giftCardResend($input: GiftCardResendInput!) {
  giftCardResend(input: $input) {
    giftCard {
      id
      code
      events {
        type
        user {
          email
        }
        app {
          name
        }
      }
    }
  }
}
{
  "input": {
    "id": "R2lmdENhcmQ6MjUw",
    "channel": "default-channel",
    "email": "saleor@example.com"
  }
}
{
  "data": {
    "giftCardResend": {
      "giftCard": {
        "id": "R2lmdENhcmQ6MjUw",
        "code": "60C5-10B9-DF19",
        "events": [
          {
            "type": "ISSUED",
            "user": {
              "email": "staff_user@saleor.io"
            },
            "app": null
          }
        ]
      }
    }
  },
  "extensions": {
    "cost": {
      "requestedQueryCost": 1,
      "maximumAvailable": 50000
    }
  }
}

Updating Gift Cards

After creation, the tag, expiry date, and balance amount can be updated.

mutation giftCardUpdate($id: ID!, $input: GiftCardUpdateInput!) {
  giftCardUpdate(id: $id, input: $input) {
    giftCard {
      id
      expiryDate
      initialBalance {
        currency
        amount
      }
      currentBalance {
        currency
        amount
      }
      events {
        type
        expiryDate
        oldExpiryDate
        oldTags
        tags
        balance {
          initialBalance {
            amount
            currency
          }
          oldInitialBalance {
            amount
            currency
          }
          currentBalance {
            amount
            currency
          }
          oldCurrentBalance {
            amount
            currency
          }
        }
      }
    }
  }
}
{
  "id": "R2lmdENhcmQ6MjUw",
  "input": {
    "balanceAmount": 70,
    "expiryDate": "2040-10-10",
    "addTags": [
      "new-tag"
    ]
  }
}
{
  "data": {
    "giftCardUpdate": {
      "giftCard": {
        "id": "R2lmdENhcmQ6MjUw",
        "expiryDate": "2040-10-10",
        "initialBalance": {
          "currency": "USD",
          "amount": 70
        },
        "currentBalance": {
          "currency": "USD",
          "amount": 70
        },
        "events": [
          {
            "type": "ISSUED",
            "expiryDate": null,
            "oldExpiryDate": null,
            "oldTags": null,
            "tags": null,
            "balance": {
              "initialBalance": {
                "amount": 200,
                "currency": "USD"
              },
              "oldInitialBalance": null,
              "currentBalance": {
                "amount": 200,
                "currency": "USD"
              },
              "oldCurrentBalance": null
            }
          },
          {
            "type": "RESENT",
            "expiryDate": null,
            "oldExpiryDate": null,
            "oldTags": null,
            "tags": null,
            "balance": null
          },
          {
            "type": "BALANCE_RESET",
            "expiryDate": null,
            "oldExpiryDate": null,
            "oldTags": null,
            "tags": null,
            "balance": {
              "initialBalance": {
                "amount": 70,
                "currency": "USD"
              },
              "oldInitialBalance": {
                "amount": 200,
                "currency": "USD"
              },
              "currentBalance": {
                "amount": 70,
                "currency": "USD"
              },
              "oldCurrentBalance": {
                "amount": 200,
                "currency": "USD"
              }
            }
          },
          {
            "type": "EXPIRY_DATE_UPDATED",
            "expiryDate": "2040-10-10",
            "oldExpiryDate": null,
            "oldTags": null,
            "tags": null,
            "balance": null
          },
          {
            "type": "TAGS_UPDATED",
            "expiryDate": null,
            "oldExpiryDate": null,
            "oldTags": [
              "example-tag"
            ],
            "tags": [
              "example-tag",
              "new-tag"
            ],
            "balance": null
          }
        ]
      }
    }
  }
}

Adjusting the Balance

Added in Saleor 3.23.

Use the giftCardBalanceAdjust mutation to change a card’s current balance by an amount instead of overwriting it. A positive amount tops the card up, and a negative amount deducts from it.

Unlike giftCardUpdate (which sets balanceAmount to an absolute value and records a BALANCE_RESET event), the adjustment is applied atomically at the database level. This makes it safe to run while a card is being charged in a concurrent checkout, so no update is silently lost. Each adjustment records a BALANCE_ADJUSTED event.

The mutation applies two clamping rules:

  • A deduction that would take the balance below zero clamps the current balance to zero.
  • A top-up above the current initial balance raises the initial balance to the new current balance.

The amount cannot be zero and must match the currency precision of the card. The staff member or app needs the MANAGE_GIFT_CARD permission.

mutation giftCardBalanceAdjust($id: ID!, $amount: Decimal!) {
  giftCardBalanceAdjust(id: $id, amount: $amount) {
    giftCard {
      id
      initialBalance {
        currency
        amount
      }
      currentBalance {
        currency
        amount
      }
      events {
        type
        balance {
          currentBalance {
            amount
            currency
          }
          oldCurrentBalance {
            amount
            currency
          }
        }
      }
    }
    errors {
      field
      code
      message
    }
  }
}
{
  "id": "R2lmdENhcmQ6MjUw",
  "amount": -20
}
{
  "data": {
    "giftCardBalanceAdjust": {
      "giftCard": {
        "id": "R2lmdENhcmQ6MjUw",
        "initialBalance": {
          "currency": "USD",
          "amount": 70
        },
        "currentBalance": {
          "currency": "USD",
          "amount": 50
        },
        "events": [
          {
            "type": "BALANCE_ADJUSTED",
            "balance": {
              "currentBalance": {
                "amount": 50,
                "currency": "USD"
              },
              "oldCurrentBalance": {
                "amount": 70,
                "currency": "USD"
              }
            }
          }
        ],
        "errors": []
      }
    }
  }
}

Activating and Deactivating Gift Cards

Cards can be activated and deactivated at any time, either individually or in bulk.

mutation giftCardDeactivate($id: ID!) {
  giftCardDeactivate(id: $id) {
    giftCard {
      id
      isActive
      events {
        type
      }
    }
  }
}
{
  "id": "R2lmdENhcmQ6MjUw"
}
{
  "data": {
    "giftCardDeactivate": {
      "giftCard": {
        "id": "R2lmdENhcmQ6MjUw",
        "isActive": false,
        "events": [
          {
            "type": "ISSUED"
          },
          {
            "type": "RESENT"
          },
          {
            "type": "BALANCE_RESET"
          },
          {
            "type": "EXPIRY_DATE_UPDATED"
          },
          {
            "type": "TAGS_UPDATED"
          },
          {
            "type": "DEACTIVATED"
          }
        ]
      }
    }
  }
}

For bulk operations, use giftCardBulkActivate and giftCardBulkDeactivate mutations.

Restricting Gift Cards to a Customer

Added in Saleor 3.23.

By default, a gift card is a bearer instrument: whoever holds the code can redeem it, including in guest checkout. Customer assignment is an opt-in restriction layered on top of this default. Once a card is restricted to a customer, only that customer’s account can use it, and the card can no longer be redeemed in guest checkout.

Assignment is distinct from usedBy:

  • assignedTo is forward-looking — the customer who is allowed to spend the card. It is a restriction that staff set on purpose.
  • usedBy is historical — the last customer who spent the card. It is an audit record and is deprecated.

Assigning a Customer

You can restrict a card to a customer at creation time by passing assignedTo (a customer’s user ID) to giftCardCreate, or afterwards with the giftCardAssignUser mutation. Both require the MANAGE_GIFT_CARD permission and trigger the GIFT_CARD_UPDATED webhook.

Assigning a customer records an ASSIGNED_TO_USER event and stores the customer’s email on the card.

mutation giftCardAssignUser($id: ID!, $userId: ID!) {
  giftCardAssignUser(id: $id, userId: $userId) {
    giftCard {
      id
      assignedTo {
        id
        email
      }
      assignedToEmail
      events {
        type
        assignedTo {
          oldAssignedToEmail
          currentAssignedToEmail
        }
      }
    }
    errors {
      field
      code
      message
    }
  }
}
{
  "id": "R2lmdENhcmQ6MjUw",
  "userId": "VXNlcjoyMg=="
}
{
  "data": {
    "giftCardAssignUser": {
      "giftCard": {
        "id": "R2lmdENhcmQ6MjUw",
        "assignedTo": {
          "id": "VXNlcjoyMg==",
          "email": "customer@example.com"
        },
        "assignedToEmail": "customer@example.com",
        "events": [
          {
            "type": "ASSIGNED_TO_USER",
            "assignedTo": {
              "oldAssignedToEmail": null,
              "currentAssignedToEmail": "customer@example.com"
            }
          }
        ],
        "errors": []
      }
    }
  }
}

A card cannot be assigned when it has already been used in an order, when it is attached to a checkout that has payments, or when it has been used by a gift card payment transaction. In those cases the mutation returns a CANNOT_ASSIGN error. If the card is attached to a checkout that has no payments, the card is detached from that checkout as part of the assignment.

Unassigning a Customer

Use the giftCardUnassignUser mutation to remove the restriction and return the card to bearer behavior. It requires the MANAGE_GIFT_CARD permission, triggers the GIFT_CARD_UPDATED webhook, and records an UNASSIGNED_FROM_USER event.

mutation giftCardUnassignUser($id: ID!) {
  giftCardUnassignUser(id: $id) {
    giftCard {
      id
      assignedTo {
        id
      }
      assignedToEmail
    }
    errors {
      field
      code
      message
    }
  }
}

Filtering by Assigned Customer

The giftCards query accepts an assignedTo filter that returns the cards restricted to the given customers. This replaces the deprecated usedBy filter.

query {
  giftCards(first: 10, filter: { assignedTo: ["VXNlcjoyMg=="] }) {
    edges {
      node {
        id
        assignedToEmail
      }
    }
  }
}

Setting Up Gift Cards as Products

To allow customers to purchase gift cards, you need to:

  1. Create a product type with GIFT_CARD kind
  2. Create a product using this product type
  3. Configure stock settings

Gift Card Fulfillment Settings

The automaticallyFulfillNonShippableGiftCard order setting controls when bought gift cards will be created:

  • If set to True: Gift card is created during checkout completion
  • If set to False: Gift card is created during order fulfillment

Gift Card Expiry Settings

Gift card settings can be configured to:

  • Never expire
  • Expire after a specific period

Example of setting expiry period to 1 year:

mutation giftCardSettingsUpdate($input: GiftCardSettingsUpdateInput!) {
  giftCardSettingsUpdate(input: $input) {
    giftCardSettings {
      expiryType
      expiryPeriod {
        type
        amount
      }
    }
  }
}
{
  "input": {
    "expiryType": "EXPIRY_PERIOD",
    "expiryPeriod": {
      "type": "YEAR",
      "amount": 1
    }
  }
}
{
  "data": {
    "giftCardSettingsUpdate": {
      "giftCardSettings": {
        "expiryType": "EXPIRY_PERIOD",
        "expiryPeriod": {
          "type": "YEAR",
          "amount": 1
        }
      }
    }
  }

Gift Cards as payment method

Transaction API allows you to use built-in payment gateway dedicated for consuming gift cards created in Saleor.

Using Gift Cards in Checkout

To use a gift card in a checkout, run the transactionInitialize mutation. Following payment gateway details must be included in mutation variables:

"paymentGateway": {
  "id": "saleor.io.gift-card-payment-gateway",
  "data": {
    "code": "valid-gift-card-code"
  }
}

Restricted cards are rejected with the generic Gift card code is not valid. message, the same one returned for a code that does not exist, so the response never reveals whether a card exists or whom it belongs to. The check runs before the balance check, so a caller who is not the assignee never learns the card’s remaining balance.

Example of using gift card to in a checkout. Notice id of payment gateway being set to saleor.io.gift-card-payment-gateway.

mutation transactionInitialize($id: ID!, $amount: PositiveDecimal!, $paymentGateway: PaymentGatewayToInitialize!) {
  transactionInitialize(id: $id, amount: $amount, paymentGateway: $paymentGateway) {
    transactionEvent {
      type
    }
    errors {
      field
      message
      code
    }
  }
}
{
  "id": "Q2hlY2tvdXQ6MjcyYzYxOGItZGU3My00Zjc0LTllNzYtZDMzNGQ1ZThkMTk0",
  "amount": "3",
  "paymentGateway": {
    "id": "saleor.io.gift-card-payment-gateway",
    "data": {
      "code": "8554-B58D-06B9"
    }
  }
}
{
  "data": {
    "transactionInitialize": {
      "transactionEvent": {
        "type": "AUTHORIZATION_SUCCESS"
      },
      "errors": []
    }
  }
}

Managing Gift Card payments

Creating Authorization Transactions

Successfully running transactionInitialization mutation results in creation of an authorization transaction.

Updating Authorization Transactions

If gift card is already authorized to a checkout but amount has to be updated run transactionInitialize with adjusted amount value. Previous authorizations will be cancelled.

Cancelling Authorization Transactions

Authorization transactions can be cancelled by either calling transactionRequestAction with CANCEL action or by applying gift card to another checkout.

Charging Transactions

When order gets confirmed Saleor attempts to charge funds from gift cards. If gift card has less funds than authorization transaction was initialized for the charge attempt will fail.

Refunding Charge Transactions

For information about refunding charge transactions refer to Refunds.

Legacy using Gift Cards in Checkout

Applying Gift Cards

To use a gift card in checkout, run the checkoutAddPromoCode mutation with the gift card code.

Tax Handling

Gift cards are applied to the checkout total after tax calculation:

  1. First, Saleor calculates all taxes for the order
  2. Then, the gift card amount is subtracted from the gross total price
  3. The net amount and tax amount are adjusted proportionally

Multiple Gift Cards

When multiple gift cards are used:

  • Saleor will always try to use the full amount from each gift card
  • The system processes gift cards in the order they were added to the checkout
  • If the checkout total is less than the gift card amount, only the necessary portion will be used
  • The remaining balance stays on the gift card for future use

Balance Changes

Gift card balances are only updated after the order is completed:

  • Adding card to the checkout does not modify the card balance
  • Used amount will be deducted during checkout completion
  • If an order is cancelled, the gift card balance is not restored
    • You can restore current balance using giftCardUpdate
    • If you used Transaction API for applying gift card you can also refund gift card transactions

Returns and Refunds

If a customer requests a return for a gift card product (i.e., the gift card code has not yet been used), you can handle the process manually:

  1. Refund the payment through your payment gateway
  2. Deactivate the associated gift card in the Saleor dashboard to prevent future use

Last updated on August 20, 2026

Was this page helpful?