建立可儲存多張票證的按鈕

如果使用者購買多張活動票券,允許使用者新增 一次複製到裝置上所有票券您可以定義多個物件或類別 寫入 JSON Web Token (JWT),即可利用這組憑證 「新增至 Google 錢包」按鈕或連結。使用者按一下按鈕後 會同時將所有已定義的票證新增到使用者的裝置。

在要簽署的 JWT 中,於 payload 屬性的 eventTicketClasseseventTicketObjects 陣列, 。以下範例說明兩種不同的操作方式。

如要進一步瞭解多張票證的 UI 表示法,請參閱 將多張活動票券分組

現有的類別和物件

這個範例使用預先建立的類別和物件,而且只需要 請注意,classId 屬性對於傳遞物件為選用屬性。是 這裡就會顯示 的示範用途

{
    "aud": "google",
    "origins": [],
    "iss": "your_iam_account@appspot.gserviceaccount.com",
    "iat": 1534891254,
    "typ": "savetowallet",
    "payload": {
        "eventTicketObjects": [
            {
                "classId": "issuerId.eventTicketClassSuffix",
                "id": "issuerId.eventTicketObjectSuffix_01"
            },
            {
                "classId": "issuerId.eventTicketClassSuffix",
                "id": "issuerId.eventTicketObjectSuffix_02"
            }
        ]
    }
}

建立新的類別和物件

這個範例定義了一個類別和多個子項物件。類別和 只有當使用者點擊 連結「新增至 Google 錢包」連結,即可將票證新增至裝置。

{
    "aud": "google",
    "origins": [],
    "iss": "your_iam_account@appspot.gserviceaccount.com",
    "iat": 1534891254,
    "typ": "savetowallet",
    "payload": {
        "eventTicketClasses": [
            {
                "id": "issuerId.eventTicketClassSuffix",
                "issuerName": "Google Wallet Events",
                "reviewStatus": "underReview",
                "eventName": {
                    "defaultValue": {
                        "language": "en-US",
                        "value": "Coding for Coffee"
                    }
                },
                "venue": {
                    "name": {
                        "defaultValue": {
                            "language": "en-US",
                            "value": "1600 Amphitheatre Pkwy, Mountain View, CA 94043"
                        }
                    },
                    "address": {
                        "defaultValue": {
                            "language": "en-US",
                            "value": "1600 Amphitheatre Pkwy, Mountain View, CA 94043"
                        }
                    }
                },
                "dateTime": {
                    "doorsOpenLabel": "doorsOpen",
                    "doorsOpen": "2027-04-12T19:20",
                    "start": "2027-04-12T20:00",
                    "end": "2027-04-12T21:20"
                }
            }
        ],
        "eventTicketObjects": [
            {
                "id": "issuerId.eventTicketObjectSuffix_1",
                "classId": "issuerId.eventTicketClassSuffix",
                "state": "active"
            },
            {
                "id": "issuerId.eventTicketObjectSuffix_2",
                "classId": "issuerId.eventTicketClassSuffix",
                "state": "active"
            }
        ]
    }
}

以下程式碼範例示範如何建立新增至 Google 錢包 連結至將建立的新 eventTicketClasseventTicketObject 當使用者按一下按鈕並將票證新增至裝置時。

Java

