Начало работы с веб-API

Оптимизируйте свои подборки Сохраняйте и классифицируйте контент в соответствии со своими настройками.

Прежде чем приступить к работе с веб-API, убедитесь, что вы выполнили все необходимые условия. Чтобы продолжить работу с веб-API, у вас должны быть учетная запись службы и ключ учетной записи службы , а также необходимо предоставить доступ к своей учетной записи службы для вызова API Google Кошелька .

Загрузите пример кода на GitHub , чтобы запустить фрагменты кода, указанные в шагах ниже.

Аутентификация и авторизация

Запросы к Google Wallet API должны быть аутентифицированы, чтобы Wallet API мог определить, что запрос выполняется вашим приложением. Это достигается за счет использования ключа учетной записи службы для получения токена доступа.

Сначала выполните необходимый импорт библиотеки и определите некоторые переменные для JSON учетной записи службы, а также идентификаторы для издателя, класса, уникального пользователя и объекта, которые будут сохранены.

Ява

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 Generic passes in Google Wallet. */
public class DemoGeneric {
  /**
   * 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 DemoGeneric() {
    keyFilePath =
        System.getenv().getOrDefault("GOOGLE_APPLICATION_CREDENTIALS", "/path/to/key.json");
  }

PHP

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

/** Demo class for creating and managing Generic passes in Google Wallet. */
class DemoGeneric
{
  /**
   * 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';
  }

Питон

import json
import os
import re
from typing import List
import uuid

from google.auth.transport.requests import AuthorizedSession
from google.oauth2.service_account import Credentials
from google.auth import jwt, crypt


class DemoGeneric:
    """Demo class for creating and managing Generic passes 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'

        # Set up authenticated client
        self.auth()

С#

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

Node.js

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

/**
 * Demo class for creating and managing Generic passes in Google Wallet.
 */
class DemoGeneric {
  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';

    /**
     * Base URL for Google Wallet API requests.
     */
    this.baseUrl = 'https://walletobjects.googleapis.com/walletobjects/v1'
  }

Затем используйте одну из библиотек фреймворка, чтобы получить необходимые учетные данные для вызова API Google Wallet.

Ява

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

  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);
}

Питон

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)

С#

/// <summary>
/// Create authenticated service client using a service account file.
/// </summary>
public void Auth()
{
  credentials = (ServiceAccountCredential)GoogleCredential
      .FromFile(keyFilePath)
      .CreateScoped(new[] {
        "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',
  });
}

Создание объекта Passes

Объект Passes является экземпляром класса Passes. Чтобы создать Passes Object, вы должны предоставить следующие атрибуты:

  • classId : id класса Passes.
  • id : уникальный идентификатор вашего клиента

Обратитесь к руководству по шаблону для получения дополнительной информации о том, как эти атрибуты представлены в универсальном проходе.

Пример кода для создания объекта Passes:

HTTP

POST /walletobjects/v1/genericObject HTTP/1.1
Host: walletobjects.googleapis.com
Content-Type: application/json
Authorization: Bearer ACCESS_TOKEN;
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

{
  "id": "ISSUER_ID.OBJECT_ID",
  "classId": "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"
  },
  "cardTitle": {
    "defaultValue": {
      "language": "en-US",
      "value": "Generic card title"
    }
  },
  "header": {
    "defaultValue": {
      "language": "en-US",
      "value": "Generic header"
    }
  },
  "hexBackgroundColor": "#4285f4",
  "logo": {
    "sourceUri": {
      "uri": "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg"
    },
    "contentDescription": {
      "defaultValue": {
        "language": "en-US",
        "value": "Generic card logo"
      }
    }
  }
}

Ява

/**
 * Create an object via the API.
 *
 * @param issuerId The issuer ID being used for this request.
 * @param classSuffix Developer-defined unique ID for this pass class.
 * @param userId Developer-defined user ID for this object.
 * @return The pass object ID: "{issuerId}.{userId}"
 * @throws IOException
 */
