JSON 웹 토큰은 정보를 JSON 객체로 안전하게 전송하기 위해 일반적으로 사용되는 업계 표준입니다. Google Wallet API를 사용할 때는 JWT('jot'라고 발음됨) 형식으로 패스 인스턴스를 만드는 데 사용할 패스 객체의 세부정보를 인코딩한 다음 Google Wallet API에 대한 요청으로 JWT를 전송합니다.
JWT는 Google Wallet API로 전송되기 전에 공유 비밀번호로 서명함으로써 안전하게 보호됩니다. Google Wallet REST API를 사용하는 경우 서명 비밀번호는 Google Cloud 서비스 계정 키입니다. Google 월렛 Android SDK를 사용하는 경우 서명 비밀번호는 Android 앱의 SHA-1 지문입니다.
JWT에서 패스 인코딩
GiftCardObject
가 생성되면 다음 스니펫과 같이 payload.GiftCardObjects
속성이 있는 서명되지 않은 JWT로 래핑합니다.
JSON
{
"iss": "OWNER_EMAIL_ADDRESS",
"aud": "google",
"typ": "savetowallet",
"iat": "UNIX_TIME",
"origins": [],
"payload": {
"giftcardObjects": [ NEW_OBJECT ]
}
}
JWT의 예상 형식에 대한 자세한 내용은 JWT 참조를 확인하세요.
JWT 서명
JWT는 Google Wallet API로 전송되기 전에 공유 비밀번호로 서명함으로써 안전하게 보호됩니다. Google Wallet REST API를 사용하는 경우 서명 비밀번호는 Google Cloud 서비스 계정 키입니다. Google 월렛 Android SDK를 사용하는 경우 서명 비밀번호는 Android 앱의 SHA-1 지문입니다.
웹, 이메일 및 SMS
JWT는 Google 월렛 비즈니스 콘솔에서 승인한 Google Cloud 서비스 계정과 연결된 서비스 계정 키를 사용하여 서명되어야 합니다. Google Wallet API는 JWT 서명을 확인하여 이러한 클레임을 검증합니다.
JWT에 서명하면 'Google 월렛에 추가'를 만드는 데 사용할 수 있는 토큰이 생성됩니다. 사용자에게 패스를 발급하는 데 사용할 수 있는 링크입니다.
자바
Java에서 통합을 시작하려면 전체 <ph type="x-smartling-placeholder"></ph> 코드 샘플을 확인하세요.
/** * Generate a signed JWT that creates a new pass class and object. * * <p>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 objectSuffix Developer-defined unique ID for the pass object. * @return An "Add to Google Wallet" link. */ public String createJWTNewObjects(String issuerId, String classSuffix, String objectSuffix) { // See link below for more information on required properties // https://developers.google.com/wallet/retail/gift-cards/rest/v1/giftcardclass GiftCardClass newClass = new GiftCardClass() .setId(String.format("%s.%s", issuerId, classSuffix)) .setIssuerName("Issuer name") .setReviewStatus("UNDER_REVIEW"); // See link below for more information on required properties // https://developers.google.com/wallet/retail/gift-cards/rest/v1/giftcardobject GiftCardObject newObject = new GiftCardObject() .setId(String.format("%s.%s", issuerId, objectSuffix)) .setClassId(String.format("%s.%s", issuerId, classSuffix)) .setState("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( List.of( 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( List.of( 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")) .setLocations( List.of( new LatLongPoint() .setLatitude(37.424015499999996) .setLongitude(-122.09259560000001))) .setCardNumber("Card number") .setPin("1234") .setBalance(new Money().setMicros(20000000L).setCurrencyCode("USD")) .setBalanceUpdateTime(new DateTime().setDate("2020-04-12T16:20:50.52-04:00")); // Create the JWT as a HashMap object HashMap<String, Object> claims = new HashMap<String, Object>(); claims.put("iss", ((ServiceAccountCredentials) credentials).getClientEmail()); claims.put("aud", "google"); claims.put("origins", List.of("www.example.com")); claims.put("typ", "savetowallet"); // Create the Google Wallet payload and add to the JWT HashMap<String, Object> payload = new HashMap<String, Object>(); payload.put("giftCardClasses", List.of(newClass)); payload.put("giftCardObjects", List.of(newObject)); claims.put("payload", payload); // The service account credentials are used to sign the JWT Algorithm algorithm = Algorithm.RSA256( null, (RSAPrivateKey) ((ServiceAccountCredentials) credentials).getPrivateKey()); String token = JWT.create().withPayload(claims).sign(algorithm); System.out.println("Add to Google Wallet link"); System.out.printf("https://pay.google.com/gp/v/save/%s%n", token); return String.format("https://pay.google.com/gp/v/save/%s", token); }
PHP
PHP에서 통합을 시작하려면 전체 <ph type="x-smartling-placeholder"></ph> 코드 샘플을 확인하세요.
/** * 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 string $issuerId The issuer ID being used for this request. * @param string $classSuffix Developer-defined unique ID for the pass class. * @param string $objectSuffix Developer-defined unique ID for the pass object. * * @return string An "Add to Google Wallet" link. */ public function createJwtNewObjects(string $issuerId, string $classSuffix, string $objectSuffix) { // See link below for more information on required properties // https://developers.google.com/wallet/retail/gift-cards/rest/v1/giftcardclass $newClass = new GiftCardClass([ 'id' => "{$issuerId}.{$classSuffix}", 'issuerName' => 'Issuer name', 'reviewStatus' => 'UNDER_REVIEW' ]); // See link below for more information on required properties // https://developers.google.com/wallet/retail/gift-cards/rest/v1/giftcardobject $newObject = new GiftCardObject([ 'id' => "{$issuerId}.{$objectSuffix}", 'classId' => "{$issuerId}.{$classSuffix}", 'state' => 'ACTIVE', 'heroImage' => new Image([ 'sourceUri' => new ImageUri([ 'uri' => 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg' ]), 'contentDescription' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'Hero image description' ]) ]) ]), 'textModulesData' => [ new TextModuleData([ 'header' => 'Text module header', 'body' => 'Text module body', 'id' => 'TEXT_MODULE_ID' ]) ], 'linksModuleData' => new LinksModuleData([ 'uris' => [ new Uri([ 'uri' => 'http://maps.google.com/', 'description' => 'Link module URI description', 'id' => 'LINK_MODULE_URI_ID' ]), new Uri([ 'uri' => 'tel:6505555555', 'description' => 'Link module tel description', 'id' => 'LINK_MODULE_TEL_ID' ]) ] ]), 'imageModulesData' => [ new ImageModuleData([ 'mainImage' => new Image([ 'sourceUri' => new ImageUri([ 'uri' => 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg' ]), 'contentDescription' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'Image module description' ]) ]) ]), 'id' => 'IMAGE_MODULE_ID' ]) ], 'barcode' => new Barcode([ 'type' => 'QR_CODE', 'value' => 'QR code value' ]), 'locations' => [ new LatLongPoint([ 'latitude' => 37.424015499999996, 'longitude' => -122.09259560000001 ]) ], 'cardNumber' => 'Card number', 'pin' => '1234', 'balance' => new Money([ 'micros' => 20000000, 'currencyCode' => 'USD' ]), 'balanceUpdateTime' => new DateTime([ 'date' => '2020-04-12T16:20:50.52-04:00' ]) ]); // The service account credentials are used to sign the JWT $serviceAccount = json_decode(file_get_contents($this->keyFilePath), true); // Create the JWT as an array of key/value pairs $claims = [ 'iss' => $serviceAccount['client_email'], 'aud' => 'google', 'origins' => ['www.example.com'], 'typ' => 'savetowallet', 'payload' => [ 'giftCardClasses' => [ $newClass ], 'giftCardObjects' => [ $newObject ] ] ]; $token = JWT::encode( $claims, $serviceAccount['private_key'], 'RS256' ); print "Add to Google Wallet link\n"; print "https://pay.google.com/gp/v/save/{$token}"; return "https://pay.google.com/gp/v/save/{$token}"; }
Python
Python에서 통합을 시작하려면 전체 <ph type="x-smartling-placeholder"></ph> 코드 샘플을 확인하세요.
def create_jwt_new_objects(self, issuer_id: str, class_suffix: str, object_suffix: str) -> str: """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. Args: issuer_id (str): The issuer ID being used for this request. class_suffix (str): Developer-defined unique ID for the pass class. object_suffix (str): Developer-defined unique ID for the pass object. Returns: An "Add to Google Wallet" link. """ # See link below for more information on required properties # https://developers.google.com/wallet/retail/gift-cards/rest/v1/giftcardclass new_class = { 'id': f'{issuer_id}.{class_suffix}', 'issuerName': 'Issuer name', 'reviewStatus': 'UNDER_REVIEW' } # See link below for more information on required properties # https://developers.google.com/wallet/retail/gift-cards/rest/v1/giftcardobject new_object = { 'id': f'{issuer_id}.{object_suffix}', 'classId': f'{issuer_id}.{class_suffix}', 'state': 'ACTIVE', 'heroImage': { 'sourceUri': { 'uri': 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg' }, 'contentDescription': { 'defaultValue': { 'language': 'en-US', 'value': 'Hero image description' } } }, 'textModulesData': [{ 'header': 'Text module header', 'body': 'Text module body', 'id': 'TEXT_MODULE_ID' }], 'linksModuleData': { 'uris': [{ 'uri': 'http://maps.google.com/', 'description': 'Link module URI description', 'id': 'LINK_MODULE_URI_ID' }, { 'uri': 'tel:6505555555', 'description': 'Link module tel description', 'id': 'LINK_MODULE_TEL_ID' }] }, 'imageModulesData': [{ 'mainImage': { 'sourceUri': { 'uri': 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg' }, 'contentDescription': { 'defaultValue': { 'language': 'en-US', 'value': 'Image module description' } } }, 'id': 'IMAGE_MODULE_ID' }], 'barcode': { 'type': 'QR_CODE', 'value': 'QR code' }, 'locations': [{ 'latitude': 37.424015499999996, 'longitude': -122.09259560000001 }], 'cardNumber': 'Card number', 'pin': '1234', 'balance': { 'micros': 20000000, 'currencyCode': 'USD' }, 'balanceUpdateTime': { 'date': '2020-04-12T16:20:50.52-04:00' } } # Create the JWT claims claims = { 'iss': self.credentials.service_account_email, 'aud': 'google', 'origins': ['www.example.com'], 'typ': 'savetowallet', 'payload': { # The listed classes and objects will be created 'giftCardClasses': [new_class], 'giftCardObjects': [new_object] }, } # The service account credentials are used to sign the JWT signer = crypt.RSASigner.from_service_account_file(self.key_file_path) token = jwt.encode(signer, claims).decode('utf-8') print('Add to Google Wallet link') print(f'https://pay.google.com/gp/v/save/{token}') return f'https://pay.google.com/gp/v/save/{token}'
C#
C#에서 통합을 시작하려면 전체 <ph type="x-smartling-placeholder"></ph> 코드 샘플을 확인하세요.
/// <summary> /// Generate a signed JWT that creates a new pass class and object. /// <para /> /// 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. /// <para /> /// The Google Wallet C# library uses Newtonsoft.Json.JsonPropertyAttribute /// to specify the property names when converting objects to JSON. The /// Newtonsoft.Json.JsonConvert.SerializeObject method will automatically /// serialize the object with the right property names. /// </summary> /// <param name="issuerId">The issuer ID being used for this request.</param> /// <param name="classSuffix">Developer-defined unique ID for this pass class.</param> /// <param name="objectSuffix">Developer-defined unique ID for the pass object.</param> /// <returns>An "Add to Google Wallet" link.</returns> public string CreateJWTNewObjects(string issuerId, string classSuffix, string objectSuffix) { // Ignore null values when serializing to/from JSON JsonSerializerSettings excludeNulls = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }; // See link below for more information on required properties // https://developers.google.com/wallet/retail/gift-cards/rest/v1/giftcardclass GiftCardClass newClass = new GiftCardClass { Id = $"{issuerId}.{classSuffix}", IssuerName = "Issuer name", ReviewStatus = "UNDER_REVIEW" }; // See below for more information on required properties // https://developers.google.com/wallet/retail/gift-cards/rest/v1/giftcardobject GiftCardObject newObject = new GiftCardObject { Id = $"{issuerId}.{objectSuffix}", ClassId = $"{issuerId}.{classSuffix}", State = "ACTIVE", HeroImage = new Image { SourceUri = new ImageUri { Uri = "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg" }, ContentDescription = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "Hero image description" } } }, TextModulesData = new List<TextModuleData> { new TextModuleData { Header = "Text module header", Body = "Text module body", Id = "TEXT_MODULE_ID" } }, LinksModuleData = new LinksModuleData { Uris = new List<Google.Apis.Walletobjects.v1.Data.Uri> { new Google.Apis.Walletobjects.v1.Data.Uri { UriValue = "http://maps.google.com/", Description = "Link module URI description", Id = "LINK_MODULE_URI_ID" }, new Google.Apis.Walletobjects.v1.Data.Uri { UriValue = "tel:6505555555", Description = "Link module tel description", Id = "LINK_MODULE_TEL_ID" } } }, ImageModulesData = new List<ImageModuleData> { new ImageModuleData { MainImage = new Image { SourceUri = new ImageUri { Uri = "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg" }, ContentDescription = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "Image module description" } } }, Id = "IMAGE_MODULE_ID" } }, Barcode = new Barcode { Type = "QR_CODE", Value = "QR code" }, Locations = new List<LatLongPoint> { new LatLongPoint { Latitude = 37.424015499999996, Longitude = -122.09259560000001 } }, CardNumber = "Card number", Pin = "1234", Balance = new Money { Micros = 20000000, CurrencyCode = "USD" }, BalanceUpdateTime = new Google.Apis.Walletobjects.v1.Data.DateTime { Date = "2020-04-12T16:20:50.52-04:00" } }; // Create JSON representations of the class and object JObject serializedClass = JObject.Parse( JsonConvert.SerializeObject(newClass, excludeNulls)); JObject serializedObject = JObject.Parse( JsonConvert.SerializeObject(newObject, excludeNulls)); // Create the JWT as a JSON object JObject jwtPayload = JObject.Parse(JsonConvert.SerializeObject(new { iss = credentials.Id, aud = "google", origins = new List<string> { "www.example.com" }, typ = "savetowallet", payload = JObject.Parse(JsonConvert.SerializeObject(new { // The listed classes and objects will be created // when the user saves the pass to their wallet giftCardClasses = new List<JObject> { serializedClass }, giftCardObjects = new List<JObject> { serializedObject } })) })); // Deserialize into a JwtPayload JwtPayload claims = JwtPayload.Deserialize(jwtPayload.ToString()); // The service account credentials are used to sign the JWT RsaSecurityKey key = new RsaSecurityKey(credentials.Key); SigningCredentials signingCredentials = new SigningCredentials( key, SecurityAlgorithms.RsaSha256); JwtSecurityToken jwt = new JwtSecurityToken( new JwtHeader(signingCredentials), claims); string token = new JwtSecurityTokenHandler().WriteToken(jwt); Console.WriteLine("Add to Google Wallet link"); Console.WriteLine($"https://pay.google.com/gp/v/save/{token}"); return $"https://pay.google.com/gp/v/save/{token}"; }
Node.js
노드에서 통합을 시작하려면 전체 <ph type="x-smartling-placeholder"></ph> 코드 샘플을 확인하세요.
/** * 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 {string} issuerId The issuer ID being used for this request. * @param {string} classSuffix Developer-defined unique ID for the pass class. * @param {string} objectSuffix Developer-defined unique ID for the pass object. * * @returns {string} An "Add to Google Wallet" link. */ createJwtNewObjects(issuerId, classSuffix, objectSuffix) { // See link below for more information on required properties // https://developers.google.com/wallet/retail/gift-cards/rest/v1/giftcardclass let newClass = { 'id': `${issuerId}.${classSuffix}`, 'issuerName': 'Issuer name', 'reviewStatus': 'UNDER_REVIEW' }; // See link below for more information on required properties // https://developers.google.com/wallet/retail/gift-cards/rest/v1/giftcardobject let newObject = { 'id': `${issuerId}.${objectSuffix}`, 'classId': `${issuerId}.${classSuffix}`, 'state': 'ACTIVE', 'heroImage': { 'sourceUri': { 'uri': 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg' }, 'contentDescription': { 'defaultValue': { 'language': 'en-US', 'value': 'Hero image description' } } }, 'textModulesData': [ { 'header': 'Text module header', 'body': 'Text module body', 'id': 'TEXT_MODULE_ID' } ], 'linksModuleData': { 'uris': [ { 'uri': 'http://maps.google.com/', 'description': 'Link module URI description', 'id': 'LINK_MODULE_URI_ID' }, { 'uri': 'tel:6505555555', 'description': 'Link module tel description', 'id': 'LINK_MODULE_TEL_ID' } ] }, 'imageModulesData': [ { 'mainImage': { 'sourceUri': { 'uri': 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg' }, 'contentDescription': { 'defaultValue': { 'language': 'en-US', 'value': 'Image module description' } } }, 'id': 'IMAGE_MODULE_ID' } ], 'barcode': { 'type': 'QR_CODE', 'value': 'QR code' }, 'locations': [ { 'latitude': 37.424015499999996, 'longitude': -122.09259560000001 } ], 'cardNumber': 'Card number', 'pin': '1234', 'balance': { 'micros': 20000000, 'currencyCode': 'USD' }, 'balanceUpdateTime': { 'date': '2020-04-12T16:20:50.52-04:00' } }; // Create the JWT claims let claims = { iss: this.credentials.client_email, aud: 'google', origins: ['www.example.com'], typ: 'savetowallet', payload: { // The listed classes and objects will be created giftCardClasses: [newClass], giftCardObjects: [newObject] }, }; // The service account credentials are used to sign the JWT let token = jwt.sign(claims, this.credentials.private_key, { algorithm: 'RS256' }); console.log('Add to Google Wallet link'); console.log(`https://pay.google.com/gp/v/save/${token}`); return `https://pay.google.com/gp/v/save/${token}`; }
Go
Go에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참고하세요. <ph type="x-smartling-placeholder"></ph> 코드 샘플을 확인하세요.
// 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. func (d *demoGiftcard) createJwtNewObjects(issuerId, classSuffix, objectSuffix string) { giftcardObject := new(walletobjects.GiftCardObject) giftcardObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix) giftcardObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix) giftcardObject.State = "ACTIVE" giftcardObject.CardNumber = "Card number" giftcardJson, _ := json.Marshal(giftcardObject) var payload map[string]any json.Unmarshal([]byte(fmt.Sprintf(` { "giftcardObjects": [%s] } `, giftcardJson)), &payload) claims := jwt.MapClaims{ "iss": d.credentials.Email, "aud": "google", "origins": []string{"www.example.com"}, "typ": "savetowallet", "payload": payload, } // The service account credentials are used to sign the JWT key, _ := jwt.ParseRSAPrivateKeyFromPEM(d.credentials.PrivateKey) token, _ := jwt.NewWithClaims(jwt.SigningMethodRS256, claims).SignedString(key) fmt.Println("Add to Google Wallet link") fmt.Println("https://pay.google.com/gp/v/save/" + token) }
Android 앱
사용자에게 패스를 발급하기 위해 savePasses
메서드가 호출되면 Google 월렛 Android SDK가 Google 월렛 비즈니스 콘솔에서 제공한 앱 서명 키의 SHA-1 디지털 지문으로 JWT에 자동으로 서명합니다. 또는 Android SDK의 savePassesJwt
메서드를 사용하여 이전에 서명된 JWT를 사용하여 패스를 실행할 수도 있습니다.
자세한 내용은 Android SDK로 패스 발급을 참조하세요.