/* * Copyright 2022 Google Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // [START setup] // [START imports] import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import com.google.api.client.googleapis.batch.BatchRequest; import com.google.api.client.googleapis.batch.json.JsonBatchCallback; import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport; import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.*; import com.google.api.client.json.gson.GsonFactory; import com.google.api.services.walletobjects.Walletobjects; import com.google.api.services.walletobjects.model.*; import com.google.auth.http.HttpCredentialsAdapter; import com.google.auth.oauth2.GoogleCredentials; import com.google.auth.oauth2.ServiceAccountCredentials; import java.io.*; import java.security.interfaces.RSAPrivateKey; import java.util.*; // [END imports] /** Demo class for creating and managing Generic passes in Google Wallet. */ public class DemoGeneric { /** * Path to service account key file from Google Cloud Console. Environment variable: * GOOGLE_APPLICATION_CREDENTIALS. */ public static String keyFilePath; /** Service account credentials for Google Wallet APIs. */ public static GoogleCredentials credentials; /** Google Wallet service client. */ public static Walletobjects service; public DemoGeneric() { keyFilePath = System.getenv().getOrDefault("GOOGLE_APPLICATION_CREDENTIALS", "/path/to/key.json"); } // [END setup] // [START auth] /** * Create authenticated HTTP client using a service account file. * * @throws Exception */ public void Auth() throws Exception { String scope = "https://www.googleapis.com/auth/wallet_object.issuer"; credentials = GoogleCredentials.fromStream(new FileInputStream(keyFilePath)) .createScoped(Arrays.asList(scope)); credentials.refresh(); HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport(); service = new Walletobjects.Builder( httpTransport, GsonFactory.getDefaultInstance(), new HttpCredentialsAdapter(credentials)) .setApplicationName("APPLICATION_NAME") .build(); } // [END auth] // [START class] /** * Create a class via the API. This can also be done in the Google Pay and Wallet console. * * @param issuerId The issuer ID being used for this request. * @param classSuffix Developer-defined unique ID for this pass class. * @return The pass class ID: "{issuerId}.{classSuffix}" * @throws IOException */ public String CreateGenericClass(String issuerId, String classSuffix) throws IOException { // See link below for more information on required properties // https://developers.google.com/wallet/generic/rest/v1/genericclass GenericClass genericClass = new GenericClass().setId(String.format("%s.%s", issuerId, classSuffix)); try { GenericClass response = service.genericclass().insert(genericClass).execute(); System.out.println("Class insert response"); System.out.println(response.toPrettyString()); return response.getId(); } catch (GoogleJsonResponseException ex) { if (ex.getStatusCode() == 409) { System.out.println(String.format("Class %s.%s already exists", issuerId, classSuffix)); return String.format("%s.%s", issuerId, classSuffix); } // Something else went wrong ex.printStackTrace(); return ex.getMessage(); } } // [END class] // [START object] /** * Create an object via the API. * * @param issuerId The issuer ID being used for this request. * @param classSuffix Developer-defined unique ID for this pass class. * @param userId Developer-defined user ID for this object. * @return The pass object ID: "{issuerId}.{userId}" * @throws IOException */ public String CreateGenericObject(String issuerId, String classSuffix, String userId) throws IOException { // Generate the object ID // Should only include alphanumeric characters, '.', '_', or '-' String newUserId = userId.replaceAll("[^\\w.-]", "_"); String objectId = String.format("%s.%s", issuerId, newUserId); try { // Check if the object exists GenericObject response = service.genericobject().get(objectId).execute(); System.out.println("Object get response"); System.out.println(response.toPrettyString()); return response.getId(); } catch (GoogleJsonResponseException ex) { if (ex.getStatusCode() != 404) { // Something else went wrong ex.printStackTrace(); return ex.getMessage(); } } // Object doesn't exist, create it now // See link below for more information on required properties // https://developers.google.com/wallet/generic/rest/v1/genericobject GenericObject genericObject = new GenericObject() .setId(objectId) .setClassId(String.format("%s.%s", issuerId, classSuffix)) .set("state", "ACTIVE") .setHeroImage( new Image() .setSourceUri( new ImageUri() .setUri( "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg")) .setContentDescription( new LocalizedString() .setDefaultValue( new TranslatedString() .setLanguage("en-US") .setValue("Hero image description")))) .setTextModulesData( Arrays.asList( new TextModuleData() .setHeader("Text module header") .setBody("Text module body") .setId("TEXT_MODULE_ID"))) .setLinksModuleData( new LinksModuleData() .setUris( Arrays.asList( new Uri() .setUri("http://maps.google.com/") .setDescription("Link module URI description") .setId("LINK_MODULE_URI_ID"), new Uri() .setUri("tel:6505555555") .setDescription("Link module tel description") .setId("LINK_MODULE_TEL_ID")))) .setImageModulesData( Arrays.asList( new ImageModuleData() .setMainImage( new Image() .setSourceUri( new ImageUri() .setUri( "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg")) .setContentDescription( new LocalizedString() .setDefaultValue( new TranslatedString() .setLanguage("en-US") .setValue("Image module description")))) .setId("IMAGE_MODULE_ID"))) .setBarcode(new Barcode().setType("QR_CODE").setValue("QR code value")) .setCardTitle( new LocalizedString() .setDefaultValue( new TranslatedString().setLanguage("en-US").setValue("Generic card title"))) .setHeader( new LocalizedString() .setDefaultValue( new TranslatedString().setLanguage("en-US").setValue("Generic header"))) .setHexBackgroundColor("#4285f4") .setLogo( new Image() .setSourceUri( new ImageUri() .setUri( "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg")) .setContentDescription( new LocalizedString() .setDefaultValue( new TranslatedString() .setLanguage("en-US") .setValue("Generic card logo")))); GenericObject response = service.genericobject().insert(genericObject).execute(); System.out.println("Object insert response"); System.out.println(response.toPrettyString()); return response.getId(); } // [END object] // [START jwt] /** * Generate a signed JWT that creates a new pass class and object. * *
When the user opens the "Add to Google Wallet" URL and saves the pass to their wallet, the
* pass class and object defined in the JWT are created. This allows you to create multiple pass
* classes and objects in one API call when the user saves the pass to their wallet.
*
* @param issuerId The issuer ID being used for this request.
* @param classSuffix Developer-defined unique ID for this pass class.
* @param userId Developer-defined user ID for this object.
* @return An "Add to Google Wallet" link.
*/
public String CreateJWTSaveURL(String issuerId, String classSuffix, String userId) {
// Generate the object ID
// Should only include alphanumeric characters, '.', '_', or '-'
String newUserId = userId.replaceAll("[^\\w.-]", "_");
String objectId = String.format("%s.%s", issuerId, newUserId);
// See link below for more information on required properties
// https://developers.google.com/wallet/generic/rest/v1/genericclass
GenericClass genericClass = new GenericClass().setId(String.format("%s.%s", issuerId, classSuffix));
// See link below for more information on required properties
// https://developers.google.com/wallet/generic/rest/v1/genericobject
GenericObject genericObject =
new GenericObject()
.setId(objectId)
.setClassId(String.format("%s.%s", issuerId, classSuffix))
.set("state", "ACTIVE")
.setHeroImage(
new Image()
.setSourceUri(
new ImageUri()
.setUri(
"https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"))
.setContentDescription(
new LocalizedString()
.setDefaultValue(
new TranslatedString()
.setLanguage("en-US")
.setValue("Hero image description"))))
.setTextModulesData(
Arrays.asList(
new TextModuleData()
.setHeader("Text module header")
.setBody("Text module body")
.setId("TEXT_MODULE_ID")))
.setLinksModuleData(
new LinksModuleData()
.setUris(
Arrays.asList(
new Uri()
.setUri("http://maps.google.com/")
.setDescription("Link module URI description")
.setId("LINK_MODULE_URI_ID"),
new Uri()
.setUri("tel:6505555555")
.setDescription("Link module tel description")
.setId("LINK_MODULE_TEL_ID"))))
.setImageModulesData(
Arrays.asList(
new ImageModuleData()
.setMainImage(
new Image()
.setSourceUri(
new ImageUri()
.setUri(
"http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg"))
.setContentDescription(
new LocalizedString()
.setDefaultValue(
new TranslatedString()
.setLanguage("en-US")
.setValue("Image module description"))))
.setId("IMAGE_MODULE_ID")))
.setBarcode(new Barcode().setType("QR_CODE").setValue("QR code value"))
.setCardTitle(
new LocalizedString()
.setDefaultValue(
new TranslatedString().setLanguage("en-US").setValue("Generic card title")))
.setHeader(
new LocalizedString()
.setDefaultValue(
new TranslatedString().setLanguage("en-US").setValue("Generic header")))
.setHexBackgroundColor("#4285f4")
.setLogo(
new Image()
.setSourceUri(
new ImageUri()
.setUri(
"https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg"))
.setContentDescription(
new LocalizedString()
.setDefaultValue(
new TranslatedString()
.setLanguage("en-US")
.setValue("Generic card logo"))));
// Create the JWT as a HashMap object
HashMap Example permissions list argument below. Copy the add entry as needed for each email address
* that will need access. Supported values for role are: 'READER', 'WRITER', and 'OWNER'
*
*
*
* @param issuerId The issuer ID being used for this request.
* @param permissions The list of email addresses and roles to assign.
* @throws IOException
*/
public void UpdateIssuerAccountPermissions(String issuerId, ArrayList
* ArrayList