Cập nhật các lớp và đối tượng thẻ và vé

Việc luôn cập nhật thẻ và vé là một cách quan trọng để tương tác với khách hàng và tạo nên trải nghiệm tích cực.

Có hai tài nguyên có thể được cập nhật: FlightClassFlightObject

Các phương pháp hay nhất

Danh sách sau đây chứa thông tin hữu ích để bạn xem xét khi cập nhật Các lớp và đối tượng của Thẻ lên máy bay:

  • Khi bạn muốn cập nhật toàn bộ lớp hoặc đối tượng, hãy gửi yêu cầu update. Khi bạn muốn cập nhật một số lượng nhỏ các trường trong một lớp hoặc đối tượng, hãy gửi một yêu cầu patch.
  • Khi bạn đưa ra yêu cầu update, toàn bộ đối tượng hoặc lớp sẽ được cập nhật. Điều này có nghĩa là mọi trường không có trong yêu cầu sẽ bị xoá. Trước khi gửi yêu cầu update, bạn nên gửi yêu cầu GET tới hãy đảm bảo rằng bạn đang làm việc với phiên bản mới nhất cũng như tất cả có trong yêu cầu của bạn.
  • Khi tạo một yêu cầu patch, chỉ những trường đã vá đã cập nhật. Trước khi gửi yêu cầu patch, hãy cân nhắc việc gửi (không bắt buộc) Yêu cầu GET để so sánh các thay đổi của bạn với phiên bản mới nhất.
  • Khi đưa ra yêu cầu patch để cập nhật mảng, mảng ban đầu sẽ là được thay thế bằng thông tin có trong nội dung yêu cầu. Bạn không thể sửa đổi trong một mảng riêng lẻ.
  • Trong một số trường hợp, bạn có thể không biết thời điểm thay đổi hoặc thời điểm kích hoạt bản cập nhật. Cân nhắc lên lịch định kỳ các yêu cầu update hoặc patch cho mọi lớp và đối tượng.

Cập nhật lớp thẻ và vé

Sử dụng Bảng điều khiển doanh nghiệp của Google Wallet

Bạn có thể sửa đổi trực tiếp các lớp truyền dữ liệu (không phải đối tượng) trong Google Pay và Bảng điều khiển Wallet.

  1. Chuyển đến bảng điều khiển
  2. Chọn Google Wallet API
  3. Chọn lớp học mà bạn muốn sửa đổi
  4. Chọn Chỉnh sửa
  5. Cập nhật các thuộc tính của lớp
  6. Chọn Lưu

Sau khi bạn lưu các thay đổi, lớp sẽ tự động được cập nhật cho bất kỳ chủ máy bay.

Sử dụng API Google Wallet

Việc cập nhật FlightClass sẽ ảnh hưởng đến tất cả người dùng đã được cấp phép Thẻ lên máy bay sử dụng hạng này. Ví dụ: để cập nhật biểu trưng cho Thẻ lên máy bay của mình, bạn sẽ gửi yêu cầu update hoặc patch tới API Google Wallet tại một trong các điểm cuối sau đây. resourceId sẽ là mã lớp (ISSUER_ID.CLASS_SUFFIX).

# Update
PUT https://walletobjects.googleapis.com/walletobjects/v1/flightclass/{resourceId}

# Patch
PATCH https://walletobjects.googleapis.com/walletobjects/v1/flightclass/{resourceId}

Để biết thêm thông tin, hãy xem Tài liệu tham khảo API.

Java

Để bắt đầu quá trình tích hợp trong Java, hãy tham khảo mã mẫu trên GitHub.

