Digitize wallet objects with Google Wallet API - step-by-step tutorial | Google I/O 2022
Key Takeaways
Demonstrates how to digitize wallet objects using the Google Wallet API, including step-by-step integration on Android
Full Transcript
Hi, I'm Jose and I work as a developer relations engineer on the Google Pay team. Today, I'm going to show you how to create a multi-purpose pass that you can add to Google Wallet using the Google Wallet API, previously known as the Google Pay API for passes. Let's get started. Even if this is the first time you're exploring the Google Wallet API, in this workshop, you'll learn how to use the new generic pass type to create passes that adapt to your needs. Check out the session introducing Google Wallet and developer API features to learn more about Google Wallet and generic passes. To make the integration more illustrative, you'll temporarily impersonate a developer from the Google I/O team to create a hypothetical and revolutionary badge that, in addition to providing identification, lets attendees collect points every time they meet someone new. By integrating with the Google Wallet API, you'll be able to create passes that can be saved to Google Wallet. The integration flow on Android is typically, first, sign up to Google Pay and Wallet console and get an issuer ID. Second, define the type of pass and create a new pass object for a user. Third and finally, integrate the API on Android to add the pass to Google Pay and once launched to Google Wallet. This workshop focuses on implementing the Android SDK in your application, so you don't need to complete steps one and two. Instead, I'll briefly touch on each of them, so you have some context when you're ready to integrate your own passes. Google Pay and Wallet console is your go-to place to manage all your new and existing integrations with Google Pay and Google Wallet APIs. You can see how they perform over time and add support for the business and developer-focused products. The console also helps you seamlessly integrate Google Pay and Google Wallet APIs. Discover resources, get support at different stages throughout your integration, and keep track of your progress along the way. To get started, head to g.co/paywalletconsole and create your business profile. Next, head over to the Google Wallet API section and request access to the API to get up production-ready issuer ID. When you're granted access to the Google Wallet API, you can start creating passes. There are two resources in the API that help you do that. First, pass classes. Think of classes as templates with common information that all your passes belonging to a program or event share. All pass objects belonging to belong to a class. And second, pass objects, which serve a concrete purpose associated to your activity as a business and your users. For example, an entry ticket or a loyalty card for your loyalty program. Each of these items are associated with a previously defined class and inherit common properties from it. Any changes to the pass class or the pass object are propagated to the user immediately. Now, coming back to the workshop. To help you get started with the Android integration, we have prepared a sample generic pass model and a test account that you can provision to complete the integration without signing up or completing a back-end integration yourself. To do that, head over to g.co/wallet/labtools, enter your email address, and click create. So, I'll be doing it on screen. Make sure to choose an email address that you can access from the Android device you're intending to test. That is, this email address needs permission on your issuer account so that the pass can be saved because this is a test account. Make sure to enable the checkbox to create a generic pass class with your account. And as you hit create, all this content will be created for this workshop. All right, so you have the result. Now, keep this window somewhere in the back of your computer because you will need it later on. Now, as you can see, we have identifiers for the issue ID, for the pass class ID, and the owner of that account. Now, this is what the class object that you just created looks like. This is the structure of the object. The modules data fields let you specify additional information in the form of images, text, and links. This information can be referenced from multiple sections in the pass. The class template info lets you override the layout of the pass and change how the different bits of information are shown. Note how in this example, you use the card template override property to include one additional row below the top row using a two item layout, which includes two more fields at the sides of the pass. And the details template override to add a detail section for the pass with an image, additional text, and a link. In a typical integration scenario, you create classes and optionally objects from a confidential system, for example, a back-end server. And issue queries against the Google Wallet API with the appropriate information to create passes. For example, you can create a new class from a private or admin tool in your company when you start a new program, and issue a new object when a user requests a new pass from a client application. This is how the generic pass used in this workshop looks. A generic pass gives you extra flexibility to structure and design your passes to adapt to your needs. You can configure a number of attributes such as the barcode or a QR code or the main image in the pass. Later in this workshop, we'll take a more detailed look at the properties available and configure the pass accordingly. With that, let's go take a look at the integration in your Android application. Feel free to digest this workshop at your own pace, pausing on sections of the video that you'd like to spend more time on. So first, I'll show you how to configure your Android application and give your users a way to add the pass to Google Wallet. You can use your own Android application to continue with the integration or, if you prefer, use our sample application as a model. If you decide to use our sample application, you can clone the repository using the following commands. Once cloned, open Android Studio to start the integration. So in the project menu wizard, hit on the open button and then locate your project in your local file system. Make sure to select the Kotlin module, which is where the integration will happen. Now, as you can see, there's a list of uh convenient uh comments throughout the code that will help you complete this codelab. The first step is to use the API to add the GMS Play Services pay. We'll do that in the build.gradle file for your application module. Right below the indication comment right here. So using the implementation tag, you'll add the com. google.android.gms. You see on the auto complete that it's giving me version 16.0.3, which is the latest right now. Now, make sure to uh use the hit on the Gradle sync button to make sure the dependencies, if needed, are downloaded and made available to you. Now, the next step is to add the Google Wallet button to your user interface. You configure the button to show on the screen according to the brand guidelines and trigger the save flow for the previously created pass. To do that, visit the button guidelines page and download the SVG files for the button with the appropriate color themes and languages. The repository that you're using, if you're using our sample application, already contains a vector drawable added to the resources. If you're following the workshop using your own application, you can import vector assets uh on Android Studio using the file new vector asset, which will open a wizard where you'll have to set name for that vector drawable and locate that file that SVG file in your file system. Click on next, finish, and that will import the vector drawable. And I'll show you how the one we're using looks like. So, you will see something very similar to this one. We recommend creating a separate layout with the button that contains both of the SVG asset and the background. So, go ahead and add the Google Wallet button to your layout file with the following snippet. As you can see, the snippet contains two elements. I'll explain these two uh when we add it to Android Studio. So, let's go back to Android Studio. So, right click on layout, new new layout resource file, and let's give it a descriptive name like add to Google Wallet button. Click on okay. Go back to the code window and paste the contents that you just copied. Now again, we have two elements. One of them is the image view that contains the SVG content of the add to Google Wallet add to add to Google Wallet button um file, the SVG file that you just loaded. Now, if you take a look in detail, you'll see that this only contains the foreground. The reason why we're using a frame layout to contain the background is because you can benefit from the resizing properties of Android shapes, and you can also add you can also add events and new different styles when you interact with the button. For example, when you disable it or when the button is clicked using on new versions of Android, the ripple effect. We're using a frame layout because one of the simplest form of containers on Android. And if you check out the split view or the design view, you'll see how the button looks like. Great. Moving on. The last step needed is to add the layout that you just constructed to your final user interface where you're planning to show the button. So, that's going to be if you're using our sample application, that is the activity checkout. If you just scroll to the bottom, you'll see another comment indicating where we think the add to Google Wallet should be placed. So, since this is a composite layout, you'll want to use the include tag with the layout that you just created. So, that is layout add to Google Wallet button. You'll give it an ID, which is going to be a new ID called add to Google Wallet button. Uh width of the entire screen because we want the button to occupy the entire contents horizontally of the screen. So, it's going to be match parent. And on the height, if you take a look at the button guidelines, you'll see that the that the height that will need to be set is 48 DP. Finally, give it a margin top so that it's separated from the rest of the content. And with that, you'll see that nothing shows on screen. The reason for that is because the container view is hidden. It's not showing. It's visibility set to gone. Let's remove that briefly to see how the button will look like. And if you're happy with the outcome, you can add the visibility gone back again. We'll get to why we have that view hidden in just a second. Next, open the activity where you're planning to show the article wallet button, and instantiate a play pay client object as a member of your class. This object helps you make calls against the Google Wallet API. The get client method receives the context of the instantiating class, which in this case is the current activity. Step number five on the collab. So, go back to Android Studio and open your main activity class. For those using the sample application, that's the checkout activity. And go to 3.1, where you'll create a member variable to hold the client. It's going to be a private lateinit var, because we're promising the compiler that we're going to construct this variable soon, not on the constructor, but soon enough, that you'll call wallet client. And that's going to be of type pay client. And next, instantiate, as we promised, that variable in the on create method, so that the client is readily available for you to use. And as we said, that's pay client, passing the calling activity as a context. Consider placing the main specific business logic appropriately if you're using other design patterns. For example, if you're using the model view view model pattern, place your UI related business logic in your activity or fragment. For example, add to wallet button or the activity result. And operational logic in your view model. For example, the instantiation of the client or the network call triggers. Now, we have the client variable ready for us to make calls against the API. And there's one call that we'll want to make first. So, before saving the pass, we'll want to verify that the API is available on the target device and respond to the result if needed. Currently, the target device needs to have Google Play Services installed. And if the API is not available, consider not showing the add to wallet button. If you remember, in the UI, the container of the button was set to visibility gone. We'll want to keep it like that if the API is not available, not to confuse the user and letting them know or in fact not not letting them know that the API is available that they cannot use the button. So, you'll do that by calling the get pay API availability status call request on the pay client. So, do that in a separate function. And we can call private function fetch Google Wallet API status. And that's a call that once again, you'll do on the wallet client. You'll see you can auto complete get pay API availability status. And that will take a extra param, which is going to be the type of request that you're planning to make. That is the save passes. What we're trying to do if the API is available is to save the pass that we'll define later on. Now, this returns a task. So, you can simply use the pre-built callbacks to check out the outcome, the result of the task. If you're using other libraries or other tools, like for example, coroutines on Kotlin, you can very well keep on using that as well for this task. Going to keep it simple and use the inbuilt callbacks. So, what I like to do is if the operation is successful, that is if the wallet API is available, I will want to show the container of the button. So, I'll go ahead because I'm using view binding, my layout is already available. And the container of the button is called pass container. And I'm going to set the visibility to view visible. So, if the API is available, that's going to show my button to add to Google Wallet on screen so that users can interact with it. If the API is not available, that's going to return through the on failure listener. And in fact, there's one thing that we are missing here. So, we are saying if the request completes successfully, that we can show the button. Well, that's not precisely the case because that request returned a status. So, let's take a look and explore the value of that status. We only want to show the UI if the status is available. That is pay API availability status is available. If it's not eligible, we want to keep the container hidden. So, only if it's available, we'll show the container of the button. If this request fails, feel free to do to perform additional operations like login or notifying the user. In this context, we're just going to keep this as a no operation. So, now the method to determine whether the API is available, is ready. Now, the only thing that's left is calling that method. In my own uh little application, I'll want this method to be called as quickly as possible so that I know if the Google Wallet API is available as quickly as possible. So, I'm going to call this at the end of the on create method. You feel free to add this method to whatever it's most convenient based on the flow of your application, whether that's the on resume, the on start, the on create, or somewhere else. Okay, so recapping a little bit, there's the uh dependencies to use the pay client. You have added the button with a vector drawable. Instantiated the pay client, and now you have checked whether the Google Wallet Pay will Wallet API is available. So, the next step now is to go ahead and call the save passes operation. But, before doing that, let's take a step back and take a look at the object that you'll create in a second. So, this is how the object looks like. These are some of the properties that a generic pass object can have. This fields, as you can see, contain visual information to display the object, like the background color, the logo at the top left, the card title, header, the barcode, or the hero image at the bottom to brand your pass according to your uh mark, as well as configuration associated with pass. This object is wrapped in an unsigned data JWT representation, which is what the API takes. This final entire object is used to save the pass. So, let me take that object. We have a set of coding here that contains definition the full definition of the object. So, you can just copy all that and take it to your main activity class. And at the bottom of it, you can add it on step five in the comments. Let's quickly go through it. So, as you can see, there is there's a set of member variables. These contain the values that you obtain at the beginning of this workshop when creating the test account. So, what I'll ask you to do is go back to that window and copy those items, the owner email address, into the issuer email. The issuer ID, that's the second value. And you can use the copy button, by the way, to conveniently copy the content to the issuer ID member variable. And finally, the pass class ID into the pass class. Now, as you can see, those fields are used in the object definition. So, few things to call out is you need to set the ID of the object, which is being created with the random UUID, uh plus the issuer ID. You have to define the class ID of that object. Remember that every object needs to be associated to a class. So, you can see we're setting the background color of the pass, a logo on the top right, title of the card, some of the values as well as the hero image to brand our uh pass object a little bit. Now, the object is created. So, you're all ready to go and try to save the pass. Process of saving a pass to Google Wallet opens up a new activity where the operation is executed. Upon completion, a result is returned to the calling activity through on activity result. So, start by creating an arbitrary request code to start the save operation and capture the result. So, let's go back to the beginning of our main class and add a new member. It's going to be a private val. Add to Google Wallet request code. Now, if you have you're familiar with Android, you'll be also familiar with this concept on how activity for results work. Basically, when you launch an operation that exits your application, you need to set a code that helps you identify that operation when it comes back to your application, giving you back control with the result of that operation. So, that's an arbitrary number, which for me I'm going to set up I'm going to set to 999 for now. Finally, the next step is you want the pass to be saved as a response of the user clicking the add to Google Wallet button. So, you can go to step 6.2 on your own create method or whatever is most convenient for you setting up your layout and grab the item, the add to Google Wallet button item. Get the root of it. Remember that we created a composite view. So, we need to get the root of the element to be able to set the on click listener on it. And then to start the save operation, use the wallet client created previously, save passes. And this method takes three params. The first one is an unsigned JWT body with the information about the pass object defined before. So, that the object that is the object that you just defined behind the new object JSON variable. Second one is the activity where the result will be received. And that's going to be right here for us on the checkout activity. And finally, you need a request code to identify the request. That's the add to Google Wallet request code. So, you have everything you need. Now, if you were to run this code, if the API is available, you'll see the button on the screen. If you click the button, the save operation will begin. But, before doing that, let's also make sure to handle the result before it can before it comes back. So, to capture the result, go ahead and implement the on activity result method in the calling activity. So, if you go to step seven on line 73, you'll see that the method on the sample application is already overridden. So, the first thing you want to do is ensure that the result that is coming back through an activity result belongs to the save operation for Google Wallet. So, you do that by checking that the request code is equal to the add to Google Wallet request code that you set when you launched the operation. Now, instead of this block, we know that we're processing the result of the add to Google Wallet operation. And there's a number of potential results that we can get. To know which one we're getting, you can just take a look at the result code. So, we're going to do a when on the result code. There's a number of different um potential scenarios that you can be in. First one is result okay. That is everything went well and the pass was saved to your user's Google Wallet. In this case, myself, I'm not going to do anything, but in your case, feel free to notify the user if you need to. Similarly, if the user cancels the process before saving the pass, for example, by hitting on the back button or by closing the new prompt, you will receive the result result canceled. If you need to do anything here, feel free to add in here. Like logging or notifying your user once again. This is a very intentional operation, so I'm not going to do anything either here. Now, let's get into the error land. You can also get a safe process result saver. And there was an issue with the um creation process because there was like something malformed or ID was referenced uh in a way that couldn't be found on the server, you'll receive that type of error. So, that means there's something you can do to fix it. This error will contain information instead of the intent. So, what you can do is check on the data intent and see if it's not null. And if it's not null, try to process the result. And we'll do it through the intent data variable for this purpose. So, once again, this will contain information. So, we'll unpack um make sure to unpack it. Uh there's a string extra that comes with it. So, you can go ahead and select the string extra from the uh intent data. And the extra is uh on the Pay Client extra API error message, right? You can assign that to a variable, for example, API error message. Then inspect that and decide what to do next. You may want to log something to your back ends. You may want to let the user know. You may want to update the object once again to see if you can fix it, right? So, we'll say handle the error. Now, there are a number of other types of results that you can get, which I'm not going to go through. The other results are basic basically non-actionable. That means that something failed on the server, uh in which case we recommend you to retry the request, and if the error is not transient, that is, the error keeps on happening, we recommend you to treat the API as being unavailable and move on. We can do that with the else. We can handle all the all the non-actionable errors using the else clause. Okay, so now we're handling the potential result of adding the pass to Google Wallet. And I think I have one curly brace too much in here. There you go. And this looks like it's fine. So, now it's time to go ahead and test your integration. So, to do that, I'm going to hit on the play button for my Pixel 4 simulator and see if I was able to complete the integration successfully. If everything goes well, an application should open. If you're using our sample application, you will see that it has like a a very basic layout of a typical uh t-shirt shop, and the add to Google Wallet button will appear at the bottom only, remember, if the API is available. So, as as it runs and install the application, you will see the layout that we just talked about. The add to Google Wallet Wallet button is showing. So, that means that the API is available. So, I'm going to go ahead and click on it to start the save operation. That's opening the Google Wallet um user interface, and it's going to show me the pass that I'm about to save if everything goes well. So, as you can see, the pass was added already to my It was added to Google Pay, and when Google Wallet launches, it will be added to Google Wallet. So, what I can do is open the app and inspect the pass to make sure that everything looks okay. So, you can see some of the properties that you set in the configuration of the object. The logo with the header with the name of the attendee. Sorry, that's the card title. That's the header with the name of the attendee. This is the two item layouts, the barcode, and the hero image at the bottom. We also modified the details page. So, you can see that we were able to add uh customized elements in this uh section here. If you're seeing something similar, congratulations. That means that you were able to integrate the API correctly. If you see any error, keep in mind that you can move back and forth in this video and use the resources in the documentation to troubleshoot the integration. So, congratulations again for making it here. You've learned how to define and save a generic pass object to Google Wallet on Android. As you saw, you can let your users save passes on Android in three simple steps. Take a look at a complete integration in the sample application in GitHub and the code lab for this workshop for additional guidance. When you're ready to issue your own passes in production, go to Google Pay and Wallet Console to request access to the Google Wallet API and authorize your Android application to issue calls against the API. Check out the documentation at g.co/wallet/api to learn more. Don't forget to follow us on Twitter at Google Pay Devs to stay up-to-date about the latest developer news on Google Pay and Google Wallet. And I'll see you soon.
Original Description
Digitize any Wallet object with the Google Wallet API. In this tutorial, Google Developers will learn how to integrate the Google Wallet API to save passes on Android. Google Wallet is a secure container that allows users to save everyday things on an Android phone. Follow step-by-step instructions to digitize any wallet object using the Generic Pass API and explore Google Wallet new features.
Resource: Digitize any wallet object with the Wallet API → https://goo.gle/3wa1nmd
Speaker: Jose Ugia
Watch more:
All Google I/O 2022 Sessions → https://goo.gle/IO22_AllSessions
Google Developers at I/O 2022 playlist → https://goo.gle/IO22_GoogleDevs
All Google I/O 2022 workshops → https://goo.gle/IO22_Workshops
Subscribe to Google Developers → https://goo.gle/developers
#GoogleIO #GoogleWallet #GoogleDevelopers
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Google for Developers · Google for Developers · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Developer Journey - Sunnyvale DSC Summit ‘19
Google for Developers
How Google is working with students - Sunnyvale DSC Summit ‘19
Google for Developers
Starting your career in the Cloud - Sunnyvale DSC Summit ‘19
Google for Developers
The Solution Challenge - Sunnyvale DSC Summit ‘19
Google for Developers
Firebase - Sunnyvale DSC Summit ‘19
Google for Developers
Cloud Hero - Sunnyvale DSC Summit ‘19
Google for Developers
Panel discussion - Sunnyvale DSC Summit ‘19
Google for Developers
The art of negotiation - Sunnyvale DSC Summit ‘19
Google for Developers
Courage to care, solve and share - Sunnyvale DSC Summit ‘19
Google for Developers
Version 9 of Angular, Glass Enterprise Edition 2, path to DX deprecation, & more!
Google for Developers
[DEPRECATING] Introducing a new series (Assistant for Developers Pro Tips)
Google for Developers
Detecting memory bugs with HWASan, Bazel 2.1, Next ‘20 session guide, & more!
Google for Developers
Why Podcast.app chose a .app domain name
Google for Developers
Machine Learning Bootcamp Jakarta 2019
Google for Developers
Android Studio 3.6, Android 11 Developer Preview, Kubeflow 1.0, & more!
Google for Developers
[DEPRECATING] Importance of community (Assistant on Air)
Google for Developers
Why the Flutter team switched from .io to a .dev domain name
Google for Developers
3 website-building tips from .dev creators
Google for Developers
Why NimbleDroid chose a .app domain name
Google for Developers
Android Platform Codelab, Bazel 2.2, Maps Android Utility Library v1.0, & more!
Google for Developers
Google for Games Developer Summit: A free, digital experience for game developers
Google for Developers
Inspecting Home Graph (Assistant for Developers Pro Tips)
Google for Developers
Google for Games Developer Summit Keynote
Google for Developers
Stadia Games & Entertainment presents: Keys to a great game pitch (Google Games Dev Summit)
Google for Developers
Empowering game developers with Stadia R&D (Google Games Dev Summit)
Google for Developers
Supercharging discoverability with Stadia (Google Games Dev Summit)
Google for Developers
Stadia Games & Entertainment presents: Creating for content creators (Google Games Dev Summit)
Google for Developers
Bringing Destiny to Stadia: A postmortem (Google Games Dev Summit)
Google for Developers
Live Captioning in Google Slides
Google for Developers
[DEPRECATING] User engagement for the Google Assistant
Google for Developers
TensorFlow Dev Summit ‘20, Google for Games Dev Summit, Cloud AI Platform Pipelines, & much more!
Google for Developers
Top 5 from the TensorFlow Dev Summit 2020
Google for Developers
Developer Student Clubs 2019 Turkey Leads Summit
Google for Developers
Building simpler payment experiences | Google Pay Plugin for Magento 2
Google for Developers
Become A Developer Student Club Lead
Google for Developers
Firebase Kotlin Extensions, ARM apps on the Android Emulator, Angular v9.1, & more!
Google for Developers
Test suite for Smart Home (Assistant for Developers Pro Tips)
Google for Developers
Google Play updates, Bazel 3.0, Business Console for Google Pay, & more!
Google for Developers
How to use error logs (Assistant for Developers Pro Tips)
Google for Developers
Contact Center AI, Android Studio 4.1 Canary 5, TensorFlow QAT API, & more!
Google for Developers
WebView DevTools, Kotlin meets gRPC, Flutter CodePen support, & more! (Episode 200)
Google for Developers
Offline handling for Smart Home (Assistant for Developers Pro Tips)
Google for Developers
Android 11 Dev Preview 3, Google Fonts for Flutter, Shielded VM, & more!
Google for Developers
Machine Learning Foundations: Ep #1 - What is ML?
Google for Developers
Flutter web support updates, BigQuery materialized views, Cloud Spanner emulator, & more!
Google for Developers
Computer vision by building a neural network with TensorFlow | Machine Learning Foundations
Google for Developers
Machine Learning Foundations: Ep #3 - Convolutions and pooling
Google for Developers
Android 11 Beta plans, Flutter 1.17, Dart 2.8, & much more!
Google for Developers
Machine Learning Foundations: Ep #4 - Coding with Convolutional Neural Networks
Google for Developers
Google Developers ML Summit
Google for Developers
Real-world image classification using convolutional neural networks | Machine Learning Foundations
Google for Developers
Adobe XD support for Flutter, Architecture Framework, temporary closures with Places API, & more!
Google for Developers
Machine Learning Foundations: Ep #6 - Convolutional cats and dogs
Google for Developers
Machine Learning Foundations: Ep #7 - Image augmentation and overfitting
Google for Developers
Announcing Firebase Live, Flutter Day, Java 11 on Google Cloud Functions, & more!
Google for Developers
Machine Learning Foundations: Ep #8 - Tokenization for Natural Language Processing
Google for Developers
Android 11 Beta, Google Play Asset Delivery, Firebase Crashlytics SDK, & much more!
Google for Developers
Natural Language Processing: Using sequencing APIs in TensorFlow | Machine Learning Foundations
Google for Developers
Build a sarcasm classifier using NLP and TensorFlow | Machine Learning Foundations
Google for Developers
AR Realism with the ARCore Depth API
Google for Developers
More on: AI Workflow Automation
View skill →Related Reads
📰
📰
📰
📰
Additive column can 500 every login (Drizzle + Better Auth + preview deploys)
Dev.to · Omar Bni
Why Auth0 E2E Tests Fail After Login: The localStorage Race Condition
Dev.to · Anand Rathnas
Basic Git Command and What is Git
Medium · Programming
When to Use an ORM vs SQL and Query Builders
Dev.to · Doogal Simpson
🎓
Tutor Explanation
DeepCamp AI