Skip to main content

Connect Apple and Google Wallet passes

Tutorial

What you'll build

A pair of « Add to Apple Wallet » / « Add to Google Wallet » buttons in your storefront or post-purchase email that issue a live, auto-updating loyalty pass to the buyer. The branding work happens in the Admin Console; this tutorial covers the client-side wiring that the Admin Console doesn't do for you.

  • Time~15 min
  • DifficultyBeginner — front-end JavaScript
  • You'll needA Loyalty application whose Apple Pass certificate and Google Wallet Issuer ID are already provisioned by Keyban (one-time setup), brand assets configured in the Admin Console, and a Keyban session for the consumer requesting the pass
Loyalty only — DPP wallet passes are not yet shipped

The endpoints below issue passes from a loyalty account. Wallet passes for individual DPP items are not exposed today.

How a pass reaches the buyer's phone

Both passes are generated on demand when the consumer's app calls the corresponding endpoint. There is no pre-creation step: the pass is built from the live loyalty account state at request time.

  1. Buyerphone
  2. Your appstorefront / receipt
  3. Keyban APIpass issuer
  4. Wallet OSApple / Google
  1. 1GET /apple-wallet/loyalty-pass
  2. 2.pkpass binary
  3. 3serve as download
  4. 4open
  5. 5GET /google-wallet/loyalty-pass
  6. 6pay.google.com/gp/v/save/<jwt>
  7. 7tap save URL
On-demand pass issuance: the consumer's app requests the pass, Keyban builds it from the live account state, the wallet OS installs it. Updates flow through the platform's native push channel.

After install, Apple polls Keyban for updates through APNs and the standard PassKit register/unregister handshake (handled internally — no client code on your side). Google syncs the loyalty object server-to-server through the Wallet API.

Step 1 — Confirm the Admin Console set-up

Before writing any code, make sure your Loyalty application is ready:

  • Credentials — open Application → Loyalty → Wallet passes and confirm both « Apple: configured » and « Google: configured » badges are green. If a badge is red, raise a support ticket — credentials are uploaded once by your Keyban contact, not self-served.
  • Brand assets — open Application → Loyalty → Branding and verify the logo, icon, colours, and background image are set for both platforms. The form mirrors the Loyalty assets guide — wrong dimensions are rejected at pass-build time, not at upload.

This step is entirely in the Admin Console. Move to Step 2 once both checks pass.

Step 2 — Issue an Apple Wallet pass

The Apple endpoint returns the .pkpass binary directly. It runs under the consumer's Keyban session (cookie or SDK token), not the partner's X-Api-Key — the buyer authenticates as themselves.

// In your authenticated React app
const response = await fetch("/apple-wallet/loyalty-pass", { credentials: "include" });
const blob = await response.blob();

// Trigger a download with .pkpass content-type
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "loyalty.pkpass";
a.click();

On iOS, opening a .pkpass file launches Apple Wallet directly. For email or SMS delivery, host the bytes yourself or generate a one-time link (Keyban does not host download links).

Step 3 — Issue a Google Wallet pass

The Google endpoint returns a JSON envelope with the install URL — typically used as the href of an « Add to Google Wallet » button.

const response = await fetch("/google-wallet/loyalty-pass", { credentials: "include" });
const { saveUrl } = await response.json();

// saveUrl looks like: https://pay.google.com/gp/v/save/<jwt>
window.location.href = saveUrl;

Behind the scenes, Keyban upserts the loyalty class and object on Google's Wallet API and signs a JWT that authorises the install. The same URL can be re-opened — the Wallet API deduplicates on the object id.

Step 4 — Surface the install buttons

In your storefront or transactional email, show the two platform-aware buttons. Browser sniffing on User-Agent is enough to pick the right one when the buyer is on their phone.

<a href="/apple-wallet/loyalty-pass" download="loyalty.pkpass" class="apple-wallet-add">
Add to Apple Wallet
</a>
<a href="${saveUrl}" class="google-wallet-add">
Add to Google Wallet
</a>

Both vendors publish official badge artwork — use them rather than custom buttons (cf. Apple PassKit guidelines and Google Wallet brand guidelines).

Step 5 — Verify a live update

Mint a few points to the same account (the Admin Console (Loyalty → Accounts → Mint)). On Apple, the pass refreshes through APNs within seconds. On Google, the loyalty object is updated server-to-server and reflects in the wallet on the next open. There is no client code to write — Keyban manages the registration handshake and the Wallet API sync.

If the balance doesn't refresh:

  • On Apple, the buyer may have disabled automatic updates (Wallet → pass → ⓘ → Automatic Updates).
  • On Google, confirm the application's Google branding title is set in Application → Loyalty → Branding — Google rejects loyalty objects without a class title.

Next steps