capacitor-apple-wallet
v1.0.8
Published
In-App Provisioning payment cards within an app, without having to go through the process of manually entering payment card details.
Readme
capacitor-apple-wallet
In-App Provisioning payment cards within an app, without having to go through the process of manually entering payment card details.
Install
npm install capacitor-apple-wallet
npx cap syncQuick Example
import { AppleWallet } from 'capacitor-apple-wallet';
const status = await AppleWallet.isTokenized({
primaryAccountIdentifier: '6854707',
});
if (status.isTokenized) {
console.log('Card is already available in Apple Wallet');
}API
startProvisioning(...)completeProvisioning(...)cancelProvisioning(...)isTokenized(...)syncExtensionState(...)clearExtensionState()getExtensionAuthToken()addListener('walletProvisioningData', ...)removeAllListeners()getButtonText()checkWalletStatus()addPass(...)- Interfaces
- Type Aliases
- Enums
startProvisioning(...)
startProvisioning(options: StartProvisioningOptions) => Promise<AddCardResult>| Param | Type |
| ------------- | ----------------------------------------------------------------------------- |
| options | StartProvisioningOptions |
Returns: Promise<AddCardResult>
completeProvisioning(...)
completeProvisioning(options: CompleteProvisioningOptions) => Promise<void>| Param | Type |
| ------------- | ----------------------------------------------------------------------------------- |
| options | CompleteProvisioningOptions |
cancelProvisioning(...)
cancelProvisioning(options?: CancelProvisioningOptions | undefined) => Promise<void>| Param | Type |
| ------------- | ------------------------------------------------------------------------------- |
| options | CancelProvisioningOptions |
isTokenized(...)
isTokenized(options: IsTokenizedOptions) => Promise<IsTokenizedResult>| Param | Type |
| ------------- | ----------------------------------------------------------------- |
| options | IsTokenizedOptions |
Returns: Promise<IsTokenizedResult>
syncExtensionState(...)
syncExtensionState(options: { state: AppleWalletExtensionState; }) => Promise<SyncExtensionStateResult>| Param | Type |
| ------------- | ------------------------------------------------------------------------------------------- |
| options | { state: AppleWalletExtensionState; } |
Returns: Promise<SyncExtensionStateResult>
clearExtensionState()
clearExtensionState() => Promise<void>getExtensionAuthToken()
getExtensionAuthToken() => Promise<GetExtensionAuthTokenResult>Returns: Promise<GetExtensionAuthTokenResult>
addListener('walletProvisioningData', ...)
addListener(eventName: 'walletProvisioningData', listenerFunc: (event: ProvisioningDataEvent) => void) => Promise<PluginListenerHandle>| Param | Type |
| ------------------ | ------------------------------------------------------------------------------------------- |
| eventName | 'walletProvisioningData' |
| listenerFunc | (event: ProvisioningDataEvent) => void |
Returns: Promise<PluginListenerHandle>
removeAllListeners()
removeAllListeners() => Promise<void>getButtonText()
getButtonText() => Promise<{ value: string; }>Returns: Promise<{ value: string; }>
checkWalletStatus()
checkWalletStatus() => Promise<CheckWalletStatusResult>Returns: Promise<CheckWalletStatusResult>
addPass(...)
addPass(options: AddPassOptions) => Promise<AddPassResult>| Param | Type |
| ------------- | --------------------------------------------------------- |
| options | AddPassOptions |
Returns: Promise<AddPassResult>
Interfaces
AddCardResult
| Prop | Type |
| -------------------------------- | ---------------------------------- |
| status | 'added' | 'canceled' |
| primaryAccountIdentifier | string |
| primaryAccountNumberSuffix | string |
| deviceAccountIdentifier | string |
| deviceAccountNumberSuffix | string |
StartProvisioningOptions
| Prop | Type |
| ------------------------------ | --------------------------------------------------------- |
| primaryAccountSuffix | string |
| cardholderName | string |
| cardId | string |
| paymentNetwork | PaymentNetwork |
| primaryAccountIdentifier | string |
| localizedDescription | string |
CompleteProvisioningOptions
| Prop | Type |
| ------------------------ | ------------------- |
| activationData | string |
| encryptedPassData | string |
| ephemeralPublicKey | string |
CancelProvisioningOptions
| Prop | Type |
| ------------ | ------------------- |
| reason | string |
IsTokenizedResult
| Prop | Type |
| ----------------- | -------------------- |
| isTokenized | boolean |
IsTokenizedOptions
| Prop | Type |
| ------------------------------ | -------------------- |
| primaryAccountIdentifier | string |
| includeRemote | boolean |
SyncExtensionStateResult
| Prop | Type |
| ----------- | ------------------------- |
| cards | WalletCard[] |
WalletCard
| Prop | Type |
| -------------------------------- | -------------------- |
| primaryAccountIdentifier | string |
| primaryAccountNumberSuffix | string |
| deviceAccountIdentifier | string |
| deviceAccountNumberSuffix | string |
| isRemote | boolean |
AppleWalletExtensionState
| Prop | Type |
| --------------- | ----------------------------------------------------------------------------------- |
| session | AppleWalletExtensionSession |
| updatedAt | number |
AppleWalletExtensionSession
| Prop | Type |
| ------------------------ | ------------------- |
| extensionAuthToken | string |
| lang | string |
| deviceId | string |
| securedToken | string |
GetExtensionAuthTokenResult
| Prop | Type |
| ------------------------ | ------------------- |
| extensionAuthToken | string |
PluginListenerHandle
| Prop | Type |
| ------------ | ----------------------------------------- |
| remove | () => Promise<void> |
ProvisioningDataEvent
| Prop | Type |
| ------------------------------ | --------------------- |
| primaryAccountIdentifier | string |
| cardId | string |
| certificates | string[] |
| nonce | string |
| nonceSignature | string |
CheckWalletStatusResult
| Prop | Type |
| ----------------- | ---------------------------------- |
| iphone | AppleWalletCardData[] |
| watch | AppleWalletCardData[] |
| watchPaired | boolean |
AppleWalletCardData
| Prop | Type |
| -------------------------------- | ------------------------------------------------------------- |
| serialNumber | number |
| primaryAccountIdentifier | string |
| primaryAccountNumberSuffix | number |
| activationState | ACTIVATION_STATE |
| deviceName | string |
AddPassResult
| Prop | Type |
| ------------------------ | ---------------------------------- |
| status | 'added' | 'canceled' |
| serialNumber | string |
| passTypeIdentifier | string |
AddPassOptions
| Prop | Type | Description |
| -------------- | ------------------- | ------------------------------------------------- |
| passData | string | Base64-encoded contents of a signed .pkpass file. |
Type Aliases
ACTIVATION_STATE
'ACTIVATED' | 'REQUIRES_ACTIVATION' | 'SUSPENDED' | 'DEACTIVATED' | 'INACTIVE'
Enums
PaymentNetwork
| Members |
| ------------------ |
| interac |
| JCB |
| mada |
| maestro |
| masterCard |
| mir |
| privateLabel |
| quicPay |
| suica |
| visa |
| vPay |
| barcode |
| girocard |
| waon |
| nanaco |
| postFinance |
| tmoney |
Adding .pkpass
addPass accepts a ready-made, signed .pkpass file encoded as base64. Apple Wallet does not accept the raw JSON payload directly, so the pass package must be assembled and signed on your backend first.
import { AppleWallet } from 'capacitor-apple-wallet';
await AppleWallet.addPass({
passData: pkpassBase64,
});What backend should build
Your backend should build a .pkpass archive with at least these files:
pass.jsonicon.png[email protected]logo.pngand[email protected]if you want a header logomanifest.jsonsignature
The high-level flow is:
- Build
pass.json. - Add required images.
- Compute SHA-1 hashes for every file and write them to
manifest.json. - Sign
manifest.jsonwith your Apple Wallet Pass Type ID certificate. - Zip the files into a
.pkpass. - Return the
.pkpassbytes as base64 to the app.
Example pass.json
This is a minimal generic pass with a QR code:
{
"formatVersion": 1,
"passTypeIdentifier": "pass.com.yourcompany.app",
"serialNumber": "1234567890",
"teamIdentifier": "YOUR_TEAM_ID",
"organizationName": "Your Company",
"description": "QR Pass",
"logoText": "Your App",
"foregroundColor": "rgb(255,255,255)",
"backgroundColor": "rgb(0,0,0)",
"barcode": {
"message": "https://your-link-or-data",
"format": "PKBarcodeFormatQR",
"messageEncoding": "iso-8859-1"
},
"generic": {
"primaryFields": [
{
"key": "title",
"label": "QR",
"value": "Scan me"
}
]
}
}Notes:
passTypeIdentifiermust match the Pass Type ID certificate used to sign the pass.teamIdentifiermust be your Apple Developer Team ID.serialNumbermust uniquely identify this pass within thatpassTypeIdentifier.- For new projects, Apple documents pass creation under Wallet Passes: Building a Pass, Creating a generic pass, Create Wallet identifiers and certificates.
How to get the Apple Wallet certificate
Apple requires a dedicated certificate for signing Wallet passes.
- Sign in to your Apple Developer account.
- Open Certificates, Identifiers & Profiles.
- Create a new
Pass Type ID, for examplepass.com.yourcompany.app. - Create a new certificate of type
Pass Type ID Certificate. - During certificate creation, upload a CSR file.
- Download the generated
.cercertificate from Apple.
Official Apple instructions: Create Wallet identifiers and certificates
How to get the private key
The private key is created on the machine where you generated the CSR.
Typical flow on macOS:
- Open
Keychain Access. - Create a
Certificate Signing Requestfrom Keychain Access. - Finish certificate issuance in Apple Developer and download the
.cer. - Double-click the downloaded
.certo import it into Keychain. - In Keychain Access, find the imported Pass Type ID certificate and expand it.
- You should see the matching private key under that certificate.
- Export the certificate together with the private key as
.p12.
Your backend will usually use:
pass certificateas.pemor.p12private keyfrom that certificate exportWWDRintermediate certificate from Apple
In practice, many backend libraries expect one of these setups:
- a
.p12file plus its password - or extracted
.pemcertificate and.pemprivate key
What the app receives
Once the backend has generated and signed the pass, it should return either:
- raw
.pkpassbytes encoded as base64 - or a downloadable
.pkpassfile that your app converts to base64 before calling the plugin
Then call:
await AppleWallet.addPass({
passData: pkpassBase64,
});