/**
 * Update a class.
 *
 * <p><strong>Warning:</strong> This replaces all existing class attributes!
 *
 * @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 updateClass(String issuerId, String classSuffix) throws IOException {
  FlightClass updatedClass;

  // Check if the class exists
  try {
    updatedClass =
        service.flightclass().get(String.format("%s.%s", issuerId, classSuffix)).execute();
  } catch (GoogleJsonResponseException ex) {
    if (ex.getStatusCode() == 404) {
      // Class does not exist
      System.out.printf("Class %s.%s not found!%n", issuerId, classSuffix);
      return String.format("%s.%s", issuerId, classSuffix);
    } else {
      // Something else went wrong...
      ex.printStackTrace();
      return String.format("%s.%s", issuerId, classSuffix);
    }
  }

  // Class exists
  // Update the class by adding a homepage
  updatedClass.setHomepageUri(
      new Uri()
          .setUri("https://developers.google.com/wallet")
          .setDescription("Homepage description"));

  // Note: reviewStatus must be 'UNDER_REVIEW' or 'DRAFT' for updates
  updatedClass.setReviewStatus("UNDER_REVIEW");

  FlightClass response =
      service
          .flightclass()
          .update(String.format("%s.%s", issuerId, classSuffix), updatedClass)
          .execute();

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

  return response.getId();
}

PHP

Để bắt đầu quá trình tích hợp trong PHP, hãy tham khảo mã mẫu trên GitHub.

/**
 * Update a class.
 *
 * **Warning:** This replaces all existing class attributes!
 *
 * @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 updateClass(string $issuerId, string $classSuffix)
{
  // Check if the class exists
  try {
    $updatedClass = $this->service->flightclass->get("{$issuerId}.{$classSuffix}");
  } catch (Google\Service\Exception $ex) {
    if (!empty($ex->getErrors()) && $ex->getErrors()[0]['reason'] == 'classNotFound') {
      // Class does not exist
      print("Class {$issuerId}.{$classSuffix} not found!");
      return "{$issuerId}.{$classSuffix}";
    } else {
      // Something else went wrong...
      print_r($ex);
      return "{$issuerId}.{$classSuffix}";
    }
  }

  // Update the class by adding a homepage
  $updatedClass->setHomepageUri(new Uri([
    'uri' => 'https://developers.google.com/wallet',
    'description' => 'Homepage description'
  ]));

  // Note: reviewStatus must be 'UNDER_REVIEW' or 'DRAFT' for updates
  $updatedClass->setReviewStatus('UNDER_REVIEW');

  $response = $this->service->flightclass->update("{$issuerId}.{$classSuffix}", $updatedClass);

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

  return $response->id;
}

Python

Để bắt đầu quá trình tích hợp bằng Python, hãy tham khảo mã mẫu trên GitHub.

def update_class(self, issuer_id: str, class_suffix: str) -> str:
    """Update a class.

    **Warning:** This replaces all existing class attributes!

    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:
        response = self.client.flightclass().get(resourceId=f'{issuer_id}.{class_suffix}').execute()
    except HttpError as e:
        if e.status_code == 404:
            print(f'Class {issuer_id}.{class_suffix} not found!')
            return f'{issuer_id}.{class_suffix}'
        else:
            # Something else went wrong...
            print(e.error_details)
            return f'{issuer_id}.{class_suffix}'

    # Class exists
    updated_class = response

    # Update the class by adding a homepage
    updated_class['homepageUri'] = {
        'uri': 'https://developers.google.com/wallet',
        'description': 'Homepage description'
    }

    # Note: reviewStatus must be 'UNDER_REVIEW' or 'DRAFT' for updates
    updated_class['reviewStatus'] = 'UNDER_REVIEW'

    response = self.client.flightclass().update(
        resourceId=f'{issuer_id}.{class_suffix}',
        body=updated_class).execute()

    print('Class update response')
    print(response)

    return f'{issuer_id}.{class_suffix}'

C#

Để bắt đầu tích hợp trong C#, hãy tham khảo mã mẫu trên GitHub.

/// <summary>
/// Update a class.
/// <para />
/// <strong>Warning:</strong> This replaces all existing class attributes!
/// </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 UpdateClass(string issuerId, string classSuffix)
{
  // Check if the class exists
  Stream responseStream = service.Flightclass
      .Get($"{issuerId}.{classSuffix}")
      .ExecuteAsStream();

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

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

  // Class exists
  FlightClass updatedClass = JsonConvert.DeserializeObject<FlightClass>(jsonResponse.ToString());

  // Update the class by adding a homepage
  updatedClass.HomepageUri = new Google.Apis.Walletobjects.v1.Data.Uri
  {
    UriValue = "https://developers.google.com/wallet",
    Description = "Homepage description"
  };

  // Note: reviewStatus must be 'UNDER_REVIEW' or 'DRAFT' for updates
  updatedClass.ReviewStatus = "UNDER_REVIEW";

  responseStream = service.Flightclass
      .Update(updatedClass, $"{issuerId}.{classSuffix}")
      .ExecuteAsStream();

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

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

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

Node.js

Để bắt đầu quá trình tích hợp trong Nút, hãy tham khảo mã mẫu trên GitHub.

/**
 * Update a class.
 *
 * **Warning:** This replaces all existing class attributes!
 *
 * @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 updateClass(issuerId, classSuffix) {
  let response;

  // Check if the class exists
  try {
    response = await this.client.flightclass.get({
      resourceId: `${issuerId}.${classSuffix}`
    });
  } catch (err) {
    if (err.response && err.response.status === 404) {
      console.log(`Class ${issuerId}.${classSuffix} not found!`);
      return `${issuerId}.${classSuffix}`;
    } else {
      // Something else went wrong...
      console.log(err);
      return `${issuerId}.${classSuffix}`;
    }
  }

  // Class exists
  let updatedClass = response.data;

  // Update the class by adding a homepage
  updatedClass['homepageUri'] = {
    'uri': 'https://developers.google.com/wallet',
    'description': 'Homepage description'
  };

  // Note: reviewStatus must be 'UNDER_REVIEW' or 'DRAFT' for updates
  updatedClass['reviewStatus'] = 'UNDER_REVIEW';

  response = await this.client.flightclass.update({
    resourceId: `${issuerId}.${classSuffix}`,
    requestBody: updatedClass
  });

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

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

Cập nhật đối tượng thẻ và vé

Việc cập nhật một FlightObject riêng lẻ chỉ ảnh hưởng đến người dùng đã đã cấp phép đối tượng cụ thể đó. Bạn nên thường xuyên cập nhật Thẻ lên máy bay để phản ánh những thay đổi ảnh hưởng đến khách hàng của bạn và tương tác nhiều hơn. Giá trị resourceId sẽ là mã đối tượng (ISSUER_ID.OBJECT_SUFFIX).

# Update
PUT https://walletobjects.googleapis.com/walletobjects/v1/flightobject/{resourceId}

# Patch
PATCH https://walletobjects.googleapis.com/walletobjects/v1/flightobject/{resourceId}

Để biết thêm thông tin, hãy xem Tài liệu tham khảo API.

Java

Để bắt đầu quá trình tích hợp trong Java, hãy tham khảo mã mẫu trên GitHub.

/**
 * Update an object.
 *
 * <p><strong>Warning:</strong> This replaces all existing object attributes!
 *
 * @param issuerId The issuer ID being used for this request.
 * @param objectSuffix Developer-defined unique ID for this pass object.
 * @return The pass object ID: "{issuerId}.{objectSuffix}"
 */
