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 our Provisioning SDK, this process is simplified to:

  • Initialize 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

Initialize the SDK

The SDK must be initialized 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 its availability, and hide the push provisioningPush Provisioning A method that allows cardholders to add their card to a digital wallet (such as Apple Pay or Google Pay) directly from your app. The card details are securely tokenized and sent to the wallet provider, streamlining the process and enhancing the user experience compared to manual provisioning. This feature is currently in beta. 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 initialized, 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":
case "requiresActivation":
setCanShowButton(true);
break;
default:
setCanShowButton(false);
}
})
.catch(console.error);

getCardStatusInWallet takes the following arguments: the last four digits of the payment card number in a string, 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 React Native 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 prop

The cardBrand prop is deprecated and ignored by the 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,
getCardStatusInWallet,
initializeWeavrSDK
} from '@weavr-io/push-provisioning-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: {cardStatus}</Text>
{(cardStatus === 'notAdded' || cardStatus === 'requiresActivation') ? (
// 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 localization

iOS localization

The PKAddPassButton provided by Apple (used by our React Native SDK) is automatically localized 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 localization:

  • 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 localization

The Android button will just display the asset image you provide via androidAssetSource, as a result, you are responsible to provide any required localizations 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 ExtensionsWallet Extension An iOS app extension that integrates an issuer app with Apple Wallet. The UI Wallet Extension provisions a card from the issuer app into Wallet (the in-app provisioning flow). The Non-UI Wallet Extension exposes the issuer's card-management actions (such as 'View card details') from inside Wallet itself. Apple requires both for a primary issuer-app integration.. 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 ExtensionsWallet Extension An iOS app extension that integrates an issuer app with Apple Wallet. The UI Wallet Extension provisions a card from the issuer app into Wallet (the in-app provisioning flow). The Non-UI Wallet Extension exposes the issuer's card-management actions (such as 'View card details') from inside Wallet itself. Apple requires both for a primary issuer-app integration.. 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

For the unified error shape, the full code reference, and platform-specific notes, see Push provisioning SDK in the React Native Troubleshooting page.

Device compatibility

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