1. 시작하기 전에
Google Wallet API를 사용하면 사전에 정의된 다양한 유형의 패스를 통해 사용자와 소통할 수 있습니다. 여기에는 사용 사례별 분야 및 기능에 따른 포인트 카드, 쿠폰, 기프트 카드, 이벤트 티켓, 대중교통 티켓, 탑승권 등이 포함됩니다. 하지만 Google에서 만든 패스가 모든 사용 사례에 맞지 않을 수 있으므로 일반 유형의 패스를 만들었습니다. 이름에서 보는 바와 같이 일반 패스 유형은 사용 사례가 어떠한 특수 유형에도 맞지 않을 때 사용해야 합니다. 다음은 일반 패스 유형의 몇 가지 사용 사례입니다.
- 주차권
- 도서관 회원 카드
- 금액이 저장된 쿠폰
- 헬스장 회원 카드
- 보험 카드
- 다양한 종류의 예약
일반 패스는 Google의 서비스이용 정책을 준수하는 한 모든 사용 사례에 사용할 수 있으며 최대 세 줄의 정보와 바코드(선택사항), 세부정보 섹션(선택사항)으로 구성된 카드 형태로 사용자에게 제공할 수 있습니다.
Google Wallet API를 사용하면 다음을 만들 수 있습니다.
- 패스 클래스. 클래스는 프로그램이나 이벤트에 속한 모든 패스가 공유하는 일반 정보가 담긴 템플릿으로 보면 됩니다. 모든 패스 객체는 클래스에 속합니다.
- 패스 객체는 비즈니스 및 사용자의 활동에 관련된 구체적인 목적(예: 주차 카드, 헬스장 회원 카드)을 지닙니다. 이러한 항목은 각각 이전에 정의된 클래스와 연결되어 있으며 여기에서 공통 속성을 상속합니다.
이 Codelab에서는 사전 정의된 클래스를 제공하고 패스 객체를 JSON으로 정의하는 방법을 설명합니다. 또한 Android 앱에 'Google 월렛에 추가' 버튼을 포함시켜 사용자가 Google 월렛에 패스를 저장할 수 있도록 합니다.
Google Wallet API 또는 Android 애플리케이션에 'Google 월렛에 추가' 버튼을 추가하는 방법에 관한 자세한 내용은 Google 월렛 개발자 문서를 참고하세요.
기본 요건
- Android 스튜디오가 설치된 컴퓨터
- Android 스튜디오에서 프로젝트를 만들고 실행하는 능력
- Git이 설치되어 있어야 함
학습할 내용
- Android 앱에 Google 월렛 SDK를 추가하는 방법
- Wallet API를 사용할 수 있는지 확인하는 방법
- 사용자가 Google 월렛에 패스를 추가할 수 있는 UI를 구현하는 방법
2. 설정
임시 발급기관 계정 만들기
사용자용 패스를 만들려면 먼저 발급기관 계정을 만들고 Wallet API를 사용 설정한 다음 클래스를 만들어야 합니다. 이러한 작업은 Google Pay 비즈니스 콘솔을 통해 완료할 수 있습니다. 그러나 콘솔에 대한 액세스는 승인 절차가 완료된 후에만 부여되므로 이 Codelab에서는 임시 발급기관 계정과 패스 클래스를 모두 만듭니다.
- 임시 발급기관 계정 및 샘플 클래스 만들기를 클릭합니다.
- 다음 단계에서 필요한 발급기관 ID와 클래스 ID를 기록해 둡니다.
git 저장소 클론
다음 명령어를 사용하여 수정할 Android 프로젝트가 포함된 git 저장소를 클론합니다.
git clone -b wallet-lab git@github.com:google-pay/android-quickstart.git
Android 스튜디오에서 열기
Android 스튜디오를 열고 시작 화면에서 'Open'을 선택한 후 새로 클론된 저장소에서 kotlin
폴더를 선택하여 프로젝트로 엽니다.
3. 앱에 Google 월렛 SDK 추가
Android 프로젝트에는 곧 수정할 빈 활동이 포함되어 있지만, 먼저 Google 월렛 SDK를 종속 항목으로 추가합니다. Android 스튜디오에서 모듈 수준 'build.gradle' 스크립트를 선택하고 다음 줄을 dependencies
섹션에 추가합니다.
dependencies {
...
implementation 'com.google.android.gms:play-services-pay:16.0.3'
}
변경을 완료하면 Android 스튜디오의 오른쪽 상단에 있는 Gradle 'Sync Project' 버튼을 클릭합니다.
4. 'Google 월렛에 추가' 버튼 추가
다음으로, 활동에 'Google 월렛에 추가' 버튼을 추가합니다. 버튼의 애셋은 이미 프로젝트에 추가되어 있으므로 레이아웃 파일에만 추가하면 됩니다. 레이아웃 파일에 추가하려면 버튼이 있는 별도의 레이아웃을 만드는 것이 좋습니다.
add_to_google_wallet_button.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:clickable="true"
android:focusable="true"
android:layout_width="match_parent"
android:layout_height="48sp"
android:background="@drawable/add_to_google_wallet_button_background_shape"
android:contentDescription="@string/add_to_google_wallet_button_content_description">
<ImageView
android:layout_width="227dp"
android:layout_height="26dp"
android:layout_gravity="center"
android:duplicateParentState="true"
android:src="@drawable/add_to_google_wallet_button_foreground"/>
</FrameLayout>
버튼은 다음과 같이 표시됩니다.
그런 다음 아래와 같이 레이아웃 파일에 애셋을 포함합니다.
<include
android:id="@+id/addToGoogleWalletButton"
layout="@layout/add_to_google_wallet_button"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginTop="10dp"/>
5. API 사용 가능 여부 확인
이제 코딩할 차례입니다. Android 스튜디오에서 Google Wallet API를 호출할 파일을 열고 (샘플 애플리케이션을 사용하는 경우 CheckoutActivity.kt
파일) PayClient
객체를 클래스의 멤버로 인스턴스화합니다. 이 객체를 사용하면 Google Wallet API를 호출할 수 있습니다. getClient
메서드는 인스턴스화하는 클래스의 컨텍스트를 수신합니다(이 경우 호출 활동임).
private lateinit var walletClient: PayClient
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
walletClient = Pay.getClient(this)
...
}
다음으로 기기에서 Google 월렛 SDK와 앱을 사용할 수 있는지 확인합니다. 클래스에 새 메서드(예: fetchCanUseGoogleWalletApi
)를 만들어서 Google Wallet API를 사용할 수 있는지 확인하고 API를 사용할 수 있는 경우 'Google 월렛에 추가' 버튼을 표시하여 결과에 반응할 수 있는 또 다른 메서드를 만듭니다.
private fun fetchCanUseGoogleWalletApi() {
walletClient
.getPayApiAvailabilityStatus(PayClient.RequestType.SAVE_PASSES)
.addOnSuccessListener { status ->
if (status == PayApiAvailabilityStatus.AVAILABLE)
layout.passContainer.visibility = View.VISIBLE
}
.addOnFailureListener {
// Hide the button and optionally show an error message
}
}
마지막으로 onCreate
메서드에서 fetchCanUseGoogleWalletApi
메서드를 호출하여 Google Wallet API를 사용할 수 있는지 확인합니다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
fetchCanUseGoogleWalletApi()
}
이제 앱을 실행하면 UI에 'Google Wallet에 추가' 버튼이 표시된 것을 확인할 수 있습니다.
6. Google 월렛에 패스 추가
이제 Google Wallet API를 사용할 수 있는 것을 확인했으므로 사용자가 Google 월렛에 패스를 추가하도록 메시지를 표시할 수 있습니다. 이 작업을 하기 전에 잠시 시간을 내어 이 워크숍에서 생성한 패스를 검토해 보겠습니다.
이 레이아웃은 일반 패스의 유연성을 사용하여 ID 배지로 작동하는 객체를 만드는 동시에 이벤트 기간 동안 참가자들이 포인트를 모으도록 유도하는 챌린지를 지원합니다. 일반 객체의 모양은 다음과 같습니다.
{
"id": "999999.d1fa-4cca1...",
"classId": "999999.a92b-129f...",
"genericType": "GENERIC_TYPE_UNSPECIFIED",
"hexBackgroundColor": "#4285f4",
"logo": { ... },
"cardTitle": { ... },
"subheader": { ... },
"header": { ... },
"barcode": { ... },
"heroImage": { ... },
"textModulesData": []
}
객체를 삽입하기 위해 API는 서명되지 않은 JWT 본문에서 새 요소를 래핑할 것을 기대합니다.
{
"iss": <owner-email-address>,
"aud": "google",
"typ": "savetowallet",
"iat": <unix-time>,
"origins": [],
"payload": {
"genericObjects": [],
"genericClasses": [],
...
}
}
앞서 임시 발급기관 계정을 만들 때 얻은 값을 종합하여 묶고 결과 객체를 클래스의 변수에 할당합니다.
private val issuerEmail = "<insert-your-issuer-email-address>"
private val issuerId = "<insert-your-issuer-id>"
private val passClass = "<insert-your-class-id>"
private val passId = UUID.randomUUID().toString()
private val newObjectJson = """
{
"iss": "$issuerEmail",
"aud": "google",
"typ": "savetowallet",
"iat": ${Date().time / 1000L},
"origins": [],
"payload": {
"genericObjects": [
{
"id": "$issuerId.$passId",
"classId": "$passClass",
"genericType": "GENERIC_TYPE_UNSPECIFIED",
"hexBackgroundColor": "#4285f4",
"logo": {
"sourceUri": {
"uri": "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg"
}
},
"cardTitle": {
"defaultValue": {
"language": "en",
"value": "Google I/O '22 [DEMO ONLY]"
}
},
"subheader": {
"defaultValue": {
"language": "en",
"value": "Attendee"
}
},
"header": {
"defaultValue": {
"language": "en",
"value": "Alex McJacobs"
}
},
"barcode": {
"type": "QR_CODE",
"value": "$passId"
},
"heroImage": {
"sourceUri": {
"uri": "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/google-io-hero-demo-only.jpg"
}
},
"textModulesData": [
{
"header": "POINTS",
"body": "${Random.nextInt(0, 9999)}",
"id": "points"
},
{
"header": "CONTACTS",
"body": "${Random.nextInt(1, 99)}",
"id": "contacts"
}
]
}
]
}
}
"""
마지막으로 onCreate
메서드로 돌아가고 클라이언트에서 savePasses
메서드를 사용하여 작업을 시작하도록 'Google 월렛에 추가' 버튼에 클릭 핸들러를 추가합니다.
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.root
addToGoogleWalletButton.setOnClickListener {
walletClient.savePasses(newObjectJson, this, addToGoogleWalletRequestCode)
}
...
}
지금까지 앞에서 만든 발급기관 ID 및 클래스 ID를 사용하여 새 객체의 JSON을 정의했습니다. 사용자가 'Google 월렛에 추가' 버튼을 클릭하면 payClient.savePasses
가 호출되고 Google 월렛에 새 패스 객체를 추가하라는 메시지가 표시됩니다.
7. 결과 처리
거의 완료되었습니다. 마지막으로, 작업 결과를 성공 또는 실패로 처리합니다. onActivityResult
메서드를 덮어쓰도록 다음 코드를 포함시킵니다.
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == addToGoogleWalletRequestCode) {
when (resultCode) {
RESULT_OK ->
// Pass saved successfully. Consider informing the user.
RESULT_CANCELED -> {
// Save canceled
}
PayClient.SavePassesResult.SAVE_ERROR -> data?.let { intentData ->
val errorMessage = intentData.getStringExtra(PayClient.EXTRA_API_ERROR_MESSAGE)
// Handle error. Consider informing the user.
}
else -> {
// Handle unexpected (non-API) exception
}
}
}
}
이 코드로 성공적으로 추가된 패스, 사용자가 작업을 취소한 경우 및 발생할 수 있는 모든 오류를 처리합니다. 애플리케이션을 다시 실행하여 예상대로 패스를 추가하고 결과를 처리할 수 있는지 확인합니다.
8. 축하합니다
축하합니다. Android에 Google Wallet API를 성공적으로 통합했습니다.
자세히 알아보기
전체 예를 보려면 GitHub의 샘플 애플리케이션에서 전체 통합을 살펴보세요.
발급기관 계정 가입
프로덕션에서 자체 패스를 발급할 준비가 되면 Google Pay 및 월렛 콘솔로 이동하여 Google Wallet API 액세스 권한을 요청하고 Android 애플리케이션이 API 호출을 실행하도록 승인받으세요. 자세한 내용은 문서를 참고하세요.