如要開始在 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/tickets/events/rest/v1/eventticketclass
  EventTicketClass newClass =
      new EventTicketClass()
          .setId(String.format("%s.%s", issuerId, classSuffix))
          .setIssuerName("Issuer name")
          .setReviewStatus("UNDER_REVIEW")
          .setEventName(
              new LocalizedString()
                  .setDefaultValue(
                      new TranslatedString().setLanguage("en-US").setValue("Event name")));

  // See link below for more information on required properties
  // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject
  EventTicketObject newObject =
      new EventTicketObject()
          .setId(String.format("%s.%s", issuerId, objectSuffix))
          .setClassId(String.format("%s.%s", issuerId, classSuffix))
          .setState("ACTIVE")
          .setHeroImage(
              new Image()
                  .setSourceUri(
                      new ImageUri()
                          .setUri(
                              "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg"))
                  .setContentDescription(
                      new LocalizedString()
                          .setDefaultValue(
                              new TranslatedString()
                                  .setLanguage("en-US")
                                  .setValue("Hero image description"))))
          .setTextModulesData(
                  List.of(
                          new TextModuleData()
                                  .setHeader("Text module header")
                                  .setBody("Text module body")
                                  .setId("TEXT_MODULE_ID")))
          .setLinksModuleData(
              new LinksModuleData()
                  .setUris(
                      Arrays.asList(
                          new Uri()
                              .setUri("http://maps.google.com/")
                              .setDescription("Link module URI description")
                              .setId("LINK_MODULE_URI_ID"),
                          new Uri()
                              .setUri("tel:6505555555")
                              .setDescription("Link module tel description")
                              .setId("LINK_MODULE_TEL_ID"))))
          .setImageModulesData(
                  List.of(
                          new ImageModuleData()
                                  .setMainImage(
                                          new Image()
                                                  .setSourceUri(
                                                          new ImageUri()
                                                                  .setUri(
                                                                          "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg"))
                                                  .setContentDescription(
                                                          new LocalizedString()
                                                                  .setDefaultValue(
                                                                          new TranslatedString()
                                                                                  .setLanguage("en-US")
                                                                                  .setValue("Image module description"))))
                                  .setId("IMAGE_MODULE_ID")))
          .setBarcode(new Barcode().setType("QR_CODE").setValue("QR code value"))
          .setLocations(
                  List.of(
                          new LatLongPoint()
                                  .setLatitude(37.424015499999996)
                                  .setLongitude(-122.09259560000001)))
          .setSeatInfo(
              new EventSeat()
                  .setSeat(
                      new LocalizedString()
                          .setDefaultValue(
                              new TranslatedString().setLanguage("en-US").setValue("42")))
                  .setRow(
                      new LocalizedString()
                          .setDefaultValue(
                              new TranslatedString().setLanguage("en-US").setValue("G3")))
                  .setSection(
                      new LocalizedString()
                          .setDefaultValue(
                              new TranslatedString().setLanguage("en-US").setValue("5")))
                  .setGate(
                      new LocalizedString()
                          .setDefaultValue(
                              new TranslatedString().setLanguage("en-US").setValue("A"))))
          .setTicketHolderName("Ticket holder name")
          .setTicketNumber("Ticket number");

  // Create the JWT as a HashMap object
  HashMap<String, Object> claims = new HashMap<String, Object>();
  claims.put("iss", ((ServiceAccountCredentials) credentials).getClientEmail());
  claims.put("aud", "google");
  claims.put("origins", List.of("www.example.com"));
  claims.put("typ", "savetowallet");

  // Create the Google Wallet payload and add to the JWT
  HashMap<String, Object> payload = new HashMap<String, Object>();
  payload.put("eventTicketClasses", List.of(newClass));
  payload.put("eventTicketObjects", List.of(newObject));
  claims.put("payload", payload);

  // The service account credentials are used to sign the JWT
  Algorithm algorithm =
      Algorithm.RSA256(
          null, (RSAPrivateKey) ((ServiceAccountCredentials) credentials).getPrivateKey());
  String token = JWT.create().withPayload(claims).sign(algorithm);

  System.out.println("Add to Google Wallet link");
  System.out.printf("https://pay.google.com/gp/v/save/%s%n", token);

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

PHP

如要在 PHP 中開始整合,請參閱我們提供的完整 查看程式碼範例

/**
 * Generate a signed JWT that creates a new pass class and object.
 *
 * When the user opens the "Add to Google Wallet" URL and saves the pass to
 * their wallet, the pass class and object defined in the JWT are
 * created. This allows you to create multiple pass classes and objects in
 * one API call when the user saves the pass to their wallet.
 *
 * @param string $issuerId The issuer ID being used for this request.
 * @param string $classSuffix Developer-defined unique ID for the pass class.
 * @param string $objectSuffix Developer-defined unique ID for the pass object.
 *
 * @return string An "Add to Google Wallet" link.
 */