public String updateObject(String issuerId, String objectSuffix) throws IOException {
  FlightObject updatedObject;

  // Check if the object exists
  try {
    updatedObject =
        service.flightobject().get(String.format("%s.%s", issuerId, objectSuffix)).execute();
  } catch (GoogleJsonResponseException ex) {
    if (ex.getStatusCode() == 404) {
      // Object does not exist
      System.out.printf("Object %s.%s not found!%n", issuerId, objectSuffix);
      return String.format("%s.%s", issuerId, objectSuffix);
    } else {
      // Something else went wrong...
      ex.printStackTrace();
      return String.format("%s.%s", issuerId, objectSuffix);
    }
  }

  // Object exists
  // Update the object by adding a link
  Uri newLink =
      new Uri()
          .setUri("https://developers.google.com/wallet")
          .setDescription("New link description");

  if (updatedObject.getLinksModuleData() == null) {
    // LinksModuleData was not set on the original object
    updatedObject.setLinksModuleData(new LinksModuleData().setUris(List.of(newLink)));
  } else {
    updatedObject.getLinksModuleData().getUris().add(newLink);
  }

  FlightObject response =
      service
          .flightobject()
          .update(String.format("%s.%s", issuerId, objectSuffix), updatedObject)
          .execute();

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

  return response.getId();
}

PHP

Để bắt đầu quá trình tích hợp trong PHP, hãy tham khảo mã mẫu trên GitHub.

/**
 * Update an object.
 *
 * **Warning:** This replaces all existing object attributes!
 *
 * @param string $issuerId The issuer ID being used for this request.
 * @param string $objectSuffix Developer-defined unique ID for this pass object.
 *
 * @return string The pass object ID: "{$issuerId}.{$objectSuffix}"
 */
