mirror of
https://github.com/google-wallet/rest-samples.git
synced 2026-01-09 21:48:09 -05:00
* Updated .NET and Java file names to be consistent * Corrected indentation in .NET files * Added missing quotes in HTTP request bodies * Updated gradle version for Java examples * Added missing JSON conversion for Java HTTP requests * Added code to generate batch statements
449 lines
14 KiB
Python
449 lines
14 KiB
Python
#
|
|
# Copyright 2022 Google Inc. All rights reserved.
|
|
#
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
|
# use this file except in compliance with the License. You may obtain a copy of
|
|
# the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations under
|
|
# the License.
|
|
#
|
|
|
|
# [START setup]
|
|
# [START imports]
|
|
import json
|
|
import os
|
|
import re
|
|
import uuid
|
|
|
|
from google.auth.transport.requests import AuthorizedSession
|
|
from google.oauth2 import service_account
|
|
from google.auth import jwt, crypt
|
|
# [END imports]
|
|
|
|
# KEY_FILE_PATH - Path to service account key file from Google Cloud Console
|
|
# - Environment variable: GOOGLE_APPLICATION_CREDENTIALS
|
|
KEY_FILE_PATH = os.environ.get("GOOGLE_APPLICATION_CREDENTIALS",
|
|
"/path/to/key.json")
|
|
|
|
# ISSUER_ID - The issuer ID being updated in this request
|
|
# - Environment variable: WALLET_ISSUER_ID
|
|
ISSUER_ID = os.environ.get("WALLET_ISSUER_ID", "issuer-id")
|
|
|
|
# CLASS_ID - Developer-defined ID for the wallet class
|
|
# - Environment variable: WALLET_CLASS_ID
|
|
CLASS_ID = os.environ.get("WALLET_CLASS_ID", "test-transit-class-id")
|
|
|
|
# USER_ID - Developer-defined ID for the user, such as an email address
|
|
# - Environment variable: WALLET_USER_ID
|
|
USER_ID = os.environ.get("WALLET_USER_ID", "test@example.com")
|
|
|
|
# objectId - ID for the wallet object
|
|
# - Format: `issuerId.identifier`
|
|
# - Should only include alphanumeric characters, '.', '_', or '-'
|
|
# - `identifier` is developer-defined and unique to the user
|
|
OBJECT_ID = "%s.%s-%s" % (ISSUER_ID, re.sub(r"[^\w.-]", "_", USER_ID), CLASS_ID)
|
|
# [END setup]
|
|
|
|
###############################################################################
|
|
# Create authenticated HTTP client, using service account file.
|
|
###############################################################################
|
|
|
|
# [START auth]
|
|
credentials = service_account.Credentials.from_service_account_file(
|
|
KEY_FILE_PATH,
|
|
scopes=["https://www.googleapis.com/auth/wallet_object.issuer"])
|
|
|
|
http_client = AuthorizedSession(credentials)
|
|
# [END auth]
|
|
|
|
###############################################################################
|
|
# Create a class via the API (this can also be done in the business console).
|
|
###############################################################################
|
|
|
|
# [START class]
|
|
CLASS_URL = "https://walletobjects.googleapis.com/walletobjects/v1/transitClass/"
|
|
class_payload = {
|
|
"id": f"{ISSUER_ID}.{CLASS_ID}",
|
|
"issuerName": "test issuer name",
|
|
"reviewStatus": "underReview",
|
|
"transitType": "bus",
|
|
"logo": {
|
|
"kind": "walletobjects#image",
|
|
"sourceUri": {
|
|
"kind": "walletobjects#uri",
|
|
"uri": "https://live.staticflickr.com/65535/48690277162_cd05f03f4d_o.png",
|
|
"description": "Test logo description"
|
|
}
|
|
}
|
|
}
|
|
|
|
class_response = http_client.post(
|
|
CLASS_URL,
|
|
json=class_payload
|
|
)
|
|
print("class POST response: ", class_response.text)
|
|
# [END class]
|
|
|
|
###############################################################################
|
|
# Get or create an object via the API.
|
|
###############################################################################
|
|
|
|
# [START object]
|
|
OBJECT_URL = "https://walletobjects.googleapis.com/walletobjects/v1/transitObject/"
|
|
object_payload = {
|
|
"id": OBJECT_ID,
|
|
"classId": f"{ISSUER_ID}.{CLASS_ID}",
|
|
"heroImage": {
|
|
"sourceUri": {
|
|
"uri": "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg",
|
|
"description": "Test heroImage description"
|
|
}
|
|
},
|
|
"textModulesData": [
|
|
{
|
|
"header": "Test text module header",
|
|
"body": "Test text module body"
|
|
}
|
|
],
|
|
"linksModuleData": {
|
|
"uris": [
|
|
{
|
|
"kind": "walletobjects#uri",
|
|
"uri": "http://maps.google.com/",
|
|
"description": "Test link module uri description"
|
|
},
|
|
{
|
|
"kind": "walletobjects#uri",
|
|
"uri": "tel:6505555555",
|
|
"description": "Test link module tel description"
|
|
}
|
|
]
|
|
},
|
|
"imageModulesData": [
|
|
{
|
|
"mainImage": {
|
|
"kind": "walletobjects#image",
|
|
"sourceUri": {
|
|
"kind": "walletobjects#uri",
|
|
"uri": "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg",
|
|
"description": "Test image module description"
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"barcode": {
|
|
"kind": "walletobjects#barcode",
|
|
"type": "qrCode",
|
|
"value": "Test QR Code"
|
|
},
|
|
"passengerType": "singlePassenger",
|
|
"passengerNames": "Test passenger names",
|
|
"ticketLeg": {
|
|
"originStationCode": "LA",
|
|
"originName": {
|
|
"kind": "walletobjects#localizedString",
|
|
"translatedValues": [
|
|
{
|
|
"kind": "walletobjects#translatedString",
|
|
"language": "en-us",
|
|
"value": "Test translated origin name"
|
|
}
|
|
],
|
|
"defaultValue": {
|
|
"kind": "walletobjects#translatedString",
|
|
"language": "en-us",
|
|
"value": "Test default origin name"
|
|
}
|
|
},
|
|
"destinationStationCode": "SFO",
|
|
"destinationName": {
|
|
"kind": "walletobjects#localizedString",
|
|
"translatedValues": [
|
|
{
|
|
"kind": "walletobjects#translatedString",
|
|
"language": "en-us",
|
|
"value": "Test translated destination name"
|
|
}
|
|
],
|
|
"defaultValue": {
|
|
"kind": "walletobjects#translatedString",
|
|
"language": "en-us",
|
|
"value": "Test default destination name"
|
|
}
|
|
},
|
|
"departureDateTime": "2020-04-12T16:20:50.52Z",
|
|
"arrivalDateTime": "2020-04-12T20:20:50.52Z",
|
|
"fareName": {
|
|
"kind": "walletobjects#localizedString",
|
|
"translatedValues": [
|
|
{
|
|
"kind": "walletobjects#translatedString",
|
|
"language": "en-us",
|
|
"value": "Test translated fare name"
|
|
}
|
|
],
|
|
"defaultValue": {
|
|
"kind": "walletobjects#translatedString",
|
|
"language": "en-us",
|
|
"value": "Test default fare name"
|
|
}
|
|
}
|
|
},
|
|
"locations": [
|
|
{
|
|
"kind": "walletobjects#latLongPoint",
|
|
"latitude": 37.424015499999996,
|
|
"longitude": -122.09259560000001
|
|
}
|
|
]
|
|
}
|
|
|
|
object_response = http_client.get(OBJECT_URL + OBJECT_ID)
|
|
if object_response.status_code == 404:
|
|
# Object does not yet exist
|
|
# Send POST request to create it
|
|
object_response = http_client.post(
|
|
OBJECT_URL,
|
|
json=object_payload
|
|
)
|
|
|
|
print("object GET or POST response:", object_response.text)
|
|
# [END object]
|
|
|
|
###############################################################################
|
|
# Create a JWT for the object, and encode it to create a "Save" URL.
|
|
###############################################################################
|
|
|
|
# [START jwt]
|
|
claims = {
|
|
"iss": http_client.credentials.service_account_email,
|
|
"aud": "google",
|
|
"origins": ["www.example.com"],
|
|
"typ": "savetowallet",
|
|
"payload": {
|
|
"transitObjects": [
|
|
{
|
|
"id": OBJECT_ID
|
|
}
|
|
]
|
|
}
|
|
}
|
|
|
|
signer = crypt.RSASigner.from_service_account_file(KEY_FILE_PATH)
|
|
token = jwt.encode(signer, claims).decode("utf-8")
|
|
save_url = f"https://pay.google.com/gp/v/save/{token}"
|
|
|
|
print(save_url)
|
|
# [END jwt]
|
|
|
|
###############################################################################
|
|
# Create a new Google Wallet issuer account
|
|
###############################################################################
|
|
|
|
# [START createIssuer]
|
|
# New issuer name
|
|
ISSUER_NAME = "name"
|
|
|
|
# New issuer email address
|
|
ISSUER_EMAIL = "email-address"
|
|
|
|
# Issuer API endpoint
|
|
ISSUER_URL = "https://walletobjects.googleapis.com/walletobjects/v1/issuer"
|
|
|
|
# New issuer information
|
|
issuer_payload = {
|
|
"name": ISSUER_NAME,
|
|
"contactInfo": {
|
|
"email": ISSUER_EMAIL
|
|
}
|
|
}
|
|
|
|
# Make the POST request
|
|
issuer_response = http_client.post(
|
|
url=ISSUER_URL,
|
|
json=issuer_payload
|
|
)
|
|
|
|
print("issuer POST response:", issuer_response.text)
|
|
# [END createIssuer]
|
|
|
|
###############################################################################
|
|
# Update permissions for an existing Google Wallet issuer account
|
|
###############################################################################
|
|
|
|
# [START updatePermissions]
|
|
# Permissions API endpoint
|
|
permissions_url = f"https://walletobjects.googleapis.com/walletobjects/v1/permissions/{ISSUER_ID}"
|
|
|
|
# New issuer permissions information
|
|
permissions_payload = {
|
|
"issuerId": ISSUER_ID,
|
|
"permissions": [
|
|
# Copy as needed for each email address that will need access
|
|
{
|
|
"emailAddress": "email-address",
|
|
"role": "READER | WRITER | OWNER"
|
|
},
|
|
]
|
|
}
|
|
|
|
permissions_response = http_client.put(
|
|
permissions_url,
|
|
json=permissions_payload
|
|
)
|
|
|
|
print("permissions PUT response:", permissions_response.text)
|
|
# [END updatePermissions]
|
|
|
|
###############################################################################
|
|
# Batch create Google Wallet objects from an existing class
|
|
###############################################################################
|
|
|
|
# [START batch]
|
|
# The request body will be a multiline string
|
|
# See below for more information
|
|
# https://cloud.google.com/compute/docs/api/how-tos/batch#example
|
|
data = ""
|
|
|
|
# Example: Generate three new pass objects
|
|
for _ in range(3):
|
|
# Generate a random user ID
|
|
USER_ID = str(uuid.uuid4()).replace("[^\\w.-]", "_")
|
|
|
|
# Generate an object ID with the user ID
|
|
OBJECT_ID = f"{ISSUER_ID}.{USER_ID}-{CLASS_ID}"
|
|
BATCH_OBJECT = {
|
|
"id": OBJECT_ID,
|
|
"classId": f"{ISSUER_ID}.{CLASS_ID}",
|
|
"heroImage": {
|
|
"sourceUri": {
|
|
"uri": "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg",
|
|
"description": "Test heroImage description"
|
|
}
|
|
},
|
|
"textModulesData": [
|
|
{
|
|
"header": "Test text module header",
|
|
"body": "Test text module body"
|
|
}
|
|
],
|
|
"linksModuleData": {
|
|
"uris": [
|
|
{
|
|
"kind": "walletobjects#uri",
|
|
"uri": "http://maps.google.com/",
|
|
"description": "Test link module uri description"
|
|
},
|
|
{
|
|
"kind": "walletobjects#uri",
|
|
"uri": "tel:6505555555",
|
|
"description": "Test link module tel description"
|
|
}
|
|
]
|
|
},
|
|
"imageModulesData": [
|
|
{
|
|
"mainImage": {
|
|
"kind": "walletobjects#image",
|
|
"sourceUri": {
|
|
"kind": "walletobjects#uri",
|
|
"uri": "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg",
|
|
"description": "Test image module description"
|
|
}
|
|
}
|
|
}
|
|
],
|
|
"barcode": {
|
|
"kind": "walletobjects#barcode",
|
|
"type": "qrCode",
|
|
"value": "Test QR Code"
|
|
},
|
|
"passengerType": "singlePassenger",
|
|
"passengerNames": "Test passenger names",
|
|
"ticketLeg": {
|
|
"originStationCode": "LA",
|
|
"originName": {
|
|
"kind": "walletobjects#localizedString",
|
|
"translatedValues": [
|
|
{
|
|
"kind": "walletobjects#translatedString",
|
|
"language": "en-us",
|
|
"value": "Test translated origin name"
|
|
}
|
|
],
|
|
"defaultValue": {
|
|
"kind": "walletobjects#translatedString",
|
|
"language": "en-us",
|
|
"value": "Test default origin name"
|
|
}
|
|
},
|
|
"destinationStationCode": "SFO",
|
|
"destinationName": {
|
|
"kind": "walletobjects#localizedString",
|
|
"translatedValues": [
|
|
{
|
|
"kind": "walletobjects#translatedString",
|
|
"language": "en-us",
|
|
"value": "Test translated destination name"
|
|
}
|
|
],
|
|
"defaultValue": {
|
|
"kind": "walletobjects#translatedString",
|
|
"language": "en-us",
|
|
"value": "Test default destination name"
|
|
}
|
|
},
|
|
"departureDateTime": "2020-04-12T16:20:50.52Z",
|
|
"arrivalDateTime": "2020-04-12T20:20:50.52Z",
|
|
"fareName": {
|
|
"kind": "walletobjects#localizedString",
|
|
"translatedValues": [
|
|
{
|
|
"kind": "walletobjects#translatedString",
|
|
"language": "en-us",
|
|
"value": "Test translated fare name"
|
|
}
|
|
],
|
|
"defaultValue": {
|
|
"kind": "walletobjects#translatedString",
|
|
"language": "en-us",
|
|
"value": "Test default fare name"
|
|
}
|
|
}
|
|
},
|
|
"locations": [
|
|
{
|
|
"kind": "walletobjects#latLongPoint",
|
|
"latitude": 37.424015499999996,
|
|
"longitude": -122.09259560000001
|
|
}
|
|
]
|
|
}
|
|
|
|
data += "--batch_createobjectbatch\n"
|
|
data += "Content-Type: application/json\n\n"
|
|
data += "POST /walletobjects/v1/transitObject/\n\n"
|
|
|
|
data += json.dumps(BATCH_OBJECT) + "\n\n"
|
|
|
|
data += "--batch_createobjectbatch--"
|
|
|
|
# Invoke the batch API calls
|
|
response = http_client.post(
|
|
"https://walletobjects.googleapis.com/batch",
|
|
data=data,
|
|
headers={
|
|
# `boundary` is the delimiter between API calls in the batch request
|
|
"Content-Type": "multipart/mixed; boundary=batch_createobjectbatch"
|
|
})
|
|
|
|
print(response.content.decode("UTF-8"))
|
|
# [END batch]
|