建立票證類別和票證物件

凡是可發出供使用者儲存在 Google 錢包中的票證,幾乎都由兩個元件定義:票證類別和票證物件。每次核發票證給使用者時,您必須同時建立「Pass 類別」和「Pass 物件」,以便 Google Wallet API 瞭解要建構的票證類型,以及要顯示在票證上的詳細資料,例如禮物卡值或票券持有人姓名。

Google Wallet API 提供一組預先定義的票證類別和票證物件,由您建立例項,可用來建立核發給使用者的票證,例如 GiftCardClassGiftCardObjectGenericClassGenericObject 等。

每個票證類別和票證物件執行個體都會定義為 JSON 物件,其中包含一組必要和選用屬性,可對應至特定票證類型適用的特定用途。

建立票證類別

「票證類別」可視為用來建立票證的共用範本。票證類別會定義特定屬性,且所有使用該屬性的票證都會包含這些屬性。票證核發機構可以建立多個類別,每個類別都有專屬的一組屬性,用來定義樣式和外觀等屬性,此外還提供智慧感應、註冊和登入等其他功能。

您可以透過 Google Wallet REST API、Google Wallet Android SDK 或 Google 錢包商家主控台建立票證類別。

對新使用者來說,建立票證類別最簡單的方法就是透過商家主控台,因為這個介面具有簡潔的使用者介面,方便您填寫表單欄位,藉此定義第一個票證類別的各種欄位。

進階使用者如要透過程式輔助方式建立票證類別,是最理想的做法。

使用 Google 錢包商家主控台

如要在 Google 錢包商家主控台中建立票證類別,請按照下列步驟操作:

  1. 前往 Google Pay 和錢包商家主控台,使用您的 Google Wallet API 核發機構帳戶登入。
  2. 在「Google Wallet API」並點選「管理票證」按鈕。
  3. 在「取得發布權限」下方,按一下「建立課程」按鈕。
  4. 從對話方塊中選擇票證類型。Google 錢包提供各種票證類型 (活動票券、優惠、會員卡等)。如果是彈性用途,請選取「一般」做為票證類型
  5. 為必填欄位填入適當的值。
  6. 按一下「建立課程」按鈕即可儲存課程。

使用 Google Wallet REST API

如要使用 Google Wallet REST API 建立 Passes 類別,請傳送 POST 要求至 https://walletobjects.googleapis.com/walletobjects/v1/offerClass。詳情請參閱參考說明文件

Java

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

/**
 * Create a class.
 *
 * @param issuerId The issuer ID being used for this request.
 * @param classSuffix Developer-defined unique ID for this pass class.
 * @return The pass class ID: "{issuerId}.{classSuffix}"
 */
public String createClass(String issuerId, String classSuffix) throws IOException {
  // Check if the class exists
  try {
    service.offerclass().get(String.format("%s.%s", issuerId, classSuffix)).execute();

    System.out.printf("Class %s.%s already exists!%n", issuerId, classSuffix);
    return String.format("%s.%s", issuerId, classSuffix);
  } catch (GoogleJsonResponseException ex) {
    if (ex.getStatusCode() != 404) {
      // Something else went wrong...
      ex.printStackTrace();
      return String.format("%s.%s", issuerId, classSuffix);
    }
  }

  // See link below for more information on required properties
  // https://developers.google.com/wallet/retail/offers/rest/v1/offerclass
  OfferClass newClass =
      new OfferClass()
          .setId(String.format("%s.%s", issuerId, classSuffix))
          .setIssuerName("Issuer name")
          .setReviewStatus("UNDER_REVIEW")
          .setProvider("Provider name")
          .setTitle("Offer title")
          .setRedemptionChannel("ONLINE");

  OfferClass response = service.offerclass().insert(newClass).execute();

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

  return response.getId();
}

PHP

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

/**
 * Create a class.
 *
 * @param string $issuerId The issuer ID being used for this request.
 * @param string $classSuffix Developer-defined unique ID for this pass class.
 *
 * @return string The pass class ID: "{$issuerId}.{$classSuffix}"
 */