public String CreateGenericObject(String issuerId, String classSuffix, String userId)
    throws IOException {
  // Generate the object ID
  // Should only include alphanumeric characters, '.', '_', or '-'
  String newUserId = userId.replaceAll("[^\\w.-]", "_");
  String objectId = String.format("%s.%s", issuerId, newUserId);

  try {
    // Check if the object exists
    GenericObject response = service.genericobject().get(objectId).execute();

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

    return response.getId();
  } catch (GoogleJsonResponseException ex) {
    if (ex.getStatusCode() != 404) {
      // Something else went wrong
      ex.printStackTrace();
      return ex.getMessage();
    }
  }

  // Object doesn't exist, create it now
  // See link below for more information on required properties
  // https://developers.google.com/wallet/generic/rest/v1/genericobject
  GenericObject genericObject =
      new GenericObject()
          .setId(objectId)
          .setClassId(String.format("%s.%s", issuerId, classSuffix))
          .set("state", "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"))
          .setCardTitle(
              new LocalizedString()
                  .setDefaultValue(
                      new TranslatedString().setLanguage("en-US").setValue("Generic card title")))
          .setHeader(
              new LocalizedString()
                  .setDefaultValue(
                      new TranslatedString().setLanguage("en-US").setValue("Generic header")))
          .setHexBackgroundColor("#4285f4")
          .setLogo(
              new Image()
                  .setSourceUri(
                      new ImageUri()
                          .setUri(
                              "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg"))
                  .setContentDescription(
                      new LocalizedString()
                          .setDefaultValue(
                              new TranslatedString()
                                  .setLanguage("en-US")
                                  .setValue("Generic card logo"))));

  GenericObject response = service.genericobject().insert(genericObject).execute();

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

  return response.getId();
}

PHP

/**
 * Create an object via the API.
 *
 * @param string $issuerId The issuer ID being used for this request.
 * @param string $classSuffix Developer-defined unique ID for this pass class.
 * @param string $userId Developer-defined user ID for this pass object.
 *
 * @return string The pass class ID: "{issuerId}.{userId}"
 */
public function createGenericObject(string $issuerId, string $classSuffix, string $userId)
{
  // Generate the object ID
  // Should only include alphanumeric characters, '.', '_', or '-'
  $newUserId = preg_replace('/[^\w.-]/i', '_', $userId);
  $objectId = "{$issuerId}.{$newUserId}";

  // See link below for more information on required properties
  // https://developers.google.com/wallet/generic/rest/v1/genericobject
  $genericObject = new Google_Service_Walletobjects_GenericObject([
    'id' => "{$objectId}",
    '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',
    ]),
    'cardTitle' => new Google_Service_Walletobjects_LocalizedString([
      'defaultValue' => new Google_Service_Walletobjects_TranslatedString([
        'language' => 'en-US',
        'value' => 'Generic card title',
      ]),
    ]),
    'header' => new Google_Service_Walletobjects_LocalizedString([
      'defaultValue' => new Google_Service_Walletobjects_TranslatedString([
        'language' => 'en-US',
        'value' => 'Generic header',
      ]),
    ]),
    'hexBackgroundColor' => '#4285f4',
    'logo' => new Google_Service_Walletobjects_Image([
      'sourceUri' => new Google_Service_Walletobjects_ImageUri([
        'uri' => 'https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg',
      ]),
      'contentDescription' => new Google_Service_Walletobjects_LocalizedString([
        'defaultValue' => new Google_Service_Walletobjects_TranslatedString([
          'language' => 'en-US',
          'value' => 'Generic card logo',
        ]),
      ]),
    ]),
  ]);

  try {
    $response = $this->service->genericobject->insert($genericObject);

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

    return $response->id;
  } catch (Google\Service\Exception $ex) {
    if ($ex->getCode() == 409) {
      print "Object {$objectId} already exists";
      return;
    }

    // Something else went wrong
    print $ex->getTraceAsString();
  }
}

Питон

