How to Add Dynamic QR Codes and Personalised Links to Shopify Email

Shopify Messaging allows brands to create personalised marketing emails using Liquid variables.

This makes it possible to build email experiences where every customer receives a different link or image, including:

  • Unique QR codes
  • Membership links
  • Loyalty account links
  • Apple Wallet links
  • Google Wallet links
  • Personalised offers
  • Customer-specific landing pages

The important part is understanding what customer data Shopify makes available inside an email.

Shopify Messaging supports Custom Liquid and HTML, including custom buttons, images and layouts. It also exposes customer variables such as customer.id, customer.email, customer.first_name and customer.tags.

However, Shopify currently limits Custom Liquid emails to its documented supported-variable list. Customer metafields aren’t included in that list.

That creates a common problem:

How do you use customer-specific information stored in Shopify metafields inside a Shopify email?

The cleanest solution is to use the Shopify customer ID as the bridge between the email and an external service.

The basic architecture

Instead of trying to put this directly into Shopify Messaging:

{{ customer.metafields.custom.apple_link.value }}

you pass the customer’s Shopify ID:

{{ customer.id }}

For example:

<a href=”https://example.com/wallet/apple?customer_id={{ customer.id }}”>

  Add to Apple Wallet

</a>

When Shopify sends the email, the Liquid variable is resolved separately for each recipient.

One customer might receive:

https://example.com/wallet/apple?customer_id=123456789

while another receives:

https://example.com/wallet/apple?customer_id=987654321

Shopify specifically documents customer.id as a supported variable for Shopify Messaging emails.

The external application can then use that ID to retrieve whatever customer-specific information it needs.

Step 1: Create your Shopify customer metafields

Start by deciding what personalised data you want to store.

For a digital membership or wallet implementation, you might create:

Namespace: custom

apple_link

google_link

qr_code_url

A customer’s Shopify profile could therefore contain:

custom.apple_link

https://example.com/apple/abc123

custom.google_link

https://example.com/google/abc123

custom.qr_code_url

https://example.com/qr/abc123.png

Shopify metafields are attached to resources such as customers and are identified by their namespace and key.

Shopify’s Admin GraphQL API also exposes customer metafields programmatically.

Step 2: Insert a personalised link into Shopify Email

Create or edit your campaign in Shopify Messaging and add a Custom Liquid section.

For an Apple Wallet link:

<a href=”https://api.example.com/shopify/apple?customer_id={{ customer.id }}”>

  Add to Apple Wallet

</a>

For Google Wallet:

<a href=”https://api.example.com/shopify/google?customer_id={{ customer.id }}”>

  Add to Google Wallet

</a>

Shopify replaces:

{{ customer.id }}

with the ID of the actual email recipient.

The flow becomes:

Customer receives Shopify email

          ↓

Customer clicks link

          ↓

Shopify customer ID is sent

          ↓

External application identifies customer

          ↓

Application retrieves customer-specific link

          ↓

Customer is redirected

Step 3: Make an image clickable

You don’t need to use a text link.

Shopify Messaging supports custom HTML and custom images inside Custom Liquid sections.

For example:

<a href=”https://api.example.com/shopify/apple?customer_id={{ customer.id }}”>

  <img

    src=”https://example.com/images/add-to-apple-wallet.png”

    alt=”Add to Apple Wallet”

    width=”180″

  >

</a>

Every customer sees the same button image, but the destination behind the image is unique to them.

The same principle works for Google Wallet:

<a href=”https://api.example.com/shopify/google?customer_id={{ customer.id }}”>

  <img

    src=”https://example.com/images/add-to-google-wallet.png”

    alt=”Add to Google Wallet”

    width=”180″

  >

</a>

How to add a unique QR code to every Shopify email

This is where the technique becomes particularly useful.

An <img> tag doesn’t require its image source to be static.

The image source can itself contain the Shopify customer ID.

For example:

<img

  src=”https://api.example.com/shopify/qr?customer_id={{ customer.id }}”

  alt=”Your QR code”

  width=”220″

>

Shopify might send the first customer:

<img src=”https://api.example.com/shopify/qr?customer_id=123456789″>

and the next:

<img src=”https://api.example.com/shopify/qr?customer_id=987654321″>

Your server receives the request, determines which Shopify customer is involved, and returns that customer’s QR image.

The result is:

One Shopify campaign

          ↓

     100,000 recipients

          ↓

   100,000 customer IDs

          ↓

   100,000 unique QR codes

You don’t need to manually build 100,000 emails.

What happens on the backend?

Your application needs an endpoint such as:

GET /shopify/qr

which accepts:

customer_id=123456789

The backend can then query the Shopify Admin API for that customer.

Conceptually:

