@ordernow/capacitor-pass-to-wallet
v1.2.10
Published
Add passes to Apple Wallet (PassKit) and Google Wallet (Google Pay API) from Capacitor apps
Maintainers
Readme
@ordernow/capacitor-pass-to-wallet
Add passes to Apple Wallet (PassKit) and Google Wallet (Google Pay API) from Capacitor apps
Why this plugin
- One package, both wallets. Apple Wallet on iOS, Google Wallet on Android, one API, one install, for Capacitor 6, 7 and 8.
- Official buttons, ready to use. Drop
<pass-to-wallet-button>into any page (Angular, React, Vue or plain HTML) and listen forwalletclick:- iOS: the real
PKAddPassButtonas Apple requires in apps, drawn natively over the web view. It follows the element while the page scrolls, animates or opens a modal, and hides when something covers it. - Android: Google's official "Add to / View in Google Wallet" artwork in 70+ languages, matched to your page or device language. Only the language in use is downloaded.
- iOS: the real
- Sized your way, never distorted. Pick the one-line (
button) or two-line (badge) Apple button, set a width and height, and the button scales as a whole with Apple's proportions kept. - A "View in Wallet" button too. Apple has no official control for passes already added; the plugin gives you one you can restyle with CSS and your own label.
- A predictable add flow.
addPassresolves only after the add sheet closes, andpassExiststells you whether the pass actually landed in Wallet, so your app (or server) never records a pass the user cancelled. - Your backend stays yours. The plugin never signs or stores passes: issue the
.pkpass(Apple) or the save JWT (Google) from any server you like. - No extra dependencies. Only
@capacitor/coreas a peer dependency.
Compatibility
| Capacitor | iOS | Android | | --- | --- | --- | | 6.x | 13+ | Java 17+ | | 7.x | 14+ | Java 17+ | | 8.x | 15+ | Java 17+ |
One source for all three (peerDependencies: @capacitor/core >=6 <9). Built and checked against 6.2.2, 7.6.9 and 8.5.3 on both platforms.
Install
npm install @ordernow/capacitor-pass-to-wallet
npx cap synciOS
- Add the Wallet capability:
com.apple.developer.pass-type-identifierswith your Pass Type ID. PKAddPassButtonand the add sheet follow the app language only for languages listed inCFBundleLocalizations(Info.plist).
Android
Nothing to configure: com.google.android.gms:play-services-pay comes with the plugin (override with playServicesPayVersion in variables.gradle).
Wallet button
import '@ordernow/capacitor-pass-to-wallet'; // registers <pass-to-wallet-button><pass-to-wallet-button mode="add" variant="button"></pass-to-wallet-button>
<pass-to-wallet-button mode="view">Open in Apple Wallet</pass-to-wallet-button>| Attribute | Values | Default |
| --- | --- | --- |
| mode | add · view (already added) | add |
| variant | button (iOS one-line, Google button) · badge (iOS two-line, Google badge) | button |
- iOS:
mode="add"is the officialPKAddPassButton, drawn natively over the element and kept in place while the page scrolls or animates (hidden when anything covers it).mode="view"is yours to design (see below): Apple has no official control and only suggests a link labelled like "View in Wallet". - Android: Google's official "Add to / View in Google Wallet" artwork in the page language: the nearest
langattribute (on the element or<html>, so apps with their own language setting just keep<html lang>current), then the device language (navigator.languages), then English. Only the chosen language is downloaded. - iOS draws
PKAddPassButtonin the app's iOS language (device or per-app language in iOS Settings, limited toCFBundleLocalizations); Apple offers no way to set it from the web page. - Web: renders nothing.
- Size: CSS
--pass-to-wallet-height(Google default48px; width follows the artwork). The iOS add button defaults to iOS's own size for itsvariant; set--pass-to-wallet-height(width follows iOS's ratio) and/or--pass-to-wallet-widthto change it: the button scales as a whole to fit (Apple's proportions kept) and its background fills the box.
Customizing the Apple "view" button
Official artwork (PKAddPassButton, Google's badges) must not be altered, so only the iOS mode="view" button is customizable. By default it is a link-style "View in Wallet" in the surrounding font (inherited from the parent).
<!-- Content: any HTML, e.g. your translated label and an icon -->
<pass-to-wallet-button mode="view">
<img src="wallet.svg" alt="" /> View in Wallet
</pass-to-wallet-button>/* Quick tweaks */
pass-to-wallet-button {
--pass-to-wallet-color: #000;
--pass-to-wallet-font: 600 15px system-ui;
}
/* Full control */
pass-to-wallet-button::part(button) {
background: #000;
color: #fff;
border-radius: 12px;
padding: 0 20px;
}- Taps fire
walletclick. Issuing the pass and callingaddPass/savePassesJwtstays with the app.
Angular: add CUSTOM_ELEMENTS_SCHEMA to the component, then (walletclick)="add()".
API
canAddPasses()passExists(...)openPass(...)addPass(...)addButtonSize(...)showAddButton(...)hideAddButton()addListener('addButtonTap', ...)isAvailable()savePassesJwt(...)openGooglePass(...)openGoogleWallet()- Interfaces
- Type Aliases
canAddPasses()
canAddPasses() => Promise<{ canAdd: boolean; }>iOS only. PKAddPassesViewController.canAddPasses().
Returns: Promise<{ canAdd: boolean; }>
passExists(...)
passExists(ref: ApplePassRef) => Promise<{ exists: boolean; }>iOS only. Whether the pass is in this device's Wallet.
| Param | Type |
| --------- | ----------------------------------------------------- |
| ref | ApplePassRef |
Returns: Promise<{ exists: boolean; }>
openPass(...)
openPass(ref: ApplePassRef) => Promise<void>iOS only. Opens the pass in Wallet; rejects when it is not on the device.
| Param | Type |
| --------- | ----------------------------------------------------- |
| ref | ApplePassRef |
addPass(...)
addPass(options: { base64: string; }) => Promise<void>iOS only. Shows the system add sheet for a signed .pkpass (base64).
Resolves once the sheet is dismissed, added or cancelled: call
passExists to know which.
| Param | Type |
| ------------- | -------------------------------- |
| options | { base64: string; } |
addButtonSize(...)
addButtonSize(options?: { layout?: AddButtonLayout | undefined; } | undefined) => Promise<AddButtonSize>iOS only. Natural size of PKAddPassButton in a layout (default one-line).
| Param | Type |
| ------------- | ------------------------------------------------------------------------- |
| options | { layout?: AddButtonLayout; } |
Returns: Promise<AddButtonSize>
showAddButton(...)
showAddButton(frame: AddButtonFrame) => Promise<void>iOS only. Draws the official PKAddPassButton over frame in frame.layout,
scaled as a whole to fit (Apple's proportions kept); taps arrive as addButtonTap events.
| Param | Type |
| ----------- | --------------------------------------------------------- |
| frame | AddButtonFrame |
hideAddButton()
hideAddButton() => Promise<void>iOS only. Hides the native add button.
addListener('addButtonTap', ...)
addListener(eventName: 'addButtonTap', listenerFunc: () => void) => Promise<PluginListenerHandle>iOS only. The native add button was tapped.
| Param | Type |
| ------------------ | --------------------------- |
| eventName | 'addButtonTap' |
| listenerFunc | () => void |
Returns: Promise<PluginListenerHandle>
isAvailable()
isAvailable() => Promise<{ available: boolean; }>Android only. PayClient.getPayApiAvailabilityStatus(SAVE_PASSES);
false also when the check itself fails.
Returns: Promise<{ available: boolean; }>
savePassesJwt(...)
savePassesJwt(options: { jwt: string; }) => Promise<{ saved: boolean; }>Android only. PayClient.savePassesJwt with a signed save JWT.
Resolves when the save screen returns: saved is true when the user saved
the pass, false when they cancelled. Rejects with code SAVE_ERROR on
SavePassesResult.SAVE_ERROR.
| Param | Type |
| ------------- | ----------------------------- |
| options | { jwt: string; } |
Returns: Promise<{ saved: boolean; }>
openGooglePass(...)
openGooglePass(options: { url: string; }) => Promise<void>Android only. Opens a saved pass link
(https://pay.google.com/gp/v/object/{issuerId}.{objectId}) in Google
Wallet, falling back to the browser when Google Play services is missing.
| Param | Type |
| ------------- | ----------------------------- |
| options | { url: string; } |
openGoogleWallet()
openGoogleWallet() => Promise<void>Android only. Opens the Google Wallet app (wallet.google.com when it is not installed), for passes without a working object link.
Interfaces
ApplePassRef
Identifies a pass already in Apple Wallet.
| Prop | Type |
| ------------------------ | ------------------- |
| passTypeIdentifier | string |
| serialNumber | string |
AddButtonSize
| Prop | Type |
| ------------ | ------------------- |
| width | number |
| height | number |
AddButtonFrame
CSS px from getBoundingClientRect() (= points relative to the web view).
| Prop | Type | Description |
| ------------ | ----------------------------------------------------------- | ------------------- |
| x | number | |
| y | number | |
| layout | AddButtonLayout | Default one-line. |
PluginListenerHandle
| Prop | Type |
| ------------ | ----------------------------------------- |
| remove | () => Promise<void> |
Type Aliases
AddButtonLayout
iOS shows one line whenever the button is at least as wide as that layout's natural width.
'one-line' | 'two-line'
Support
If this plugin saves you time, you can support its development via PayPal.
