Wallet - Creating Passes
This page covers the part that happens before you ever call Wallet.addPasses — building and signing the pass itself, on your own backend. WebToNative never creates, edits, or signs a pass; it only hands whatever you give it to the OS wallet app. See Google Wallet / Apple Wallet for the JS API this feeds into.
Google Wallet (Android)
A Google Wallet pass isn't a file you generate once and host — it's a JWT your backend signs on the fly (or a save link built from one), referencing pass data that lives in your Google Wallet Issuer account.
1. Create a Google Wallet Issuer Account
Sign up at the Google Wallet Business Console and get your Issuer ID — every pass class/object you create is scoped to it.
2. Set Up a Service Account
In Google Cloud Console, enable the Google Wallet API, create a service account, and download its JSON key. This key's private key is what signs the JWT in step 4 — keep it server-side only.
3. Define a Pass Class
A class is the reusable template for a pass type — the loyalty program, the event, the flight route. Create it once via the Google Wallet REST API (POST https://walletobjects.googleapis.com/walletobjects/v1/<type>Class), picking the type that matches what you're issuing:
genericClass · loyaltyClass · offerClass · eventTicketClass · flightClass · giftCardClass · transitClass
4. Create a Pass Object
An object is one instance of that class for one specific user — their points balance, their seat, their gift card value. Create it via the matching <type>Object endpoint (e.g. loyaltyObject), referencing the classId from step 3.
5. Build & Sign the Save JWT
To hand a pass to Wallet.addPasses, sign a JWT whose claims are:
iss
Your service account's email address.
aud
Always "google".
typ
Always "savetowallet".
iat
Issued-at timestamp.
payload
An object keyed by the class/object type, e.g. { "loyaltyObjects": [{ "id": "...", "classId": "..." }] }. Accepted keys: genericClasses/genericObjects, loyaltyClasses/loyaltyObjects, offerClasses/offerObjects, eventTicketClasses/eventTicketObjects, flightClasses/flightObjects, giftCardClasses/giftCardObjects, transitClasses/transitObjects.
Sign with RS256 using the service account's private key.
Requires firebase/php-jwt (composer require firebase/php-jwt).
Handing It to WebToNative
The signed JWT is exactly what Wallet.addPasses expects in passes:
You can also wrap it as https://pay.google.com/gp/v/save/<jwt> and pass that string instead — both are accepted.
Apple Wallet (iOS)
An Apple Wallet pass is a file — a .pkpass, which is really just a signed zip. Unlike Google Wallet, there's no live API call per pass; you build and sign the file, then host it or hand over its bytes.
1. Get a Pass Type ID & Certificates
In your Apple Developer account, register a Pass Type ID (e.g. pass.com.example.loyalty) and generate its certificate. You'll also need Apple's WWDR intermediate certificate.
2. Build the Pass Bundle
A pass is a folder containing:
pass.json— the pass's data: style (boardingPass,coupon,eventTicket,storeCard, orgeneric), your Pass Type ID, aserialNumber+authenticationToken(needed if you'll later usegetPasses/checkPassExists/removePass), and the fields shown on the pass (header/primary/secondary/auxiliary/back fields).Images —
icon.png,logo.png, and style-specific assets (@2x/@3xvariants).
3. Generate & Sign the Manifest
manifest.json lists a SHA hash of every file in the bundle. Sign that manifest with your Pass Type ID certificate + the WWDR certificate to produce a detached signature file:
4. Package as .pkpass
Zip pass.json, manifest.json, signature, and the images together (flat, no subfolder) with a .pkpass extension.
5. Host or Base64-Encode It
Once you have the .pkpass bytes:
Host it at an HTTPS URL (serve with
Content-Type: application/vnd.apple.pkpass), orBase64-encode it and send the string directly.
Handing It to WebToNative
See Also
Google Wallet / Apple Wallet — the
Wallet.*JavaScript API this feeds into.