public function createClass(string $issuerId, string $classSuffix)
{
  // Check if the class exists
  try {
    $this->service->offerclass->get("{$issuerId}.{$classSuffix}");

    print("Class {$issuerId}.{$classSuffix} already exists!");
    return "{$issuerId}.{$classSuffix}";
  } catch (Google\Service\Exception $ex) {
    if (empty($ex->getErrors()) || $ex->getErrors()[0]['reason'] != 'classNotFound') {
      // Something else went wrong...
      print_r($ex);
      return "{$issuerId}.{$classSuffix}";
    }
  }

  // See link below for more information on required properties
  // https://developers.google.com/wallet/retail/offers/rest/v1/offerclass
  $newClass = new OfferClass([
    'id' => "{$issuerId}.{$classSuffix}",
    'issuerName' => 'Issuer name',
    'reviewStatus' => 'UNDER_REVIEW',
    'provider' => 'Provider name',
    'title' => 'Offer title',
    'redemptionChannel' => 'ONLINE'
  ]);

  $response = $this->service->offerclass->insert($newClass);

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

  return $response->id;
}

Python

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

def create_class(self, issuer_id: str, class_suffix: str) -> str:
    """Create a class.

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

    Returns:
        The pass class ID: f"{issuer_id}.{class_suffix}"
    """

    # Check if the class exists
    try:
        self.client.offerclass().get(resourceId=f'{issuer_id}.{class_suffix}').execute()
    except HttpError as e:
        if e.status_code != 404:
            # Something else went wrong...
            print(e.error_details)
            return f'{issuer_id}.{class_suffix}'
    else:
        print(f'Class {issuer_id}.{class_suffix} already exists!')
        return f'{issuer_id}.{class_suffix}'

    # See link below for more information on required properties
    # https://developers.google.com/wallet/retail/offers/rest/v1/offerclass
    new_class = {
        'id': f'{issuer_id}.{class_suffix}',
        'issuerName': 'Issuer name',
        'reviewStatus': 'UNDER_REVIEW',
        'provider': 'Provider name',
        'title': 'Offer title',
        'redemptionChannel': 'ONLINE'
    }

    response = self.client.offerclass().insert(body=new_class).execute()

    print('Class insert response')
    print(response)

    return f'{issuer_id}.{class_suffix}'

C#

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

/// <summary>
/// Create a class.
/// </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>
/// <returns>The pass class ID: "{issuerId}.{classSuffix}"</returns>
public string CreateClass(string issuerId, string classSuffix)
{
  // Check if the class exists
  Stream responseStream = service.Offerclass
      .Get($"{issuerId}.{classSuffix}")
      .ExecuteAsStream();

  StreamReader responseReader = new StreamReader(responseStream);
  JObject jsonResponse = JObject.Parse(responseReader.ReadToEnd());

  if (!jsonResponse.ContainsKey("error"))
  {
    Console.WriteLine($"Class {issuerId}.{classSuffix} already exists!");
    return $"{issuerId}.{classSuffix}";
  }
  else if (jsonResponse["error"].Value<int>("code") != 404)
  {
    // Something else went wrong...
    Console.WriteLine(jsonResponse.ToString());
    return $"{issuerId}.{classSuffix}";
  }

  // See link below for more information on required properties
  // https://developers.google.com/wallet/retail/offers/rest/v1/offerclass
  OfferClass newClass = new OfferClass
  {
    Id = $"{issuerId}.{classSuffix}",
    IssuerName = "Issuer name",
    ReviewStatus = "UNDER_REVIEW",
    Provider = "Provider name",
    Title = "Offer title",
    RedemptionChannel = "ONLINE"
  };

  responseStream = service.Offerclass
      .Insert(newClass)
      .ExecuteAsStream();

  responseReader = new StreamReader(responseStream);
  jsonResponse = JObject.Parse(responseReader.ReadToEnd());

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

  return $"{issuerId}.{classSuffix}";
}

Node.js

如要在節點環境中展開整合作業,請參閱我們提供的完整 查看程式碼範例

/**
 * Create a class.
 *
 * @param {string} issuerId The issuer ID being used for this request.
 * @param {string} classSuffix Developer-defined unique ID for this pass class.
 *
 * @returns {string} The pass class ID: `${issuerId}.${classSuffix}`
 */
