Web API를 시작하기 전에 기본 요건을 완료해야 합니다. Web API를 계속 사용하려면 서비스 계정과 서비스 계정 키가 있어야 하며 Pass API를 호출할 수 있는 액세스 권한을 서비스 계정에 부여해야 합니다.
GitHub에서 샘플 코드를 다운로드하여 아래 단계에서 참조되는 코드 스니펫을 실행합니다.
인증 및 승인
Google Wallet API에 대한 요청은 Google Wallet API가 애플리케이션에 의한 요청임을 식별할 수 있도록 인증되어야 합니다. 서비스 계정 키를 사용하여 액세스 토큰을 가져오면 됩니다.
먼저 필요한 라이브러리 가져오기를 수행하고 서비스 계정 JSON에 사용할 몇 가지 변수와 저장할 발급기관, 클래스, 순 사용자, 객체의 ID를 정의합니다.
Java
자바에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참고하세요.
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.*; /** Demo class for creating and managing Offers in Google Wallet. */ public class DemoOffer { /** * 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 DemoOffer() throws Exception { keyFilePath = System.getenv().getOrDefault("GOOGLE_APPLICATION_CREDENTIALS", "/path/to/key.json"); auth(); }
2,399필리핀
PHP에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
use Firebase\JWT\JWT; use Google\Auth\Credentials\ServiceAccountCredentials; use Google\Client as Google_Client; /** Demo class for creating and managing Offers in Google Wallet. */ class DemoOffer { /** * Path to service account key file from Google Cloud Console. Environment * variable: GOOGLE_APPLICATION_CREDENTIALS. */ public string $keyFilePath; /** * Service account credentials for Google Wallet APIs. */ public ServiceAccountCredentials $credentials; /** * Google Wallet service client. */ public Google_Service_Walletobjects $service; public function __construct() { $this->keyFilePath = getenv('GOOGLE_APPLICATION_CREDENTIALS') ?: '/path/to/key.json'; $this->auth(); }
Python
Python에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
import json import os import uuid from google.auth.transport.requests import AuthorizedSession from google.oauth2.service_account import Credentials from google.auth import jwt, crypt class DemoOffer: """Demo class for creating and managing Offers in Google Wallet. Attributes: key_file_path: Path to service account key file from Google Cloud Console. Environment variable: GOOGLE_APPLICATION_CREDENTIALS. base_url: Base URL for Google Wallet API requests. """ def __init__(self): self.key_file_path = os.environ.get('GOOGLE_APPLICATION_CREDENTIALS', '/path/to/key.json') self.base_url = 'https://walletobjects.googleapis.com/walletobjects/v1' self.batch_url = 'https://walletobjects.googleapis.com/batch' self.class_url = f'{self.base_url}/offerClass' self.object_url = f'{self.base_url}/offerObject' # Set up authenticated client self.auth()
C#
C#에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
using System.IdentityModel.Tokens.Jwt; using System.Net.Http.Headers; using System.Text.RegularExpressions; using Google.Apis.Auth.OAuth2; using Google.Apis.Services; using Google.Apis.Walletobjects.v1; using Google.Apis.Walletobjects.v1.Data; using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using Newtonsoft.Json.Linq; /// <summary> /// Demo class for creating and managing Offers in Google Wallet. /// </summary> class DemoOffer { /// <summary> /// Path to service account key file from Google Cloud Console. Environment /// variable: GOOGLE_APPLICATION_CREDENTIALS. /// </summary> public static string keyFilePath; /// <summary> /// Service account credentials for Google Wallet APIs /// </summary> public static ServiceAccountCredential credentials; /// <summary> /// Google Wallet service client /// </summary> public static WalletobjectsService service; public DemoOffer() { keyFilePath = Environment.GetEnvironmentVariable( "GOOGLE_APPLICATION_CREDENTIALS") ?? "/path/to/key.json"; Auth(); }
Node.js
노드에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
const { GoogleAuth } = require('google-auth-library'); const jwt = require('jsonwebtoken'); const { v4: uuidv4 } = require('uuid'); /** * Demo class for creating and managing Offers in Google Wallet. */ class DemoOffer { constructor() { /** * Path to service account key file from Google Cloud Console. Environment * variable: GOOGLE_APPLICATION_CREDENTIALS. */ this.keyFilePath = process.env.GOOGLE_APPLICATION_CREDENTIALS || '/path/to/key.json'; this.baseUrl = 'https://walletobjects.googleapis.com/walletobjects/v1'; this.batchUrl = 'https://walletobjects.googleapis.com/batch'; this.classUrl = `${this.baseUrl}/offerClass`; this.objectUrl = `${this.baseUrl}/offerObject`; this.auth(); }
Go
Go에서 통합을 시작하려면 GitHub의 GitHub 코드 샘플의 전체 코드 샘플을 참조하세요.
package main import ( "bytes" "encoding/json" "fmt" "github.com/golang-jwt/jwt" "github.com/google/uuid" "golang.org/x/oauth2" "golang.org/x/oauth2/google" oauthJwt "golang.org/x/oauth2/jwt" "io" "net/http" "os" "strings" ) const ( batchUrl = "https://walletobjects.googleapis.com/batch" classUrl = "https://walletobjects.googleapis.com/walletobjects/v1/offerClass" objectUrl = "https://walletobjects.googleapis.com/walletobjects/v1/offerObject" )
그런 다음 프레임워크 라이브러리 중 하나를 사용하여 Google Wallet API 호출에 필요한 사용자 인증 정보를 검색합니다.
Java
자바에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참고하세요.
/** * Create authenticated HTTP client using a service account file. * */ public void auth() throws Exception { String scope = "https://www.googleapis.com/auth/wallet_object.issuer"; credentials = GoogleCredentials.fromStream(new FileInputStream(keyFilePath)) .createScoped(List.of(scope)); credentials.refresh(); HttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport(); // Initialize Google Wallet API service service = new Walletobjects.Builder( httpTransport, GsonFactory.getDefaultInstance(), new HttpCredentialsAdapter(credentials)) .setApplicationName("APPLICATION_NAME") .build(); }
2,399필리핀
PHP에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
/** * Create authenticated HTTP client using a service account file. */ public function auth() { $scope = 'https://www.googleapis.com/auth/wallet_object.issuer'; $this->credentials = new ServiceAccountCredentials( $scope, $this->keyFilePath ); // Initialize Google Wallet API service $this->client = new Google_Client(); $this->client->setApplicationName('APPLICATION_NAME'); $this->client->setScopes($scope); $this->client->setAuthConfig($this->keyFilePath); $this->service = new Google_Service_Walletobjects($this->client); }
Python
Python에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
def auth(self): """Create authenticated HTTP client using a service account file.""" self.credentials = Credentials.from_service_account_file( self.key_file_path, scopes=['https://www.googleapis.com/auth/wallet_object.issuer']) self.http_client = AuthorizedSession(self.credentials)
C#
C#에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
/// <summary> /// Create authenticated service client using a service account file. /// </summary> public void Auth() { credentials = (ServiceAccountCredential)GoogleCredential .FromFile(keyFilePath) .CreateScoped(new List<string> { "https://www.googleapis.com/auth/wallet_object.issuer" }) .UnderlyingCredential; service = new WalletobjectsService( new BaseClientService.Initializer() { HttpClientInitializer = credentials }); }
Node.js
노드에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
/** * Create authenticated HTTP client using a service account file. */ auth() { this.credentials = require(this.keyFilePath); this.httpClient = new GoogleAuth({ credentials: this.credentials, scopes: 'https://www.googleapis.com/auth/wallet_object.issuer' }); }
Go
Go에서 통합을 시작하려면 GitHub의 GitHub 코드 샘플의 전체 코드 샘플을 참조하세요.
// Create authenticated HTTP client using a service account file. func (d *demoOffer) auth() { b, _ := os.ReadFile(os.Getenv("GOOGLE_APPLICATION_CREDENTIALS")) credentials, _ := google.JWTConfigFromJSON(b, "https://www.googleapis.com/auth/wallet_object.issuer") d.credentials = credentials d.httpClient = d.credentials.Client(oauth2.NoContext) }
패스 객체 만들기
패스 객체는 패스 클래스의 인스턴스입니다. 패스 객체를 만들려면 다음 속성을 제공해야 합니다.
classId
: Passes 클래스의id
id
: 고객의 고유 ID입니다. 이러한 속성이 'Offer'에 표시되는 방식에 대한 자세한 내용은 템플릿 가이드라인을 참조하세요.
패스 객체를 만드는 코드 샘플:
Java
자바에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참고하세요.
/** * Create an object. * * @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 this pass object. * @return The pass object ID: "{issuerId}.{objectSuffix}" */ public String createObject(String issuerId, String classSuffix, String objectSuffix) throws IOException { // Check if the object exists try { service.offerobject().get(String.format("%s.%s", issuerId, objectSuffix)).execute(); System.out.printf("Object %s.%s already exists!%n", issuerId, objectSuffix); return String.format("%s.%s", issuerId, objectSuffix); } catch (GoogleJsonResponseException ex) { if (ex.getStatusCode() == 404) { // Object does not exist // Do nothing } else { // Something else went wrong... ex.printStackTrace(); return String.format("%s.%s", issuerId, objectSuffix); } } // See link below for more information on required properties // https://developers.google.com/wallet/retail/offers/rest/v1/offerobject OfferObject newObject = new OfferObject() .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))) .setValidTimeInterval( new TimeInterval() .setStart(new DateTime().setDate("2023-06-12T23:20:50.52Z")) .setEnd(new DateTime().setDate("2023-12-12T23:20:50.52Z"))); OfferObject response = service.offerobject().insert(newObject).execute(); System.out.println("Object insert response"); System.out.println(response.toPrettyString()); return response.getId(); }
2,399필리핀
PHP에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
/** * Create an object. * * @param string $issuerId The issuer ID being used for this request. * @param string $classSuffix Developer-defined unique ID for this pass class. * @param string $objectSuffix Developer-defined unique ID for this pass object. * * @return string The pass object ID: "{$issuerId}.{$objectSuffix}" */ public function createObject(string $issuerId, string $classSuffix, string $objectSuffix) { // Check if the object exists try { $this->service->offerobject->get("{$issuerId}.{$objectSuffix}"); print("Object {$issuerId}.{$objectSuffix} already exists!"); return "{$issuerId}.{$objectSuffix}"; } catch (Google\Service\Exception $ex) { if (empty($ex->getErrors()) || $ex->getErrors()[0]['reason'] != 'resourceNotFound') { // Something else went wrong... print_r($ex); return "{$issuerId}.{$objectSuffix}"; } } // See link below for more information on required properties // https://developers.google.com/wallet/retail/offers/rest/v1/offerobject $newObject = new Google_Service_Walletobjects_OfferObject([ 'id' => "{$issuerId}.{$objectSuffix}", 'classId' => "{$issuerId}.{$classSuffix}", 'state' => 'ACTIVE', 'heroImage' => new Google_Service_Walletobjects_Image([ 'sourceUri' => new Google_Service_Walletobjects_ImageUri([ 'uri' => 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg' ]), 'contentDescription' => new Google_Service_Walletobjects_LocalizedString([ 'defaultValue' => new Google_Service_Walletobjects_TranslatedString([ 'language' => 'en-US', 'value' => 'Hero image description' ]) ]) ]), 'textModulesData' => [ new Google_Service_Walletobjects_TextModuleData([ 'header' => 'Text module header', 'body' => 'Text module body', 'id' => 'TEXT_MODULE_ID' ]) ], 'linksModuleData' => new Google_Service_Walletobjects_LinksModuleData([ 'uris' => [ new Google_Service_Walletobjects_Uri([ 'uri' => 'http://maps.google.com/', 'description' => 'Link module URI description', 'id' => 'LINK_MODULE_URI_ID' ]), new Google_Service_Walletobjects_Uri([ 'uri' => 'tel:6505555555', 'description' => 'Link module tel description', 'id' => 'LINK_MODULE_TEL_ID' ]) ] ]), 'imageModulesData' => [ new Google_Service_Walletobjects_ImageModuleData([ 'mainImage' => new Google_Service_Walletobjects_Image([ 'sourceUri' => new Google_Service_Walletobjects_ImageUri([ 'uri' => 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg' ]), 'contentDescription' => new Google_Service_Walletobjects_LocalizedString([ 'defaultValue' => new Google_Service_Walletobjects_TranslatedString([ 'language' => 'en-US', 'value' => 'Image module description' ]) ]) ]), 'id' => 'IMAGE_MODULE_ID' ]) ], 'barcode' => new Google_Service_Walletobjects_Barcode([ 'type' => 'QR_CODE', 'value' => 'QR code value' ]), 'locations' => [ new Google_Service_Walletobjects_LatLongPoint([ 'latitude' => 37.424015499999996, 'longitude' => -122.09259560000001 ]) ], 'validTimeInterval' => new Google_Service_Walletobjects_TimeInterval([ 'start' => new Google_Service_Walletobjects_DateTime([ 'date' => '2023-06-12T23:20:50.52Z' ]), 'end' => new Google_Service_Walletobjects_DateTime([ 'date' => '2023-12-12T23:20:50.52Z' ]) ]) ]); $response = $this->service->offerobject->insert($newObject); print "Object insert response\n"; print_r($response); return $response->id; }
Python
Python에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
def create_object(self, issuer_id: str, class_suffix: str, object_suffix: str) -> str: """Create an object. 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: The pass object ID: f"{issuer_id}.{object_suffix}" """ # Check if the object exists response = self.http_client.get( url=f'{self.object_url}/{issuer_id}.{object_suffix}') if response.status_code == 200: print(f'Object {issuer_id}.{object_suffix} already exists!') print(response.text) return f'{issuer_id}.{object_suffix}' elif response.status_code != 404: # Something else went wrong... print(response.text) return f'{issuer_id}.{object_suffix}' # See link below for more information on required properties # https://developers.google.com/wallet/retail/offers/rest/v1/offerobject 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 }], 'validTimeInterval': { 'start': { 'date': '2023-06-12T23:20:50.52Z' }, 'end': { 'date': '2023-12-12T23:20:50.52Z' } } } # Create the object response = self.http_client.post(url=self.object_url, json=new_object) print('Object insert response') print(response.text) return response.json().get('id')
C#
C#에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
/// <summary> /// Create an object. /// </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 this pass object.</param> /// <returns>The pass object ID: "{issuerId}.{objectSuffix}"</returns> public string CreateObject(string issuerId, string classSuffix, string objectSuffix) { // Check if the object exists Stream responseStream = service.Offerobject .Get($"{issuerId}.{objectSuffix}") .ExecuteAsStream(); StreamReader responseReader = new StreamReader(responseStream); JObject jsonResponse = JObject.Parse(responseReader.ReadToEnd()); if (!jsonResponse.ContainsKey("error")) { Console.WriteLine($"Object {issuerId}.{objectSuffix} already exists!"); return $"{issuerId}.{objectSuffix}"; } else if (jsonResponse["error"].Value<int>("code") != 404) { // Something else went wrong... Console.WriteLine(jsonResponse.ToString()); return $"{issuerId}.{objectSuffix}"; } // See link below for more information on required properties // https://developers.google.com/wallet/retail/offers/rest/v1/offerobject OfferObject newObject = new OfferObject { 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 } }, ValidTimeInterval = new TimeInterval { Start = new Google.Apis.Walletobjects.v1.Data.DateTime { Date = "2023-06-12T23:20:50.52Z" }, End = new Google.Apis.Walletobjects.v1.Data.DateTime { Date = "2023-12-12T23:20:50.52Z" } } }; responseStream = service.Offerobject .Insert(newObject) .ExecuteAsStream(); responseReader = new StreamReader(responseStream); jsonResponse = JObject.Parse(responseReader.ReadToEnd()); Console.WriteLine("Object insert response"); Console.WriteLine(jsonResponse.ToString()); return $"{issuerId}.{objectSuffix}"; }
Node.js
노드에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
/** * Create an object. * * @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} The pass object ID: `${issuerId}.${objectSuffix}` */ async createObject(issuerId, classSuffix, objectSuffix) { let response; // Check if the object exists try { response = await this.httpClient.request({ url: `${this.objectUrl}/${issuerId}.${objectSuffix}`, method: 'GET' }); console.log(`Object ${issuerId}.${objectSuffix} already exists!`); return `${issuerId}.${objectSuffix}`; } catch (err) { if (err.response && err.response.status !== 404) { // Something else went wrong... console.log(err); return `${issuerId}.${objectSuffix}`; } } // See link below for more information on required properties // https://developers.google.com/wallet/retail/offers/rest/v1/offerobject 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 } ], 'validTimeInterval': { 'start': { 'date': '2023-06-12T23:20:50.52Z' }, 'end': { 'date': '2023-12-12T23:20:50.52Z' } } }; response = await this.httpClient.request({ url: this.objectUrl, method: 'POST', data: newObject }); console.log('Object insert response'); console.log(response); return `${issuerId}.${objectSuffix}`; }
Go
Go에서 통합을 시작하려면 GitHub의 GitHub 코드 샘플의 전체 코드 샘플을 참조하세요.
// Create an object. func (d *demoOffer) createObject(issuerId, classSuffix, objectSuffix string) { newObject := fmt.Sprintf(` { "classId": "%s.%s", "heroImage": { "contentDescription": { "defaultValue": { "value": "Hero image description", "language": "en-US" } }, "sourceUri": { "uri": "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg" } }, "barcode": { "type": "QR_CODE", "value": "QR code" }, "locations": [ { "latitude": 37.424015499999996, "longitude": -122.09259560000001 } ], "validTimeInterval": { "start": { "date": "2023-06-12T23:20:50.52Z" }, "end": { "date": "2023-12-12T23:20:50.52Z" } }, "state": "ACTIVE", "linksModuleData": { "uris": [ { "id": "LINK_MODULE_URI_ID", "uri": "http://maps.google.com/", "description": "Link module URI description" }, { "id": "LINK_MODULE_TEL_ID", "uri": "tel:6505555555", "description": "Link module tel description" } ] }, "imageModulesData": [ { "id": "IMAGE_MODULE_ID", "mainImage": { "contentDescription": { "defaultValue": { "value": "Image module description", "language": "en-US" } }, "sourceUri": { "uri": "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg" } } } ], "textModulesData": [ { "body": "Text module body", "header": "Text module header", "id": "TEXT_MODULE_ID" } ], "id": "%s.%s" } `, issuerId, classSuffix, issuerId, objectSuffix) res, err := d.httpClient.Post(objectUrl, "application/json", bytes.NewBuffer([]byte(newObject))) if err != nil { fmt.Println(err) } else { b, _ := io.ReadAll(res.Body) fmt.Printf("Object insert response:\n%s\n", b) } }
완료되면 고객의 패스 객체가 서버에 생성됩니다. 단, 이 단계에서 패스 객체는 Google 사용자 또는 사용자의 기기에 연결되지 않았습니다. 패스를 Google 월렛 사용자와 연결하려면 사용자가 먼저 Google 월렛에 패스를 추가해야 합니다.
Google 월렛에 추가 중
Google 월렛에 패스를 추가하면 패스 객체가 Google 사용자에게 연결되며, 로그인한 Google ID의 컨텍스트에서만 시작할 수 있습니다. 사용자를 'Google 월렛에 추가' URL로 안내하면 됩니다.
'Google 월렛에 추가' URL은 동적으로 생성되는 URL로, 이전 단계에서 만든 패스 객체 ID에 대한 다음 정보를 포함합니다. 이 정보는 JSON 웹 토큰 (JWT)로 인코딩됩니다.
JSON 웹 토큰(JWT)
JWT에는 사용자가 저장할 패스 객체에 대해 발급기관이 작성한 클레임이 포함됩니다. JWT는 서비스 계정 만들기 단계에서 얻은 서비스 계정 키의 private_key를 사용하여 서명해야 합니다. Google은 JWT 서명을 확인하여 이러한 클레임을 검증합니다.
JWT 클레임의 구조는 다음과 같습니다.
{
"aud": "google",
"origins": ["https://example.com"],
"iss": "my-service-account@my-project-id.iam.gserviceaccount.com",
"typ": "savetowallet",
"payload": {
"offerObjects": [
{
"id": "PASSES_OBJECT_ID_1234567890"
}
]
}
}
JWT claims
를 구성하고 (1단계) 서비스 계정 키의 private_key
로 클레임에 서명하여 token
를 가져옵니다 (2단계).
Java
자바에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참고하세요.
/** * 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/offers/rest/v1/offerclass OfferClass newClass = new OfferClass() .setId(String.format("%s.%s", issuerId, classSuffix)) .setIssuerName("Issuer name") .setReviewStatus("UNDER_REVIEW") .setProvider("Provider name") .setTitle("Offer title") .setRedemptionChannel("ONLINE"); // See link below for more information on required properties // https://developers.google.com/wallet/retail/offers/rest/v1/offerobject OfferObject newObject = new OfferObject() .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))) .setValidTimeInterval( new TimeInterval() .setStart(new DateTime().setDate("2023-06-12T23:20:50.52Z")) .setEnd(new DateTime().setDate("2023-12-12T23:20:50.52Z"))); // 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("offerClasses", List.of(newClass)); payload.put("offerObjects", 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); }
2,399필리핀
PHP에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
/** * 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/offers/rest/v1/offerclass $newClass = new Google_Service_Walletobjects_OfferClass([ 'id' => "{$issuerId}.{$classSuffix}", 'issuerName' => 'Issuer name', 'reviewStatus' => 'UNDER_REVIEW', 'provider' => 'Provider name', 'title' => 'Offer title', 'redemptionChannel' => 'ONLINE' ]); // See link below for more information on required properties // https://developers.google.com/wallet/retail/offers/rest/v1/offerobject $newObject = new Google_Service_Walletobjects_OfferObject([ 'id' => "{$issuerId}.{$objectSuffix}", 'classId' => "{$issuerId}.{$classSuffix}", 'state' => 'ACTIVE', 'heroImage' => new Google_Service_Walletobjects_Image([ 'sourceUri' => new Google_Service_Walletobjects_ImageUri([ 'uri' => 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg' ]), 'contentDescription' => new Google_Service_Walletobjects_LocalizedString([ 'defaultValue' => new Google_Service_Walletobjects_TranslatedString([ 'language' => 'en-US', 'value' => 'Hero image description' ]) ]) ]), 'textModulesData' => [ new Google_Service_Walletobjects_TextModuleData([ 'header' => 'Text module header', 'body' => 'Text module body', 'id' => 'TEXT_MODULE_ID' ]) ], 'linksModuleData' => new Google_Service_Walletobjects_LinksModuleData([ 'uris' => [ new Google_Service_Walletobjects_Uri([ 'uri' => 'http://maps.google.com/', 'description' => 'Link module URI description', 'id' => 'LINK_MODULE_URI_ID' ]), new Google_Service_Walletobjects_Uri([ 'uri' => 'tel:6505555555', 'description' => 'Link module tel description', 'id' => 'LINK_MODULE_TEL_ID' ]) ] ]), 'imageModulesData' => [ new Google_Service_Walletobjects_ImageModuleData([ 'mainImage' => new Google_Service_Walletobjects_Image([ 'sourceUri' => new Google_Service_Walletobjects_ImageUri([ 'uri' => 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg' ]), 'contentDescription' => new Google_Service_Walletobjects_LocalizedString([ 'defaultValue' => new Google_Service_Walletobjects_TranslatedString([ 'language' => 'en-US', 'value' => 'Image module description' ]) ]) ]), 'id' => 'IMAGE_MODULE_ID' ]) ], 'barcode' => new Google_Service_Walletobjects_Barcode([ 'type' => 'QR_CODE', 'value' => 'QR code value' ]), 'locations' => [ new Google_Service_Walletobjects_LatLongPoint([ 'latitude' => 37.424015499999996, 'longitude' => -122.09259560000001 ]) ], 'validTimeInterval' => new Google_Service_Walletobjects_TimeInterval([ 'start' => new Google_Service_Walletobjects_DateTime([ 'date' => '2023-06-12T23:20:50.52Z' ]), 'end' => new Google_Service_Walletobjects_DateTime([ 'date' => '2023-12-12T23:20:50.52Z' ]) ]) ]); // 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' => [ 'offerClasses' => [ $newClass ], 'offerObjects' => [ $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에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
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/offers/rest/v1/offerclass new_class = { 'id': f'{issuer_id}.{class_suffix}', 'issuerName': 'Issuer name', 'reviewStatus': 'UNDER_REVIEW', 'provider': 'Provider name', 'title': 'Offer title', 'redemptionChannel': 'ONLINE' } # See link below for more information on required properties # https://developers.google.com/wallet/retail/offers/rest/v1/offerobject 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 }], 'validTimeInterval': { 'start': { 'date': '2023-06-12T23:20:50.52Z' }, 'end': { 'date': '2023-12-12T23:20:50.52Z' } } } # 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 'offerClasses': [new_class], 'offerObjects': [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#에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
/// <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/offers/rest/v1/offerclass OfferClass newClass = new OfferClass { Id = $"{issuerId}.{classSuffix}", IssuerName = "Issuer name", ReviewStatus = "UNDER_REVIEW", Provider = "Provider name", Title = "Offer title", RedemptionChannel = "ONLINE" }; // See link below for more information on required properties // https://developers.google.com/wallet/retail/offers/rest/v1/offerobject OfferObject newObject = new OfferObject { 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 } }, ValidTimeInterval = new TimeInterval { Start = new Google.Apis.Walletobjects.v1.Data.DateTime { Date = "2023-06-12T23:20:50.52Z" }, End = new Google.Apis.Walletobjects.v1.Data.DateTime { Date = "2023-12-12T23:20:50.52Z" } } }; // 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 offerClasses = new List<JObject> { serializedClass }, offerObjects = 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
노드에서 통합을 시작하려면 GitHub의 전체 코드 샘플을 참조하세요.
/** * 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/offers/rest/v1/offerclass let newClass = { 'id': `${issuerId}.${classSuffix}`, 'issuerName': 'Issuer name', 'reviewStatus': 'UNDER_REVIEW', 'provider': 'Provider name', 'title': 'Offer title', 'redemptionChannel': 'ONLINE', }; // See link below for more information on required properties // https://developers.google.com/wallet/retail/offers/rest/v1/offerobject 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 } ], 'validTimeInterval': { 'start': { 'date': '2023-06-12T23:20:50.52Z' }, 'end': { 'date': '2023-12-12T23:20:50.52Z' } } }; // 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 offerClasses: [newClass], offerObjects: [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의 GitHub 코드 샘플의 전체 코드 샘플을 참조하세요.
// 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 *demoOffer) createJwtNewObjects(issuerId, classSuffix, objectSuffix string) { newClass := fmt.Sprintf(` { "redemptionChannel": "ONLINE", "reviewStatus": "UNDER_REVIEW", "title": "Offer title", "issuerName": "Issuer name", "provider": "Provider name", "id": "%s.%s" } `, issuerId, classSuffix) newObject := fmt.Sprintf(` { "classId": "%s.%s", "heroImage": { "contentDescription": { "defaultValue": { "value": "Hero image description", "language": "en-US" } }, "sourceUri": { "uri": "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg" } }, "barcode": { "type": "QR_CODE", "value": "QR code" }, "locations": [ { "latitude": 37.424015499999996, "longitude": -122.09259560000001 } ], "validTimeInterval": { "start": { "date": "2023-06-12T23:20:50.52Z" }, "end": { "date": "2023-12-12T23:20:50.52Z" } }, "state": "ACTIVE", "linksModuleData": { "uris": [ { "id": "LINK_MODULE_URI_ID", "uri": "http://maps.google.com/", "description": "Link module URI description" }, { "id": "LINK_MODULE_TEL_ID", "uri": "tel:6505555555", "description": "Link module tel description" } ] }, "imageModulesData": [ { "id": "IMAGE_MODULE_ID", "mainImage": { "contentDescription": { "defaultValue": { "value": "Image module description", "language": "en-US" } }, "sourceUri": { "uri": "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg" } } } ], "textModulesData": [ { "body": "Text module body", "header": "Text module header", "id": "TEXT_MODULE_ID" } ], "id": "%s.%s" } `, issuerId, classSuffix, issuerId, objectSuffix) var payload map[string]interface{} json.Unmarshal([]byte(fmt.Sprintf(` { "genericClasses": [%s], "genericObjects": [%s] } `, newClass, newObject)), &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) }
서명된 JWT를 가져온 후 이 정보를 사용하여 Google 월렛에 추가 링크를 구성할 수 있습니다.
Google 월렛 링크에 추가
'Google 월렛에 추가' 링크의 형식은 다음과 같습니다.
https://pay.google.com/gp/v/save/{token}
이 링크는 웹페이지에 삽입하거나 이메일에 하이퍼링크로 삽입할 수 있습니다. 채팅 및 SMS와 같은 다른 채널을 사용하여 고객에게 보낼 수도 있습니다.
인코딩된 JWT의 안전한 길이는 1,800자입니다. JWT가 이 한도보다 작으면 서명된 JWT에 전체 객체가 포함될 수 있습니다. JWT를 이 한도 미만으로 유지해야 합니다. 길이가 1, 800자를 넘으면 웹브라우저에서 잘린 상태로 표시되어 저장 기능이 작동하지 않을 수 있습니다.
Google 월렛에 추가 버튼
최상의 결과를 얻으려면 웹페이지, 이메일 또는 Android 애플리케이션에서 Google 월렛 버튼 애셋을 활용하세요.
Google 월렛 버튼은 두 가지 방법으로 렌더링할 수 있습니다.
- 자바스크립트 웹 버튼은 웹사이트에 사용할 수 있습니다.
- Google 월렛 버튼이 있는 JWT 링크는 이메일, SMS, 앱, 웹사이트에 사용할 수 있습니다.
[테스트 전용] 통과
아직 데모 모드를 실행 중일 때는 생성한 모든 패스의 제목에 '[테스트 전용]'이라는 추가 텍스트가 표시됩니다. 이는 데모 패스와 라이브 패스를 구분하기 위함입니다. Google팀의 프로덕션 승인을 받으면 사용자가 연결된 기기에서 월렛 앱을 다시 열 때 이 데모 모드 패스에 더 이상 추가 텍스트가 포함되지 않습니다.
다음 단계
- 혜택 업데이트
- 쿠폰의 모양 맞춤설정
- 통합 테스트 및 게시
- 궁금하신 사항이 더 있나요? FAQ를 참고하세요.