Skip to main content

Google Pay – Flutter SDK

Learn how to integrate Google Pay Push Provisioning into your Flutter app using Nium’s SDK. This guide walks through project setup, Android configuration, SDK integration, and troubleshooting.

Step 1: Create a Flutter project​

  1. Open your terminal and run:
flutter create google_push_provisioning_demo
  1. Navigate into the project directory:
cd google_push_provisioning_demo
  1. Open the project in your preferred IDE (such as VS Code or Android Studio).

Step 2: Add the SDK to your Android project​

  1. Create a libs folder (if it doesn't already exist):
cd android/app
mkdir libs
  1. Move the SDK .aar files into the libs folder:
mv ./NiumPushPay_SDK.aar
./your/path/google_push_provisioning_demo/android/app/libs
  1. Move play-services-tapandpay-17.0.1.aar to /app/libs directory:
mv ./play-services-tapandpay-17.0.1.aar
~/google_push_provisioning_demo/android/app/libs
  1. Update the /build.gradle.kts configuration at the root of the project.
allprojects {
repositories {
flatDir {
dirs("libs")
}
}
}
  1. Add the dependencies in android/app/build.gradle.kts:
dependencies {
implementation(name:'NiumPushPaySDK', ext:'aar');
implementation(name:'play-services-tapandpay-17.0.1', ext:'aar');
}

Step 3: Add card provisioning logic​

You’ll need to implement a method channel in your Flutter app and handle the corresponding logic in native Android code.

Flutter method channel​

Update lib/main.dart:

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: HomePage(),
);
}
}

class HomePage extends StatefulWidget {
@override
_HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
static const MethodChannel _channel = MethodChannel('push_provisioning');

Future<void> provisionCard(Map<String, dynamic> parameters) async {
try {
final result = await _channel.invokeMethod('provisionCard', parameters);
print('Card provisioned: $result');
} on PlatformException catch (e) {
print('Failed to provision card: ${e.message}');
}
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Google Push Provisioning SDK')),
body: Center(
child: ElevatedButton(
onPressed: () => provisionCard({
'cardId': 'CardId',
'additionalParam': 'value',
}),
child: Text('Provision Card'),
),
),
);
}
}

Android platform code​

Update MainActivity.kt:

package com.example.google_push_provisioning_demo

import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
import android.content.Intent
import android.util.Log
import com.nium.pushpay.sdk.NiumPushPay
import com.nium.pushpay.sdk.listeners.CardListResultListener
import com.nium.pushpay.sdk.listeners.CardResultListener
import com.nium.pushpay.sdk.listeners.PushProvisioningListener
import com.nium.pushpay.sdk.models.CardResultEntity
import com.nium.pushpay.sdk.models.ErrorEntity

class MainActivity : FlutterActivity() {
private val CHANNEL = "push_provisioning"

override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)

// Initialize SDK
NiumPushPay.initialize(
application,
"clientHashId",
"customerHashId",
"walletHashId",
"apiSecret"
)

MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
when (call.method) {
"provisionCard" -> {
val args = call.arguments as? Map<*, *>
val cardId = args?.get("cardId") as? String

if (cardId == null) {
result.error("INVALID_ARGUMENT", "Card ID is required", null)
return@setMethodCallHandler
}

// Adding the card to the wallet
NiumPushPay.getInstance().addToWallet(cardId, object : PushProvisioningListener {
override fun onPushProvisioningSuccess(tokenId: String, cardHashId: String) {
runOnUiThread {
result.success(mapOf(
"success" to true,
"tokenId" to tokenId,
"cardHashId" to cardHashId
))
}
}

override fun onPushProvisioningFailure(errorEntity: ErrorEntity) {
runOnUiThread {
result.error("PROVISION_FAILED", errorEntity.errMsg, null)
}
}
})
}

"checkCardStatus" -> {
val args = call.arguments as? Map<*, *>
val cardId = args?.get("cardId") as? String

if (cardId == null) {
result.error("INVALID_ARGUMENT", "Card ID is required", null)
return@setMethodCallHandler
}

// Verify if card added to wallet (Single card)
NiumPushPay.getInstance().checkIfCardIsAddedToWallet(cardId, object : CardResultListener {
override fun onCardStatusSuccess(isCardAddedToWallet: Boolean) {
runOnUiThread {
result.success(mapOf("isCardAddedToWallet" to isCardAddedToWallet))
}
}

override fun onCardStatusFailure(errorEntity: ErrorEntity) {
runOnUiThread {
result.error("STATUS_CHECK_FAILED", errorEntity.errMsg, null)
}
}
})
}

"getAllCards" -> {
// Verify if cards added to wallet (All cards)
NiumPushPay.getInstance().getCards(object : CardListResultListener {
override fun onCardStatusSuccess(cardResultEntity: List<CardResultEntity>) {
val cardsList = cardResultEntity.map { card ->
mapOf(
"cardHashId" to card.cardHashId,
"isAddedToWallet" to card.isAddedToWallet
)
}

runOnUiThread {
result.success(mapOf("cards" to cardsList))
}
}

override fun onCardStatusFailure(errorEntity: ErrorEntity) {
runOnUiThread {
result.error("GET_CARDS_FAILED", errorEntity.errMsg, null)
}
}
})
}

else -> {
result.notImplemented()
}
}
}
}

// Override onActivityResult as required by documentation
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
NiumPushPay.getInstance().onActivityResult(requestCode, resultCode, data)
}
}

Step 4: Build and test​

  1. Run the Flutter app:
flutter run
  1. In the app, tap Provision Card. If successful, the card will be added to Google Wallet.

Troubleshooting​

Bitbucket authentication​

If you're pulling private SDKs from Bitbucket, use your username and an App Password.

Example:

source 'https://<username>:<app_password>@bitbucket.org/instadevelopers/push-provisioning-pod.git'

If you continue to run into issues, please contact your Nium account manager or Nium support for additional assistance.

LLM-ready documentation:: llms.txt and llms-full.txt
Was this page helpful?