public function updateObject(string $issuerId, string $objectSuffix)
{
  // Check if the object exists
  try {
    $updatedObject = $this->service->flightobject->get("{$issuerId}.{$objectSuffix}");
  } catch (Google\Service\Exception $ex) {
    if (!empty($ex->getErrors()) && $ex->getErrors()[0]['reason'] == 'resourceNotFound') {
      print("Object {$issuerId}.{$objectSuffix} not found!");
      return "{$issuerId}.{$objectSuffix}";
    } else {
      // Something else went wrong...
      print_r($ex);
      return "{$issuerId}.{$objectSuffix}";
    }
  }

  // Update the object by adding a link
  $newLink = new Uri([
    'uri' => 'https://developers.google.com/wallet',
    'description' => 'New link description'
  ]);

  $linksModuleData = $updatedObject->getLinksModuleData();
  if (is_null($linksModuleData)) {
    // LinksModuleData was not set on the original object
    $linksModuleData = new LinksModuleData([
      'uris' => []
    ]);
  }
  $uris = $linksModuleData->getUris();
  array_push(
    $uris,
    $newLink
  );
  $linksModuleData->setUris($uris);

  $updatedObject->setLinksModuleData($linksModuleData);

  $response = $this->service->flightobject->update("{$issuerId}.{$objectSuffix}", $updatedObject);

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

  return $response->id;
}

Python

Để bắt đầu quá trình tích hợp bằng Python, hãy tham khảo mã mẫu trên GitHub.

