Как добавить оплату через Google Pay в мобильное приложение на Flutter

Вы выпустили приложение на Flutter, и теперь нужно принимать платежи. Google Pay — один из самых удобных способов: пользователь нажимает одну кнопку, подтверждает оплату отпечатком пальца — и готово. Никаких ручного ввода карт. Разберёмся, как это подключить технически, что подготовить заранее и где подстерегаются подводные камни.

Что нужно до начала работы

Прежде чем писать код, нужно подготовить инфраструктуру. Без этого интеграция просто не заработает — Google строго проверяет, кто и что принимает платежи.

  • Merchant ID в Google Pay Console. Регистрируетесь в Google Pay Business Console, создаёте профиль мерчанта и получаете уникальный ID. Он понадобится в коде.
  • Платёжный шлюз (payment gateway). Google Pay сам по себе не обрабатывает платежи — он токенизирует карту и передаёт токен вашему платёжному провайдеру. На Flutter чаще всего работают через Stripe, Braintree, Checkout.com или нативные решения вроде ЮKassa (для РФ). Выбор шлюза определяет дальнейший код.
  • Поддерживаемая карта или сеть. Убедитесь, что ваш шлюз поддерживает нужные платёжные сети (Visa, Mastercard, Amex и т.д.) в тех регионах, где вы работаете.
  • Тестировочный аккаунт шлюза. Никогда не разрабатывайте платежи сразу на боевых данных. У всех крупных провайдеров есть sandbox-режим.

Как устроен процесс оплаты через Google Pay

Понимание общей схемы помогает не путаться в коде. Вот что происходит шаг за шагом:

  1. Приложение запрашивает у Google Pay данные карты, привязанной к аккаунту пользователя.
  2. Google Pay возвращает не номер карты, а токен — зашифрованную строку, которую может расшифровать только ваш платёжный шлюз.
  3. Приложение отправляет этот токен на ваш сервер.
  4. Сервер передаёт токен платёжному шлюзу и списывает деньги.
  5. Результат возвращается обратно в приложение.

Ключевой момент: номер карты никогда не проходит через ваше приложение и ваш сервер в открытом виде. Это и есть главная ценность Google Pay с точки зрения безопасности — вы не имеете дела с чувствительными данными и не усложняете себе работу с PCI DSS.

Подключаем пакет google_pay

Google официально поддерживает платформу Flutter через пакет google_pay. Добавляем в pubspec.yaml:

dependencies:
  google_pay: ^1.0.11

После этого запускаем flutter pub get и переходим к настройке для каждой платформы.

Настройка Android

В файле android/app/src/main/AndroidManifest.xml нужно добавить метаданные с вашим Merchant ID и указать поддерживаемые платёжные сети:

<application ...>
  <meta-data
    android:name="com.google.android.gms.wallet.api.enabled"
    android:value="true" />
</application>

Также в android/app/build.gradle убедитесь, что версия com.google.android.gms:play-services-wallet актуальна. Обычно она подтягивается автоматически вместе с пакетом, но проверить не помешает.

Настройка iOS

На iOS Google Pay работает через Apple Pay под капотом — это важный нюанс. Вам нужно добавить идентификатор мерчанта в Xcode и настроить Info.plist. Если вы ориентируетесь только на Android (что для Flutter-приложений часто и происходит), этот шаг можно пропустить.

Пишем код: показываем кнопку Google Pay

Пакет работает по простой логике: вы проверяете, доступен ли Google Pay на устройстве, показываете кнопку, а по нажатию запускаете платёжный поток. Вот минимальный рабочий пример:

import 'package:google_pay/google_pay.dart';

class PaymentScreen extends StatefulWidget {
  @override
  _PaymentScreenState createState() => _PaymentScreenState();
}

class _PaymentScreenState extends State<PaymentScreen> {
  String _paymentItems = '';

  @override
  void initState() {
    super.initState();
    _getPaymentItems();
  }

  void _getPaymentItems() async {
    final GooglePay googlePay = GooglePay();
    final bool isAvailable = await googlePay.isAvailable();
    if (isAvailable) {
      setState(() {
        _paymentItems = '[{"label":"Total","type":"LINE_ITEM","price":"10.00","status":"FINAL"}]';
      });
    }
  }

  void _onGooglePayPressed() async {
    final GooglePay googlePay = GooglePay();
    final result = await googlePay.openPaymentSelector(
      paymentItems: _paymentItems,
      merchantName: 'Ваш бизнес',
      countryCode: 'RU',
      currencyCode: 'RUB',
    );
    // result — это ответ от платёжного шлюза, который нужно обработать
  }
}

Обратите внимание на параметр merchantName — он отображается в платёжном листе Google Pay пользователю. Указывайте понятное название вашей компании, а не технический идентификатор.

Что передавать в paymentItems

Это JSON-строка, в которой описывается заказ. Поля стандартизированы Google:

  • label — название позиции или итоговой строки.
  • type — тип: LINE_ITEM для позиции заказа, TOTAL для итоговой суммы.
  • price — сумма в формате строки с двумя знаками после точки.
  • statusFINAL для финальной суммы, FINAL или NOT_FINAL для промежуточных.

Пример для заказа из двух товаров:

[
  {"label":"Кофе латте","type":"LINE_ITEM","price":"350.00","status":"FINAL"},
  {"label":"Круассан","type":"LINE_ITEM","price":"250.00","status":"FINAL"},
  {"label":"Итого","type":"TOTAL","price":"600.00","status":"FINAL"}
]

