الرموز المميّزة للويب JSON هي معيار شائع الاستخدام في المجال لنقل المعلومات بأمان ككائن JSON. عند استخدام واجهة برمجة تطبيقات Google Wallet، يمكنك ترميز تفاصيل "عنصر البطاقات" الذي تريد استخدامه لإنشاء مثيل بطاقة بتنسيق JWT (يُنطق "jot") ثم إرسال JWT هذا في طلب إلى Google Wallet API.
يتم الحفاظ على أمان بيانات JWT من خلال توقيعها باستخدام سر مشترك قبل إرسالها إلى Google Wallet API. إذا كنت تستخدم Google Wallet REST API، يكون سر التوقيع هو مفتاح حسابك في خدمة Google Cloud. إذا كنت تستخدم حزمة تطوير البرامج (SDK) لنظام التشغيل Android لـ "محفظة Google"، يكون سر التوقيع هو بصمة الإصبع SHA-1 لتطبيق Android.
ترميز بطاقة في JWT
عند إنشاء TransitObject
، يجب لفّه برمز JWT غير موقَّع مع السمة payload.TransitObjects
، كما هو موضّح في المقتطف التالي:
JSON
{
"iss": "OWNER_EMAIL_ADDRESS",
"aud": "google",
"typ": "savetowallet",
"iat": "UNIX_TIME",
"origins": [],
"payload": {
"transitObjects": [ NEW_OBJECT ]
}
}
لمزيد من المعلومات حول التنسيق المتوقع لرموز JWT، يمكنك الاطّلاع على مرجع JWT.
التوقيع على JWT
يتم الحفاظ على أمان بيانات JWT من خلال توقيعها باستخدام سر مشترك قبل إرسالها إلى Google Wallet API. إذا كنت تستخدم Google Wallet REST API، يكون سر التوقيع هو مفتاح حسابك في خدمة Google Cloud. إذا كنت تستخدم حزمة تطوير البرامج (SDK) لنظام التشغيل Android لـ "محفظة Google"، يكون سر التوقيع هو بصمة الإصبع SHA-1 لتطبيق Android.
الويب والبريد الإلكتروني والرسائل القصيرة SMS
يجب توقيع JWT باستخدام مفتاح حساب الخدمة المرتبط بحساب خدمة Google Cloud الذي منحته الإذن في Business Console في "محفظة Google". ستتحقّق Google Wallet API من هذه المطالبات من خلال تأكيد توقيع JWT.
سينتج عن توقيع JWT رمز يمكن استخدامه لإنشاء رابط "إضافة إلى محفظة Google" يمكن استخدامه لإصدار البطاقة إلى أحد المستخدمين، وذلك باتّباع الخطوات التالية:
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/transit-passes/qr-code/rest/v1/transitclass TransitClass newClass = new TransitClass() .setId(String.format("%s.%s", issuerId, classSuffix)) .setIssuerName("Issuer name") .setReviewStatus("UNDER_REVIEW") .setLogo( new Image() .setSourceUri( new ImageUri() .setUri( "https://live.staticflickr.com/65535/48690277162_cd05f03f4d_o.png")) .setContentDescription( new LocalizedString() .setDefaultValue( new TranslatedString() .setLanguage("en-US") .setValue("Logo description")))) .setTransitType("BUS"); // See link below for more information on required properties // https://developers.google.com/wallet/tickets/transit-passes/qr-code/rest/v1/transitobject TransitObject newObject = new TransitObject() .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))) .setPassengerType("SINGLE_PASSENGER") .setPassengerNames("Passenger names") .setTripType("ONE_WAY") .setTicketLeg( new TicketLeg() .setOriginStationCode("LA") .setOriginName( new LocalizedString() .setDefaultValue( new TranslatedString() .setLanguage("en-US") .setValue("Origin name"))) .setDestinationStationCode("SFO") .setDestinationName( new LocalizedString() .setDefaultValue( new TranslatedString() .setLanguage("en-US") .setValue("Origin name"))) .setDepartureDateTime("2020-04-12T16:20:50.52Z") .setArrivalDateTime("2020-04-12T20:20:50.52Z") .setFareName( new LocalizedString() .setDefaultValue( new TranslatedString() .setLanguage("en-US") .setValue("Fare name")))); // 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("transitClasses", List.of(newClass)); payload.put("transitObjects", 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/transit-passes/qr-code/rest/v1/transitclass $newClass = new TransitClass([ 'id' => "{$issuerId}.{$classSuffix}", 'issuerName' => 'Issuer name', 'reviewStatus' => 'UNDER_REVIEW', 'logo' => new Image([ 'sourceUri' => new ImageUri([ 'uri' => 'https://live.staticflickr.com/65535/48690277162_cd05f03f4d_o.png' ]), 'contentDescription' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'Logo description' ]) ]) ]), 'transitType' => 'BUS' ]); // See link below for more information on required properties // https://developers.google.com/wallet/tickets/transit-passes/qr-code/rest/v1/transitobject $newObject = new TransitObject([ 'id' => "{$issuerId}.{$objectSuffix}", 'classId' => "{$issuerId}.{$classSuffix}", 'state' => 'ACTIVE', 'heroImage' => new Image([ 'sourceUri' => new ImageUri([ 'uri' => 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg' ]), 'contentDescription' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'Hero image description' ]) ]) ]), 'textModulesData' => [ new TextModuleData([ 'header' => 'Text module header', 'body' => 'Text module body', 'id' => 'TEXT_MODULE_ID' ]) ], 'linksModuleData' => new LinksModuleData([ 'uris' => [ new Uri([ 'uri' => 'http://maps.google.com/', 'description' => 'Link module URI description', 'id' => 'LINK_MODULE_URI_ID' ]), new Uri([ 'uri' => 'tel:6505555555', 'description' => 'Link module tel description', 'id' => 'LINK_MODULE_TEL_ID' ]) ] ]), 'imageModulesData' => [ new ImageModuleData([ 'mainImage' => new Image([ 'sourceUri' => new ImageUri([ 'uri' => 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg' ]), 'contentDescription' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'Image module description' ]) ]) ]), 'id' => 'IMAGE_MODULE_ID' ]) ], 'barcode' => new Barcode([ 'type' => 'QR_CODE', 'value' => 'QR code value' ]), 'locations' => [ new LatLongPoint([ 'latitude' => 37.424015499999996, 'longitude' => -122.09259560000001 ]) ], 'passengerType' => 'SINGLE_PASSENGER', 'passengerNames' => 'Passenger names', 'tripType' => 'ONE_WAY', 'ticketLeg' => new TicketLeg([ 'originStationCode' => 'LA', 'originName' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'Origin name' ]) ]), 'destinationStationCode' => 'SFO', 'destinationName' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'Destination name' ]) ]), 'departureDateTime' => '2020-04-12T16:20:50.52Z', 'arrivalDateTime' => '2020-04-12T20:20:50.52Z', 'fareName' => new LocalizedString([ 'defaultValue' => new TranslatedString([ 'language' => 'en-US', 'value' => 'Fare name' ]) ]) ]) ]); // 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' => [ 'transitClasses' => [ $newClass ], 'transitObjects' => [ $newObject ] ] ]; $token = JWT::encode( $claims, $serviceAccount['private_key'], 'RS256' ); print "Add to Google Wallet link\n"; print "https://pay.google.com/gp/v/save/{$token}"; return "https://pay.google.com/gp/v/save/{$token}"; }
Python
لبدء عملية الدمج في Python، يمكنك الرجوع إلى نماذج الرموز البرمجية على GitHub الكاملة.
def create_jwt_new_objects(self, issuer_id: str, class_suffix: str, object_suffix: str) -> str: """Generate a signed JWT that creates a new pass class and object. When the user opens the "Add to Google Wallet" URL and saves the pass to their wallet, the pass class and object defined in the JWT are created. This allows you to create multiple pass classes and objects in one API call when the user saves the pass to their wallet. Args: issuer_id (str): The issuer ID being used for this request. class_suffix (str): Developer-defined unique ID for the pass class. object_suffix (str): Developer-defined unique ID for the pass object. Returns: An "Add to Google Wallet" link. """ # See link below for more information on required properties # https://developers.google.com/wallet/tickets/transit-passes/qr-code/rest/v1/transitclass new_class = { 'id': f'{issuer_id}.{class_suffix}', 'issuerName': 'Issuer name', 'reviewStatus': 'UNDER_REVIEW', 'logo': { 'sourceUri': { 'uri': 'https://live.staticflickr.com/65535/48690277162_cd05f03f4d_o.png' }, 'contentDescription': { 'defaultValue': { 'language': 'en-US', 'value': 'Logo description' } } }, 'transitType': 'BUS' } # See link below for more information on required properties # https://developers.google.com/wallet/tickets/transit-passes/qr-code/rest/v1/transitobject 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 }], 'passengerType': 'SINGLE_PASSENGER', 'passengerNames': 'Passenger names', 'tripType': 'ONE_WAY', 'ticketLeg': { 'originStationCode': 'LA', 'originName': { 'defaultValue': { 'language': 'en-US', 'value': 'Origin name' } }, 'destinationStationCode': 'SFO', 'destinationName': { 'defaultValue': { 'language': 'en-US', 'value': 'Destination name' } }, 'departureDateTime': '2020-04-12T16:20:50.52Z', 'arrivalDateTime': '2020-04-12T20:20:50.52Z', 'fareName': { 'defaultValue': { 'language': 'en-US', 'value': 'Fare name' } } } } # 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 'transitClasses': [new_class], 'transitObjects': [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/transit-passes/qr-code/rest/v1/transitclass TransitClass newClass = new TransitClass { Id = $"{issuerId}.{classSuffix}", IssuerName = "Issuer name", ReviewStatus = "UNDER_REVIEW", Logo = new Image { SourceUri = new ImageUri { Uri = "https://live.staticflickr.com/65535/48690277162_cd05f03f4d_o.png" }, ContentDescription = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "Logo description" } } }, TransitType = "BUS" }; // See link below for more information on required properties // https://developers.google.com/wallet/tickets/transit-passes/qr-code/rest/v1/transitobject TransitObject newObject = new TransitObject { 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 } }, PassengerType = "SINGLE_PASSENGER", PassengerNames = "Passenger names", TripType = "ONE_WAY", TicketLeg = new TicketLeg { OriginStationCode = "LA", OriginName = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "Origin name" } }, DestinationStationCode = "SFO", DestinationName = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "Destination name" } }, DepartureDateTime = "2020-04-12T16:20:50.52Z", ArrivalDateTime = "2020-04-12T20:20:50.52Z", FareName = new LocalizedString { DefaultValue = new TranslatedString { Language = "en-US", Value = "Fare name" } } } }; // 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 transitClasses = new List<JObject> { serializedClass }, TransitObjects = 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/tickets/transit-passes/qr-code/rest/v1/transitclass let newClass = { 'id': `${issuerId}.${classSuffix}`, 'issuerName': 'Issuer name', 'reviewStatus': 'UNDER_REVIEW', 'logo': { 'sourceUri': { 'uri': 'https://live.staticflickr.com/65535/48690277162_cd05f03f4d_o.png' }, 'contentDescription': { 'defaultValue': { 'language': 'en-US', 'value': 'Logo description' } } }, 'transitType': 'BUS' }; // See link below for more information on required properties // https://developers.google.com/wallet/tickets/transit-passes/qr-code/rest/v1/transitobject 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 } ], 'passengerType': 'SINGLE_PASSENGER', 'passengerNames': 'Passenger names', 'tripType': 'ONE_WAY', 'ticketLeg': { 'originStationCode': 'LA', 'originName': { 'defaultValue': { 'language': 'en-US', 'value': 'Origin name' } }, 'destinationStationCode': 'SFO', 'destinationName': { 'defaultValue': { 'language': 'en-US', 'value': 'Destination name' } }, 'departureDateTime': '2020-04-12T16:20:50.52Z', 'arrivalDateTime': '2020-04-12T20:20:50.52Z', 'fareName': { 'defaultValue': { 'language': 'en-US', 'value': 'Fare name' } } } }; // 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 transitClasses: [newClass], transitObjects: [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 *demoTransit) createJwtNewObjects(issuerId, classSuffix, objectSuffix string) { transitObject := new(walletobjects.TransitObject) transitObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix) transitObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix) transitObject.State = "ACTIVE" transitObject.PassengerNames = "Passenger names" transitObject.TripType = "ONE_WAY" transitObject.PassengerType = "SINGLE_PASSENGER" transitObject.TicketLeg = &walletobjects.TicketLeg{ DestinationStationCode: "SFO", OriginStationCode: "LA", } transitJson, _ := json.Marshal(transitObject) var payload map[string]any json.Unmarshal([]byte(fmt.Sprintf(` { "transitObjects": [%s] } `, transitJson)), &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 for new objects") fmt.Println("https://pay.google.com/gp/v/save/" + token) }
تطبيقات Android
عندما يتم طلب طريقة savePasses
لإصدار بطاقة إلى أحد المستخدمين، فإنّ حزمة تطوير البرامج (SDK) لنظام التشغيل Android في "محفظة Google" توقيع مستند JWT تلقائيًا باستخدام بصمة SHA-1 لمفتاح توقيع التطبيق الذي قدّمته في Business Console في "محفظة Google". بدلاً من ذلك، يمكنك أيضًا إصدار البطاقة باستخدام مستند JWT موقَّع سابقًا باستخدام طريقة savePassesJwt
من حزمة تطوير البرامج (SDK) لنظام التشغيل Android.
لمزيد من المعلومات، راجِع إصدار البطاقات باستخدام حزمة تطوير البرامج (SDK) لنظام التشغيل Android.