def update_object(self, issuer_id: str, object_suffix: str) -> str:
    """Update an object.

    **Warning:** This replaces all existing object attributes!

    Args:
        issuer_id (str): The issuer ID being used for this request.
        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:
        response = self.client.flightobject().get(resourceId=f'{issuer_id}.{object_suffix}').execute()
    except HttpError as e:
        if e.status_code == 404:
            print(f'Object {issuer_id}.{object_suffix} not found!')
            return f'{issuer_id}.{object_suffix}'
        else:
            # Something else went wrong...
            print(e.error_details)
            return f'{issuer_id}.{object_suffix}'

    # Object exists
    updated_object = response

    # Update the object by adding a link
    new_link = {
        'uri': 'https://developers.google.com/wallet',
        'description': 'New link description'
    }
    if not updated_object.get('linksModuleData'):
        updated_object['linksModuleData'] = {'uris': []}
    updated_object['linksModuleData']['uris'].append(new_link)

    response = self.client.flightobject().update(
        resourceId=f'{issuer_id}.{object_suffix}',
        body=updated_object).execute()

    print('Object update response')
    print(response)

    return f'{issuer_id}.{object_suffix}'

C#

Để bắt đầu tích hợp trong C#, hãy tham khảo mã mẫu trên GitHub.

/// <summary>
/// Update an object.
/// <para />
/// <strong>Warning:</strong> This replaces all existing class attributes!
/// </summary>
/// <param name="issuerId">The issuer ID being used for this request.</param>
/// <param name="objectSuffix">Developer-defined unique ID for this pass object.</param>
/// <returns>The pass object ID: "{issuerId}.{objectSuffix}"</returns>
public string UpdateObject(string issuerId, string objectSuffix)
{
  // Check if the object exists
  Stream responseStream = service.Flightobject
      .Get($"{issuerId}.{objectSuffix}")
      .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
      Console.WriteLine($"Object {issuerId}.{objectSuffix} not found!");
      return $"{issuerId}.{objectSuffix}";
    }
    else
    {
      // Something else went wrong...
      Console.WriteLine(jsonResponse.ToString());
      return $"{issuerId}.{objectSuffix}";
    }
  }

  // Object exists
  FlightObject updatedObject = JsonConvert.DeserializeObject<FlightObject>(jsonResponse.ToString());

  // Update the object by adding a link
  Google.Apis.Walletobjects.v1.Data.Uri newLink = new Google.Apis.Walletobjects.v1.Data.Uri
  {
    UriValue = "https://developers.google.com/wallet",
    Description = "New link description"
  };

  if (updatedObject.LinksModuleData == null)
  {
    // LinksModuleData was not set on the original object
    updatedObject.LinksModuleData = new LinksModuleData
    {
      Uris = new List<Google.Apis.Walletobjects.v1.Data.Uri>()
    };
  }
  updatedObject.LinksModuleData.Uris.Add(newLink);

  responseStream = service.Flightobject
      .Update(updatedObject, $"{issuerId}.{objectSuffix}")
      .ExecuteAsStream();

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

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

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

Node.js

Để bắt đầu quá trình tích hợp trong Nút, hãy tham khảo mã mẫu trên GitHub.

/**
 * Update an object.
 *
 * **Warning:** This replaces all existing object attributes!
 *
 * @param {string} issuerId The issuer ID being used for this request.
 * @param {string} objectSuffix Developer-defined unique ID for the pass object.
 *
 * @returns {string} The pass object ID: `${issuerId}.${objectSuffix}`
 */
async updateObject(issuerId, objectSuffix) {
  let response;

  // Check if the object exists
  try {
    response = await this.client.flightobject.get({
      resourceId: `${issuerId}.${objectSuffix}`
    });
  } catch (err) {
    if (err.response && err.response.status === 404) {
      console.log(`Object ${issuerId}.${objectSuffix} not found!`);
      return `${issuerId}.${objectSuffix}`;
    } else {
      // Something else went wrong...
      console.log(err);
      return `${issuerId}.${objectSuffix}`;
    }
  }

  // Object exists
  let updatedObject = response.data;

  // Update the object by adding a link
  let newLink = {
    'uri': 'https://developers.google.com/wallet',
    'description': 'New link description'
  }
  if (updatedObject['linksModuleData'] === undefined) {
    updatedObject['linksModuleData'] = {
      'uris': [newLink]
    };
  } else {
    updatedObject['linksModuleData']['uris'].push(newLink);
  }

  response = await this.client.flightobject.update({
    resourceId: `${issuerId}.${objectSuffix}`,
    requestBody: updatedObject
  });

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

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

Nguồn dữ liệu để cập nhật về chuyến bay

Nếu thời gian do class.localScheduledDepartureDateTime cung cấp là trong 24 giờ qua hoặc trong vòng 48 giờ tới, thẻ trạng thái chuyến bay sẽ xuất hiện với người dùng. Khi điều này xảy ra, Google Wallet có thể hiển thị dữ liệu từ Google Chuyến bay hoặc thông tin đã cung cấp trong thẻ và vé trong Google Wallet. Nguồn nào được sử dụng phụ thuộc vào sau:

  • Nếu bạn không cung cấp class.localEstimatedOrActualDepartureDateTime thì Google Chuyến bay được sử dụng. Trong trường hợp này, mọi class.flightStatus bạn đặt sẽ bị bỏ qua.

    Ví dụ: nếu chuyến bay bị hoãn, người dùng sẽ thấy một thẻ trong phần "Nhà riêng" thẻ của Google Wallet ứng dụng hiển thị thời gian khởi hành mới. Một thẻ trì hoãn tương tự cũng hiển thị cho người dùng trong "Thẻ và vé" .

  • Nếu bạn đã cung cấp class.localEstimatedOrActualDepartureDateTime nhưng không class.flightStatus, thời gian đã cho dùng để xác định xem chuyến bay có bị hoãn hay không. Sau đó, trạng thái chuyến bay trên thẻ sẽ hiển thị cho người dùng theo logic sau:
    • Nếu class.localEstimatedOrActualDepartureDateTime lớn hơn class.localScheduledDepartureDateTime, hãy hiển thị cho người dùng thẻ có thông tin chuyến bay bị trì hoãn.
    • Nếu class.localEstimatedOrActualDepartureDateTime không lớn hơn class.localScheduledDepartureDateTime, hãy hiển thị cho người dùng thẻ có thông tin chuyến bay nhưng không kèm theo bất kỳ thông báo trạng thái nào.

Nếu bạn không muốn sử dụng Google Chuyến bay làm nguồn thông tin về chuyến bay, hãy nhớ cung cấp flightStatus, localScheduledDepartureDateTimelocalEstimatedOrActualDepartureDateTime/FlightClass. Chỉ dữ liệu của bạn được dùng trên thẻ. Ngoài ra, nếu bạn sử dụng mã hãng vận chuyển ICAO thay vì mã IATA bằng FlightClass thân mến, Google Chuyến bay không được dùng làm nguồn thông tin chuyến bay.

Khi một số trường nhất định thay đổi, người dùng sẽ nhận được thông báo đẩy về những thay đổi đó. Để biết thêm để biết chi tiết, hãy xem Nhận thông báo cập nhật về chuyến bay.