ก่อนเริ่มต้นใช้งาน Web API โปรดตรวจสอบว่าคุณได้ดำเนินการตามข้อกำหนดเบื้องต้นแล้ว หากต้องการใช้ Web API ต่อไป คุณต้องมีบัญชีบริการและคีย์บัญชีบริการ รวมถึงต้องให้สิทธิ์บัญชีบริการเพื่อเรียกใช้ Google Wallet API
ดาวน์โหลดโค้ดตัวอย่างบน GitHub เพื่อเรียกใช้ข้อมูลโค้ดที่อ้างถึงในขั้นตอนด้านล่าง
การตรวจสอบสิทธิ์และการให้สิทธิ์
คำขอที่ส่งไปยัง Google Wallet API ต้องผ่านการตรวจสอบสิทธิ์เพื่อให้ API ระบุได้ว่าคำขอดังกล่าวมาจากแอปพลิเคชันของคุณ ซึ่งทำได้ด้วยการใช้คีย์บัญชีบริการเพื่อรับโทเค็นเพื่อการเข้าถึง
ก่อนอื่น ให้นำเข้าไลบรารีที่จำเป็น แล้วกำหนดตัวแปรบางอย่างสำหรับ JSON ของบัญชีบริการ รวมทั้งรหัสของผู้ออก คลาส ผู้ใช้ที่ไม่ซ้ำ และออบเจ็กต์ที่จะบันทึก
Java
หากต้องการเริ่มการผสานรวมใน 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 Flights in Google Wallet. */ public class DemoFlight { /** * 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 DemoFlight() 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 Flights in Google Wallet. */ class DemoFlight { /** * Path to service account key file from Google Cloud Console. Environment * variable: GOOGLE_APPLICATION_CREDENTIALS. */ public string $keyFilePath; /** * Service account credentials for Google Wallet APIs. */ public ServiceAccountCredentials $credentials; /** * Google Wallet service client. */ public Google_Service_Walletobjects $service; public function __construct() { $this->keyFilePath = getenv('GOOGLE_APPLICATION_CREDENTIALS') ?: '/path/to/key.json'; $this->auth(); }
Python
หากต้องการเริ่มการผสานรวมใน Python โปรดดู ตัวอย่างโค้ดทั้งหมดใน GitHub
import json import os import uuid from google.auth.transport.requests import AuthorizedSession from google.oauth2.service_account import Credentials from google.auth import jwt, crypt class DemoFlight: """Demo class for creating and managing Flights 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}/flightClass' self.object_url = f'{self.base_url}/flightObject' # Set up authenticated client self.auth()
C#
หากต้องการเริ่มการผสานรวมใน C# โปรดดู ตัวอย่างโค้ดทั้งหมดใน GitHub
using System.IdentityModel.Tokens.Jwt; using System.Net.Http.Headers; using System.Text.RegularExpressions; using Google.Apis.Auth.OAuth2; using Google.Apis.Services; using Google.Apis.Walletobjects.v1; using Google.Apis.Walletobjects.v1.Data; using Microsoft.IdentityModel.Tokens; using Newtonsoft.Json; using Newtonsoft.Json.Linq; /// <summary> /// Demo class for creating and managing Flights in Google Wallet. /// </summary> class DemoFlight { /// <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 DemoFlight() { keyFilePath = Environment.GetEnvironmentVariable( "GOOGLE_APPLICATION_CREDENTIALS") ?? "/path/to/key.json"; Auth(); }
Node.js
หากต้องการเริ่มการผสานรวมในโหนด โปรดดู ตัวอย่างโค้ดทั้งหมดใน GitHub
const { GoogleAuth } = require('google-auth-library'); const jwt = require('jsonwebtoken'); const { v4: uuidv4 } = require('uuid'); /** * Demo class for creating and managing Flights in Google Wallet. */ class DemoFlight { 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}/flightClass`; this.objectUrl = `${this.baseUrl}/flightObject`; this.auth(); }
Go
หากต้องการเริ่มการผสานรวมใน Go ให้อ้างอิงตัวอย่างโค้ดที่สมบูรณ์ใน ตัวอย่างโค้ดใน GitHub ของ GitHub
package main import ( "bytes" "encoding/json" "fmt" "github.com/golang-jwt/jwt" "github.com/google/uuid" "golang.org/x/oauth2" "golang.org/x/oauth2/google" oauthJwt "golang.org/x/oauth2/jwt" "io" "net/http" "os" "strings" ) const ( batchUrl = "https://walletobjects.googleapis.com/batch" classUrl = "https://walletobjects.googleapis.com/walletobjects/v1/flightClass" objectUrl = "https://walletobjects.googleapis.com/walletobjects/v1/flightObject" )
ถัดไป ให้ใช้ไลบรารีเฟรมเวิร์กตัวใดตัวหนึ่งเพื่อเรียกข้อมูลเข้าสู่ระบบที่จำเป็นในการเรียกใช้ { api_name }
Java
หากต้องการเริ่มการผสานรวมใน 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
หากต้องการเริ่มการผสานรวมใน Python โปรดดู ตัวอย่างโค้ดทั้งหมดใน GitHub
def auth(self): """Create authenticated HTTP client using a service account file.""" self.credentials = Credentials.from_service_account_file( self.key_file_path, scopes=['https://www.googleapis.com/auth/wallet_object.issuer']) self.http_client = AuthorizedSession(self.credentials)
C#
หากต้องการเริ่มการผสานรวมใน C# โปรดดู ตัวอย่างโค้ดทั้งหมดใน GitHub
/// <summary> /// Create authenticated service client using a service account file. /// </summary> public void Auth() { credentials = (ServiceAccountCredential)GoogleCredential .FromFile(keyFilePath) .CreateScoped(new List<string> { "https://www.googleapis.com/auth/wallet_object.issuer" }) .UnderlyingCredential; service = new WalletobjectsService( new BaseClientService.Initializer() { HttpClientInitializer = credentials }); }
Node.js
หากต้องการเริ่มการผสานรวมในโหนด โปรดดู ตัวอย่างโค้ดทั้งหมดใน GitHub
/** * Create authenticated HTTP client using a service account file. */ auth() { this.credentials = require(this.keyFilePath); this.httpClient = new GoogleAuth({ credentials: this.credentials, scopes: 'https://www.googleapis.com/auth/wallet_object.issuer' }); }
Go
หากต้องการเริ่มการผสานรวมใน Go ให้อ้างอิงตัวอย่างโค้ดที่สมบูรณ์ใน ตัวอย่างโค้ดใน GitHub ของ GitHub
// Create authenticated HTTP client using a service account file. func (d *demoFlight) 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
ของชั้นเรียนบัตรid
: รหัสบอร์ดดิ้งพาสที่ไม่ซ้ำกันสำหรับผู้โดยสารstate
:active
สำหรับบัตรใหม่ที่กำลังสร้าง
เราขอแนะนำให้คุณระบุแอตทริบิวต์ต่อไปนี้ด้วย
passengerName
: ชื่อผู้โดยสารที่จะปรากฏในบอร์ดดิ้งพาสboardingAndSeatingInfo
: ข้อมูลเฉพาะผู้โดยสารเกี่ยวกับการขึ้นเครื่องและที่นั่ง (BoardingAndSeatingInfo)barcode
: ประเภทและค่าบาร์โค้ด (บาร์โค้ด)
โปรดดูเทมเพลตเลย์เอาต์สำหรับข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่แอตทริบิวต์เหล่านี้ในบอร์ดดิ้งพาส
ตัวอย่างโค้ดสำหรับสร้างออบเจ็กต์ Passes
Java
หากต้องการเริ่มการผสานรวมใน 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.flightobject().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/tickets/boarding-passes/rest/v1/flightobject FlightObject newObject = new FlightObject() .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))) .setPassengerName("Passenger name") .setBoardingAndSeatingInfo( new BoardingAndSeatingInfo().setBoardingGroup("B").setSeatNumber("42")) .setReservationInfo(new ReservationInfo().setConfirmationCode("Confirmation code")); FlightObject response = service.flightobject().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->flightobject->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/tickets/boarding-passes/rest/v1/flightobject $newObject = new Google_Service_Walletobjects_FlightObject([ '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 ]) ], 'passengerName' => 'Passenger name', 'boardingAndSeatingInfo' => new Google_Service_Walletobjects_BoardingAndSeatingInfo([ 'boardingGroup' => 'B', 'seatNumber' => '42' ]), 'reservationInfo' => new Google_Service_Walletobjects_ReservationInfo([ 'confirmationCode' => 'Confirmation code' ]) ]); $response = $this->service->flightobject->insert($newObject); print "Object insert response\n"; print_r($response); return $response->id; }
Python
หากต้องการเริ่มการผสานรวมใน Python โปรดดู ตัวอย่างโค้ดทั้งหมดใน GitHub
def create_object(self, issuer_id: str, class_suffix: str, object_suffix: str) -> str: """Create an object. Args: issuer_id (str): The issuer ID being used for this request. class_suffix (str): Developer-defined unique ID for the pass class. object_suffix (str): Developer-defined unique ID for the pass object. Returns: The pass object ID: f"{issuer_id}.{object_suffix}" """ # Check if the object exists response = self.http_client.get( url=f'{self.object_url}/{issuer_id}.{object_suffix}') if response.status_code == 200: print(f'Object {issuer_id}.{object_suffix} already exists!') print(response.text) return f'{issuer_id}.{object_suffix}' elif response.status_code != 404: # Something else went wrong... print(response.text) return f'{issuer_id}.{object_suffix}' # See link below for more information on required properties # https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightobject 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 }], 'passengerName': 'Passenger name', 'boardingAndSeatingInfo': { 'boardingGroup': 'B', 'seatNumber': '42' }, 'reservationInfo': { 'confirmationCode': 'Confirmation code' } } # Create the object response = self.http_client.post(url=self.object_url, json=new_object) print('Object insert response') print(response.text) return response.json().get('id')
C#
หากต้องการเริ่มการผสานรวมใน C# โปรดดู ตัวอย่างโค้ดทั้งหมดใน GitHub
/// <summary> /// Create an object. /// </summary> /// <param name="issuerId">The issuer ID being used for this request.</param> /// <param name="classSuffix">Developer-defined unique ID for this pass class.</param> /// <param name="objectSuffix">Developer-defined unique ID for this pass object.</param> /// <returns>The pass object ID: "{issuerId}.{objectSuffix}"</returns> public string CreateObject(string issuerId, string classSuffix, string objectSuffix) { // Check if the object exists Stream responseStream = service.Flightobject .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/tickets/boarding-passes/rest/v1/flightobject FlightObject newObject = new FlightObject { 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 } }, PassengerName = "Passenger name", BoardingAndSeatingInfo = new BoardingAndSeatingInfo { BoardingGroup = "B", SeatNumber = "42" }, ReservationInfo = new ReservationInfo { ConfirmationCode = "Confirmation code" } }; responseStream = service.Flightobject .Insert(newObject) .ExecuteAsStream(); responseReader = new StreamReader(responseStream); jsonResponse = JObject.Parse(responseReader.ReadToEnd()); Console.WriteLine("Object insert response"); Console.WriteLine(jsonResponse.ToString()); return $"{issuerId}.{objectSuffix}"; }
Node.js
หากต้องการเริ่มการผสานรวมในโหนด โปรดดู ตัวอย่างโค้ดทั้งหมดใน GitHub
/** * Create an object. * * @param {string} issuerId The issuer ID being used for this request. * @param {string} classSuffix Developer-defined unique ID for the pass class. * @param {string} objectSuffix Developer-defined unique ID for the pass object. * * @returns {string} The pass object ID: `${issuerId}.${objectSuffix}` */ async createObject(issuerId, classSuffix, objectSuffix) { let response; // Check if the object exists try { response = await this.httpClient.request({ url: `${this.objectUrl}/${issuerId}.${objectSuffix}`, method: 'GET' }); console.log(`Object ${issuerId}.${objectSuffix} already exists!`); return `${issuerId}.${objectSuffix}`; } catch (err) { if (err.response && err.response.status !== 404) { // Something else went wrong... console.log(err); return `${issuerId}.${objectSuffix}`; } } // See link below for more information on required properties // https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightobject 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 } ], 'passengerName': 'Passenger name', 'boardingAndSeatingInfo': { 'boardingGroup': 'B', 'seatNumber': '42' }, 'reservationInfo': { 'confirmationCode': 'Confirmation code' } }; response = await this.httpClient.request({ url: this.objectUrl, method: 'POST', data: newObject }); console.log('Object insert response'); console.log(response); return `${issuerId}.${objectSuffix}`; }
Go
หากต้องการเริ่มการผสานรวมใน Go ให้อ้างอิงตัวอย่างโค้ดที่สมบูรณ์ใน ตัวอย่างโค้ดใน GitHub ของ GitHub
// Create an object. func (d *demoFlight) createObject(issuerId, classSuffix, objectSuffix string) { newObject := fmt.Sprintf(` { "classId": "%s.%s", "passengerName": "Passenger name", "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 } ], "boardingAndSeatingInfo": { "boardingGroup": "B", "seatNumber": "42" }, "reservationInfo": { "confirmationCode": "Confirmation code" }, "state": "ACTIVE", "linksModuleData": { "uris": [ { "id": "LINK_MODULE_URI_ID", "uri": "http://maps.google.com/", "description": "Link module URI description" }, { "id": "LINK_MODULE_TEL_ID", "uri": "tel:6505555555", "description": "Link module tel description" } ] }, "imageModulesData": [ { "id": "IMAGE_MODULE_ID", "mainImage": { "contentDescription": { "defaultValue": { "value": "Image module description", "language": "en-US" } }, "sourceUri": { "uri": "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg" } } } ], "textModulesData": [ { "body": "Text module body", "header": "Text module header", "id": "TEXT_MODULE_ID" } ], "id": "%s.%s" } `, issuerId, classSuffix, issuerId, objectSuffix) res, err := d.httpClient.Post(objectUrl, "application/json", bytes.NewBuffer([]byte(newObject))) if err != nil { fmt.Println(err) } else { b, _ := io.ReadAll(res.Body) fmt.Printf("Object insert response:\n%s\n", b) } }
เมื่อดำเนินการเสร็จแล้ว ระบบจะสร้างออบเจ็กต์บัตรของผู้โดยสารขึ้นบนเซิร์ฟเวอร์ แต่ในขั้นตอนนี้ ออบเจ็กต์ Passes ยังไม่ได้ลิงก์กับผู้ใช้ Google หรืออุปกรณ์ของผู้ใช้ หากต้องการให้บัตรเชื่อมโยงกับผู้ใช้ Google Wallet ผู้ใช้ต้องเพิ่มบัตรลงใน Google Wallet ก่อน
กำลังเพิ่มลงใน Google Wallet
การเพิ่มบัตรไปยัง Google Wallet จะลิงก์ออบเจ็กต์บัตรกับผู้ใช้ Google และจะเริ่มได้ก็ต่อเมื่อมีข้อมูลประจำตัวที่ลงชื่อเข้าสู่ระบบของ Google เท่านั้น ซึ่งสามารถทำได้โดยการนำผู้ใช้ไปยัง URL เพิ่มลงใน Google Wallet
URL ของ "เพิ่มลงใน Google Wallet" เป็น URL ที่สร้างขึ้นแบบไดนามิกซึ่งมีข้อมูลต่อไปนี้เกี่ยวกับรหัสออบเจ็กต์บัตรที่สร้างขึ้นในขั้นตอนก่อนหน้า ข้อมูลนี้มีการเข้ารหัสเป็นโทเค็นเว็บ 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": {
"flightObjects": [
{
"id": "PASSES_OBJECT_ID_1234567890"
}
]
}
}
สร้าง JWT claims
และรับ token
โดยลงชื่อในการอ้างสิทธิ์ด้วยคีย์บัญชีบริการ
private_key
:
Java
หากต้องการเริ่มการผสานรวมใน 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/tickets/boarding-passes/rest/v1/flightclass FlightClass newClass = new FlightClass() .setId(String.format("%s.%s", issuerId, classSuffix)) .setIssuerName("Issuer name") .setReviewStatus("UNDER_REVIEW") .setLocalScheduledDepartureDateTime("2023-07-02T15:30:00") .setFlightHeader( new FlightHeader() .setCarrier(new FlightCarrier().setCarrierIataCode("LX")) .setFlightNumber("123")) .setOrigin(new AirportInfo().setAirportIataCode("LAX").setTerminal("1").setGate("A2")) .setDestination( new AirportInfo().setAirportIataCode("SFO").setTerminal("2").setGate("C3")); // See link below for more information on required properties // https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightobject FlightObject newObject = new FlightObject() .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))) .setPassengerName("Passenger name") .setBoardingAndSeatingInfo( new BoardingAndSeatingInfo().setBoardingGroup("B").setSeatNumber("42")) .setReservationInfo(new ReservationInfo().setConfirmationCode("Confirmation code")); // 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("flightClasses", List.of(newClass)); payload.put("flightObjects", 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/tickets/boarding-passes/rest/v1/flightclass $newClass = new Google_Service_Walletobjects_FlightClass([ 'id' => "{$issuerId}.{$classSuffix}", 'issuerName' => 'Issuer name', 'reviewStatus' => 'UNDER_REVIEW', 'localScheduledDepartureDateTime' => '2023-07-02T15:30:00', 'flightHeader' => new Google_Service_Walletobjects_FlightHeader([ 'carrier' => new Google_Service_Walletobjects_FlightCarrier([ 'carrierIataCode' => 'LX' ]), 'flightNumber' => '123' ]), 'origin' => new Google_Service_Walletobjects_AirportInfo([ 'airportIataCode' => 'LAX', 'terminal' => '1', 'gate' => 'A2' ]), 'destination' => new Google_Service_Walletobjects_AirportInfo([ 'airportIataCode' => 'SFO', 'terminal' => '2', 'gate' => 'C3' ]) ]); // See link below for more information on required properties // https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightobject $newObject = new Google_Service_Walletobjects_FlightObject([ '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 ]) ], 'passengerName' => 'Passenger name', 'boardingAndSeatingInfo' => new Google_Service_Walletobjects_BoardingAndSeatingInfo([ 'boardingGroup' => 'B', 'seatNumber' => '42' ]), 'reservationInfo' => new Google_Service_Walletobjects_ReservationInfo([ 'confirmationCode' => 'Confirmation code' ]) ]); // 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' => [ 'flightClasses' => [ $newClass ], 'flightObjects' => [ $newObject ] ] ]; $token = JWT::encode( $claims, $serviceAccount['private_key'], 'RS256' ); print "Add to Google Wallet link\n"; print "https://pay.google.com/gp/v/save/{$token}"; return "https://pay.google.com/gp/v/save/{$token}"; }
Python
หากต้องการเริ่มการผสานรวมใน Python โปรดดู ตัวอย่างโค้ดทั้งหมดใน GitHub
def create_jwt_new_objects(self, issuer_id: str, class_suffix: str, object_suffix: str) -> str: """Generate a signed JWT that creates a new pass class and object. When the user opens the "Add to Google Wallet" URL and saves the pass to their wallet, the pass class and object defined in the JWT are created. This allows you to create multiple pass classes and objects in one API call when the user saves the pass to their wallet. Args: issuer_id (str): The issuer ID being used for this request. class_suffix (str): Developer-defined unique ID for the pass class. object_suffix (str): Developer-defined unique ID for the pass object. Returns: An "Add to Google Wallet" link. """ # Seelink below for more information on required properties # https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightclass new_class = { 'id': f'{issuer_id}.{class_suffix}', 'issuerName': 'Issuer name', 'reviewStatus': 'UNDER_REVIEW', 'localScheduledDepartureDateTime': '2023-07-02T15:30:00', 'flightHeader': { 'carrier': { 'carrierIataCode': 'LX' }, 'flightNumber': '123' }, 'origin': { 'airportIataCode': 'LAX', 'terminal': '1', 'gate': 'A2' }, 'destination': { 'airportIataCode': 'SFO', 'terminal': '2', 'gate': 'C3' } } # See link below for more information on required properties # https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightclass 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 }], 'passengerName': 'Passenger name', 'boardingAndSeatingInfo': { 'boardingGroup': 'B', 'seatNumber': '42' }, 'reservationInfo': { 'confirmationCode': 'Confirmation code' } } # 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 'flightClasses': [new_class], 'flightObjects': [new_object] } } # The service account credentials are used to sign the JWT signer = crypt.RSASigner.from_service_account_file(self.key_file_path) token = jwt.encode(signer, claims).decode('utf-8') print('Add to Google Wallet link') print(f'https://pay.google.com/gp/v/save/{token}') return f'https://pay.google.com/gp/v/save/{token}'
C#
หากต้องการเริ่มการผสานรวมใน C# โปรดดู ตัวอย่างโค้ดทั้งหมดใน GitHub
/// <summary> /// Generate a signed JWT that creates a new pass class and object. /// <para /> /// When the user opens the "Add to Google Wallet" URL and saves the pass to /// their wallet, the pass class and object defined in the JWT are created. /// This allows you to create multiple pass classes and objects in one API /// call when the user saves the pass to their wallet. /// <para /> /// The Google Wallet C# library uses Newtonsoft.Json.JsonPropertyAttribute /// to specify the property names when converting objects to JSON. The /// Newtonsoft.Json.JsonConvert.SerializeObject method will automatically /// serialize the object with the right property names. /// </summary> /// <param name="issuerId">The issuer ID being used for this request.</param> /// <param name="classSuffix">Developer-defined unique ID for this pass class.</param> /// <param name="objectSuffix">Developer-defined unique ID for the pass object.</param> /// <returns>An "Add to Google Wallet" link.</returns> public string CreateJWTNewObjects(string issuerId, string classSuffix, string objectSuffix) { // Ignore null values when serializing to/from JSON JsonSerializerSettings excludeNulls = new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }; // See link below for more information on required properties // https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightclass FlightClass newClass = new FlightClass { Id = $"{issuerId}.{classSuffix}", IssuerName = "Issuer name", ReviewStatus = "UNDER_REVIEW", LocalScheduledDepartureDateTime = "2023-07-02T15:30:00", FlightHeader = new FlightHeader { Carrier = new FlightCarrier { CarrierIataCode = "LX" }, FlightNumber = "123" }, Origin = new AirportInfo { AirportIataCode = "LAX", Terminal = "1", Gate = "A2" }, Destination = new AirportInfo { AirportIataCode = "SFO", Terminal = "2", Gate = "C3" } }; // See link below for more information on required properties // https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightobject FlightObject newObject = new FlightObject { 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 } }, PassengerName = "Passenger name", BoardingAndSeatingInfo = new BoardingAndSeatingInfo { BoardingGroup = "B", SeatNumber = "42" }, ReservationInfo = new ReservationInfo { ConfirmationCode = "Confirmation code" } }; // 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 flightClasses = new List<JObject> { serializedClass }, flightObjects = new List<JObject> { serializedObject } })) })); // Deserialize into a JwtPayload JwtPayload claims = JwtPayload.Deserialize(jwtPayload.ToString()); // The service account credentials are used to sign the JWT RsaSecurityKey key = new RsaSecurityKey(credentials.Key); SigningCredentials signingCredentials = new SigningCredentials( key, SecurityAlgorithms.RsaSha256); JwtSecurityToken jwt = new JwtSecurityToken( new JwtHeader(signingCredentials), claims); string token = new JwtSecurityTokenHandler().WriteToken(jwt); Console.WriteLine("Add to Google Wallet link"); Console.WriteLine($"https://pay.google.com/gp/v/save/{token}"); return $"https://pay.google.com/gp/v/save/{token}"; }
Node.js
หากต้องการเริ่มการผสานรวมในโหนด โปรดดู ตัวอย่างโค้ดทั้งหมดใน GitHub
/** * Generate a signed JWT that creates a new pass class and object. * * When the user opens the "Add to Google Wallet" URL and saves the pass to * their wallet, the pass class and object defined in the JWT are * created. This allows you to create multiple pass classes and objects in * one API call when the user saves the pass to their wallet. * * @param {string} issuerId The issuer ID being used for this request. * @param {string} classSuffix Developer-defined unique ID for the pass class. * @param {string} objectSuffix Developer-defined unique ID for the pass object. * * @returns {string} An "Add to Google Wallet" link. */ createJwtNewObjects(issuerId, classSuffix, objectSuffix) { // See link below for more information on required properties // https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightclass let newClass = { 'id': `${issuerId}.${classSuffix}`, 'issuerName': 'Issuer name', 'reviewStatus': 'UNDER_REVIEW', 'localScheduledDepartureDateTime': '2023-07-02T15:30:00', 'flightHeader': { 'carrier': { 'carrierIataCode': 'LX' }, 'flightNumber': '123' }, 'origin': { 'airportIataCode': 'LAX', 'terminal': '1', 'gate': 'A2' }, 'destination': { 'airportIataCode': 'SFO', 'terminal': '2', 'gate': 'C3' } }; // See link below for more information on required properties // https://developers.google.com/wallet/tickets/boarding-passes/rest/v1/flightobject 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 } ], 'passengerName': 'Passenger name', 'boardingAndSeatingInfo': { 'boardingGroup': 'B', 'seatNumber': '42' }, 'reservationInfo': { 'confirmationCode': 'Confirmation code' } }; // 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 flightClasses: [newClass], flightObjects: [newObject] } }; // The service account credentials are used to sign the JWT let token = jwt.sign(claims, this.credentials.private_key, { algorithm: 'RS256' }); console.log('Add to Google Wallet link'); console.log(`https://pay.google.com/gp/v/save/${token}`); return `https://pay.google.com/gp/v/save/${token}`; }
Go
หากต้องการเริ่มการผสานรวมใน Go ให้อ้างอิงตัวอย่างโค้ดที่สมบูรณ์ใน ตัวอย่างโค้ดใน GitHub ของ GitHub
// Generate a signed JWT that creates a new pass class and object. // // When the user opens the "Add to Google Wallet" URL and saves the pass to // their wallet, the pass class and object defined in the JWT are // created. This allows you to create multiple pass classes and objects in // one API call when the user saves the pass to their wallet. func (d *demoFlight) createJwtNewObjects(issuerId, classSuffix, objectSuffix string) { newClass := fmt.Sprintf(` { "origin": { "terminal": "1", "gate": "A2", "airportIataCode": "LAX" }, "flightHeader": { "carrier": { "carrierIataCode": "LX" }, "flightNumber": "123" }, "localScheduledDepartureDateTime": "2023-07-02T15:30:00", "reviewStatus": "UNDER_REVIEW", "issuerName": "Issuer name", "destination": { "terminal": "2", "gate": "C3", "airportIataCode": "SFO" }, "id": "%s.%s" } `, issuerId, classSuffix) newObject := fmt.Sprintf(` { "classId": "%s.%s", "passengerName": "Passenger name", "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 } ], "boardingAndSeatingInfo": { "boardingGroup": "B", "seatNumber": "42" }, "reservationInfo": { "confirmationCode": "Confirmation code" }, "state": "ACTIVE", "linksModuleData": { "uris": [ { "id": "LINK_MODULE_URI_ID", "uri": "http://maps.google.com/", "description": "Link module URI description" }, { "id": "LINK_MODULE_TEL_ID", "uri": "tel:6505555555", "description": "Link module tel description" } ] }, "imageModulesData": [ { "id": "IMAGE_MODULE_ID", "mainImage": { "contentDescription": { "defaultValue": { "value": "Image module description", "language": "en-US" } }, "sourceUri": { "uri": "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg" } } } ], "textModulesData": [ { "body": "Text module body", "header": "Text module header", "id": "TEXT_MODULE_ID" } ], "id": "%s.%s" } `, issuerId, classSuffix, issuerId, objectSuffix) var payload map[string]interface{} json.Unmarshal([]byte(fmt.Sprintf(` { "genericClasses": [%s], "genericObjects": [%s] } `, newClass, newObject)), &payload) claims := jwt.MapClaims{ "iss": d.credentials.Email, "aud": "google", "origins": []string{"www.example.com"}, "typ": "savetowallet", "payload": payload, } // The service account credentials are used to sign the JWT key, _ := jwt.ParseRSAPrivateKeyFromPEM(d.credentials.PrivateKey) token, _ := jwt.NewWithClaims(jwt.SigningMethodRS256, claims).SignedString(key) fmt.Println("Add to Google Wallet link") fmt.Println("https://pay.google.com/gp/v/save/" + token) }
หลังจากได้รับ JWT ที่ลงนามแล้ว คุณจะใช้ข้อมูลนี้เพื่อสร้างลิงก์ "เพิ่มลงใน Google Wallet" ได้
เพิ่มลงในลิงก์ Google Wallet
ลิงก์ "เพิ่มลงใน Google Wallet" จะมีรูปแบบดังต่อไปนี้
https://pay.google.com/gp/v/save/{token}
คุณสามารถฝังลิงก์นี้ลงในหน้าเว็บหรืออีเมลเป็นไฮเปอร์ลิงก์ และยังสามารถส่งไปยังผู้โดยสารโดยใช้ ช่องทางอื่นๆ เช่น แชทและ SMS ได้อีกด้วย
ความยาวที่ปลอดภัยของ JWT ที่เข้ารหัสคือ 1,800 อักขระ หาก JWT ของคุณต่ำกว่าขีดจำกัดนี้ ทั้งออบเจ็กต์จะรวมอยู่ใน JWT ที่ลงชื่อได้ JWT ของคุณต้องต่ำกว่าขีดจำกัดนี้ หากมีความยาวเกิน 1, 800 อักขระ ฟีเจอร์ "เพิ่มลงใน Google Wallet" อาจไม่ทำงานเนื่องจากมีการตัดโดยเว็บเบราว์เซอร์
เพิ่มลงในปุ่ม Google Wallet
เพื่อผลลัพธ์ที่ดีที่สุด ให้ใช้ประโยชน์จากเนื้อหาปุ่ม Google Wallet ในหน้าเว็บ อีเมล หรือแอปพลิเคชัน Android
ปุ่ม Google Wallet จะแสดงผลได้ 2 แบบดังนี้
- คุณใช้ปุ่มเว็บ JavaScript สำหรับเว็บไซต์ได้
- ลิงก์ JWT ที่มีปุ่ม Google Wallet สามารถใช้สำหรับอีเมล, SMS, แอป และเว็บไซต์ต่างๆ
[ทดสอบเท่านั้น] บัตร
เมื่อคุณยังอยู่ในโหมดสาธิต บัตรทั้งหมดที่คุณสร้างจะมีข้อความเพิ่มเติม "[ทดสอบเท่านั้น]" ในชื่อบัตรผ่าน วิธีนี้มีไว้เพื่อแยกความแตกต่างของบัตรสาธิตกับบัตรผ่านแบบสด เมื่อคุณได้รับการอนุมัติการใช้งานจริงจากทีมของเรา บัตรผ่านในโหมดสาธิตเหล่านี้จะไม่มีข้อความเพิ่มเติมอีกเมื่อผู้ใช้เปิดแอป Wallet อีกครั้งในอุปกรณ์ที่เชื่อมต่อ
ขั้นตอนถัดไป
- ประเมินกรณีการใช้งานของบอร์ดดิ้งพาสและปรับใช้ให้เหมาะกับความต้องการทางธุรกิจ
- ปรับแต่งรูปลักษณ์ของบอร์ดดิ้งพาสโดยทำตามหลักเกณฑ์ของแบรนด์
- ส่งขั้นตอน UX เพื่อรับการตรวจสอบครั้งสุดท้ายโดยใช้แบบฟอร์มติดต่อฝ่ายสนับสนุนใน Google Pay และ Wallet Console
- ทดสอบการผสานรวมแล้วถ่ายทอดสด
- หากมีคำถาม โปรดอ่านคําถามที่พบบ่อย