Прежде чем приступить к работе с веб-API, убедитесь, что вы выполнили предварительные требования. Чтобы продолжить работу с веб-API, у вас должна быть учетная запись службы и ключ учетной записи службы , а также вам необходимо предоставить доступ к своей учетной записи службы для вызова API Google Кошелька .
Загрузите пример кода на GitHub , чтобы запустить фрагменты кода, указанные в приведенных ниже шагах.
Аутентификация и авторизация
Запросы к API Google Кошелька должны пройти аутентификацию, чтобы API мог определить, что запрос выполняется вашим приложением. Это достигается за счет использования ключа учетной записи службы для получения токена доступа.
Сначала выполните необходимый импорт библиотеки и определите некоторые переменные для JSON учетной записи службы, а также идентификаторы издателя, класса, уникального пользователя и объекта, который будет сохранен.
Джава
Чтобы начать интеграцию с 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 Gift cards in Google Wallet. */ public class DemoGiftCard { /** * 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 DemoGiftCard() throws Exception { keyFilePath = System.getenv().getOrDefault("GOOGLE_APPLICATION_CREDENTIALS", "/path/to/key.json"); auth(); }
PHP
Чтобы начать интеграцию с PHP, ознакомьтесь с нашими полными примерами кода на Github .
use Firebase\JWT\JWT; use Google\Auth\Credentials\ServiceAccountCredentials; use Google\Client as Google_Client; /** Demo class for creating and managing Gift cards in Google Wallet. */ class DemoGiftCard { /** * 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, ознакомьтесь с нашими полными примерами кода на 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 DemoGiftCard: """Demo class for creating and managing Gift cards 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}/giftCardClass' self.object_url = f'{self.base_url}/giftCardObject' # Set up authenticated client self.auth()
С#
Чтобы начать интеграцию с 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 Gift cards in Google Wallet. /// </summary> class DemoGiftCard { /// <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 DemoGiftCard() { keyFilePath = Environment.GetEnvironmentVariable( "GOOGLE_APPLICATION_CREDENTIALS") ?? "/path/to/key.json"; Auth(); }
Node.js
Чтобы начать интеграцию в Node, ознакомьтесь с полными примерами кода на Github .
const { GoogleAuth } = require('google-auth-library'); const jwt = require('jsonwebtoken'); const { v4: uuidv4 } = require('uuid'); /** * Demo class for creating and managing Gift cards in Google Wallet. */ class DemoGiftCard { 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}/giftCardClass`; this.objectUrl = `${this.baseUrl}/giftCardObject`; this.auth(); }
Идти
Чтобы начать интеграцию в 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/giftCardClass" objectUrl = "https://walletobjects.googleapis.com/walletobjects/v1/giftCardObject" )
Затем используйте одну из библиотек платформы, чтобы получить необходимые учетные данные для вызова API Google Кошелька.
Джава
Чтобы начать интеграцию с 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(); }
PHP
Чтобы начать интеграцию с 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, ознакомьтесь с нашими полными примерами кода на 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#, ознакомьтесь с полными примерами кода на 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
Чтобы начать интеграцию в Node, ознакомьтесь с полными примерами кода на 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, ознакомьтесь с нашими полными примерами кода на github. Примеры кода на Github .
// Create authenticated HTTP client using a service account file. func (d *demoGiftcard) 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) }
Создание объекта пропусков
Объект Passes является экземпляром класса Passes. Чтобы создать объект Passes, необходимо предоставить следующие атрибуты:
-
classId
:id
класса Passes. -
id
: уникальный идентификатор, обозначающий подарочную карту клиента.
Обратитесь к рекомендациям по шаблонам для получения дополнительной информации о том, как эти атрибуты представлены в проходе.
Пример кода для создания объекта Passes:
Джава
Чтобы начать интеграцию с 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.giftcardobject().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) { // 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/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")); GiftCardObject response = service.giftcardobject().insert(newObject).execute(); System.out.println("Object insert response"); System.out.println(response.toPrettyString()); return response.getId(); }
PHP
Чтобы начать интеграцию с 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->eventticketobject->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/gift-cards/rest/v1/giftcardobject $newObject = new Google_Service_Walletobjects_GiftCardObject([ '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 ]) ], 'cardNumber' => 'Card number', 'pin' => '1234', 'balance' => new Google_Service_Walletobjects_Money([ 'micros' => 20000000, 'currencyCode' => 'USD' ]), 'balanceUpdateTime' => new Google_Service_Walletobjects_DateTime([ 'date' => '2020-04-12T16:20:50.52-04:00' ]) ]); $response = $this->service->giftcardobject->insert($newObject); print "Object insert response\n"; print_r($response); return $response->id; }
Питон
Чтобы начать интеграцию с 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/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 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#, ознакомьтесь с полными примерами кода на 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.Giftcardobject .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/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" } }; responseStream = service.Giftcardobject .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
Чтобы начать интеграцию в Node, ознакомьтесь с полными примерами кода на 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/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' } }; response = await this.httpClient.request({ url: this.objectUrl, method: 'POST', data: newObject }); console.log('Object insert response'); console.log(response); return `${issuerId}.${objectSuffix}`; }
Идти
Чтобы начать интеграцию в Go, ознакомьтесь с нашими полными примерами кода на github. Примеры кода на Github .
// Create an object. func (d *demoGiftcard) createObject(issuerId, classSuffix, objectSuffix string) { newObject := fmt.Sprintf(` { "classId": "%s.%s", "pin": "1234", "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 } ], "balanceUpdateTime": { "date": "2020-04-12T16:20:50.52-04:00" }, "state": "ACTIVE", "cardNumber": "Card number", "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" } ], "balance": { "micros": 20000000, "currencyCode": "USD" }, "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) } }
После завершения объект Passes вашего клиента будет создан на сервере. Однако на данном этапе объект Passes не связан с пользователем Google или его устройством. Чтобы пропуск был связан с пользователем Google Кошелька, пользователь должен сначала добавить его в Google Кошелек .
Добавление в Google Кошелек
Добавление пропуска в Google Кошелек связывает объект Passes с пользователем Google и может быть инициировано только в контексте вошедшего в систему удостоверения Google. Этого можно добиться, направив пользователя по URL-адресу «Добавить в Google Кошелек».
URL-адрес «Добавить в Google Кошелек» — это динамически создаваемый URL-адрес, который содержит следующую информацию об идентификаторе объекта Passes, созданном на предыдущем шаге. Эта информация закодирована как веб-токен JSON (JWT) .
Веб-токен JSON (JWT)
JWT содержит утверждения, которые вы (эмитент) делаете в отношении объекта Passes, который будет сохранен пользователем. JWT должен быть подписан с использованием частного_ключа из ключа учетной записи службы, полученного на этапе создания учетной записи службы , и Google проверит эти утверждения, проверив подпись JWT.
Заявления JWT должны иметь следующую структуру:
{
"aud": "google",
"origins": ["https://example.com"],
"iss": "my-service-account@my-project-id.iam.gserviceaccount.com",
"typ": "savetowallet",
"payload": {
"giftCardObjects": [
{
"id": "PASSES_OBJECT_ID_1234567890"
}
]
}
}
Создайте claims
JWT (шаг 1) и получите token
, подписав утверждения с помощью private_key
ключа учетной записи службы (шаг 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/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, ознакомьтесь с нашими полными примерами кода на 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/gift-cards/rest/v1/giftcardclass $newClass = new Google_Service_Walletobjects_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 Google_Service_Walletobjects_GiftCardObject([ '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 ]) ], 'cardNumber' => 'Card number', 'pin' => '1234', 'balance' => new Google_Service_Walletobjects_Money([ 'micros' => 20000000, 'currencyCode' => 'USD' ]), 'balanceUpdateTime' => new Google_Service_Walletobjects_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, ознакомьтесь с нашими полными примерами кода на 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/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#, ознакомьтесь с полными примерами кода на 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/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
Чтобы начать интеграцию в Node, ознакомьтесь с полными примерами кода на 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/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, ознакомьтесь с нашими полными примерами кода на 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 *demoGiftcard) createJwtNewObjects(issuerId, classSuffix, objectSuffix string) { newClass := fmt.Sprintf(` { "issuerName": "Issuer name", "id": "%s.%s", "reviewStatus": "UNDER_REVIEW" } `, issuerId, classSuffix) newObject := fmt.Sprintf(` { "classId": "%s.%s", "pin": "1234", "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 } ], "balanceUpdateTime": { "date": "2020-04-12T16:20:50.52-04:00" }, "state": "ACTIVE", "cardNumber": "Card number", "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" } ], "balance": { "micros": 20000000, "currencyCode": "USD" }, "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 составляет 1800 символов. Если ваш JWT ниже этого предела, весь объект может быть включен в подписанный JWT. Ваши JWT должны оставаться ниже этого предела. Если длина превышает 1800 символов, сохранение может не работать из-за усечения веб-браузерами.
Кнопка «Добавить в Google Кошелек»
Для достижения наилучших результатов используйте ресурсы кнопок Google Кошелька на своей веб-странице, в электронной почте или в приложении Android.
Кнопку Google Кошелька можно отобразить двумя способами:
- Кнопку JavaScript Web можно использовать для веб-сайтов.
- Ссылку JWT с кнопкой можно использовать для электронной почты, SMS, приложений и веб-сайтов.
[ТОЛЬКО ТЕСТ] пройден
Пока вы все еще находитесь в демонстрационном режиме, все созданные вами пропуска будут иметь дополнительный текст «[ТОЛЬКО ТЕСТ]» в заголовке вашего пропуска. Это сделано для того, чтобы отличать демо-пропуски от живых. Как только вы получите одобрение производства от нашей команды, эти пропуска демонстрационного режима больше не будут содержать дополнительный текст, когда пользователь повторно открывает приложение кошелька на подключенном устройстве.
Следующие шаги
- Настройте внешний вид карты
- Проверьте свою интеграцию и приступайте к работе!
- Остались вопросы? Пожалуйста, ознакомьтесь с нашими часто задаваемыми вопросами .
Прежде чем приступить к работе с веб-API, убедитесь, что вы выполнили предварительные требования. Чтобы продолжить работу с веб-API, у вас должна быть учетная запись службы и ключ учетной записи службы , а также вам необходимо предоставить доступ к своей учетной записи службы для вызова API Google Кошелька .
Загрузите пример кода на GitHub , чтобы запустить фрагменты кода, указанные в приведенных ниже шагах.
Аутентификация и авторизация
Запросы к API Google Кошелька должны пройти аутентификацию, чтобы API мог определить, что запрос выполняется вашим приложением. Это достигается за счет использования ключа учетной записи службы для получения токена доступа.
Сначала выполните необходимый импорт библиотеки и определите некоторые переменные для JSON учетной записи службы, а также идентификаторы издателя, класса, уникального пользователя и объекта, который будет сохранен.
Джава
Чтобы начать интеграцию с 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 Gift cards in Google Wallet. */ public class DemoGiftCard { /** * 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 DemoGiftCard() throws Exception { keyFilePath = System.getenv().getOrDefault("GOOGLE_APPLICATION_CREDENTIALS", "/path/to/key.json"); auth(); }
PHP
Чтобы начать интеграцию с PHP, ознакомьтесь с нашими полными примерами кода на Github .
use Firebase\JWT\JWT; use Google\Auth\Credentials\ServiceAccountCredentials; use Google\Client as Google_Client; /** Demo class for creating and managing Gift cards in Google Wallet. */ class DemoGiftCard { /** * 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, ознакомьтесь с нашими полными примерами кода на 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 DemoGiftCard: """Demo class for creating and managing Gift cards 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}/giftCardClass' self.object_url = f'{self.base_url}/giftCardObject' # Set up authenticated client self.auth()
С#
Чтобы начать интеграцию с 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 Gift cards in Google Wallet. /// </summary> class DemoGiftCard { /// <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 DemoGiftCard() { keyFilePath = Environment.GetEnvironmentVariable( "GOOGLE_APPLICATION_CREDENTIALS") ?? "/path/to/key.json"; Auth(); }
Node.js
Чтобы начать интеграцию в Node, ознакомьтесь с полными примерами кода на Github .
const { GoogleAuth } = require('google-auth-library'); const jwt = require('jsonwebtoken'); const { v4: uuidv4 } = require('uuid'); /** * Demo class for creating and managing Gift cards in Google Wallet. */ class DemoGiftCard { 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}/giftCardClass`; this.objectUrl = `${this.baseUrl}/giftCardObject`; this.auth(); }
Идти
Чтобы начать интеграцию в 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/giftCardClass" objectUrl = "https://walletobjects.googleapis.com/walletobjects/v1/giftCardObject" )
Затем используйте одну из библиотек платформы, чтобы получить необходимые учетные данные для вызова API Google Кошелька.
Джава
Чтобы начать интеграцию с 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(); }
PHP
Чтобы начать интеграцию с 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, ознакомьтесь с нашими полными примерами кода на 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#, ознакомьтесь с полными примерами кода на 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
Чтобы начать интеграцию в Node, ознакомьтесь с полными примерами кода на 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, ознакомьтесь с нашими полными примерами кода на github. Примеры кода на Github .
// Create authenticated HTTP client using a service account file. func (d *demoGiftcard) 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) }
Создание объекта пропусков
Объект Passes является экземпляром класса Passes. Чтобы создать объект Passes, необходимо предоставить следующие атрибуты:
-
classId
:id
класса Passes. -
id
: уникальный идентификатор, обозначающий подарочную карту клиента.
Обратитесь к рекомендациям по шаблонам для получения дополнительной информации о том, как эти атрибуты представлены в проходе.
Пример кода для создания объекта Passes:
Джава
Чтобы начать интеграцию с 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.giftcardobject().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) { // 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/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")); GiftCardObject response = service.giftcardobject().insert(newObject).execute(); System.out.println("Object insert response"); System.out.println(response.toPrettyString()); return response.getId(); }
PHP
Чтобы начать интеграцию с 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->eventticketobject->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/gift-cards/rest/v1/giftcardobject $newObject = new Google_Service_Walletobjects_GiftCardObject([ '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 ]) ], 'cardNumber' => 'Card number', 'pin' => '1234', 'balance' => new Google_Service_Walletobjects_Money([ 'micros' => 20000000, 'currencyCode' => 'USD' ]), 'balanceUpdateTime' => new Google_Service_Walletobjects_DateTime([ 'date' => '2020-04-12T16:20:50.52-04:00' ]) ]); $response = $this->service->giftcardobject->insert($newObject); print "Object insert response\n"; print_r($response); return $response->id; }
Питон
Чтобы начать интеграцию с 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/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 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#, ознакомьтесь с полными примерами кода на 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.Giftcardobject .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/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" } }; responseStream = service.Giftcardobject .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
Чтобы начать интеграцию в Node, ознакомьтесь с полными примерами кода на 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/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' } }; response = await this.httpClient.request({ url: this.objectUrl, method: 'POST', data: newObject }); console.log('Object insert response'); console.log(response); return `${issuerId}.${objectSuffix}`; }
Идти
Чтобы начать интеграцию в Go, ознакомьтесь с нашими полными примерами кода на github. Примеры кода на Github .
// Create an object. func (d *demoGiftcard) createObject(issuerId, classSuffix, objectSuffix string) { newObject := fmt.Sprintf(` { "classId": "%s.%s", "pin": "1234", "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 } ], "balanceUpdateTime": { "date": "2020-04-12T16:20:50.52-04:00" }, "state": "ACTIVE", "cardNumber": "Card number", "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" } ], "balance": { "micros": 20000000, "currencyCode": "USD" }, "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) } }
После завершения объект Passes вашего клиента будет создан на сервере. Однако на данном этапе объект Passes не связан с пользователем Google или его устройством. Чтобы пропуск был связан с пользователем Google Кошелька, пользователь должен сначала добавить его в Google Кошелек .
Добавление в Google Кошелек
Добавление пропуска в Google Кошелек связывает объект Passes с пользователем Google и может быть инициировано только в контексте вошедшего в систему удостоверения Google. Этого можно добиться, направив пользователя по URL-адресу «Добавить в Google Кошелек».
URL-адрес «Добавить в Google Кошелек» — это динамически создаваемый URL-адрес, который содержит следующую информацию об идентификаторе объекта Passes, созданном на предыдущем шаге. Эта информация закодирована как веб-токен JSON (JWT) .
Веб-токен JSON (JWT)
JWT содержит утверждения, которые вы (эмитент) делаете в отношении объекта Passes, который будет сохранен пользователем. JWT должен быть подписан с использованием частного_ключа из ключа учетной записи службы, полученного на этапе создания учетной записи службы , и Google проверит эти утверждения, проверив подпись JWT.
Заявления JWT должны иметь следующую структуру:
{
"aud": "google",
"origins": ["https://example.com"],
"iss": "my-service-account@my-project-id.iam.gserviceaccount.com",
"typ": "savetowallet",
"payload": {
"giftCardObjects": [
{
"id": "PASSES_OBJECT_ID_1234567890"
}
]
}
}
Создайте claims
JWT (шаг 1) и получите token
, подписав утверждения с помощью private_key
ключа учетной записи службы (шаг 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/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, ознакомьтесь с нашими полными примерами кода на 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/gift-cards/rest/v1/giftcardclass $newClass = new Google_Service_Walletobjects_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 Google_Service_Walletobjects_GiftCardObject([ '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 ]) ], 'cardNumber' => 'Card number', 'pin' => '1234', 'balance' => new Google_Service_Walletobjects_Money([ 'micros' => 20000000, 'currencyCode' => 'USD' ]), 'balanceUpdateTime' => new Google_Service_Walletobjects_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, ознакомьтесь с нашими полными примерами кода на 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/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#, ознакомьтесь с полными примерами кода на 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/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
Чтобы начать интеграцию в Node, ознакомьтесь с полными примерами кода на 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/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, ознакомьтесь с нашими полными примерами кода на 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 *demoGiftcard) createJwtNewObjects(issuerId, classSuffix, objectSuffix string) { newClass := fmt.Sprintf(` { "issuerName": "Issuer name", "id": "%s.%s", "reviewStatus": "UNDER_REVIEW" } `, issuerId, classSuffix) newObject := fmt.Sprintf(` { "classId": "%s.%s", "pin": "1234", "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 } ], "balanceUpdateTime": { "date": "2020-04-12T16:20:50.52-04:00" }, "state": "ACTIVE", "cardNumber": "Card number", "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" } ], "balance": { "micros": 20000000, "currencyCode": "USD" }, "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 составляет 1800 символов. Если ваш JWT ниже этого предела, весь объект может быть включен в подписанный JWT. Ваши JWT должны оставаться ниже этого предела. Если длина превышает 1800 символов, сохранение может не работать из-за усечения веб-браузерами.
Кнопка «Добавить в Google Кошелек»
Для достижения наилучших результатов используйте ресурсы кнопок Google Кошелька на своей веб-странице, в электронной почте или в приложении Android.
Кнопку Google Кошелька можно отобразить двумя способами:
- Кнопку JavaScript Web можно использовать для веб-сайтов.
- Ссылку JWT с кнопкой можно использовать для электронной почты, SMS, приложений и веб-сайтов.
[ТОЛЬКО ТЕСТ] пройден
Пока вы все еще находитесь в демонстрационном режиме, все созданные вами пропуска будут иметь дополнительный текст «[ТОЛЬКО ТЕСТ]» в заголовке вашего пропуска. Это сделано для того, чтобы отличать демо-пропуски от живых. Как только вы получите одобрение производства от нашей команды, эти пропуска демонстрационного режима больше не будут содержать дополнительный текст, когда пользователь повторно открывает приложение кошелька на подключенном устройстве.
Следующие шаги
- Настройте внешний вид карты
- Проверьте свою интеграцию и приступайте к работе!
- Остались вопросы? Пожалуйста, ознакомьтесь с нашими часто задаваемыми вопросами .