Shopify Gift Card Syncing: Navigating Webhooks & External POS Integration

Hello fellow store owners and developers! Let's talk about a challenge that often comes up: keeping your Shopify gift card balances in sync with external systems, especially your Point of Sale (POS). It's a critical piece of the puzzle for many omnichannel businesses, and getting it right can save a lot of headaches.

I recently dove into a really insightful community thread where a developer, amf-devs, was trying to bridge this gap, and another helpful member, lumine, offered some crucial advice. It's a perfect example of the real-world problem-solving happening in the Shopify ecosystem, and I want to share the key takeaways with you.

The Mystery of the Missing Gift Card Webhooks

The core of the discussion, and a common point of confusion, centered on the existence of gift_cards/create and gift_cards/update webhooks. These sound like a perfect fit for real-time syncing, right? A webhook when a new gift card is issued, and another when its balance changes – ideal for updating an external POS or ERP system.

However, despite some community mentions and even AI assistants hinting at their existence, amf-devs hit a brick wall when trying to subscribe. They received clear errors from both the Admin REST API and GraphQL:

422 Unprocessable Entity
"Invalid topic specified: gift_cards/create. Does it exist?
Is there a missing access scope?"

And for GraphQL:

INVALID_VARIABLE — Expected "GIFT_CARDS_CREATE" to be one of [list of valid topics]

This is a major piece of information! It strongly indicates that, for the general developer and most Shopify plans, these specific webhooks are either not publicly available, have been deprecated, or are gated behind specific enterprise plans (like Shopify Plus, as lumine hinted might be the case historically). The fact that they don't appear in the WebhookSubscriptionTopic enum is a pretty definitive sign.

The clear takeaway? For most developers and Shopify plans, we can't reliably depend on gift_cards/create or gift_cards/update for real-time syncing. But don't worry, the community quickly pointed to a more robust strategy.

The Golden Rule: Webhooks as Signals, Shopify as Source of Truth

One of the most valuable pieces of advice from lumine, even if those direct webhooks were available, is this: always treat webhooks as a "go re-read" signal, not the source of truth itself.

Think about it: webhooks can sometimes arrive out of order, or multiple quick changes to a gift card balance might get collapsed into a single, delayed notification. If you just trust the payload of a webhook, you could easily end up with an incorrect balance in your external system. Instead, when you receive any relevant webhook, your external system should immediately query the Shopify API (using something like giftCard(id) in GraphQL) to fetch the authoritative, current balance. This ensures your POS always reflects what Shopify considers the true balance.

This principle is critical for any robust integration: Shopify is your master for gift card balances, period.

Building a Robust Gift Card Sync: The Recommended Pattern

Given the webhook situation, amf-devs laid out a thoughtful alternative approach, which, combined with lumine's advice, forms a solid strategy for syncing gift cards. Let's break down the recommended pattern for keeping your Shopify-issued gift card balances in sync with an external system:

1. Detecting Gift Card Issuance

When a customer buys a gift card product on your Shopify storefront, Shopify handles the issuance. To detect this and mirror it to your POS:

  • Subscribe to the orders/paid webhook. This webhook fires when an order is paid, which is when a new gift card would be issued.
  • Inspect the line items in the orders/paid payload. Look for a line item where gift_card: true. This tells you a gift card product was part of the purchase.
  • Query the Gift Card via API: Once you detect a gift card product in the order, you'll need the actual GiftCard object. You can fetch this using the GraphQL Admin API with a query like giftCards(query: "order_id:X"), replacing X with the Shopify order ID. This will give you the full details of the newly issued gift card, including its initial balance and code, which you can then push to your POS. :white_check_mark: (As amf-devs confirmed, this part is already working for them!)

2. Detecting Shopify-Side Redemptions & Balance Changes

Tracking redemptions or manual adjustments within Shopify gets trickier without a direct gift_cards/update webhook. Here's how you can approach it:

  • For Redemptions during Checkout: Again, the orders/paid webhook is your friend! When a customer redeems a gift card at Shopify checkout, the gift_cards array embedded within the orders/paid payload will contain details of the gift cards used and the amounts debited. You can use this to update your POS.
  • For Admin Adjustments and Other Balance Changes: This is where polling comes in. Since there's no direct webhook for every single balance change, you'll need a scheduled task (e.g., every 5-15 minutes) that:
    • Queries the Shopify API for gift cards that have been recently updated. You can use a query like giftCards(query: "updated_at>..."), where ... is a timestamp indicating your last check.
    • Compares the fetched balance with the balance stored in your external POS. If there's a discrepancy, update your POS to reflect Shopify's authoritative balance.

3. Handling POS-Initiated Debits (Reverse Direction)

What about when a customer uses their gift card at your physical store, and you need to debit the balance in Shopify? amf-devs confirmed that calling giftCardDebit on the Shopify side works well, assuming you have the write_gift_card_transactions scope. This is great!

The follow-up question was how to be informed by Shopify that your own debit was processed, other than just querying the balance. For now, querying the balance after your giftCardDebit call is the most direct way to confirm the change and get the new authoritative balance. This ties back perfectly to lumine's "go re-read" rule – even for changes you initiate, confirming with a fresh query is best practice.

Key Considerations for Your Integration

  • API Scopes: Ensure your app has all the necessary gift card scopes: read_gift_cards, write_gift_cards, read_gift_card_transactions, and write_gift_card_transactions. amf-devs confirmed they had these, which further highlights that the issue wasn't a simple permissions problem.
  • Shopify Plan Limitations: As mentioned, certain API functionalities, especially around gift cards, have historically been Plus-gated. While the specific webhooks seem generally unavailable now, always be mindful that your Shopify plan might influence API access.
  • Error Handling and Retries: Building robust error handling and retry mechanisms for your API calls is crucial, especially when dealing with external systems and financial data.

So, while the direct gift_cards/create and gift_cards/update webhooks might remain elusive for many of us, don't let that stop you. By leveraging the orders/paid webhook, smart API querying, and strategic polling, you can build a reliable system to keep your Shopify gift card balances perfectly in sync. It's more involved than direct webhooks, but the peace of mind from accurate balances is well worth it.

Share:

Use cases

Explore use cases

Agencies, store owners, enterprise — find the migration path that fits.

Explore use cases