async createClass(issuerId, classSuffix) {
  let response;

  // Check if the class exists
  try {
    response = await this.client.offerclass.get({
      resourceId: `${issuerId}.${classSuffix}`
    });

    console.log(`Class ${issuerId}.${classSuffix} already exists!`);

    return `${issuerId}.${classSuffix}`;
  } catch (err) {
    if (err.response && err.response.status !== 404) {
      // Something else went wrong...
      console.log(err);
      return `${issuerId}.${classSuffix}`;
    }
  }

  // See link below for more information on required properties
  // https://developers.google.com/wallet/retail/offers/rest/v1/offerclass
  let newClass = {
    'id': `${issuerId}.${classSuffix}`,
    'issuerName': 'Issuer name',
    'reviewStatus': 'UNDER_REVIEW',
    'provider': 'Provider name',
    'title': 'Offer title',
    'redemptionChannel': 'ONLINE'
  };

  response = await this.client.offerclass.insert({
    requestBody: newClass
  });

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

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

Go

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

// Create a class.
func (d *demoOffer) createClass(issuerId, classSuffix string) {
	offerClass := new(walletobjects.OfferClass)
	offerClass.Id = fmt.Sprintf("%s.%s", issuerId, classSuffix)
	offerClass.RedemptionChannel = "ONLINE"
	offerClass.ReviewStatus = "UNDER_REVIEW"
	offerClass.Title = "Offer title"
	offerClass.IssuerName = "Issuer name"
	offerClass.Provider = "Provider name"
	res, err := d.service.Offerclass.Insert(offerClass).Do()
	if err != nil {
		log.Fatalf("Unable to insert class: %v", err)
	} else {
		fmt.Printf("Class insert id:\n%v\n", res.Id)
	}
}

建立票證物件

票證物件是票證類別的執行個體。建立票證 物件,您必須提供下列屬性:

  • classId:票證類別的 id
  • id:客戶的專屬 ID

    詳情請參閱 版面配置範本 ,進一步瞭解這些屬性在 方案。

    建立 Passes 物件的程式碼範例:

    Java

    如要開始在 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}"
     */
    public String createObject(String issuerId, String classSuffix, String objectSuffix)
        throws IOException {
      // Check if the object exists
      try {
        service.offerobject().get(String.format("%s.%s", issuerId, objectSuffix)).execute();
    
        System.out.printf("Object %s.%s already exists!%n", issuerId, objectSuffix);
        return String.format("%s.%s", issuerId, objectSuffix);
      } catch (GoogleJsonResponseException ex) {
        if (ex.getStatusCode() == 404) {
          // Object does not exist
          // Do nothing
        } else {
          // 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/offers/rest/v1/offerobject
      OfferObject newObject =
          new OfferObject()
              .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)))
              .setValidTimeInterval(
                  new TimeInterval()
                      .setStart(new DateTime().setDate("2023-06-12T23:20:50.52Z"))
                      .setEnd(new DateTime().setDate("2023-12-12T23:20:50.52Z")));
    
      OfferObject response = service.offerobject().insert(newObject).execute();
    
      System.out.println("Object insert response");
      System.out.println(response.toPrettyString());
    
      return response.getId();
    }
    

    PHP

    如要在 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->offerobject->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/offers/rest/v1/offerobject
      $newObject = new OfferObject([
        '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
          ])
        ],
        'validTimeInterval' => new TimeInterval([
          'start' => new DateTime([
            'date' => '2023-06-12T23:20:50.52Z'
          ]),
          'end' => new DateTime([
            'date' => '2023-12-12T23:20:50.52Z'
          ])
        ])
      ]);
    
      $response = $this->service->offerobject->insert($newObject);
    
      print "Object insert response\n";
      print_r($response);
    
      return $response->id;
    }
    

    Python

    如要開始以 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
        try:
            self.client.offerobject().get(resourceId=f'{issuer_id}.{object_suffix}').execute()
        except HttpError as e:
            if e.status_code != 404:
                # Something else went wrong...
                print(e.error_details)
                return f'{issuer_id}.{object_suffix}'
        else:
            print(f'Object {issuer_id}.{object_suffix} already exists!')
            return f'{issuer_id}.{object_suffix}'
    
        # See link below for more information on required properties
        # https://developers.google.com/wallet/retail/offers/rest/v1/offerobject
        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
            }],
            'validTimeInterval': {
                'start': {
                    'date': '2023-06-12T23:20:50.52Z'
                },
                'end': {
                    'date': '2023-12-12T23:20:50.52Z'
                }
            }
        }
    
        # Create the object
        response = self.client.offerobject().insert(body=new_object).execute()
    
        print('Object insert response')
        print(response)
    
        return f'{issuer_id}.{object_suffix}'
    

    C#

    如要開始在 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.Offerobject
          .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/offers/rest/v1/offerobject
      OfferObject newObject = new OfferObject
      {
        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
          }
        },
        ValidTimeInterval = new TimeInterval
        {
          Start = new Google.Apis.Walletobjects.v1.Data.DateTime
          {
            Date = "2023-06-12T23:20:50.52Z"
          },
          End = new Google.Apis.Walletobjects.v1.Data.DateTime
          {
            Date = "2023-12-12T23:20:50.52Z"
          }
        }
      };
    
      responseStream = service.Offerobject
          .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.client.offerobject.get({
          resourceId: `${issuerId}.${objectSuffix}`
        });
    
        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/offers/rest/v1/offerobject
      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
          }
        ],
        'validTimeInterval': {
          'start': {
            'date': '2023-06-12T23:20:50.52Z'
          },
          'end': {
            'date': '2023-12-12T23:20:50.52Z'
          }
        }
      };
    
      response = await this.client.offerobject.insert({
        requestBody: newObject
      });
    
      console.log('Object insert response');
      console.log(response);
    
      return `${issuerId}.${objectSuffix}`;
    }
    

    Go

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

    // Create an object.
    func (d *demoOffer) createObject(issuerId, classSuffix, objectSuffix string) {
    	offerObject := new(walletobjects.OfferObject)
    	offerObject.Id = fmt.Sprintf("%s.%s", issuerId, objectSuffix)
    	offerObject.ClassId = fmt.Sprintf("%s.%s", issuerId, classSuffix)
    	offerObject.State = "ACTIVE"
    	offerObject.ValidTimeInterval = &walletobjects.TimeInterval{
    		Start: &walletobjects.DateTime{
    			Date: "2023-06-12T23:20:50.52Z",
    		},
    		End: &walletobjects.DateTime{
    			Date: "2023-12-12T23:20:50.52Z",
    		},
    	}
    	offerObject.HeroImage = &walletobjects.Image{
    		SourceUri: &walletobjects.ImageUri{
    			Uri: "https://farm4.staticflickr.com/3723/11177041115_6e6a3b6f49_o.jpg",
    		},
    	}
    	offerObject.Barcode = &walletobjects.Barcode{
    		Type:  "QR_CODE",
    		Value: "QR code",
    	}
    	offerObject.Locations = []*walletobjects.LatLongPoint{
    		&walletobjects.LatLongPoint{
    			Latitude:  37.424015499999996,
    			Longitude: -122.09259560000001,
    		},
    	}
    	offerObject.LinksModuleData = &walletobjects.LinksModuleData{
    		Uris: []*walletobjects.Uri{
    			&walletobjects.Uri{
    				Id:          "LINK_MODULE_URI_ID",
    				Uri:         "http://maps.google.com/",
    				Description: "Link module URI description",
    			},
    			&walletobjects.Uri{
    				Id:          "LINK_MODULE_TEL_ID",
    				Uri:         "tel:6505555555",
    				Description: "Link module tel description",
    			},
    		},
    	}
    	offerObject.ImageModulesData = []*walletobjects.ImageModuleData{
    		&walletobjects.ImageModuleData{
    			Id: "IMAGE_MODULE_ID",
    			MainImage: &walletobjects.Image{
    				SourceUri: &walletobjects.ImageUri{
    					Uri: "http://farm4.staticflickr.com/3738/12440799783_3dc3c20606_b.jpg",
    				},
    			},
    		},
    	}
    	offerObject.TextModulesData = []*walletobjects.TextModuleData{
    		&walletobjects.TextModuleData{
    			Body:   "Text module body",
    			Header: "Text module header",
    			Id:     "TEXT_MODULE_ID",
    		},
    	}
    
    	res, err := d.service.Offerobject.Insert(offerObject).Do()
    	if err != nil {
    		log.Fatalf("Unable to insert object: %v", err)
    	} else {
    		fmt.Printf("Object insert id:\n%s\n", res.Id)
    	}
    }
    

    完成後,系統會在 伺服器不過,這個階段的 Passes 物件尚未連結至 Google 使用者或其裝置。為了讓票證與 Google 錢包使用者,必須核發票證。