A pass is a file, not a live connection
An Apple Wallet pass is a signed zip file called a .pkpass. Inside it there's a pass.json, a few images, a manifest, and a signature. Once it's on the phone it is completely static. Nothing inside that file talks to your database.
What makes it updateable are two keys in pass.json: webServiceURL and authenticationToken. Together with the passTypeIdentifier and the serialNumber, they form an address the phone can use later. The meaning is roughly "come to this URL, with this token, to get a newer version of me."
When the customer taps Add, iOS registers the device against that URL. It sends a POST to /v1/devices/{deviceLibraryIdentifier}/registrations/{passTypeIdentifier}/{serialNumber}, with a pushToken in the body. The server stores that row. That single handshake is the entire subscription — there is no socket, no polling loop, and no background app.
Google Wallet solves the same problem from the other end. The loyalty object lives on Google's servers, the merchant's server PATCHes it through the walletobjects API, and the phone reads Google's copy. There is no per-device registration and no push token to keep alive, which is why Google-side updates involve less plumbing but also give the merchant less visibility.
What happens between the stamp and the screen
Start at the counter. A staff member scans the customer's card on an ordinary phone, the balance row changes, and that change enqueues a wallet update job. On Waya the queue worker runs on a 30-second tick and is also kicked immediately when a balance moves, so the job rarely sits waiting.
The worker then sends a push to Apple's push service for every device registered against that serial number. The push carries no data. Apple's payload for a pass update is an empty object, so the push is a doorbell, not a delivery.
The phone wakes Wallet, which asks what changed: GET /v1/devices/{deviceLibraryIdentifier}/registrations/{passTypeIdentifier}?passesUpdatedSince=<tag>. The server answers with a list of serial numbers and a fresh tag, or with HTTP 204 No Content when nothing moved. 204 is not an error. It is the correct and most common answer.
For each serial in that list, the phone asks for the pass itself: GET /v1/passes/{passTypeIdentifier}/{serialNumber}, with an Authorization header of ApplePass followed by the token baked into the pass. The server signs a brand-new .pkpass and returns it as application/vnd.apple.pkpass. iOS swaps the installed pass in place: same serial number, same spot in Wallet, new stamp count.
The lock-screen line is a separate decision. A field only produces a visible notification if that field carries a changeMessage and its value actually changed. Same push, identical value, no notification. Google's equivalent is an explicit message added to the loyalty object.
Backoff, retries, and dead device tokens
Pushes fail. Apple's service returns 5xx errors, networks time out, and the second HTTPS round trip can land on a server that's restarting. A wallet update queue that retries instantly is a queue that amplifies every outage it meets.
Waya's schedule is exponential and capped. The first retry waits 30 seconds, the second 2 minutes, the third 8 minutes, and the fourth 30 minutes, with the formula capped at 2 hours. After 5 failed attempts the job is marked dead and written to an events log for a human to look at.
One status code has to be handled differently. Apple returns 410 when a device token is no longer valid, which happens when the customer deletes the pass, resets the phone, or the token is reissued. 410 is terminal: stop retrying and delete the registration row. Treating it as retryable is how a push queue slowly fills with garbage.
A dead-letter state matters more than it sounds. In May 2026 we dead-lettered 66 Google Wallet update jobs because one internal call was missing an authorization header. We only found it quickly because those jobs stopped in a visible dead state with an error code, instead of silently disappearing.
Why a pass sometimes shows stale points
The device may never have registered. No push token means there is nothing to push to, and the pass then only refreshes when the customer opens it. This is also the expected behavior for a web card fallback, which is a page rather than a wallet pass and simply shows the current number on load.
The callback may have failed. The push arrives, the phone calls back, the server answers 401 or 500, and the phone stops trying until something triggers it again. We shipped exactly this bug: we rotated the pass authentication token on every fetch, so retries already in flight hit 401 against a token the database had replaced. Stamps froze for the customers whose phones happened to retry, and the fix was to reuse the same token when re-issuing the pass.
The push may simply be late. Apple's push service is store-and-forward and best-effort. Low Power Mode, a phone in a basement, or a sleeping device on weak Wi-Fi all delay delivery, sometimes by a long time. Nothing is lost, because the balance lives on the server and the pass is only a rendering of it.
Sometimes the number never changed at all. The most common stale-pass report we see is a card that was never stamped. Waya has no POS integration, so a purchase does not create a stamp by itself — a staff member has to scan the customer's card. Check the dashboard before you suspect the wallet.
What to tell the customer, and what to tell your staff
Tell the customer to open the pass. Opening it in Apple Wallet triggers a refresh against the same web service, and in Google Wallet a pull-down on the pass does the same thing. That resolves most stale-number complaints in a couple of seconds, with no support ticket.
Tell them deleting the pass is safe. The balance is a server record, not a value stored in the file. Scanning the shop's QR code again, or reopening the same enrollment link, brings back the same card with the same count. Say this out loud, because plenty of customers assume removing a pass burns their stamps.
Tell your staff that the scan is the event. If a customer's card looks wrong, the first place to look is the dashboard, not the phone. When the dashboard is right and the phone is behind, it is a delivery problem and it clears itself.
Questions worth asking any wallet loyalty vendor
Most loyalty vendors ship genuine Apple and Google Wallet passes, so that alone is not a differentiator. The real difference is what happens after a push fails. Ask three questions: does the pass carry a web service URL with a stable authentication token, what is the retry and backoff policy, and what does the system do when a device token returns 410.
If you are comparing options in Saudi Arabia, note that pricing moves. As of August 2026, Btaqa published tiers of 108, 250, and 380 SAR a month, OneCup sits around 150 SAR, Watily is 149 SAR with loyalty bundled into a wider plan, and Niqati is quote-based. Check each vendor's current page before you decide.
Waya's own position, stated plainly: free forever up to 100 customers, 100 wallet messages a month, 1 stamp card, and 1 branch, with no credit card. Paid plans start at 85 SAR a month. There is no POS integration and no SMS, and the free tier stops hard at those two limits, though already-enrolled customers keep their cards and keep collecting.
Frequently asked questions
Why does my wallet pass show the wrong number of stamps?
Almost always because the update never reached the phone, not because the balance is wrong. Open the pass in Apple Wallet, or pull down on it in Google Wallet, and it refetches a freshly signed copy from the server. If the number is still wrong after that, check the merchant's dashboard — the usual cause is a visit that was never scanned.
Do wallet passes update without the customer opening anything?
Yes. The server sends a silent push to the phone, the phone calls the pass web service over HTTPS, and Wallet replaces the installed pass with a newly signed version. The customer sees the new number the next time they look, with no app installed and no action taken.
How long does a wallet pass take to update?
A few seconds in the normal case. Waya's queue worker runs every 30 seconds and is also triggered the moment a balance changes, and the update itself is two HTTPS requests after the push lands. Push delivery is best-effort, so a phone in Low Power Mode or out of coverage may see the change minutes later.
If I delete the pass and add it again, do I lose my stamps?
No. The stamp count is stored on the server, and the pass file on your phone is only a view of it. Scanning the same shop QR code or opening the same enrollment link returns the same card with the same balance.
Do customers need an app for a self-updating loyalty card?
No. Apple Wallet and Google Wallet ship with the phone, and the refresh mechanism is part of the operating system rather than an app. On Waya, enrollment is a QR scan, a first name and a mobile number, then one tap to add the pass, and the free plan covers up to 100 customers and 100 wallet messages a month.