Skip to main content
Zupy can deliver a customer’s loyalty card or coupon as an Apple Wallet / Google Wallet pass. As a partner you only tell Zupy which customer and which platform — Zupy generates the pass from the merchant’s existing card/coupon design and template.
Generation is reference-only. The integration cannot personalize the pass (no custom fields, colors, or templates). Zupy builds it from the data and wallet template the merchant already configured — exactly the same pass the customer would get from the program landing page.

How it works

Both the program landing page and the partner API use the same generator (PassGenerationService). The only difference is delivery: The pass_url is the same Apple .pkpass URL / Google Wallet save link the LoyaltyCard carries. The customer opens it to add the card to their wallet.

Generate a loyalty card pass

Request body:
Response (201)
Deliver pass_url to the customer (link, button, QR). Opening it adds the card to their wallet.

Generate a coupon pass

Same idea, plus the issued coupon to wrap:

Check pass status

Returns whether the pass was added/removed by the customer (useful for engagement metrics).

List a customer’s passes

Know if the customer installed the pass (and on which platform)

Before firing a push notification, you usually want to know whether the customer actually added the pass to their wallet — and on which platform — so you can act intelligently (e.g. show an “Add to Wallet” prompt instead of pushing into the void, or send an SMS fallback when no wallet install exists).
The response separates Apple Wallet (per-device list, because PassKit registers each iPhone explicitly) from Google Wallet (flat pass list, because Google syncs across devices server-side and we have no per-device telemetry).
summary.apple.installed + summary.google.installed is the fastest signal: at least one side true means a POST /api/v2/wallet/notifications/ call will reach the customer.

Send a push notification to the wallet pass

Push an update + message into the customer’s wallet pass. The notification fans out automatically to all platforms the customer has the pass installed on — Apple (APNs silent push → iPhone re-downloads the pkpass with the new back-field message) and Google (server-side PATCH on the Wallet object → surfaces in the user’s Google Wallet feed).
Request body Response — 202 Accepted

When to use each type

The choice doesn’t change delivery behavior — it’s metadata that helps the customer’s wallet UI group similar notifications. Pick the one that best matches the trigger.

Notification errors

This is a best-effort fire-and-forget dispatch. A 202 means we accepted the request, not that the push reached the customer’s device. Reasons it may silently drop later:
  • The customer has no wallet pass installed (verify with GET /customers/{id}/wallet-devices/ first if you need a guarantee).
  • The customer uninstalled the pass after generation (Apple returns BadDeviceToken → registration is purged).
  • Rate-limit guard: max 10 notifications per customer per hour (Redis-tracked, returns 202 but logs the throttle).

What the customer actually sees

  • iPhone (Apple Wallet): silent APNs push (no banner) → Wallet quietly re-downloads the pkpass → the back-field "Última Mensagem" updates to your message. The pass icon may pulse briefly on the lock screen depending on iOS settings.
  • Android (Google Wallet): server-side objects.patch → notification appears in the Google Wallet feed with the merchant’s class branding. May trigger a system notification on the device depending on the user’s Wallet notification settings.
Typical latency: 5-15 seconds to APNs, 30-60 seconds to Google. If the iPhone shows the old message after a push, the customer can pull-to-refresh on the pass — that forces a non-conditional GET /v1/passes/.../ and bypasses any stale cache.
Wallet endpoints require a read-write API key (they create passes). Read-only keys get 403 on the create endpoints.