После создания талона и его кодирования в JWT вы готовы выдать его в приложении для Android. Для этого вам необходимо убедиться, что API Google Wallet доступен на устройстве пользователя, нажать кнопку «Добавить в Google Wallet» и сохранить талон в Google Wallet после нажатия кнопки.
Предпосылки
Прежде чем попытаться оформить пропуск, убедитесь, что вы выполнили следующее:
- Выполнены все шаги, указанные в руководстве по адаптации .
- Создайте как минимум один класс пропусков .
- Создайте хотя бы один объект Passes .
- Закодируйте класс пропусков и объект пропусков в JWT.
1. Установите Google Wallet Android SDK
 Чтобы использовать Google Wallet Android SDK, добавьте com.google.android.gms:play-services-pay в раздел dependencies файла build.gradle уровня приложения:
implementation "com.google.android.gms:play-services-pay:16.5.0"
2. Проверьте доступность API Google Wallet.
 Перед сохранением нового объекта убедитесь, что API Google Wallet доступен на целевом устройстве, вызвав метод getPayApiAvailabilityStatus в классе PayClient .
Начните с добавления переменной-члена в действие, в котором вы будете отображать кнопку и создавать ее экземпляр при создании действия:
Котлин
import com.google.android.gms.pay.PayClient
private lateinit var walletClient: PayClient
override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  walletClient = Pay.getClient(this)
  // Additional logic in your onCreate method
}Ява
import com.google.android.gms.pay.PayClient;
private final PayClient walletClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  walletClient = Pay.getClient(application);
  // Additional logic in your onCreate method
}Если вы используете другие шаблоны проектирования, рассмотрите возможность размещения бизнес-логики, специфичной для предметной области. Например, если вы используете шаблон MVVM, разместите бизнес-логику, связанную с пользовательским интерфейсом, в Activity или Fragment (например, элементы пользовательского интерфейса, результаты активности), а операционную логику — в модели представления (например, создание экземпляров клиента, триггеры сетевых вызовов).
 Далее используйте PayClient , чтобы проверить доступность API: 
Котлин
import com.google.android.gms.pay.PayApiAvailabilityStatus
private fun fetchCanUseGoogleWalletApi() {
  walletClient
    .getPayApiAvailabilityStatus(PayClient.RequestType.SAVE_PASSES)
    .addOnSuccessListener { status ->
      if (status == PayApiAvailabilityStatus.AVAILABLE) {
        // The API is available, show the button in your UI
      } else {
        // The user or device is not eligible for using the Pay API
      }
    }
    .addOnFailureListener {
      // Hide the button and optionally show an error message
    }
}Ява
import com.google.android.gms.pay.PayApiAvailabilityStatus;
private void fetchCanAddPassesToGoogleWallet() {
  walletClient
    .getPayApiAvailabilityStatus(PayClient.RequestType.SAVE_PASSES)
    .addOnSuccessListener(status -> {
      if (status == PayApiAvailabilityStatus.AVAILABLE) {
        // The API is available, show the button in your UI
      } else {
        // The user or device is not eligible for using the Pay API
      };
    })
    .addOnFailureListener(exception -> {
      // Google Play Services is too old, or API availability not verified
      // Hide the button and optionally show an error message
    });
}Наконец, вызовите метод, который вы только что определили в своем приложении, когда вам нужно будет определить доступность API.
Обработка недоступности API
К причинам недоступности API относятся устаревшие версии сервисов Android или Google Play, а также недоступность Google Wallet в стране пользователя.
Если API недоступен, попробуйте скрыть кнопку и использовать другой способ интеграции (например , с помощью ссылки JWT ). Обратите внимание, что пользователь может получить право использовать API в будущем.
3. Добавьте кнопку «Добавить в Google Кошелек».
Google Wallet предоставляет привычную кнопку, которую можно использовать для запуска процесса добавления в Google Wallet в вашем приложении. Векторные ресурсы для кнопки доступны в руководстве по кнопкам .
 Векторные ресурсы можно импортировать в Android Studio, выбрав File > New > Vector Asset . В мастере выберите «Локальный файл», добавьте имя (например, add_to_google_wallet_button.xml ) и найдите файл на локальном диске для импорта. 
