WalletPasses.EventHandler behaviour (wallet_passes v0.6.0)

Copy Markdown View Source

Behaviour for reacting to wallet pass lifecycle events from both Apple and Google.

Configure with:

config :wallet_passes, :event_handler, MyApp.WalletEventHandler

All callbacks are optional — implement only the ones you care about.

Callbacks run asynchronously in a supervised Task (see WalletPasses.EventHandler.Dispatch) so they cannot extend Apple/Google response times. Their return value is ignored. Exceptions are captured, logged, and reported via telemetry; they do not bring down the request or the supervisor.

Summary

Callbacks

Fires when a pass is added to a user's wallet.

Fires when an Apple device fetches the latest version of a pass. This is high-volume — iOS may fetch the pass several times per day per device. Treat as informational; do not write a row per fetch to a consumer DB without rate-limiting.

Types

event_meta()

@type event_meta() :: map()

platform()

@type platform() :: :apple | :google

Callbacks

on_pass_added(serial_number, platform, event_meta)

(optional)
@callback on_pass_added(serial_number :: String.t(), platform(), event_meta()) :: any()

Fires when a pass is added to a user's wallet.

  • Apple: when a device registers for push notifications for this pass.
  • Google: when a save callback is received from Google Wallet.

meta:

  • Apple: %{device_library_id: String.t(), push_token: String.t()}
  • Google: %{object_id: String.t(), class_id: String.t(), nonce: String.t(), exp_time_millis: integer()}

on_pass_fetched(serial_number, platform, event_meta)

(optional)
@callback on_pass_fetched(serial_number :: String.t(), platform(), event_meta()) :: any()

Fires when an Apple device fetches the latest version of a pass. This is high-volume — iOS may fetch the pass several times per day per device. Treat as informational; do not write a row per fetch to a consumer DB without rate-limiting.

Google does not have an analogue (Google serves pass updates itself).

meta:

  • Apple: %{}

on_pass_removed(serial_number, platform, event_meta)

(optional)
@callback on_pass_removed(serial_number :: String.t(), platform(), event_meta()) :: any()

Fires when a pass is removed.

  • Google: unambiguous — the user removed the pass from their wallet.
  • Apple: ambiguous. This event fires on any device unregister, which includes iOS push-token rotation, app uninstall, the user disabling notifications for the pass, or genuine pass removal. There is no on-device signal to disambiguate. Treat the Apple variant as "this device is no longer reachable for push," not as a definitive removal signal. For an authoritative wallet-presence check, use WalletPasses.wallet_presence/1 (which reports both platforms separately) or rely on Google's del.

meta:

  • Apple: %{device_library_id: String.t()}
  • Google: %{object_id: String.t(), class_id: String.t(), nonce: String.t(), exp_time_millis: integer()}