def create_generic_object(self, issuer_id: str, class_suffix: str,
                          user_id: str) -> str:
    """Create an object via the API.

    Args:
        issuer_id (str): The issuer ID being used for this request.
        class_suffix (str): Developer-defined unique ID for this pass class.
        user_id (str): Developer-defined user ID for this pass object.

    Returns:
        The pass object ID: f"{issuer_id}.{user_id}"
    """
    object_url = f'{self.base_url}/genericObject'

    # Generate the object ID
    # Should only include alphanumeric characters, '.', '_', or '-'
    new_user_id = re.sub(r'[^\w.-]', '_', user_id)
    object_id = f'{issuer_id}.{new_user_id}'

    # See below for more information on required properties
    # https://developers.google.com/wallet/generic/rest/v1/genericobject
    generic_object = {
        'id': f'{object_id}',
        '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',
        },
        'cardTitle': {
            'defaultValue': {
                'language': 'en-US',
                'value': 'Generic card title',
            },
        },
        'header': {
            'defaultValue': {
                'language': 'en-US',
                'value': 'Generic header',
            },
        },
        'hexBackgroundColor': '#4285f4',
        'logo': {
            'sourceUri': {
                'uri':
                    'https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg',
            },
            'contentDescription': {
                'defaultValue': {
                    'language': 'en-US',
                    'value': 'Generic card logo',
                },
            },
        },
    }

    response = self.http_client.get(f'{object_url}{object_id}')
    if response.status_code == 404:
        # Object does not yet exist
        # Send POST request to create it
        response = self.http_client.post(
            url=object_url,
            json=generic_object,
        )

        print('Object insert response')
        print(response.text)
    else:
        print('Object get response')
        print(response.text)

    return response.json().get('id')

С#

/// <summary>
/// Create an object via the API.
/// </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="userId">Developer-defined user ID for this object.</param>
/// <returns>The pass object ID: "{issuerId}.{userId}"</returns>
public string CreateGenericObject(string issuerId, string classSuffix, string userId)
{
  // Generate the object ID
  // Should only include alphanumeric characters, '.', '_', or '-'
  string newUserId = new Regex(@"[^\w.-]", RegexOptions.Compiled)
      .Replace(userId, "_");
  string objectId = $"{issuerId}.{newUserId}";

  // Check if the object exists
  Stream responseStream = service.Genericclass
      .Get(objectId)
      .ExecuteAsStream();
  StreamReader responseReader = new StreamReader(responseStream);
  JObject jsonResponse = JObject.Parse(responseReader.ReadToEnd());

  if (jsonResponse.ContainsKey("error"))
  {
    if (jsonResponse["error"].Value<int>("code") == 404)
    {
      // Object does not exist
      // Send insert request to create it
      // See link below for more information on required properties
      // https://developers.google.com/wallet/generic/rest/v1/genericobject
      GenericObject genericObject = new GenericObject
      {
        Id = objectId,
        ClassId = $"{issuerId}.{classSuffix}",
        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"
        },
        CardTitle = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "Generic card title"
          }
        },
        Header = new LocalizedString
        {
          DefaultValue = new TranslatedString
          {
            Language = "en-US",
            Value = "Generic header"
          }
        },
        HexBackgroundColor = "#4285f4",
        Logo = new Image
        {
          SourceUri = new ImageUri
          {
            Uri = "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg"
          },
          ContentDescription = new LocalizedString
          {
            DefaultValue = new TranslatedString
            {
              Language = "en-US",
              Value = "Generic card logo"
            }
          },
        }
      };

      responseStream = service.Genericobject
          .Insert(genericObject)
          .ExecuteAsStream();
      responseReader = new StreamReader(responseStream);
      jsonResponse = JObject.Parse(responseReader.ReadToEnd());

      Console.WriteLine("Object insert response");
      Console.WriteLine(jsonResponse.ToString());

      return jsonResponse.Value<string>("id");
    }
    else
    {
      Console.WriteLine("Something else went wrong");
      Console.WriteLine(jsonResponse.ToString());

      return jsonResponse.ToString();
    }
  }
  else
  {
    Console.WriteLine("Object get response");
    Console.WriteLine(jsonResponse.ToString());

    return jsonResponse.Value<string>("id");
  }
}

Node.js

/**
 * Create an object via the API.
 *
 * @param {string} issuerId The issuer ID being used for this request.
 * @param {string} classSuffix Developer-defined unique ID for this pass class.
 * @param {string} userId Developer-defined user ID for this object.
 *
 * @returns {string} The pass object ID: `${issuerId}.${userId}`
 */
