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 { initialize } from '@weavr-io/push-provisioning-react-native';

export default function App() {
const [hasGooglePay, setHasGooglePay] = useState();

useEffect(() => {
const environment = 'Sandbox'; // or 'Production'
const uiKey = 'MY-UI-KEY; // As obtained via the Weavr portal
return initialize(environment, uiKey);
}, [])

checkGooglePayAvailability().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 />
);
}

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 getCardStatus function:

import {
AddToWalletButton,
getCardStatus,
} from "@weavr-io/push-provisioning-react-native";

getCardStatus(
"<Last four digits of the PAN>",
"<Card Description>",
"phone" /* or ‘watch’, or ‘either’ */
)
.then((state) => {
switch (state) {
case "NotProvisioned":
setCanShowButton(true);
default:
setCanShowButton(false);
}
})
.catch(console.error);

getCardStatus 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 getCardStatus 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 NotProvisioned or NeedsIdentityVerification, 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"
style={styles.payButton}
cardHolderName="<Card Holder Name>"
cardDescription="<Card description>"
cardLastFour="<PAN Last Four>"
cardBrand="<Card Brand>"
cardId="<Card ID>"
authenticationToken="<User auth token>"
onComplete={({ error }) => {
if (error) {
console.error(error);
return;
}

// Success
}}
/>

The parameters accepted by the component are:

  • cardHolderName - String. The full name of the cardholder.
  • cardDescription - String. The friendly name, that was provided at card creation.
  • cardLastFour - String. The last four digits of the long card number
  • androidAssetSource - This element sets the source of the AddToWalletButton for Google Pay. Please make sure it complies with Google’s brand guidelines.
  • cardBrand: String. The card scheme, or brand of the card. "MASTERCARD" or "VISA"
  • cardId: String. The Weavr unique reference/identifier for the card.
  • authenticationToken: String. User authentication token (access token) of the specific session, needed to validate the current session.
  • onComplete: Called when the card is added to Apple Wallet. It includes an error that is null if the card was added.

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,
initialize
} from '@weavr/react-native';

export default function App() {
const [cardStatus, setCardStatus] = useState<CardStatus | undefined>();
useEffect(() => {
const environment = 'Sandbox'; // or 'Production'
const uiKey = 'MY-UI-KEY; // As obtained via the Weavr portal
initialize(environment, uiKey);

// Perform a card status check to see if card can be added. Here we just check the phone
// but can do more than one check, or use `either` if preferred.
getCardStatus('<PAN Last Four>', '<Card Description>', 'phone').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>"
cardBrand="<Card Brand>"
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>
);
}

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 so that the user can also provision a card from within Apple Wallet, rather than just from your app.

To achieve this requires you to configure the iOS project, as well as adding native code for the Wallet Extensions. Please 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

Please refer to the native sections on error handling: