Skip to main content

Push Provisioning to Google Pay

Provisioning a card in 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 or WPPComponents.getPushProvisioningLauncher method

Initialise the SDK

The first step is to initialise the Weavr Provisioning SDK by providing a Context, and your UI key obtained from the Weavr Portal.

MyApp.kt
import io.weavr.push_provisioning.WPPComponents
import android.app.Application

class MyApp : Application() {

override fun onCreate() {
super.onCreate()
WPPComponents.initializeWeavrSDK(this, "<MY_UI_KEY>")
}
}

Google Pay availability check

Your app needs to check whether Google Pay is available on the user's device. Consider that some countries and devices do not support Google Pay.

If Google Pay is not present on the device, but the country and device supports it, you can prompt the user to install it from Google Play. If Google Pay is not present and not available, you should not display the feature.

The SDK offers you the WPPComponents.isGooglePayAvailable() method to check if it is present or not.

fun checkGooglePayAvailability() {
WPPComponents.isGooglePayAvailable().onSuccess {
if (it) {
println("Google Pay is available")
} else {
println("Google Pay is NOT available")
}
}.onFailure {
// TODO Handle the WPPException
}
}

Check the card status

Once the SDK is initialised, you have to check the status of a card in relation to Google Wallet.

note

Google Wallet guidelines require you to hide the Add To Wallet prompt when the card is already present in the Wallet.

In this scenario you should inform the user that the card is already provisioned.

To do this check, call the WPPComponents.getCardStatus method, pass the last four digits of the card, and the brand of the card (so far only MasterCard is supported). You can follow this snippet as a baseline:

suspend fun displayButtonIfPossible(card: MyCardModel) {
WPPComponents.getCardStatus(card.cardNumberLastFour, CardBrand.MASTERCARD).onFailure {
// TODO Handle the WPPException
}.onSuccess {
val shouldShowButton = when (it) {
CardStatus.UNAVAILABLE -> false
CardStatus.PROVISIONED -> false
CardStatus.NOT_PROVISIONED -> true
CardStatus.NEEDS_IDENTITY_VERIFICATION -> true
CardStatus.PENDING -> false
CardStatus.SUSPENDED -> false
CardStatus.UNKNOWN -> false
else -> false
}

if (shouldShowButton) showButton()
}
}

The potential states a card can have are listed in the Card Status page.

Provisioning the card

There are two ways to provision a card using the Weavr Provisioning SDK:

  • Using the AddToWalletButton (recommended)
  • Using the WPPComponents.getPushProvisioningLauncher method

Provision a card with AddToWalletButton

AddToWalletButton is a UI Component that encapsulates the logic required to provision a card.

The following snippet showcases how you can create and initialise the button:

fun createButton(card: Card): AddToWalletButton {
val payButton = AddToWalletButton(this)
payButton.setImageResource(R.drawable.dark_no_shadow)
payButton.cardId = card.id
payButton.cardBrand = CardBrand.MASTERCARD
payButton.cardHolderName = card.cardholder
payButton.cardLastFour = card.cardNumberLastFour
payButton.token = "MyToken"

payButton.setAddToWalletListener(object : AddToWalletListener {
override fun onCancelled() {
TODO("Not yet implemented")
}

override fun onSuccess() {
TODO("Not yet implemented")
}

override fun onError(error: WPPException) {
TODO("Not yet implemented")
}
})
return payButton
}

Additionally, you may also include it within your layout xml. However, you'll still need to initialise it's properties via code after locating the button with findViewById:

<io.weavr.push_provisioning.AddToWalletButton
android:id="@+id/addToWalletBtn"
android:layout_width="200dp"
android:layout_height="80dp"
android:src="@drawable/dark_no_shadow"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button">
</io.weavr.push_provisioning. AddToWalletButton>

Provision a card via WPPComponents.getPushProvisioningLauncher

In order to provision a card using the WPPComponents class rather than the AddToWalletButton you need to ensure that you call getPushProvisioningLauncher at the right time, and that you unregister the launcher when your Activity or Fragment is destroyed.

The call to get the launcher may (under the hood) call the registerForActivityResult Android method. This method requires you to call it BEFORE the Activity or Fragment provided are created.

Once the call is made, the SDK provides a launcher object with two methods, a provisionCard method, which attempts to provision the card, and an unregister method, to destroy the launcher.

The unregister method must be called on the onDestroy method of your Activity or Fragment to ensure the resources are released correctly.

Finally, you have to forward the call to your Activity.onActivityResult to WPPComponents.handleOnActivityResult so that the codes and data received can be translated into a meaningful callback to your listener.

The following Activity showcases how this can be implemented:

MyActivity.kt
class MyActivity: AppCompatActivity() {

private val provisioningLauncher = WPPComponents.getPushProvisioningLauncher(this, object: AddToWalletListener {
override fun onSuccess() {
TODO("Not yet implemented")
}

override fun onError(error: WPPException) {
TODO("Not yet implemented")
}

override fun onCancelled() {
TODO("Not yet implemented")
}
})

override fun onActivityResult(
requestCode: Int,
resultCode: Int,
data: Intent?,
caller: ComponentCaller
) {
super.onActivityResult(requestCode, resultCode, data, caller)
WPPComponents.handleOnActivityResult(requestCode, resultCode, data, this)
}

override fun onDestroy() {
provisioningLauncher.unregister()
super.onDestroy()
}
}
note

The SDK supports two different providers to provision cards to maximise up-time and reliability.

As a result, the SDK may use startActivityForResult or not, depending on which provider it is being used to provision the card.

This requires you to respect both this approach, as well as the traditional onActivityResult.