async createGenericObject(issuerId, classSuffix, userId) {
  const genericObjectUrl = `${this.baseUrl}/genericObject`;

  // Generate the object ID
  // Should only include alphanumeric characters, '.', '_', or '-'
  let objectId = `${issuerId}.${userId.replace(/[^\w.-]/g, '_')}`;

  // See link below for more information on required properties
  // https://developers.google.com/wallet/generic/rest/v1/genericobject
  let genericObject = {
    'id': `${objectId}`,
    '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',
    },
    'cardTitle': {
      'defaultValue': {
        'language': 'en-US',
        'value': 'Generic card title',
      },
    },
    'header': {
      'defaultValue': {
        'language': 'en-US',
        'value': 'Generic header',
      },
    },
    'hexBackgroundColor': '#4285f4',
    'logo': {
      'sourceUri': {
        'uri': 'https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg',
      },
      'contentDescription': {
        'defaultValue': {
          'language': 'en-US',
          'value': 'Generic card logo',
        },
      },
    },
  };

  let response;
  try {
    response = await this.httpClient.request({
      url: `${genericObjectUrl}/${objectId}`,
      method: 'GET',
    });

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

    return response.data.id;
  } catch (err) {
    if (err.response && err.response.status === 404) {
      // Object does not yet exist
      // Send POST request to create it
      response = await this.httpClient.request({
        url: genericObjectUrl,
        method: 'POST',
        data: genericObject,
      });

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

      return response.data.id;
    } else {
      // Something else went wrong
      console.log(err);
    }
  }
}

После завершения объект Passes вашего клиента будет создан на сервере. Однако на данном этапе объект Passes не был связан с пользователем Google или его устройством. Чтобы пропуск был связан с пользователем Google Кошелька, пользователь должен сначала сохранить пропуск в Google Кошелек .

Добавление в Google Кошелек

Добавление пропуска в Google Wallet связывает объект Passes с пользователем Google и может быть инициировано только в контексте входа в учетную запись Google. Этого можно добиться, перенаправив пользователя по URL-адресу «Добавить в Google Кошелек».

URL-адрес добавления в Google Wallet — это динамически сгенерированный URL-адрес, который содержит следующую информацию об идентификаторе объекта Passes, созданном на предыдущем шаге. Эта информация закодирована как JSON Web Token (JWT) .

Веб-токен JSON (JWT)

JWT содержит утверждения, которые вы (эмитент) делаете об объекте Passes, который будет сохранен пользователем. JWT должен быть подписан с помощью private_key из ключа учетной записи службы, полученного на этапе создания учетной записи службы , и Google проверит эти утверждения, проверив подпись JWT.

Утверждения JWT должны иметь следующую структуру:

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

Создайте claims JWT (шаг 1) и получите token , подписав утверждения с помощью private_key ключа учетной записи службы (шаг 2):

Ява

/**
 * 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 userId Developer-defined user ID for this object.
 * @return An "Add to Google Wallet" link.
 */
public String CreateJWTSaveURL(String issuerId, String classSuffix, String userId) {
  // Generate the object ID
  // Should only include alphanumeric characters, '.', '_', or '-'
  String newUserId = userId.replaceAll("[^\\w.-]", "_");
  String objectId = String.format("%s.%s", issuerId, newUserId);

  // See link below for more information on required properties
  // https://developers.google.com/wallet/generic/rest/v1/genericclass
  GenericClass genericClass = new GenericClass().setId(String.format("%s.%s", issuerId, classSuffix));

  // See link below for more information on required properties
  // https://developers.google.com/wallet/generic/rest/v1/genericobject
  GenericObject genericObject =
      new GenericObject()
          .setId(objectId)
          .setClassId(String.format("%s.%s", issuerId, classSuffix))
          .set("state", "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"))
          .setCardTitle(
              new LocalizedString()
                  .setDefaultValue(
                      new TranslatedString().setLanguage("en-US").setValue("Generic card title")))
          .setHeader(
              new LocalizedString()
                  .setDefaultValue(
                      new TranslatedString().setLanguage("en-US").setValue("Generic header")))
          .setHexBackgroundColor("#4285f4")
          .setLogo(
              new Image()
                  .setSourceUri(
                      new ImageUri()
                          .setUri(
                              "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg"))
                  .setContentDescription(
                      new LocalizedString()
                          .setDefaultValue(
                              new TranslatedString()
                                  .setLanguage("en-US")
                                  .setValue("Generic card logo"))));

  // 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("genericClasses", Arrays.asList(genericClass));
  payload.put("genericObjects", Arrays.asList(genericObject));
  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 class ID for this class.
 * @param string $userId Developer-defined user ID for this object.
 *
 * @return string An "Add to Google Wallet" link.
 */