public function createJwtNewObjects(string $issuerId, string $classSuffix, string $objectSuffix)
{
  // See link below for more information on required properties
  // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketclass
  $newClass = new EventTicketClass([
    'id' => "{$issuerId}.{$classSuffix}",
    'issuerName' => 'Issuer name',
    'reviewStatus' => 'UNDER_REVIEW',
    'eventName' => new LocalizedString([
      'defaultValue' => new TranslatedString([
        'language' => 'en-US',
        'value' => 'Event name'
      ])
    ])
  ]);

  // See link below for more information on required properties
  // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject
  $newObject = new EventTicketObject([
    'id' => "{$issuerId}.{$objectSuffix}",
    'classId' => "{$issuerId}.{$classSuffix}",
    'state' => 'ACTIVE',
    'heroImage' => new Image([
      'sourceUri' => new ImageUri([
        'uri' => 'https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg'
      ]),
      'contentDescription' => new LocalizedString([
        'defaultValue' => new TranslatedString([
          'language' => 'en-US',
          'value' => 'Hero image description'
        ])
      ])
    ]),
    'textModulesData' => [
      new TextModuleData([
        'header' => 'Text module header',
        'body' => 'Text module body',
        'id' => 'TEXT_MODULE_ID'
      ])
    ],
    'linksModuleData' => new LinksModuleData([
      'uris' => [
        new Uri([
          'uri' => 'http://maps.google.com/',
          'description' => 'Link module URI description',
          'id' => 'LINK_MODULE_URI_ID'
        ]),
        new Uri([
          'uri' => 'tel:6505555555',
          'description' => 'Link module tel description',
          'id' => 'LINK_MODULE_TEL_ID'
        ])
      ]
    ]),
    'imageModulesData' => [
      new ImageModuleData([
        'mainImage' => new Image([
          'sourceUri' => new ImageUri([
            'uri' => 'http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg'
          ]),
          'contentDescription' => new LocalizedString([
            'defaultValue' => new TranslatedString([
              'language' => 'en-US',
              'value' => 'Image module description'
            ])
          ])
        ]),
        'id' => 'IMAGE_MODULE_ID'
      ])
    ],
    'barcode' => new Barcode([
      'type' => 'QR_CODE',
      'value' => 'QR code value'
    ]),
    'locations' => [
      new LatLongPoint([
        'latitude' => 37.424015499999996,
        'longitude' =>  -122.09259560000001
      ])
    ],
    'seatInfo' => new EventSeat([
      'seat' => new LocalizedString([
        'defaultValue' => new TranslatedString([
          'language' => 'en-US',
          'value' => '42'
        ])
      ]),
      'row' => new LocalizedString([
        'defaultValue' => new TranslatedString([
          'language' => 'en-US',
          'value' => 'G3'
        ])
      ]),
      'section' => new LocalizedString([
        'defaultValue' => new TranslatedString([
          'language' => 'en-US',
          'value' => '5'
        ])
      ]),
      'gate' => new LocalizedString([
        'defaultValue' => new TranslatedString([
          'language' => 'en-US',
          'value' => 'A'
        ])
      ])
    ]),
    'ticketHolderName' => 'Ticket holder name',
    'ticketNumber' => 'Ticket number'
  ]);

  // 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' => [
      'eventTicketClasses' => [
        $newClass
      ],
      'eventTicketObjects' => [
        $newObject
      ]
    ]
  ];

  $token = JWT::encode(
    $claims,
    $serviceAccount['private_key'],
    'RS256'
  );

  print "Add to Google Wallet link\n";
  print "https://pay.google.com/gp/v/save/{$token}";

  return "https://pay.google.com/gp/v/save/{$token}";
}

