Push provisioning to Apple Pay and Google Pay
Provisioning a card in Apple Pay or Google Wallet requires your app to trigger the provisioning flow.
With the Weavr Provisioning SDK, this process is simplified to:
- Initialise the SDK
- Check the card status so that the flow is only triggered if the card is not yet provisioned
- Trigger the provisioning flow via
AddToWalletButton
Initialise the SDK
The SDK must be initialised as early as possible within your App's lifecycle. For instance, this can be achieved with a useEffect with no dependencies triggered at the root of your app's component.
Some Android devices don't support Google Pay. You should check it's availability, and hide the push provisioning feature from devices that don't support it.
This can be achieved with the following code:
// ... other imports
import { initializeWeavrSDK, isGooglePayAvailable } from '@weavr-io/push-provisioning-react-native';
export default function App() {
const [hasGooglePay, setHasGooglePay] = useState();
useEffect(() => {
const uiKey = 'MY-UI-KEY; // As obtained via the Weavr portal
return initializeWeavrSDK({uiKey});
}, [])
isGooglePayAvailable().then((res: GooglePayCheckResult) => {
if (res.errorMessage) {
console.log(res.errorMessage);
return;
}
setHasGooglePay(res.isAvailable);
});
// Use hasGooglePay within your app while checking that the platform is Android.
return (
<Main />
);
}
Mandatory: Adding google wallet manifest metadata (Android)
Add the following to your AndroidManifest.xml within the <application> tag:
<application>
<!-- ... other declarations ... -->
<meta-data
android:name="com.google.android.gms.wallet.api.enabled"
android:value="true" />
</application>
Without this metadata, Google Pay features will not function correctly.
Check the card status
Once the SDK is initialised, you need to check the status of a card in relation to the device's digital wallet to determine if it can be added. If the card cannot be added you need to hide the add to wallet button.
You can do this with the getCardStatusInWallet function:
import {
AddToWalletButton,
getCardStatusInWallet,
} from "@weavr-io/push-provisioning-react-native";
getCardStatusInWallet(
"<Last four digits of the PAN>",
"either" /* or 'phone', or 'watch' */
)
.then((state) => {
switch (state) {
case "notAdded":
setCanShowButton(true);
default:
setCanShowButton(false);
}
})
.catch(console.error);
getCardStatusInWallet takes the following arguments: the last four digits of the payment card number in a string, a card description, and a device type.
The DeviceType is an enumeration of either phone, watch or either.
The result of a successful call to getCardStatusInWallet is a CardStatus as described in the Card status page.
You should ensure that you only display the Add to Wallet button when the card state is notAdded or requiresActivation, and hide it for all other states.
Add an Add to Wallet button
The SDK offers an AddToWalletButton ReactNative component.
The button should only be shown when a card is in an appropriate state to be added to a digital wallet.
The button can be added to your UI as follows:
<AddToWalletButton
androidAssetSource={Image.resolveAssetSource(AddToGooglePayPNG)}
iOSButtonStyle="onLightBackground"
// Ensure you set the height and width desired or it won't be displayed
style={styles.payButton}
cardHolderName="<Card Holder Name>"
cardDescription="<Card description>"
cardLastFour="<PAN Last Four>"
cardId="<Card ID>"
authenticationToken="<User auth token>"
onComplete={({ error, value }) => {
if (error) {
console.error(error);
return;
}
// Success
console.log(value);
}}
/>
The parameters accepted by the component are:
| Prop | Type | Required | Description |
|---|---|---|---|
style | StyleProp<ViewStyle> | No | Custom style for the component. |
iOSButtonStyle | 'onDarkBackground' | 'onLightBackground' | Yes | Sets the Apple Wallet/Google Pay button style. |
androidAssetSource | ImageSourcePropType | Yes | The image asset to use as the Google Pay button. |
cardHolderName | string | Yes | Sets the card holder name (used only on iOS). |
cardDescription | string | Yes | Sets the card description (used only on iOS). |
cardLastFour | string | Yes | Last 4 digits of the card. Required on Android. |
cardId | string | Yes | The unique identifier for the card. |
authenticationToken | string | Yes | The user's authentication token. |
onComplete | (event: { error: WeavrError | null }) => void | Yes | Called when the flow completes. If error is null, the card was successfully added. |
Deprecated: cardBrand prop (ignored by SDK in v4.0+)
The following code showcases an example screen with the button integrated:
import React, { useState, useEffect } from 'react';
import {
StyleSheet,
View,
Text,
Alert,
Image
} from 'react-native';
import {
AddToWalletButton,
getCardStatus,
initializeWeavrSDK
} from '@weavr/react-native';
export default function App() {
const [cardStatus, setCardStatus] = useState<CardStatus | undefined>();
useEffect(() => {
const uiKey = 'MY-UI-KEY; // As obtained via the Weavr portal
initializeWeavrSDK({ uiKey });
// Perform a card status check to see if card can be added.
getCardStatusInWallet('<PAN Last Four>', 'either').then(setCardStatus);
}, []);
return (
<View style={styles.container}>
<Text>Result: {result}</Text>
{(result === 'NotProvisioned' || result === 'NeedsIdentityVerification') ? (
// Show Add to Wallet button
<AddToWalletButton
androidAssetSource={Image.resolveAssetSource(AddToGooglePayPNG)}
iOSButtonStyle="onLightBackground"
style={styles.payButton}
cardHolderName="<Card Holder Name>"
cardDescription="<Card description>"
cardLastFour="<PAN Last Four>"
cardId="<Card ID>"
authenticationToken="<User auth token>"
onComplete={({ error }) => {
Alert.alert(
error ? error.code : 'Success',
error ? error.message : 'Card was successfully added to the wallet.'
);
}}
/>
) : (
<Text>Card can't be added.</Text>
)}
</View>
);
}
AddToWallet button localisation
iOS localisation
The PKAddPassButton provided by Apple (used by the Weavr React Native SDK) is automatically localised by the system based on the user's device language settings. You do not need to provide your own translations for the button’s title or appearance.
To ensure correct localisation:
- Make sure your app supports the desired languages in your Xcode project settings (
Info.plist>CFBundleLocalizations). - The device language must be set to one of your supported languages.
Android localisation
The Android button will just display the asset image you provide via androidAssetSource, as a result, you are responsible to provide any required localisations for this value.
Apple Wallet Extensions
Once your app is able to provision cards, you also need to set up your app to integrate with Apple Wallet Extensions. This lets the user provision a card from within Apple Wallet, in addition to from your app.
To achieve this requires you to configure the iOS project, as well as adding native code for the Wallet Extensions. Refer to the native SDK instructions: Integration from Apple Wallet using Wallet Extensions on how to set this up.
If you are working on an Expo managed project you may need to either migrate to a non-managed project, or build an equivalent implementation using Expo's app extensions guide.
Error handling
| Error Code | Platform | Scenario | Recommended Action |
|---|---|---|---|
SDK_NOT_INITIALISED | Both | Initialisation missing | Initialise SDK before any call. |
CARD_NOT_PROVISIONED | Both | Attempting to set default for unknown card | Prompt user to add card first. |
NETWORK_ERROR | Both | Connectivity issues | Retry with backoff; surface offline state. |
CARD_NOT_ELIGIBLE | Both | Backend flagged card ineligible | Show user-friendly message; escalate to issuer. |
COULD_NOT_FETCH_PROVIDER | Both | Missing routing data from backend | Validate backend response and provisioning config. |
UNAUTHORIZED | Both | Token unauthorized or missing | Refresh authentication token. |
GOOGLE_PAY_PROVISIONING_PAYLOAD_ERROR | Android | Google Pay SDK payload error | Validate card data and retry. |
INSECURE_DEVICE_ERROR | Android | Device not secure (debugging, rooted) | Inform user; provisioning blocked on insecure devices. |
CLIENT_NOT_AVAILABLE_ERROR | Android | Google Pay client unavailable | Prompt user to update Google Play Services. |
GOOGLE_PAY_ERROR | Android | Google Pay SDK general error | Check device compatibility and Play Services. |
GOOGLE_PAY_TOKEN_ALREADY_EXISTS | Android | Card already provisioned | Update UI to reflect provisioned state. |
GOOGLE_PAY_TOKEN_NOT_FOUND | Android | Token not found in Google Pay | Retry card status check or prompt re-provisioning. |
SETUP_ERROR | Both | Local app misconfiguration | Revisit installation steps; check manifest metadata (Android) or bundle configuration (iOS). |
UNKNOWN_ERROR | Both | Unmapped exception | Capture logs for support. |
Note: Google Pay-specific errors (3000-series) are Android-only. iOS uses Apple Pay which has its own error handling mechanisms.
Device compatibility
| Release | iOS | Android |
|---|---|---|
| 4.0.X | 15.1+ | 24+ |
| 3.0.X | 14+ | 21+ |