1. Introduction
What you'll build
At the completion of this codelab, you will have a minimum viable Flutter app with a working Google Pay integration for Android. This project retrieves a payment token which may be sent to a payment service provider for processing.
What you'll learn
- How to install and configure the Google Pay Flutter library
- How to display the Google Pay button and handle clicks
- How to request a payment token from Google Pay
What you'll need
- A text editor of your choice to edit Dart files.
- A Flutter development environment set up for Android.
- For production, you will need a Google Pay
merchantId. It only takes a minute to register at Google Pay & Wallet Console so might as well take care of it now.
2. Create the Flutter project
Create project files
- Create a new Flutter project named
googlepay_flutter.flutter create googlepay_flutter
- Install the Google Pay Flutter library.
cd googlepay_flutter flutter pub add pay
- Open
lib/main.dartin your IDE of choice and replace the contents with the following code:import 'package:flutter/material.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( home: PaySampleApp(), ); } } class PaySampleApp extends StatefulWidget { const PaySampleApp({super.key}); @override State<PaySampleApp> createState() => _PaySampleAppState(); } class _PaySampleAppState extends State<PaySampleApp> { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Google Pay Codelab'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text('Transaction info and errors will be logged to the console.'), ], ), ), ); } }
3. Configure Google Pay
A Google Pay payment request requires a request object. The object defined here as _paymentItems contains the minimum common settings for all requests. Additional settings will be added depending on the request made which we'll review in this codelab.
- Add the Google Pay configuration constants to
lib/main.dart:
import 'package:pay/pay.dart';
const _paymentItems = [
PaymentItem(
label: 'Total',
amount: '14.95',
status: PaymentItemStatus.final_price,
)
];
- Add the default payment configuration json to the path
assets/google_pay_config.json:
{
"provider": "google_pay",
"data": {
"environment": "TEST",
"apiVersion": 2,
"apiVersionMinor": 0,
"allowedPaymentMethods": [
{
"type": "CARD",
"tokenizationSpecification": {
"type": "PAYMENT_GATEWAY",
"parameters": {
"gateway": "example",
"gatewayMerchantId": "exampleGatewayMerchantId"
}
},
"parameters": {
"allowedCardNetworks": ["VISA", "MASTERCARD"],
"allowedAuthMethods": ["PAN_ONLY", "CRYPTOGRAM_3DS"],
"billingAddressRequired": true,
"billingAddressParameters": {
"format": "FULL",
"phoneNumberRequired": true
}
}
}
],
"merchantInfo": {
"merchantName": "Example Merchant Name"
},
"transactionInfo": {
"countryCode": "US",
"currencyCode": "USD"
}
}
}
Resources
- API Reference: Google Pay API request objects documentation
- API Reference: Refer to
PaymentMethodfor more information about the allowed authorization methods, allowed card networks, and tokenization specifications including the proper gateway value.
4. Add the Google Pay button
The pay library includes a native Google Pay button component.
Update the _PaySampleAppState class in lib/main.dart with the following code:
class _PaySampleAppState extends State<PaySampleApp> {
late final Future<PaymentConfiguration> _gpayConfig;
void onGooglePayResult(paymentResult) {
// Send 'token' to your payment service provider (PSP)
print(paymentResult);
}
@override
void initState() {
super.initState();
_gpayConfig = PaymentConfiguration.fromAsset('google_pay_config.json');
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Google Pay Codelab')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
FutureBuilder<PaymentConfiguration>(
future: _gpayConfig,
builder: (context, snapshot) {
if (snapshot.connectionState != ConnectionState.done) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError || !snapshot.hasData) {
return const Text('Error loading Google Pay config');
}
return GooglePayButton(
paymentConfiguration: snapshot.data!,
onPaymentResult: onGooglePayResult,
paymentItems: _paymentItems,
height: 48,
type: GooglePayButtonType.buy,
theme: GooglePayButtonTheme.dark,
margin: const EdgeInsets.only(top: 15.0),
loadingIndicator: const Center(
child: CircularProgressIndicator(),
),
);
},
),
const Text('Transaction info and errors will be logged to the console.'),
],
),
),
);
}
}
Code explanation
_paymentItemsdescribes the transaction that should be processed with this button click.- The
paymentConfigurationAssetin theGooglePayButtonwidget loads the configuration from theassets/google_pay_config.jsonfile. - When the
GooglePayButtonis pressed, theonGooglePayResultfunction is called. This function receives the payment result. - Once you have the payment token from the response, you would send it to your payment gateway for processing the transaction.
5. Trigger payment on click
Tapping the GooglePayButton opens the Google Pay sheet and returns a result — no separate "make payment" call is required. Add handlers to log the token, surface errors, and optionally log the button press.
- Add or update the result handler inside
_PaySampleAppState:
void onGooglePayResult(dynamic paymentResult) {
try {
final token = paymentResult['paymentMethodData']['tokenizationData']['token'];
debugPrint('Google Pay payment token: $token');
} catch (e) {
debugPrint('Unexpected payment result: $e');
}
}
- Update the
GooglePayButtonto include press and error handlers:
GooglePayButton(
paymentConfiguration: snapshot.data!,
paymentItems: _paymentItems,
onPaymentResult: onGooglePayResult,
onError: (Object err) => debugPrint('Google Pay error: $err'),
onPressed: () => debugPrint('Google Pay button pressed'),
height: 48,
type: GooglePayButtonType.buy,
theme: GooglePayButtonTheme.dark,
margin: const EdgeInsets.only(top: 15.0),
loadingIndicator: const Center(child: CircularProgressIndicator()),
)
Notes
- The tap itself triggers the payment sheet;
onPaymentResultreceives the payload. - In production, send the token to your payment service provider to complete the charge.
6. Conclusion
Congratulations on completing this Codelab! You have learned how to integrate the Google Pay API into a Flutter app for Android.
Run the project
Run the following command to start your app:
flutter run
Where to go from here
Additional resources
- Join the conversation in the #payments channel on Discord
- Follow @GooglePayDevs on X
- Watch Google Pay related videos on YouTube