Skip to main content

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.

note

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:

PropTypeRequiredDescription
styleStyleProp<ViewStyle>NoCustom style for the component.
iOSButtonStyle'onDarkBackground' | 'onLightBackground'YesSets the Apple Wallet/Google Pay button style.
androidAssetSourceImageSourcePropTypeYesThe image asset to use as the Google Pay button.
cardHolderNamestringYesSets the card holder name (used only on iOS).
cardDescriptionstringYesSets the card description (used only on iOS).
cardLastFourstringYesLast 4 digits of the card. Required on Android.
cardIdstringYesThe unique identifier for the card.
authenticationTokenstringYesThe user's authentication token.
onComplete(event: { error: WeavrError | null }) => voidYesCalled 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.

note

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 CodePlatformScenarioRecommended Action
SDK_NOT_INITIALISEDBothInitialisation missingInitialise SDK before any call.
CARD_NOT_PROVISIONEDBothAttempting to set default for unknown cardPrompt user to add card first.
NETWORK_ERRORBothConnectivity issuesRetry with backoff; surface offline state.
CARD_NOT_ELIGIBLEBothBackend flagged card ineligibleShow user-friendly message; escalate to issuer.
COULD_NOT_FETCH_PROVIDERBothMissing routing data from backendValidate backend response and provisioning config.
UNAUTHORIZEDBothToken unauthorized or missingRefresh authentication token.
GOOGLE_PAY_PROVISIONING_PAYLOAD_ERRORAndroidGoogle Pay SDK payload errorValidate card data and retry.
INSECURE_DEVICE_ERRORAndroidDevice not secure (debugging, rooted)Inform user; provisioning blocked on insecure devices.
CLIENT_NOT_AVAILABLE_ERRORAndroidGoogle Pay client unavailablePrompt user to update Google Play Services.
GOOGLE_PAY_ERRORAndroidGoogle Pay SDK general errorCheck device compatibility and Play Services.
GOOGLE_PAY_TOKEN_ALREADY_EXISTSAndroidCard already provisionedUpdate UI to reflect provisioned state.
GOOGLE_PAY_TOKEN_NOT_FOUNDAndroidToken not found in Google PayRetry card status check or prompt re-provisioning.
SETUP_ERRORBothLocal app misconfigurationRevisit installation steps; check manifest metadata (Android) or bundle configuration (iOS).
UNKNOWN_ERRORBothUnmapped exceptionCapture 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

ReleaseiOSAndroid
4.0.X15.1+24+
3.0.X14+21+