HomeFeaturesFor merchantsPricingAboutJournalContact
Appearance
Questions? Call 07447 476948
or email hello@stempy.co.uk
Engineering

How Stempy signs wallet passes for thousands of merchants without a deployment per tenant.

Kwame Osei·Engineering·10 min read·

Every Apple Wallet pass needs to be cryptographically signed before it reaches a customer's device. Every Google Wallet pass needs to come from an authenticated service account with a valid JWT signature. At Stempy, every merchant gets a fully branded pass: their own logo, colours, reward copy, and pass design. The question we faced in 2024 was how to issue and sign thousands of distinct merchant passes without maintaining a separate Apple developer account or certificate chain per tenant.

This post explains the approach we settled on, the trade-offs involved, and the operational lessons we've learned running it at scale. If you're building a multi-merchant loyalty platform, a white-label wallet solution, or any service that issues passes on behalf of third parties, the problems we solved here are the same ones you'll encounter.

How Apple Wallet pass signing works

An Apple Wallet pass is a .pkpass file: a ZIP archive containing a pass.json descriptor, a manifest.json with SHA-1 hashes of every file in the archive, and a signature file that cryptographically signs the manifest. The signature is created using a Pass Type ID certificate — a certificate issued by Apple, tied to a specific bundle identifier of the form pass.com.example.identifier. Apple validates this certificate chain on-device when the pass is added to Wallet.

The signing chain has three parts: the merchant's Pass Type ID certificate (issued by Apple), the WWDR intermediate certificate (Apple's Worldwide Developer Relations CA), and the pass manifest. All three must be present and valid. The WWDR certificate has a fixed expiry and must be kept current; Apple rotated it in 2022 and caught many developers off guard. The Pass Type ID certificate itself has a 12-month expiry from the date of issue.

The naive multi-tenant approach and why it doesn't scale

The obvious first approach to multi-tenant pass issuance is to register a separate Pass Type ID for each merchant in your platform. Each merchant gets their own bundle identifier, their own certificate, their own signing key. This is perfectly correct from Apple's perspective and eliminates any ambiguity about who issued which pass.

It is also completely unworkable at scale. Pass Type ID registration requires manual steps in Apple Developer portal — there is no programmatic API for creating new pass types. The process takes one to three days. Each certificate requires annual renewal with a 12-month expiry. At 200 merchants, you have 200 certificates to track, renew, and rotate. At 2,000 merchants, certificate management becomes a full-time job. And if a certificate lapses, every pass issued under that bundle ID stops receiving updates on-device until it's renewed.

The shared-certificate signing model

The model we use — and the model most multi-tenant wallet pass platforms converge on — is a single Stempy Pass Type ID certificate as the cryptographic root, with all merchant customisation handled at the data layer inside the pass.json. The certificate proves to Apple's on-device validation that the pass was issued by Stempy's signing infrastructure. The pass content — logo, background colour, strip image, merchant name, stamp count, reward copy — is merchant-specific and variable, but signed by the same certificate.

Practically, this means the 'issuer' visible in Apple's pass infrastructure metadata is Stempy, not the individual merchant. Every customer-facing element of the pass is merchant-branded: they see the merchant's logo, the merchant's colours, the merchant's name and reward copy. The Stempy brand is invisible during normal wallet use. The certificate is a plumbing detail.

The trade-off to know about before building this way

There is one place in the iOS Wallet UI where the issuer certificate becomes visible to the end user: the 'Pass Information' screen, accessible by long-pressing a pass in the Wallet app and selecting 'Pass Information.' This screen shows the pass type identifier, which in Stempy's case begins with 'pass.co.uk.stempy.' It is not visible during normal pass use — the main pass view, the lock screen notification, the stamp animation — only in this deep-link metadata view.

In twelve months of production operation, we have had exactly one merchant raise this as a concern. Our guidance to them: this is an Apple platform constraint that applies to all multi-tenant wallet pass platforms, not a limitation specific to Stempy. Apple has not announced plans to support per-tenant Pass Type ID registration via API, which would be the alternative path. We continue to monitor the Apple Wallet developer documentation for any changes in this area.

The other trade-off is that pass update delivery — when a merchant updates their pass design, the changes need to push to every active pass — flows through Stempy's update infrastructure. The update is Stempy-initiated, not a direct connection between the merchant's systems and Apple's servers. In practice, this means pass updates propagate within 24 hours on average. For time-sensitive changes, we also expose a manual 'push update' option in the merchant portal that triggers an immediate propagation request.

Google Wallet: a different architecture, different trade-offs

Google Wallet's Passes API works on a fundamentally different model from Apple. Instead of a local certificate bundle, Google uses a server-side class-and-object architecture. A pass 'class' is a template registered with Google under a service account — it defines the structure and branding of a merchant's pass. A pass 'object' is an instance of that class for a specific customer, issued via a signed JWT.

The signing mechanism is a JWT signed with a Google service account key. When a customer adds a pass via the 'Add to Google Wallet' button on a sign-up page or QR code, their device exchanges the JWT with Google's servers, which validate the signature against the service account credentials and issue the pass to the customer's wallet. The signing key never leaves Stempy's signing service.

The key difference from Apple is that there is no visible 'issuer' element in the Google Wallet UI that surfaces our service account credentials to end users. From the customer's perspective, the pass looks entirely like a Stempy-issued loyalty card from the merchant they know. There is no equivalent of Apple's 'Pass Information' screen that shows backend infrastructure details.

Certificate rotation and operational reliability

The signing infrastructure runs as a dedicated service, isolated from the main merchant portal API. This was an architectural decision made deliberately: if the portal API is experiencing elevated latency or has a deployment in progress, pass signing should still work without interruption. The two services share a message queue but no synchronous dependencies.

Apple Pass Type ID certificate rotation is automated with a 60-day lead time. The automation monitors the certificate expiry date, requests renewal through our Apple Developer account 60 days out, validates the new certificate against a test pass in staging, and rotates the production signing service to use the new certificate with a 15-minute overlap window during which both old and new certificates are valid. The rotation has happened twice since launch with no production impact.

The one near-miss was in December 2025: a stale cache entry on one signing node held an expired WWDR intermediate certificate that hadn't been invalidated after Apple published a renewed version. The staging environment caught it two hours before the same condition would have affected production. We added an explicit WWDR certificate freshness check to the pre-deployment checklist as a result.

What this means if you are evaluating Stempy for your business

The signing architecture is transparent to merchants using Stempy — you don't need to register anything with Apple or Google, manage any certificates, or handle any signing operations yourself. All of that is handled by Stempy's infrastructure. The pass your customers add to their wallets is fully branded to your business and works identically to a pass issued under a dedicated certificate for everything that matters to a customer experience.

The current production record is 99.98% uptime on pass signing with zero cryptographic signing failures in production since launch. For merchants evaluating the reliability of wallet-based loyalty relative to a custom-built solution, the question is not whether Stempy's signing model is elegant — it is whether the passes it produces work reliably on every device, every time. On that measure, the answer is yes.

KO
Kwame Osei
Engineering, Stempy
Kwame leads engineering at Stempy, including the wallet pass signing infrastructure. Previously at Square.

See Stempy in action for your business — 7-day trial, cancel anytime.

Book a demo