I designed and built this system end-to-end. The wallet pass and its brand-configurable theming, the staff scanner embed and its UX, the auto-issuance and auto-revocation automations, the Apps Script backend, the Airtable schema, and the per-brand deployments. It replaced manual paper pickup lists across every venue and gave brands their first real reporting on member behavior.
The work started from two real problems that brands and venue staff were running into. Solving both at once is why the system spans member identity, staff redemption, brand reporting, and venue operations in one loop.
Brands couldn't tell how often members were showing up, what they were redeeming, or how frequently. Front-of-house staff often didn't know what each member's actual benefits were, or what limitations applied. Members would arrive, ask for a pour or a bottle, and staff would have to guess, ask the brand, or quietly say no.
A scan that surfaces what redemptions are available to the member at that exact moment, what the guidelines are, and a way to log each redemption as it happens. Real reporting back to the brand about who's showing up and what they're using.
The previous workflow leaned on an Airtable CRM where bottle pickups, gifts, and merch were tracked. It required a central computer or iPad with someone logged in. Staff resisted using it. Some brands printed paper lists at the front desk, highlighted them by hand, then bulk-updated the CRM after the fact. Updates lagged, errors compounded, members got confused, brands lost the data.
A tool any staff member could use on any device (company-issued or personal) that checked pickup eligibility in real time and marked items as picked up the moment they were handed over. No central computer. No paper. No after-the-fact reconciliation.
From the wallet pass on a member's phone to the activity row in Airtable, the whole loop runs through this stack. Same shape for every brand, customized at each layer.
Every brand is wired the same way. Per-brand variation lives in the embed (themed UI, action vocabulary), the script (action types, cap rules, fallback logic), and the Airtable schema (which aggregate fields to track). Same architecture, different soul.
Within the wallet pass format (a header strip, a hero band, a body band, and a centered QR) I designed the full brand layer for every program. A custom hero graphic per brand, brand mark assets, the color palette across all four bands, and the field choices that surface what staff need to read at a glance. The pass is one surface; I designed and built the rest of the system around it.
Brand identity for each program is set upstream: logo, mark, color palette, voice. By the time a pass is built, the brand kit already exists. Each pass adds a custom hero graphic (often a photographic distillery aerial, a brand environment shot, or an illustration) and applies the existing kit across the four bands: brand mark in the header, color palette across header, hero, body, and accent, and the field labels. The pass extends the program's identity rather than reinventing it.
Two fields earn visual prominence on the pass itself: Member ID in the header, the unique identifier referenced on every interaction, and Plan Type in the body (Family, Individual, or whatever tier structure the program uses). Staff at the door can read both before they even reach for the scanner.
Everything else lives downstream of the QR. The pass doesn't try to surface it.
The pass arrives in the wallet automatically when membership is created, and disappears automatically when membership ends. The whole loop runs through Stripe and Memberstack webhooks plus a Zapier automation layer talking to PassKit. No manual issuance. No manual revocation.
The moment a membership is created, the pass is issued. The member never logs into a portal, never downloads a PDF, never requests a card. They just get one.
When a plan is canceled, fails to renew, or expires, the pass is automatically revoked from the member's wallet. They can no longer access it. The credential is gone the moment the membership is.
Why this matters: the pass mirrors the membership state in real time, with zero manual ops in between. No staff time spent issuing or pulling cards. No member confusion about whether their card is current. The card is always exactly as live as the underlying membership, because the same source of truth controls both.
Every brand's redemption page lives at [brand].vip/admin/redeem. First-time staff configure the device once. Then the scanner runs all day across back-to-back members.
Plus three more transient states: loading, success (after a redemption), and error. Every screen leads with the staff-use-only banner and the device label, so it's always clear which iPad is logging which action.
What the system does between the moment a member shows their pass and the moment the activity row exists.
Wallet pass appears on the member's phone or Apple Watch. QR code is the credential.
Camera reads the QR. URL params (id, first, last, email) open the brand's redemption page pre-filled.
Embed calls Apps Script. Script returns aggregate stats and any pending bottle / merch pickups.
Check-in, pour, cocktail, thieving, hunt, or pickup, depending on the brand. Caps and rules apply automatically.
Activity row written to Airtable. Aggregate counts increment. Pickup status updates if applicable. Member view refreshes.
A sample of brand-themed passes from across the ecosystem. Same field structure, same wallet integration. The brand layer customizes color, type, voice, and the small details that make each program feel like its own thing.
A scanner that just logged taps would last about a week before staff and members noticed the gaps. Three pieces of logic do the heavy lifting in the field.
Some programs have a daily pour cap (Private Stock Society) and others have annual caps (Cedar Ridge's "Pours This Year"). The scanner reads the current count from the aggregate, shows a "limit reached" badge tucked under the pour button, and disables the action unless an authorized override is invoked.
Date logic resets the daily counter at midnight. The aggregate field stores the count plus the date it applies to, so the script can detect a stale day and reset cleanly.
A real-world problem: bottle pickups arrive under one household email, but the member who shows up is the spouse on a different email. Before the fallback, the system would say "no pickups available," a real bottle would go home unscanned, and the additional family member would feel, fairly, like they weren't really part of the program.
The fallback queries an optional Members table by Family: Email, retries the pickup lookup under the primary email, and surfaces a subtle email indicator on the pickup card so staff know which email resolved the match. The additional member sees their family's pickups, picks up their bottle, feels included.
One brand had been holding off on adoption specifically because of this issue. They came online happily after this shipped.
Every action logs the device that performed it (Front Desk iPad, Sarah's Phone) plus an auto-generated device ID. Useful for ops, debugging, and venue accountability.
Critical detail: localStorage keys are prefixed per brand (fr_, cc_, pss_) so a single shared iPad at a multi-brand event doesn't bleed device names or staff confirmations between programs.
Many loyalty passes lean on points, badges, and progress bars. We deliberately removed all of that from the front. The pass shows who the member is and what tier they're in, nothing else. The result is a surface that feels like a credential, not a video game HUD.
Lost some at-a-glance progression cues. Gained durability across categories: a credential design that feels right for a heritage spirits society and a sports club and a hospitality program.
We locked field positions, type rhythm, and the scanner's state shapes. Brand teams customize gradient color, brand mark, program label, action vocabulary, and voice. They don't move fields, change hierarchy, or add modules.
Less brand expressiveness on a per-pass basis. In return, every brand's pass and scanner read correctly to every member and staffer, and we ship new programs in days instead of weeks.
The temptation with internal tools is to ship something functional and ugly. We didn't. The scanner has a polished setup state, a clear staff-only confirmation, full UI states for loading, success, and error, and per-brand theming. Staff are the most-frequent users of this system, and treating their app as a real product changed the operational quality.
More design and engineering surface area. In return, the scanner became a reliable production tool that staff trust, and the brand felt continuous from member surface to staff surface.
Caps, fallbacks, and overrides could've been client-side rules. We pushed them into the Apps Script and Airtable schema, where they belong. The embed is presentation; the script is logic; Airtable is truth. That separation made it possible to reuse the same embed across more than a dozen brands with as many different rule sets.
Slightly more deployment overhead per brand. In return, the system has held up across every implementation without rewriting the front-end embed for any of them.
The system was designed to be reused, not rebuilt. Once the first deployment proved the architecture, the next ten came online with progressively less custom work, validating the "design once, theme everywhere" model in real time.
Beyond the numbers: brands gained their first real reporting on member behavior. Frequency of visit, which benefits got used, where redemptions clustered. Staff stopped guessing what a member was eligible for. Adoption was universal: every brand on the platform retired their paper pickup lists, highlighted printouts, and after-the-fact CRM reconciliation. Programs that had been running on heroics started running on a system, and the ecosystem keeps growing.
And brands started using the data to make actual program decisions. Daily and annual pour caps now get set from real usage data instead of educated guesses. Benefits that members never redeem get identified and retired. The program design tightens because the system finally tells brands what's actually happening at their venues.
The hardest part wasn't the wallet pass. It was the staff scanner. Members see the pass for two seconds; staff use the scanner for hours. It had to be fast, forgiving, and obvious enough to hand to a new bartender on their first shift, on whatever device happened to be in their hand. That's where most of the design rigor went.
The other lesson was about who owns the workflow. The previous system asked staff to log into a CRM no one wanted to use. This one asked them to do something they were already doing (looking at a member's card) and gave them the answer instantly. The behavior change went away because the friction did.
The third lesson was about scope. I could have stopped at one brand and called it a feature. I didn't. I treated the first deployment as a template and the second as a stress test. By the third, the patterns were obvious. A dozen brands came online in under three months, with more rolling out continuously. The reusability wasn't an accident; it was the design.
What I'd push next: bringing this under a true platform instead of a Webflow embed. A secure native app for staff would unlock offline support, push notifications when members arrive, faster scan-to-action loops, and proper role-based permissions. The current Webflow + Apps Script + Airtable stack proved the system worked across a dozen+ brands. The next stage is consolidating it into the kind of product that scales beyond manual deployment per brand.