public function createJwtSaveUrl(string $issuerId, string $classSuffix, string $userId)
{
  // Generate the object ID
  // Should only include alphanumeric characters, '.', '_', or '-'
  $newUserId = preg_replace('/[^\w.-]/i', '_', $userId);
  $objectId = "{$issuerId}.{$newUserId}";

  // See link below for more information on required properties
  // https://developers.google.com/wallet/generic/rest/v1/genericclass
  $genericClass = new Google_Service_Walletobjects_GenericClass([
    'id' => "{$issuerId}.{$classSuffix}",
  ]);

  // See link below for more information on required properties
  // https://developers.google.com/wallet/generic/rest/v1/genericobject
  $genericObject = new Google_Service_Walletobjects_GenericObject([
    'id' => "{$objectId}",
    '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',
    ]),
    'cardTitle' => new Google_Service_Walletobjects_LocalizedString([
      'defaultValue' => new Google_Service_Walletobjects_TranslatedString([
        'language' => 'en-US',
        'value' => 'Generic card title',
      ]),
    ]),
    'header' => new Google_Service_Walletobjects_LocalizedString([
      'defaultValue' => new Google_Service_Walletobjects_TranslatedString([
        'language' => 'en-US',
        'value' => 'Generic header',
      ]),
    ]),
    'hexBackgroundColor' => '#4285f4',
    'logo' => new Google_Service_Walletobjects_Image([
      'sourceUri' => new Google_Service_Walletobjects_ImageUri([
        'uri' => 'https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg',
      ]),
      'contentDescription' => new Google_Service_Walletobjects_LocalizedString([
        'defaultValue' => new Google_Service_Walletobjects_TranslatedString([
          'language' => 'en-US',
          'value' => 'Generic card logo',
        ]),
      ]),
    ]),
  ]);

  // Create the JWT as an array of key/value pairs
  $serviceAccount = json_decode(file_get_contents($this->keyFilePath), true);
  $claims = [
    'iss' => $serviceAccount['client_email'],
    'aud' => 'google',
    'origins' => ['www.example.com'],
    'typ' => 'savetowallet',
    'payload' => [
      'genericClasses' => [
        $genericClass,
      ],
      'genericObjects' => [
        $genericObject,
      ],
    ],
  ];

  // The service account credentials are used to sign the JWT
  $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}";
}

Питон

