Wallet Cards

Members can add a membership card to Apple Wallet or Google Wallet and show it to prove membership away from your site — at a club shop, a partner offering a members’ discount, or the gate.

You supply the credentials. Both platforms bind a card to the organisation issuing it, so the certificates and accounts are yours, not Headcount’s — no plugin can ship them. You will need an Apple Developer account for Apple Wallet, and a Google Cloud project plus a Google Pay & Wallet Console issuer account for Google Wallet. Either can be used on its own.

What a Card Shows

The member’s name, their plan, their status, and the date the membership runs out — plus a QR code.

The Scan

Scanning the QR opens a verification page on your own site. It answers Valid or Not valid in one word, with the member’s name and expiry underneath.

This is deliberately a URL rather than an opaque token: the people scanning it are shop staff with no app and no reader hardware. A plain phone camera is enough, and nothing has to be installed anywhere for the card to be useful.

Style it yourself by adding headcount/wallet/verify.twig to your own templates directory — it receives valid (boolean) and card (the card’s fields, or null). Requesting the same URL with Accept: application/json returns the answer as JSON, if you would rather build a scanner app around it.

Apple Wallet Setup

From your Apple Developer account you need four things:

  1. A Pass Type ID registered under Identifiers — for example pass.com.yourclub.membership.
  2. Its certificate, downloaded and then exported from Keychain Access as a .p12 file.
  3. Apple’s WWDR intermediate certificate in .pem form.
  4. Your ten-character team identifier.

Enter these under Headcount → Settings → Wallet Cards. Store both certificate files outside your web root, and put the .p12 password in an environment variable — every field on that screen accepts one.

You also need an image directory containing at least icon.png. Apple rejects a pass with no icon. Optionally add [email protected], logo.png and [email protected].

Keeping Cards Up To Date

Leave Keep Cards Up To Date on and Headcount runs Apple’s pass web service: devices register themselves against each card, and whenever a membership changes Headcount sends a silent push so the phone re-fetches it. A membership cancelled in March greys out in the member’s wallet straight away instead of waiting for its expiry date.

This needs two things of your server:

  • HTTPS with a valid certificate. Devices silently refuse to register otherwise — there is no error a member would see.
  • PHP with curl built against HTTP/2. Apple’s push service speaks nothing else.

Turn it off and cards are still issued and still carry their expiry date, so a season card stops looking valid on its own. Only mid-term changes go unnoticed on the device.

Google Wallet Setup

From the Google Pay & Wallet Console:

  1. Create an issuer account and note its numeric issuer ID.
  2. Create a Google Cloud service account with the Wallet Object Issuer role, authorise it in the console, and download its JSON key.

Point the settings at the key file — again, outside your web root. Google needs no per-device machinery: the card lives on Google’s servers, so an update is a single API call that reaches every device the member added it to.

Linking to Cards

Each helper returns null when that platform is not configured, so a site issuing only Google cards needs no conditional of its own:

{% if craft.headcount.walletEnabled() %}
  {% for sub in craft.headcount.subscriptions() %}
    {% set appleUrl = craft.headcount.appleWalletUrl(sub) %}
    {% if appleUrl %}
      <a href="{{ appleUrl }}">Add to Apple Wallet</a>
    {% endif %}

    {% set googleUrl = craft.headcount.googleWalletUrl(sub) %}
    {% if googleUrl %}
      <a href="{{ googleUrl }}">Save to Google Wallet</a>
    {% endif %}
  {% endfor %}
{% endif %}

Members can only download their own cards. Control-panel users with the Manage subscriptions permission can download any member’s card from that subscription’s page, which is the quickest way to check what a member is actually seeing.

Privacy

Cards carry no secret you would mind being photographed. The membership number on the card is derived from the subscription’s identifier, not from a sequential ID, so it reveals nothing about how many members you have or who joined first — and the token in the QR code is scoped to verification only, so capturing it grants nothing beyond the answer the scan page already gives.

More in Site Features

Pairs well with Headcount

The bigger pieces a client asks for by name. Events, bookings, memberships, courses, reviews, a support desk, job listings and the rest.