Creating native Apple Wallet passes (.pkpass files) allows businesses to deliver loyalty cards, event tickets, boarding passes, coupons, and membership cards directly onto iPhone and Apple Watch lock screens without forcing users to download a dedicated mobile application.
This complete 2026 guide covers everything developers and product leaders need to know about Apple PassKit architecture, cryptographic signing, distribution, and real-time push updates.
1. Anatomy of an Apple Wallet Pass (.pkpass)
An Apple Wallet pass is a compressed ZIP archive with a .pkpass file extension containing structured JSON, localized asset images, and Apple-validated cryptographic signature manifests.
Required Bundle Structure
my-pass.pkpass
├── pass.json # Primary layout, field definitions, and metadata
├── logo.png # Top-left brand emblem (160x160 @2x)
├── logo@2x.png
├── icon.png # Lock-screen notification icon (58x58 @2x)
├── icon@2x.png
├── strip.png # Hero image for event tickets and coupons (375x144 @2x)
├── strip@2x.png
├── manifest.json # SHA-1 hashes of all files in the bundle
└── signature # Cryptographic PKCS#7 signature created with your Pass Type ID cert
2. Apple Developer Setup & Certificate Signing
To sign Apple Wallet passes natively, Apple requires PKCS#12 signing credentials derived from an active Apple Developer account.
Step-by-Step Signing Pipeline:
- •Pass Type ID: Register a unique identifier (e.g.
pass.com.yourcompany.loyalty) in the Apple Developer Portal. - •Certificate Signing Request (CSR): Generate a 2048-bit RSA private key and CSR via OpenSSL or Keychain Access.
- •Pass Type Certificate: Download your issued
.cerfile and export it as a.p12container with its private key. - •WWDR Intermediate Certificate: Include the Apple Worldwide Developer Relations G6 Intermediate Certificate in your trust chain.
.pkpass compilation automatically via managed cloud certificates.
3. Configuring pass.json Fields
The pass.json file dictates pass layout style (storeCard, coupon, eventTicket, boardingPass, generic) and dynamic data fields:
{
"formatVersion": 1,
"passTypeIdentifier": "pass.com.passinstance.loyalty",
"serialNumber": "PASS-8842-2026",
"teamIdentifier": "ABC123XYZ",
"organizationName": "Artisan Coffee",
"description": "Artisan Coffee Loyalty Card",
"logoText": "Artisan Coffee",
"foregroundColor": "rgb(255, 255, 255)",
"backgroundColor": "rgb(10, 90, 84)",
"labelColor": "rgb(164, 243, 222)",
"storeCard": {
"primaryFields": [
{
"key": "stamps",
"label": "REWARD PROGRESS",
"value": "8 of 10 Stamps"
}
],
"secondaryFields": [
{
"key": "holder",
"label": "MEMBER",
"value": "Jane Doe"
}
]
},
"barcodes": [
{
"format": "PKBarcodeFormatQR",
"message": "PASS-LOYALTY-8842",
"messageEncoding": "iso-8859-1"
}
],
"webServiceURL": "https://api.passinstance.com/v1/apple",
"authenticationToken": "sec_tok_99182348"
}
4. Native Lock-Screen Geofencing & Location Triggers
Apple Wallet passes support up to 10 location coordinates (relevantLocations) that trigger native lock-screen notifications when a customer physically approaches your store or venue.
"locations": [
{
"latitude": 37.774929,
"longitude": -122.419416,
"relevantText": "Welcome back! Scan your card at the counter for 10% off."
}
]
5. Pushing Real-Time Lock-Screen Updates (APNs)
When a customer's pass balance, tier, or expiration changes, Apple Wallet updates the pass over the air using Apple Push Notification service (APNs):
- •When installed, iOS sends a POST request to your
webServiceURLwith a device push token (pushToken). - •To update the pass, send an empty APNs push payload to Apple's push servers targeting the device
pushToken. - •iOS wakes up silently, fetches the latest
pass.jsonfrom your server, updates the card artwork, and displays a lock-screen banner if achangeMessagewas updated.
6. Creating Apple Wallet Passes in Seconds with Passinstance
Rather than maintaining custom OpenSSL signing pipelines, APNs server infrastructure, and device registration endpoints, Passinstance automates the entire process:
import { Passinstance } from "@passinstance/sdk";
const client = new Passinstance({ apiKey: process.env.PASSINSTANCE_API_KEY });
// Issue an Apple Wallet pass with live signing
const pass = await client.passes.create({
templateId: "tpl_coffee_loyalty",
data: {
holderName: "Jane Doe",
stamps: "8 of 10 Stamps",
},
});
console.log("Add to Apple Wallet Link:", pass.appleWalletUrl);

