Erste Schritte mit der Web API

Bevor du mit der Web API beginnst, musst du alle Voraussetzungen erfüllen. Du benötigst ein Dienstkonto und einen Dienstkontoschlüssel, um mit der Web API fortfahren zu können. Außerdem musst du Zugriff auf dein Dienstkonto gewähren, um die Google Wallet API aufzurufen.

Lade den Beispielcode von GitHub herunter, um die Code-Snippets auszuführen, auf die in den folgenden Schritten verwiesen wird.

Authentifizierung und Autorisierung

Anfragen an die Google Wallet API müssen authentifiziert werden, damit die Wallet API erkennen kann, dass die Anfrage von deiner Anwendung stammt. Dazu wird mit dem Dienstkontoschlüssel ein Zugriffstoken abgerufen.

Führe zuerst die erforderlichen Bibliotheksimporte durch und definiere einige Variablen für die JSON-Datei des Dienstkontos sowie IDs für den Aussteller, die Klasse, den einzelnen Nutzer und das Objekt, das gespeichert werden soll.

Java

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 Loyalty cards in Google Wallet. */
public class DemoLoyalty {
  /**
   * 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 DemoLoyalty() throws Exception {
    keyFilePath =
        System.getenv().getOrDefault("GOOGLE_APPLICATION_CREDENTIALS", "/path/to/key.json");

    Auth();
  }

PHP

use Firebase\JWT\JWT;
use Google\Auth\Credentials\ServiceAccountCredentials;
use Google\Client as Google_Client;

/** Demo class for creating and managing Loyalty cards in Google Wallet. */
class DemoLoyalty
{
  /**
   * 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

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 DemoLoyalty:
    """Demo class for creating and managing Loyalty 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}/loyaltyClass'
        self.object_url = f'{self.base_url}/loyaltyObject'

        # Set up authenticated client
        self.auth()

C#

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 Loyalty cards in Google Wallet.
/// </summary>
class DemoLoyalty
{
  /// <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 DemoLoyalty()
  {
    keyFilePath = Environment.GetEnvironmentVariable(
        "GOOGLE_APPLICATION_CREDENTIALS") ?? "/path/to/key.json";

    Auth();
  }

Node.js

const { GoogleAuth } = require('google-auth-library');
const jwt = require('jsonwebtoken');
const { v4: uuidv4 } = require('uuid');

/**
 * Demo class for creating and managing Loyalty cards in Google Wallet.
 */
class DemoLoyalty {
  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}/loyaltyClass`;
    this.objectUrl = `${this.baseUrl}/loyaltyObject`;

    this.auth();
  }

Verwende als Nächstes eine der Framework-Bibliotheken, um die erforderlichen Anmeldedaten für den Aufruf der { api_name } abzurufen.

Java

/**
 * Create authenticated HTTP client using a service account file.
 *
 * @throws Exception
 */
public void Auth() throws Exception {
  String scope = "https://www.googleapis.com/auth/wallet_object.issuer";

  credentials =
      GoogleCredentials.fromStream(new FileInputStream(keyFilePath))
          .createScoped(Arrays.asList(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

/**
 * 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

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#

/// <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

/**
 * 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'
  });
}

Karten-/Ticketobjekt erstellen

Ein Karten-/Ticketobjekt ist eine Instanz einer Karten-/Ticketklasse. Zum Erstellen eines Karten-/Ticketobjekts musst du die folgenden Attribute angeben:

  • classId: Die ID der Karten-/Ticketklasse
  • id: Eine eindeutige ID für das Treuepunkteprogramm deines Kunden
  • state: active für die neue Karte bzw das neue Ticket

Wir empfehlen außerdem, folgende Attribute anzugeben:

  • accountId
  • accountName

Weitere Informationen zur Darstellung dieser Attribute auf Kundenkarten findest du in den Vorlagenrichtlinien.

Codebeispiel zum Erstellen eines Karten-/Ticketobjekts:

Java

/**
 * 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}"
 * @throws IOException
 */
public String CreateObject(String issuerId, String classSuffix, String objectSuffix)
    throws IOException {
  // Check if the object exists
  try {
    service.loyaltyobject().get(String.format("%s.%s", issuerId, objectSuffix)).execute();

    System.out.println(String.format("Object %s.%s already exists!", 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/loyalty-cards/rest/v1/loyaltyobject
  LoyaltyObject newObject =
      new LoyaltyObject()
          .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(
              Arrays.asList(
                  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(
              Arrays.asList(
                  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(
              Arrays.asList(
                  new LatLongPoint()
                      .setLatitude(37.424015499999996)
                      .setLongitude(-122.09259560000001)))
          .setAccountId("Account ID")
          .setAccountName("Account name")
          .setLoyaltyPoints(
              new LoyaltyPoints()
                  .setLabel("Points")
                  .setBalance(new LoyaltyPointsBalance().setInt(800)));

  LoyaltyObject response = service.loyaltyobject().insert(newObject).execute();

  System.out.println("Object insert response");
  System.out.println(response.toPrettyString());

  return response.getId();
}

PHP

/**
 * 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->loyaltyobject->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/loyalty-cards/rest/v1/loyaltyobject
  $newObject = new Google_Service_Walletobjects_LoyaltyObject([
    '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
      ])
    ],
    'accountId' => 'Account ID',
    'accountName' => 'Account name',
    'loyaltyPoints' => new Google_Service_Walletobjects_LoyaltyPoints([
      'balance' => new Google_Service_Walletobjects_LoyaltyPointsBalance([
        'int' => 800
      ])
    ])
  ]);

  $response = $this->service->loyaltyobject->insert($newObject);

  print "Object insert response\n";
  print_r($response);

  return $response->id;
}

Python

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/loyalty-cards/rest/v1/loyaltyobject
    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
        }],
        'accountId': 'Account id',
        'accountName': 'Account name',
        'loyaltyPoints': {
            'label': 'Points',
            'balance': {
                'int': 800
            }
        }
    }

    # 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#

/// <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.Loyaltyobject
      .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/loyalty-cards/rest/v1/loyaltyobject
  LoyaltyObject newObject = new LoyaltyObject
  {
    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
      }
    },
    AccountId = "Account id",
    AccountName = "Account name",
    LoyaltyPoints = new LoyaltyPoints
    {
      Label = "Points",
      Balance = new LoyaltyPointsBalance
      {
        Int__ = 800
      }
    }
  };

  responseStream = service.Loyaltyobject
      .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

/**
 * 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/loyalty-cards/rest/v1/loyaltyobject
  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
      }
    ],
    'accountId': 'Account id',
    'accountName': 'Account name',
    'loyaltyPoints': {
      'label': 'Points',
      'balance': {
        'int': 800
      }
    }
  };

  response = await this.httpClient.request({
    url: this.objectUrl,
    method: 'POST',
    data: newObject
  });

  console.log('Object insert response');
  console.log(response);

  return `${issuerId}.${objectSuffix}`;
}

Sobald der Vorgang abgeschlossen ist, wird das Karten-/Ticketobjekt des Kunden auf dem Server erstellt. Allerdings ist das Karten-/Ticketobjekt dann noch nicht mit einem Google-Nutzer oder dessen Gerät verknüpft. Damit die Karte oder das Ticket einem Google Wallet-Nutzer zugeordnet werden kann, muss der Nutzer zuerst die Karte oder das Ticket in Google Wallet hinzufügen.

Zu Google Wallet hinzufügen

Durch das Hinzufügen einer Karte oder eines Tickets zu Google Wallet wird das Karten-/Ticketobjekt mit einem Google-Nutzer verknüpft und kann nur im Kontext einer angemeldeten Google-Identität initiiert werden. Dazu muss der Nutzer zu einer „Zu Google Wallet hinzufügen“-URL geleitet werden.

Die „Zu Google Wallet hinzufügen“-URL ist eine dynamisch generierte URL, die die folgenden Informationen über die im vorherigen Schritt erstellte ID des Karten-/Ticketobjekts enthält. Diese Informationen sind als JSON-Webtoken (JWT) codiert.

JSON-Webtoken (JWT)

Das JWT enthält Anforderungen, die du (der Aussteller) bezüglich des Karten-/Ticketobjekts stellst, das vom Nutzer gespeichert wird. Das JWT muss mit dem private_key aus dem Dienstkontoschlüssel signiert werden, der im Schritt Dienstkonto erstellen abgerufen wurde. Google validiert diese Anforderungen dann durch Bestätigen der JWT-Signatur.

Die JWT-Anforderungen müssen folgende Struktur haben:

{
  "aud": "google",
  "origins": ["https://example.com"],
  "iss": "my-service-account@my-project-id.iam.gserviceaccount.com",
  "typ": "savetowallet",
  "payload": {
    "loyaltyObjects": [
      {
        "id": "PASSES_OBJECT_ID_1234567890"
      }
    ]
  }
}

Erstelle die JWT-claims und rufe das token ab. Signiere dazu die Anforderungen mit dem private_key des Dienstkontoschlüssels:

Java

/**
 * 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/loyalty-cards/rest/v1/loyaltyclass
  LoyaltyClass newClass =
      new LoyaltyClass()
          .setId(String.format("%s.%s", issuerId, classSuffix))
          .setIssuerName("Issuer name")
          .setReviewStatus("UNDER_REVIEW")
          .setProgramName("Program name")
          .setProgramLogo(
              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("Logo description"))));

  // See link below for more information on required properties
  // https://developers.google.com/wallet/retail/loyalty-cards/rest/v1/loyaltyobject
  LoyaltyObject newObject =
      new LoyaltyObject()
          .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(
              Arrays.asList(
                  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(
              Arrays.asList(
                  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(
              Arrays.asList(
                  new LatLongPoint()
                      .setLatitude(37.424015499999996)
                      .setLongitude(-122.09259560000001)))
          .setAccountId("Account ID")
          .setAccountName("Account name")
          .setLoyaltyPoints(
              new LoyaltyPoints()
                  .setLabel("Points")
                  .setBalance(new LoyaltyPointsBalance().setInt(800)));

  // 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", Arrays.asList("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("loyaltyClasses", Arrays.asList(newClass));
  payload.put("loyaltyObjects", Arrays.asList(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.println(String.format("https://pay.google.com/gp/v/save/%s", token));

  return String.format("https://pay.google.com/gp/v/save/%s", token);
}

PHP

/**
 * 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/loyalty-cards/rest/v1/loyaltyclass
  $newClass = new Google_Service_Walletobjects_LoyaltyClass([
    'id' => "{$issuerId}.{$classSuffix}",
    'issuerName' => 'Issuer name',
    'reviewStatus' => 'UNDER_REVIEW',
    'programName' => 'Program name',
    'programLogo' => new Google_Service_Walletobjects_Image([
      'sourceUri' => new Google_Service_Walletobjects_ImageUri([
        'uri' => 'http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg'
      ]),
      'contentDescription' => new Google_Service_Walletobjects_LocalizedString([
        'defaultValue' => new Google_Service_Walletobjects_TranslatedString([
          'language' => 'en-US',
          'value' => 'Logo description'
        ])
      ])
    ])
  ]);

  // See link below for more information on required properties
  // https://developers.google.com/wallet/retail/loyalty-cards/rest/v1/loyaltyobject
  $newObject = new Google_Service_Walletobjects_LoyaltyObject([
    '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
      ])
    ],
    'accountId' => 'Account ID',
    'accountName' => 'Account name',
    'loyaltyPoints' => new Google_Service_Walletobjects_LoyaltyPoints([
      'balance' => new Google_Service_Walletobjects_LoyaltyPointsBalance([
        'int' => 800
      ])
    ])
  ]);

  // 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' => [
      'loyaltyClasses' => [
        $newClass
      ],
      'loyaltyObjects' => [
        $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

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/loyalty-cards/rest/v1/loyaltyclass
    new_class = {
        'id': f'{issuer_id}.{class_suffix}',
        'issuerName': 'Issuer name',
        'reviewStatus': 'UNDER_REVIEW',
        'programName': 'Program name',
        'programLogo': {
            'sourceUri': {
                'uri':
                    'http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg'
            },
            'contentDescription': {
                'defaultValue': {
                    'language': 'en-US',
                    'value': 'Logo description'
                }
            }
        }
    }

    # See link below for more information on required properties
    # https://developers.google.com/wallet/retail/loyalty-cards/rest/v1/loyaltyobject
    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
        }],
        'accountId': 'Account id',
        'accountName': 'Account name',
        'loyaltyPoints': {
            'label': 'Points',
            'balance': {
                'int': 800
            }
        }
    }

    # 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
            'loyaltyClasses': [new_class],
            'loyaltyObjects': [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#

/// <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/loyalty-cards/rest/v1/loyaltyclass
  LoyaltyClass newClass = new LoyaltyClass
  {
    Id = $"{issuerId}.{classSuffix}",
    IssuerName = "Issuer name",
    ReviewStatus = "UNDER_REVIEW",
    ProgramName = "Program name",
    ProgramLogo = new Image
    {
      SourceUri = new ImageUri
      {
        Uri = "http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg"
      },
      ContentDescription = new LocalizedString
      {
        DefaultValue = new TranslatedString
        {
          Language = "en-US",
          Value = "Logo description"
        }
      }
    }
  };

  // See link below for more information on required properties
  // https://developers.google.com/wallet/retail/loyalty-cards/rest/v1/loyaltyobject
  LoyaltyObject newObject = new LoyaltyObject
  {
    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
      }
    },
    AccountId = "Account id",
    AccountName = "Account name",
    LoyaltyPoints = new LoyaltyPoints
    {
      Label = "Points",
      Balance = new LoyaltyPointsBalance
      {
        Int__ = 800
      }
    }
  };

  // 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
      loyaltyClasses = new List<JObject>
      {
        serializedClass
      },
      loyaltyObjects = 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

/**
 * 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/loyalty-cards/rest/v1/loyaltyclass
  let newClass = {
    'id': `${issuerId}.${classSuffix}`,
    'issuerName': 'Issuer name',
    'reviewStatus': 'UNDER_REVIEW',
    'programName': 'Program name',
    'programLogo': {
      'sourceUri': {
        'uri': 'http://farm8.staticflickr.com/7340/11177041185_a61a7f2139_o.jpg'
      },
      'contentDescription': {
        'defaultValue': {
          'language': 'en-US',
          'value': 'Logo description'
        }
      }
    }
  };

  // See link below for more information on required properties
  // https://developers.google.com/wallet/retail/loyalty-cards/rest/v1/loyaltyobject
  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
      }
    ],
    'accountId': 'Account id',
    'accountName': 'Account name',
    'loyaltyPoints': {
      'label': 'Points',
      'balance': {
        'int': 800
      }
    }
  };

  // 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
      loyaltyClasses: [newClass],
      loyaltyObjects: [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}`;
}

Nachdem du ein signiertes JWT abgerufen hast, kannst du anhand dieser Informationen einen Link Zu Google Wallet hinzufügen erstellen.

Der Link „Zu Google Wallet hinzufügen“ hat folgendes Format:

https://pay.google.com/gp/v/save/{token}

Dieser Link kann als Hyperlink in deine Webseite oder eine E-Mail eingefügt werden. Er kann auch über andere Kanäle wie Chat und SMS an den Kunden gesendet werden.

Die sichere Länge eines codierten JWT beträgt 1.800 Zeichen. Wenn dein JWT unter diesem Grenzwert liegt, kann das gesamte Objekt in das signierte JWT aufgenommen werden. Deine JWTs sollten unter diesem Limit bleiben. Wenn das JWT über 1.800 Zeichen lang ist, wird es vom Webbrowser abgeschnitten, sodass die Schaltfläche „Zu Google Wallet hinzufügen“ möglicherweise nicht funktioniert.

Schaltfläche „Zu Google Wallet hinzufügen“

Die besten Ergebnisse erzielst du, wenn du die Google Wallet-Schaltflächen auf deiner Webseite, in deiner E-Mail oder in deiner Android-Anwendung verwendest.

Die Google Wallet-Schaltfläche kann auf zwei Arten gerendert werden:

  • Die JavaScript-Webschaltfläche kann für Websites verwendet werden.
  • Der JWT-Link mit einer Schaltfläche kann für E-Mails, SMS, Apps und Websites verwendet werden.

[TEST ONLY] Karten/Tickets

Wenn du dich noch im Demomodus befindest, haben alle erstellten Karten/Tickets den zusätzlichen Text „[TEST ONLY]“ im Titel der Karte bzw. des Tickets. Damit lassen sich Demokarten/-tickets von Livekarten/-tickets unterscheiden. Sobald du die Produktionsgenehmigung von unserem Team erhalten hast, werden diese Demokarten/-tickets nicht mehr den zusätzlichen Text enthalten, wenn der Nutzer die Wallet-App auf einem verbundenen Gerät öffnet.

Nächste Schritte