
If you run marketing for local businesses, you already know the problem with loyalty programs: paper punch cards get lost, and almost nobody installs a dedicated app to collect stamps at a coffee shop. A digital loyalty card platform solves that by putting the card where customers already keep their boarding passes and tickets, which is Apple Wallet and Google Wallet. The hard part is not the card itself. It is fitting the whole thing into the tools agencies already use, without adding another login.
This post walks through how we approached that problem for VEXION, a loyalty platform that runs as a hosted app inside GoHighLevel (GHL). We will cover the architecture, why each piece was chosen, and what you should think about if you are building something similar.
What a digital loyalty card platform actually needs to do
Strip away the marketing language and a loyalty system has a short list of jobs:
- Configure a program. Points, stamps, rewards and tiers, set per business.
- Issue a card. Something the customer can carry on their phone and show at the counter.
- Update the card. When a stamp is added or a reward unlocks, the card should reflect it without the customer doing anything.
- Re-engage. Tell the customer about a reward or a promotion at the right moment.
- Manage the lifecycle. Create, update and revoke cards cleanly.
VEXION had one extra requirement that shaped everything else. Agencies were already running client programs inside GoHighLevel, and a separate login for a loyalty tool would have broken that workflow. The system also had to serve three levels at once: the agency, the admin for each client business, and the end customer holding the card.
How to integrate a loyalty app with GoHighLevel SSO
The first architectural decision was authentication. GoHighLevel supports hosted apps that load inside the GHL interface, and it can pass the signed-in user's context to that app. We built VEXION to use GHL SSO, so identity, role and session state flow straight from GoHighLevel into the loyalty system. The result is zero separate logins: an agency user opens the loyalty tool from inside GHL and is already authenticated with the right permissions.
The general pattern for this kind of integration looks like this:
- GHL loads the hosted app and provides an SSO payload identifying the user, their location or sub-account, and their role.
- The backend verifies that payload server-side. Never trust identity data that the browser can modify.
- The backend maps the GHL identity onto its own user and account records, creating them on first use, and issues its own session.
- Every subsequent API call is checked against role-based access control, not just authentication.
That last step matters more than it sounds. Because the platform models an agency, admin and customer hierarchy, "is this user logged in" is the wrong question. The right question is "is this user allowed to touch this specific client's program". An agency user needs a multi-client dashboard. An admin should only ever see their own business. A customer should only see their own card. We enforced those boundaries in the REST API layer so that the frontend cannot accidentally widen them.
If your product lives inside another platform, this is the single most valuable thing to get right. It is the difference between a tool people adopt and a tool people forget the password to. We cover the broader version of this argument in our post on signs your business needs a custom CRM.
Generating Apple Wallet and Google Wallet loyalty passes
Apple Wallet and Google Wallet both support loyalty passes, but they work quite differently, so it pays to design your own internal card model first and treat each wallet as an output format.
Apple Wallet
Apple Wallet passes are signed bundles: a JSON description of the pass plus images, signed with a certificate issued through an Apple Developer account. The pass includes a web service URL and an authentication token, which is what allows the pass to be updated later. When something changes, the server notifies the device through APNs (Apple Push Notification service), the device asks your web service for the latest version, and the pass refreshes in the wallet. Apple's Wallet Passes documentation is the reference for the format.
Google Wallet
Google Wallet uses a class and object model through the Google Wallet API. A loyalty class defines the program and its look, and each customer gets a loyalty object holding their own balance. You update the object through the API and Google pushes the change to the device.
In VEXION, both are generated from the same underlying loyalty record, and the platform handles the full card lifecycle automatically: creating a card when a customer joins, updating it when stamps or points change, and revoking it when needed. The customer-facing card view shows live reward updates, so the wallet card and the web view never disagree.
Design one internal card model and treat each wallet as a renderer. If you start from Apple's or Google's format, you end up maintaining two products.
Why a PWA fallback matters for loyalty cards
Not every device supports Google Wallet, and some customers simply will not add a pass. If the card only exists in a wallet, those customers fall out of the program entirely. VEXION includes a Progressive Web App (PWA) for devices without Google Wallet support, so every customer gets a working card regardless of their phone.
A PWA is a good fit here because a loyalty card is a small, read-mostly interface. The customer needs to open it quickly, show a code or a stamp count, and see what rewards are available. A PWA can be added to the home screen, loads fast, and avoids the friction of an app store install. Most importantly, it reads from the same backend as the wallet passes, so there is still one source of truth.
We are generally cautious about recommending a native app for something this simple. For a loyalty card, wallet passes plus a PWA cover nearly every case. If your product genuinely needs native features, our React Native vs native comparison is a better starting point.
Push notifications: APNs and web push for re-engagement
A loyalty program that never talks to the customer is a discount nobody remembers. VEXION uses event-driven notifications to keep customers up to date on stamp updates, reward unlocks and promotions. Two channels cover the device landscape:
- APNs for Apple Wallet passes, which also triggers the pass to refresh on the device.
- Web push notifications for the PWA and browser-based users.
The design principle we follow is that notifications are side effects of domain events, not something the UI triggers directly. When a stamp is recorded, the system emits an event; the card update, the wallet refresh and the notification all react to that event. This keeps the logic in one place and makes it much harder to end up with a card that says one thing and a notification that says another.
One practical piece of advice: be conservative with promotional pushes. Wallet and web push are permission-based channels, and customers who feel spammed will remove the pass. Reward unlocks and stamp confirmations are welcome. Daily promotions usually are not.
Building for agencies: multi-tenant roles and dashboards
The agency model is what turns a loyalty card generator into a SaaS product. In VEXION, the role hierarchy is agency, then admin, then customer, and each level has its own view:
- Agency dashboard for multi-client management, so one agency can oversee every client business it runs a program for.
- Admin tools for configuring a single business's program: points, stamps, rewards and tiers.
- Customer card view showing the card and live reward balance.
Getting tenancy right early is far cheaper than retrofitting it. Every record should know which agency and which client it belongs to from the first database migration. We wrote more about this in how to build a SaaS MVP that scales, and it applies directly to platforms like this one.
What to consider before building a loyalty platform
If you are planning your own digital loyalty card platform, here is the honest checklist we would walk you through:
- Where do your users already work? If they live in a CRM like GoHighLevel, build inside it with SSO rather than alongside it.
- Do you have the wallet accounts sorted? Apple Wallet requires an Apple Developer account and pass signing certificates. Google Wallet requires issuer access. Sort these out early, because approvals can take time.
- Can every customer get a card? Plan the fallback, such as a PWA, from day one.
- Who owns updates? Make card state server-driven and event-based, so wallets, the PWA and notifications stay consistent.
- Do you actually need a custom build? If you run one business and a single program, an off-the-shelf loyalty tool may be enough. A custom platform earns its cost when you need multi-client management, CRM integration, or your own branded product to resell.
You can see the finished product in our VEXION case study, and the live site is at vexioncards.one.
Frequently Asked Questions
Can a loyalty card in Apple Wallet update automatically?
Yes. Apple Wallet passes can include a web service URL. When the loyalty balance changes, the server sends a push through APNs, the device fetches the updated pass, and the card refreshes without the customer doing anything.
Do customers need to install an app to use a digital loyalty card?
No. Wallet passes live in Apple Wallet or Google Wallet, which are already on the phone. For devices without wallet support, a PWA gives customers a working card in the browser that can be added to the home screen.
How does GoHighLevel SSO work for a hosted app?
GoHighLevel passes the signed-in user's context to the hosted app. The app's backend verifies it server-side, maps it to its own user and account records, and starts a session, so users never need a second username and password.
Is a custom digital loyalty card platform worth it for one business?
Often not. For a single location, an existing loyalty product is usually faster and cheaper. Custom builds make sense for agencies, franchises, or anyone who needs CRM integration, multi-client management, or a white-label product.
If you are planning a loyalty product, a GoHighLevel integration, or any CRM-connected tool, our CRM and business solutions team has done this before and will tell you plainly whether a custom build is the right call. Get in touch and tell us what you are trying to build.