query CustomerWalletData($id: ID!) {

  customer(id: $id) {

    appleLink: metafield(

      namespace: “custom”

      key: “apple_link”

    ) {

      value

    }

    googleLink: metafield(

      namespace: “custom”

      key: “google_link”

    ) {

      value

    }

    qrCode: metafield(

      namespace: “custom”

      key: “qr_code_url”

    ) {

      value

    }

  }

}

Shopify’s Customer object supports retrieving metafields by namespace and key and requires the relevant customer-data access permissions.

Your application then has three possible behaviours.

For Apple:

/apple

↓

retrieve custom.apple_link

↓

redirect customer

For Google:

/google

↓

retrieve custom.google_link

↓

redirect customer

For QR:

/qr

↓

retrieve custom.qr_code_url

↓

return QR image

Complete Shopify Email example

A complete Custom Liquid section could look like this:

<div style=”text-align:center;”>

  <p>Add your membership to your phone:</p>

  <!– Apple Wallet –>

  <a href=”https://api.example.com/shopify/apple?customer_id={{ customer.id }}”>

    <img

      src=”https://example.com/images/apple-wallet.png”

      alt=”Add to Apple Wallet”

      width=”180″

      style=”border:0;”

    >

  </a>

  <br><br>

  <!– Google Wallet –>

  <a href=”https://api.example.com/shopify/google?customer_id={{ customer.id }}”>

    <img

      src=”https://example.com/images/google-wallet.png”

      alt=”Add to Google Wallet”

      width=”180″

      style=”border:0;”

    >

  </a>

  <br><br>

  <p>Or scan this QR code with your phone:</p>

  <!– Unique customer QR –>

  <img

    src=”https://api.example.com/shopify/qr?customer_id={{ customer.id }}”

    alt=”Your unique QR code”

    width=”220″

  >

</div>

The merchant only manages one email. The personalisation happens automatically. A final example may look like the following:

Why not reference the metafield directly?

In other Shopify Liquid environments, you might normally reference a customer metafield using syntax such as:

{{ customer.metafields.custom.apple_link.value }}

But Shopify Messaging only permits its documented set of supported Liquid variables, and customer.metafields isn’t currently included.

So rather than relying on unsupported Liquid:

Shopify Email

→ customer metafield

use:

Shopify Email

→ customer.id

→ your application

→ Shopify API

→ customer metafield

This also keeps the integration logic outside the email template.

Dynamic images can go beyond QR codes

The same architecture can be used for any customer-specific image.

For example:

<img src=”https://api.example.com/member-image?customer_id={{ customer.id }}”>

Your application could return a different image depending on:

Gold Member

Silver Member

Bronze Member

$10 Reward Available

$20 Reward Available

VIP Member

Points: 1,250

Reward Expiring Soon

That allows a Shopify email to display content generated specifically for the person opening it.

Important security consideration

Avoid treating a bare Shopify customer ID as authentication.

Something like:

?customer_id=123456789

is useful as an identifier, but it shouldn’t automatically grant access to sensitive account information or transferable rewards.

If the QR code, wallet pass or destination provides access to valuable or private customer data, the implementation should use an appropriate secure token or verification layer.

Shopify also treats customer information as protected customer data and requires apps to request only the access needed for their functionality.

Using this with Apple Wallet and Google Wallet

For a platform such as Litecard, this architecture creates a simple bridge between Shopify and the mobile wallet.

The merchant can send a normal Shopify campaign containing:

Add to Apple Wallet

Add to Google Wallet

Unique QR Code (for Desktop users)

while Litecard handles:

Shopify customer identification

↓

Customer data lookup

↓

Wallet pass identification

↓

Apple / Google Wallet destination

↓

Dynamic QR generation

This means Shopify remains the email platform while the wallet platform handles the customer-specific wallet experience. The architecture and concept are very similar to if you are using Litecard with Klaviyo, Braze, Dotdigital, Insider One, Mailchimp, etc. (any other CDP/CEP)

In summary

Shopify Messaging already gives developers enough customer-level context to create highly personalised links and images because customer.id can be inserted dynamically into Custom Liquid.

The key is not to force customer metafields directly into the email.

Instead:

1. Store the personalised data against the Shopify customer.
2. Pass {{ customer.id }} from Shopify Messaging.
3. Resolve the customer’s metafields through your backend.
4. Return the correct link, image or QR code.

That creates a reusable architecture for personalised QR codes, loyalty journeys, membership experiences and Apple or Google Wallet activation directly from Shopify email.

Want to add personalised Apple Wallet and Google Wallet experiences to Shopify?

Litecard connects Shopify customer data with Apple and Google Wallet, allowing brands to distribute personalised wallet passes, QR codes and customer-specific wallet experiences directly through their existing marketing channels.

Scanning customers in at PoS? You can use Litecard’s Shopify PoS app here too: https://apps.shopify.com/litecard-pos

If you want to learn more about how Litecard works with other platforms, you can read our knowledge base here: https://litecard.com/knowledge-base/

Updated on September 12, 2026