Python

如要開始以 Python 進行整合,請參閱我們提供的完整 查看程式碼範例

def create_jwt_new_objects(self, issuer_id: str, class_suffix: str,
                           object_suffix: str) -> str:
    """Generate a signed JWT that creates a new pass class and object.

    When the user opens the "Add to Google Wallet" URL and saves the pass to
    their wallet, the pass class and object defined in the JWT are
    created. This allows you to create multiple pass classes and objects in
    one API call when the user saves the pass to their wallet.

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

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

    # See link below for more information on required properties
    # https://developers.google.com/wallet/tickets/events/rest/v1/eventticketclass
    new_class = {
        'id': f'{issuer_id}.{class_suffix}',
        'issuerName': 'Issuer name',
        'reviewStatus': 'UNDER_REVIEW',
        'eventName': {
            'defaultValue': {
                'language': 'en-US',
                'value': 'Event name'
            }
        }
    }

    # See link below for more information on required properties
    # https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject
    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
        }],
        'seatInfo': {
            'seat': {
                'defaultValue': {
                    'language': 'en-US',
                    'value': '42'
                }
            },
            'row': {
                'defaultValue': {
                    'language': 'en-US',
                    'value': 'G3'
                }
            },
            'section': {
                'defaultValue': {
                    'language': 'en-US',
                    'value': '5'
                }
            },
            'gate': {
                'defaultValue': {
                    'language': 'en-US',
                    'value': 'A'
                }
            }
        },
        'ticketHolderName': 'Ticket holder name',
        'ticketNumber': 'Ticket number'
    }

    # 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
            'eventTicketClasses': [new_class],
            'eventTicketObjects': [new_object]
        }
    }

    # The service account credentials are used to sign the JWT
    signer = crypt.RSASigner.from_service_account_file(self.key_file_path)
    token = jwt.encode(signer, claims).decode('utf-8')

    print('Add to Google Wallet link')
    print(f'https://pay.google.com/gp/v/save/{token}')

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

C#

如要開始在 C# 中整合,請參閱我們提供的完整 查看程式碼範例

/// <summary>
/// Generate a signed JWT that creates a new pass class and object.
/// <para />
/// When the user opens the "Add to Google Wallet" URL and saves the pass to
/// their wallet, the pass class and object defined in the JWT are created.
/// This allows you to create multiple pass classes and objects in one API
/// call when the user saves the pass to their wallet.
/// <para />
/// The Google Wallet C# library uses Newtonsoft.Json.JsonPropertyAttribute
/// to specify the property names when converting objects to JSON. The
/// Newtonsoft.Json.JsonConvert.SerializeObject method will automatically
/// serialize the object with the right property names.
/// </summary>
/// <param name="issuerId">The issuer ID being used for this request.</param>
/// <param name="classSuffix">Developer-defined unique ID for this pass class.</param>
/// <param name="objectSuffix">Developer-defined unique ID for the pass object.</param>
/// <returns>An "Add to Google Wallet" link.</returns>
public string CreateJWTNewObjects(string issuerId, string classSuffix, string objectSuffix)
{
  // Ignore null values when serializing to/from JSON
  JsonSerializerSettings excludeNulls = new JsonSerializerSettings()
  {
    NullValueHandling = NullValueHandling.Ignore
  };

  // See link below for more information on required properties
  // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketclass
  EventTicketClass newClass = new EventTicketClass
  {
    Id = $"{issuerId}.{classSuffix}",
    IssuerName = "Issuer name",
    ReviewStatus = "UNDER_REVIEW",
    EventId = classSuffix,
    EventName = new LocalizedString
    {
      DefaultValue = new TranslatedString
      {
        Language = "en-US",
        Value = "Event name"
      }
    }
  };

  // See link below for more information on required properties
  // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject
  EventTicketObject newObject = new EventTicketObject
  {
    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
      }
    },
    SeatInfo = new EventSeat
    {
      Seat = new LocalizedString
      {
        DefaultValue = new TranslatedString
        {
          Language = "en-US",
          Value = "42"
        }
      },
      Row = new LocalizedString
      {
        DefaultValue = new TranslatedString
        {
          Language = "en-US",
          Value = "G3"
        }
      },
      Section = new LocalizedString
      {
        DefaultValue = new TranslatedString
        {
          Language = "en-US",
          Value = "5"
        }
      },
      Gate = new LocalizedString
      {
        DefaultValue = new TranslatedString
        {
          Language = "en-US",
          Value = "A"
        }
      }
    },
    TicketHolderName = "Ticket holder name",
    TicketNumber = "Ticket number"
  };

  // 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
      eventTicketClasses = new List<JObject>
      {
        serializedClass
      },
      eventTicketObjects = 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/tickets/events/rest/v1/eventticketclass
  let newClass = {
    'id': `${issuerId}.${classSuffix}`,
    'issuerName': 'Issuer name',
    'reviewStatus': 'UNDER_REVIEW',
    'eventName': {
      'defaultValue': {
        'language': 'en-US',
        'value': 'Event name'
      }
    }
  };

  // See link below for more information on required properties
  // https://developers.google.com/wallet/tickets/events/rest/v1/eventticketobject
  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
      }
    ],
    'seatInfo': {
      'seat': {
        'defaultValue': {
          'language': 'en-US',
          'value': '42'
        }
      },
      'row': {
        'defaultValue': {
          'language': 'en-US',
          'value': 'G3'
        }
      },
      'section': {
        'defaultValue': {
          'language': 'en-US',
          'value': '5'
        }
      },
      'gate': {
        'defaultValue': {
          'language': 'en-US',
          'value': 'A'
        }
      }
    },
    'ticketHolderName': 'Ticket holder name',
    'ticketNumber': 'Ticket number'
  };

  // 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
      eventTicketClasses: [newClass],
      eventTicketObjects: [newObject]
    }
  };

  // The service account credentials are used to sign the JWT
  let token = jwt.sign(claims, this.credentials.private_key, { algorithm: 'RS256' });

  console.log('Add to Google Wallet link');
  console.log(`https://pay.google.com/gp/v/save/${token}`);

  return `https://pay.google.com/gp/v/save/${token}`;
}

Go

如要在 Go 中開始進行整合作業,請參閱 GitHub 上的完整程式碼範例 GitHub 上的程式碼範例

// Generate a signed JWT that creates a new pass class and object.
//
// When the user opens the "Add to Google Wallet" URL and saves the pass to
// their wallet, the pass class and object defined in the JWT are
// created. This allows you to create multiple pass classes and objects in
// one API call when the user saves the pass to their wallet.
func (d *demoEventticket) createJwtNewObjects(issuerId, classSuffix, objectSuffix string) {
	eventticketObject := new(walletobjects.EventTicketObject)
	eventticketObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix)
	eventticketObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix)
	eventticketObject.TicketHolderName = "Ticket holder name"
	eventticketObject.TicketNumber = "Ticket number"
	eventticketObject.State = "ACTIVE"

	eventticketJson, _ := json.Marshal(eventticketObject)
	var payload map[string]any
	json.Unmarshal([]byte(fmt.Sprintf(`
	{
		"eventticketObjects": [%s]
	}
	`, eventticketJson)), &payload)
	claims := jwt.MapClaims{
		"iss":     d.credentials.Email,
		"aud":     "google",
		"origins": []string{"www.example.com"},
		"typ":     "savetowallet",
		"payload": payload,
	}

	// The service account credentials are used to sign the JWT
	key, _ := jwt.ParseRSAPrivateKeyFromPEM(d.credentials.PrivateKey)
	token, _ := jwt.NewWithClaims(jwt.SigningMethodRS256, claims).SignedString(key)

	fmt.Println("Add to Google Wallet link")
	fmt.Println("https://pay.google.com/gp/v/save/" + token)
}