Какой платёжный шлюз выбрать для Flutter

Это ключевое решение, которое определяет объём работы. Вот сравнение наиболее распространённых вариантов:

Шлюз Поддержка Flutter Google Pay через токен Регионы Сложность интеграции
Stripe Отличная (stripe_sdk, flutter_stripe) Полная поддержка токенов Google Pay 40+ стран Средняя — хорошая документация, много примеров
Braintree Хорошая (braintree_payment) Поддерживается нативный SDK 45+ стран Средняя — нужно повозиться с нативной частью
ЮKassa Средняя (yookassa_payments_flutter) Поддерживается через их SDK Россия Простая для РФ, но документация только на русском
Adyen Хорошая (adyen_checkout) Полная поддержка Глобально Выше среднего — сложнее в настройке

Что выбрать в зависимости от вашей ситуации

Если вы работаете в России и принимаете платежи только от российских пользователей — смотрите в сторону ЮKassa или Сбербанка. У них есть готовые Flutter-пакеты и поддержка Google Pay через токенизацию. Но учтите, что в текущих условиях доступность Google Pay с российскими картами может быть ограничена — проверяйте актуальный статус у шлюза.

Если вы работаете на международном рынке — Stripe будет самым простым вариантом. У них отличная документация по Flutter, готовые виджеты и понятный sandbox для тестирования.

Если у вас уже есть работающий бэкенд с определённым шлюзом — просто проверьте, поддерживает ли он приём токенов Google Pay. Если да, вам нужно только на стороне бэкенда добавить обработку токена, а на фронтенде — передать его из приложения.

Обработка ответа от платёжного шлюза

После вызова openPaymentSelector вы получаете результат. Но это ещё не значит, что деньги поступили. Токен нужно отправить на ваш сервер, и уже сервер инициирует реальное списание через API шлюза. Типичная цепочка:

  1. Приложение получает токен от Google Pay.
  2. Отправляет POST-запрос на ваш сервер с токеном и суммой.
  3. Сервер вызывает API шлюза (например, Stripe API) для создания платежа.
  4. Сервер возвращает приложению статус: успех или ошибка.

Не делайте списание прямо из приложения — это небезопасно. Секретный ключ шлюза должен храниться только на сервере.

Тестирование: как не потратить реальные деньги

У всех основных шлюзов есть тестовые режимы. Вот что использовать:

  • Stripe: карта 4242 4242 4242 4242, любая будущая дата, любой CVC.
  • Braintree: тестовые номера карт из документации, sandbox-окружение.
  • ЮKassa: тестовые банковские карты из личного кабинета.

В Google Pay Console также есть тестовый режим. Добавьте тестовых пользователей в консоль, и они смогут привязывать тестовые карты к Google Pay на своих устройствах.

Частые ошибки при интеграции

Merchant ID не совпадает. Если в коде указан один Merchant ID, а в Google Pay Console зарегистрирован другой — платёж не пройдёт. Проверьте дважды, что ID в консоли и в коде идентичны.

Забыли про серверную часть. Некоторые разработчики пытаются обработать платёж целиком на клиенте. Это грубая ошибка — секретный ключ шлюза нельзя хранить в клиенте. Всегда отправляйте токен на сервер.

Неправильный формат суммы. Google Pay ожидает строку вида "10.00", а не "10" или 10.0. Если формат не тот — платёжный лист может не открыться или показать неверную сумму.

Тестируете на устройстве без Google Play Services. Google Pay не работает на устройствах без GMS (некоторые Huawei, кастомные прошивки). Проверяйте доступность сервиса перед показом кнопки.

Не обрабатываете отмену пользователем. Пользователь может открыть платёжный лист и закрыть его без выбора карты. Ваш код должен корректно обрабатывать этот сценарий — не показывать ошибку, а просто вернуться к экрану выбора.

Рекомендации по показу кнопки Google Pay

Не показывайте кнопку Google Pay всегда — сначала проверьте, доступен ли сервис на устройстве и настроен ли у пользователя способ оплаты. Пакет google_pay предоставляет метод isAvailable(), который как раз это делает.

Если Google Pay недоступен, предложите альтернативу — ввод карты вручную или другой способ оплаты. Пользователь не должен видеть неактивную кнопку без объяснения причины.

Также учитывайте, что на iOS кнопка Google Pay по дизайну отличается от Android. Используйте официальные ассеты из брендбука Google — их можно скачать из Google Pay Business Console.

Что в итоге

Интеграция Google Pay в Flutter-приложение — задача на пару дней, если у вас уже настроен платёжный шлюз и есть Merchant ID. Основные шаги:

  1. Получить Merchant ID в Google Pay Console.
  2. Выбрать и подключить платёжный шлюз, который поддерживает приём токенов Google Pay.
  3. Добавить пакет google_pay и настроить манифесты для каждой платформы.
  4. Реализовать проверку доступности сервиса и показ кнопки.
  5. Передавать токен на сервер для фактического списания.
  6. Протестировать в sandbox-режиме шлюза и в тестовом режиме Google Pay.

Если вы только начинаете работу с платежами в Flutter — начните со Stripe. У них самая понятная документация, активное сообщество и минимальный порог входа. Для российского рынка — ЮKassa, но обязательно уточните текущую поддержку Google Pay у них напрямую, ситуация может меняться.

Platejigid.ru