def create_jwt_save_url(self, issuer_id: str, class_suffix: str,
                        user_id: 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 this pass class.
        user_id (str): Developer-defined user ID for this pass object.

    Returns:
        An "Add to Google Wallet" link
    """

    # Generate the object ID
    # Should only include alphanumeric characters, '.', '_', or '-'
    new_user_id = re.sub(r'[^\w.-]', '_', user_id)
    object_id = f'{issuer_id}.{new_user_id}'

    # See below for more information on required properties
    # https://developers.google.com/wallet/generic/rest/v1/genericclass
    generic_class = {
        'id': f'{issuer_id}.{class_suffix}',
    }

    # See below for more information on required properties
    # https://developers.google.com/wallet/generic/rest/v1/genericobject
    generic_object = {
        'id': f'{object_id}',
        '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',
        },
        'cardTitle': {
            'defaultValue': {
                'language': 'en-US',
                'value': 'Generic card title',
            },
        },
        'header': {
            'defaultValue': {
                'language': 'en-US',
                'value': 'Generic header',
            },
        },
        'hexBackgroundColor': '#4285f4',
        'logo': {
            'sourceUri': {
                'uri':
                    'https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg',
            },
            'contentDescription': {
                'defaultValue': {
                    'language': 'en-US',
                    'value': 'Generic card logo',
                },
            },
        },
    }

    # 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
            'genericClasses': [generic_class,],
            'genericObjects': [generic_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}'

С#

/// <summary>
/// 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.
///
/// 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="userId">Developer-defined user ID for this object.</param>
/// <returns>An "Add to Google Wallet" link.</returns>
public string CreateJWTSaveURL(string issuerId, string classSuffix, string userId)
{
  // Ignore null values when serializing to/from JSON
  JsonSerializerSettings excludeNulls = new JsonSerializerSettings()
  {
    NullValueHandling = NullValueHandling.Ignore
  };

  // Generate the object ID
  // Should only include alphanumeric characters, '.', '_', or '-'
  string newUserId = new Regex(@"[^\w.-]", RegexOptions.Compiled)
      .Replace(userId, "_");
  string objectId = $"{issuerId}.{newUserId}";

  // See link below for more information on required properties
  // https://developers.google.com/wallet/generic/rest/v1/genericclass
  GenericClass genericClass = new GenericClass
  {
    Id = $"{issuerId}.{classSuffix}"
  };

  // Create a JSON representation of the class
  JObject serializedClass = JObject.Parse(
      JsonConvert.SerializeObject(genericClass, excludeNulls));

  // See link below for more information on required properties
  // https://developers.google.com/wallet/generic/rest/v1/genericobject
  GenericObject genericObject = new GenericObject
  {
    Id = objectId,
    ClassId = $"{issuerId}.{classSuffix}",
    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"
    },
    CardTitle = new LocalizedString
    {
      DefaultValue = new TranslatedString
      {
        Language = "en-US",
        Value = "Generic card title"
      }
    },
    Header = new LocalizedString
    {
      DefaultValue = new TranslatedString
      {
        Language = "en-US",
        Value = "Generic header"
      }
    },
    HexBackgroundColor = "#4285f4",
    Logo = new Image
    {
      SourceUri = new ImageUri
      {
        Uri = "https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg"
      },
      ContentDescription = new LocalizedString
      {
        DefaultValue = new TranslatedString
        {
          Language = "en-US",
          Value = "Generic card logo"
        }
      },
    }
  };

  // Create a JSON representation of the pass
  JObject serializedObject = JObject.Parse(
      JsonConvert.SerializeObject(genericObject, excludeNulls));

  // Create the JWT as a JSON object
  JObject jwtPayload = JObject.Parse(JsonConvert.SerializeObject(new
  {
    iss = credentials.Id,
    aud = "google",
    origins = new 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
      genericClasses = new JObject[]
      {
        serializedClass
      },
      genericObjects = new 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 this pass class.
 * @param {string} userId Developer-defined user ID for this object.
 *
 * @returns {string} An "Add to Google Wallet" link.
 */
createJwtSaveUrl(issuerId, classSuffix, userId) {
  // Generate the object ID
  // Should only include alphanumeric characters, '.', '_', or '-'
  let objectId = `${issuerId}.${userId.replace(/[^\w.-]/g, '_')}`;

  // See link below for more information on required properties
  // https://developers.google.com/wallet/generic/rest/v1/genericclass
  let genericClass = {
    'id': `${issuerId}.${classSuffix}`,
  };

  // See link below for more information on required properties
  // https://developers.google.com/wallet/generic/rest/v1/genericobject
  let genericObject = {
    'id': `${objectId}`,
    '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',
    },
    'cardTitle': {
      'defaultValue': {
        'language': 'en-US',
        'value': 'Generic card title',
      },
    },
    'header': {
      'defaultValue': {
        'language': 'en-US',
        'value': 'Generic header',
      },
    },
    'hexBackgroundColor': '#4285f4',
    'logo': {
      'sourceUri': {
        'uri': 'https://storage.googleapis.com/wallet-lab-tools-codelab-artifacts-public/pass_google_logo.jpg',
      },
      'contentDescription': {
        'defaultValue': {
          'language': 'en-US',
          'value': 'Generic card logo',
        },
      },
    },
  };

  // 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
      genericClasses: [genericClass,],
      genericObjects: [genericObject,],
    },
  };

  // 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}`;
}

Получив подписанный JWT, вы можете использовать эту информацию для создания ссылки «Добавить в Google Кошелек» .

Ссылка «Добавить в Google Кошелек» имеет следующий формат:

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

Эта ссылка может быть встроена в вашу веб-страницу или отправлена ​​по электронной почте в виде гиперссылки. Его также можно отправить клиенту, используя другие каналы, такие как чат и SMS.

Безопасная длина закодированного JWT составляет 1800 символов. Если ваш JWT ниже этого предела, весь объект может быть включен в подписанный JWT. Ваши JWT должны оставаться ниже этого предела. Если длина превышает 1800 символов, сохранение может не работать из-за усечения веб-браузерами.

Кнопка «Добавить в Google Кошелек»

Для достижения наилучших результатов используйте кнопки Google Кошелька на своей веб-странице, в электронной почте или в приложении для Android.

Кнопка Google Wallet может отображаться двумя способами:

  • Кнопку JavaScript Web можно использовать для веб-сайтов.
  • Ссылку JWT с кнопкой можно использовать для электронной почты, SMS, приложений и веб-сайтов.

Следующие шаги