Теперь вы можете использовать импортированный объект для добавления кнопки в свой пользовательский интерфейс:
<ImageButton android:id="@+id/addToGoogleWalletButton" android:layout_width="match_parent" android:layout_height="48dp" android:minWidth="200dp" android:clickable="true" android:src="@drawable/add_to_google_wallet_button" />
 Кнопка имеет layout_height 48 dp и должна быть шириной не менее 200 dp.
4. Добавьте пропуск в Google Wallet пользователя.
 OfferObject можно добавить, передав неподписанный JWT-токен методу savePasses . Операция добавления запускается нажатием кнопки Google Wallet.
Котлин
import android.os.Bundle
import android.view.View
import com.google.android.gms.samples.wallet.databinding.ActivityCheckoutBinding
private val addToGoogleWalletRequestCode = 1000
private lateinit var layout: ActivityCheckoutBinding
private lateinit var addToGoogleWalletButton: View
override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  // Use view binding to access the UI elements
  layout = ActivityCheckoutBinding.inflate(layoutInflater)
  setContentView(layout.root)
  addToGoogleWalletButton = layout.addToGoogleWalletButton
  addToGoogleWalletButton.setOnClickListener {
    walletClient.savePasses(newObjectJson, this, addToGoogleWalletRequestCode)
  }
  // Additional logic in your onCreate method
}Ява
import android.os.Bundle;
import android.view.View;
import com.google.android.gms.samples.wallet.databinding.ActivityCheckoutBinding;
private static final int ADD_TO_GOOGLE_WALLET_REQUEST_CODE = 999;
private ActivityCheckoutBinding layout:
private View addToGoogleWalletButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // Use view binding to access the UI elements
  layout = ActivityCheckoutBinding.inflate(getLayoutInflater());
  setContentView(layout.getRoot());
  addToGoogleWalletButton = layout.addToGoogleWalletButton;
  addToGoogleWalletButton.setOnClickListener(v -> {
    walletClient.savePasses(newObjectJson, this, ADD_TO_GOOGLE_WALLET_REQUEST_CODE);
  });
  // Additional logic in your onCreate method
}Обработка результатов
 Метод savePasses запускает поток сохранения и вызывает метод onActivityResult после его завершения. Реализация метода onActivityResult должна быть аналогична следующей: 
Котлин
import android.content.Intent
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
  super.onActivityResult(requestCode, resultCode, data)
  if (requestCode == addToGoogleWalletRequestCode) {
    when (resultCode) {
      RESULT_OK -> {
        // Pass saved successfully
      }
      RESULT_CANCELED -> {
        // Save operation canceled
      }
      PayClient.SavePassesResult.SAVE_ERROR -> data?.let { intentData ->
        val errorMessage = intentData.getStringExtra(PayClient.EXTRA_API_ERROR_MESSAGE)
        // Handle error
      }
      else -> {
          // Handle unexpected (non-API) exception
      }
    }
  }
}Ява
import android.content.Intent;
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  if (requestCode == ADD_TO_GOOGLE_WALLET_REQUEST_CODE) {
    switch (resultCode) {
      case RESULT_OK: {
        // Pass saved successfully
        break;
      }
      case RESULT_CANCELED: {
        // Save operation canceled
        break;
      }
      case PayClient.SavePassesResult.SAVE_ERROR: {
        if (data != null) {
          String apiErrorMessage = data.getStringExtra(PayClient.EXTRA_API_ERROR_MESSAGE);
          // Handle error
        }
        break;
      }
      default: {
        // Handle unexpected (non-API) exception
      }
    }
  }
} При успешном добавлении пропуска resultCode содержит значение Activity.RESULT_OK .
 
    
