用例

选择以下一种卡券类别可详细了解其使用方式。


使用 Google Pay API for Passes,您可以通过公交卡、船票、火车票等与用户互动。本指南中介绍的概念可帮助您更好地了解公交卡的功能。

要实现公交卡,请使用 JWT POST 请求方法“瘦”JWT 链接,它们是预先插入类和对象的方法。

TransitClass 和 TransitObject

与 Google Pay API for Passes 中的其他类别一样,公交卡的数据存储在两个数据结构中:TransitClassTransitObject。本指南介绍了如何使用这些数据结构来支持使用您的公交卡。

TransitClass

TransitClass 可定义用于显示与类相关联的任一对象的模板。该模板可定义要在卡券的不同部分中显示的字段,以及由对象共用的徽标和发卡机构名称。

如果两个卡券类型要求在卡券的一个或多个部分中显示不同的数据,您可能会希望创建两个单独的 TransitClasses。例如,一个 TransitClass 用于任何点对点一次性卡券,另一个 TransitClass 用于季票。

TransitObject

TransitObject 可保存表示旅程、公交运营商和乘客的所有数据。例如,TransitObject 包含旅程出发地、旅程目的地、出发时间、公交运营商号码、乘客姓名、座位号等。其中一些值由多个 TransitObjects. 共用

TransitObject 中包含的资源将保存到用户的 Google Pay 应用中。

支持的国家/地区

要了解哪些国家/地区支持 Google Pay 应用,请参阅支持的国家/地区列表。我们建议您根据用户购买车票所在的位置来限制保存到 Google Pay 按钮的显示位置。

用例

以下用例仅适用于公交卡类别:

更新卡券

如果卡券在创建后发生了变化,请使用 REST API 将这些变化传达给用户。如果这些变化仅影响类型,您还可以使用 Google Pay Merchant Center。卡券更新是与用户互动的重要途径。

要更新卡券的显示方式,例如徽标发生更改时,您只需要 updatepatch TransitClass,或者使用 Google Pay Merchant Center。Google 会将此信息传播到与已更新的 TransitClass 关联的所有 TransitObject。在 TransitClass 级别定义的所有字段就属于这种情况。

要更新单个卡券(例如当出发时间发生变化时),您需要 updatepatch 单个 TransitObject。在 TransitObject 级别定义的所有字段就属于这种情况。

有时,您可能不知道何时会发生变化,或何时会触发 updatepatch 请求。在这种情况下,您可以安排定期针对每个类和对象发出 updatepatch 请求。如果您调用 TransitClass list 方法,则可以找到特定发卡机构帐号的所有类。如果您调用 TransitObject list 方法,则可以找到特定类的所有对象。

定义多路段旅程

通常,一次旅程会包含多个路段,而不是直接到达乘客的目的地。 为了完成此旅程,公交运营商可以为旅程的每个路段发放一张卡券,也可以共发放单独一张卡券。Google Pay API for Passes 也参照了这种方式,为每个路段提供一个 TransitObject 或提供一个多路段 TransitObject

针对每个路段使用一个 TransitObject 非常简单。您可以使用 object.ticketLeg 来定义路段。您可以创建和更新每张卡券,就好像它们是独立的一样。但是,您可能需要定义一种将这些卡券归为一组的方法。如需了解详情,请参阅对多个公交卡分组。这是定义多路段旅程的首选方式。

只有在每个路段中都接受这种类型的集合卡券,并且卡券上的信息(例如二维码)对于所有路段都相同时,才应使用多路段 TransitObject 对象。您可以使用 object.ticketLegs[] 列表来定义路段。卡券的卡片部分仅显示第一个路段的出发地和最后一个路段的目的地,而完整行程显示在卡券的详细信息部分。

创建可保存多个卡券的按钮

如果用户购买了多张卡券,并且他们可能会将所有卡券保存到 Google Pay,那么一种很有用的做法是让用户只需点击一下保存到 Google Pay 按钮或链接,即可保存许多对象。您可以在对 JSON Web 令牌 (JWT) 进行签名时定义多个对象或类。

您必须使用以下任一格式创建 JWT:

  • 仅使用预先插入的类和对象。
  • 仅使用完全在 JWT 中定义的对象和类资源。

如需详细了解“卡券”的界面表示,请参阅对多个公交卡分组

对多个公交卡分组

有些功能在用于一组对象(而非单个对象)时会具有不同的工作方式,例如在界面上保存多个卡券时的状态通知或组织方式。

TransitObject 对象仅在共用一个 object.classId, object.ticketLeg.departureDateTime 以及按优先级列出的以下属性之一时,才能分为一组:

  1. object.tripId
  2. object.purchaseDetails.confirmationCode

这是为了对同一旅程不同乘客的卡券分组。

如果您希望对卡券进行分组,我们建议您统一设置这些字段,即使特定 TransitObject 未与任何其他 TransitObject 分为一组也是如此。

接收即将开始的行程的通知

Google Pay 会在旅程开始前一小时向用户发送通知。旅程时间由 object.ticketLeg.departureDateTime 或第一个 object.ticketLegs[].departureDateTime 定义。

若要接收此通知,用户必须启用通知功能。如需检查此功能是否已启用,用户可以转至设置 > 通知,并查看卡券的动态是否已开启。

如果用户启用了在锁定屏幕上显示通知的设置,那么通知会显示在通知区域和锁定屏幕中。

通知采用以下不可修改的格式:

Ticket fot your upcoming trip to object.ticketLeg.destinationName
Expand for more options

如果用户点按通知并解锁设备,Google Pay 应用中会显示他们的卡券。

如果用户有多张卡券,只显示即将可用的卡券。如果他们按照将多个公交卡归为一组保存了分组卡券,则通知仅会显示组内的一个卡券。但是,用户点按这张卡券后,可以左右滑动来查看该组内的其他卡券。

通知会被固定,而不是在用户打开后自动关闭。自动关闭的时间是 object.ticketLeg.departureDateTime 或第一个 object.ticketLegs[].departureDateTime 之后 60 分钟。

处理过期卡券

在 Google Pay 应用的“卡券”标签页下,有一个“过期卡券”部分,其中包含所有已归档或无效的卡券。如果卡券至少满足下面的一个条件,系统就会将其移至“过期卡券”部分:

  • object.ticketLeg.arrivalDateTime 或最后一个 object.ticketLegs[].arrivalDateTime 已过期至少 24 小时。在 object.ticketLeg.arrivalDateTime 或最后一个 object.ticketLegs[].arrivalDateTime 过期后的 24-48 小时之间,卡券会随时移至“过期卡券”。
  • object.validTimeInterval.end.date 过期。在 object.validTimeInterval.end.date 过期后的 24 小时内,卡券会随时移至“过期卡券”。
  • object.state 字段标记为 ExpiredInactiveCompleted

用户保存某张卡券后,可以通过引用其 objectId 链接到该卡券。

可以使用以下链接来引用卡券:

https://pay.google.com/gp/v/object/{<issuerId>}.{<ObjectId>}

您可以使用 Google Pay 应用或网络浏览器查看卡券。

您可以链接到已保存的 Google Pay 卡券标题下方的应用或网站。此功能适用于所有类型的 Google Pay 卡券。

请求权限

使用面向店内商家的支持表单申请访问权限。请注意以下几点:

  • 您必须在表单中共享您的发卡机构 ID。
  • 在“问题类型”下面,选择“技术/API 集成”。
  • 选择链接 Google Pay 卡券下方的应用或网站

对于指定的 Google Pay 卡券,定义 appLinkData 来设置您的应用或网站的 URI。URI 可采用任何格式,但我们建议您使用动态链接

在下面的源代码中可以查看 appLinkData 字段的格式和上下文:

{
  "id": string,
  "classId": string,
  …
  …
  …
  "appLinkData": {
    "androidAppLinkInfo": {
      "appLogoImage": {
        "sourceUri": {
          "uri": string
        }
      },
        "title": {
          "defaultValue": {
            "language": string,
              "value": string
          }
        },
          "description": {
            "defaultValue": {
              "language": string,
                "value": string
            }
          },
            "appTarget": {
              "targetUri": {
                "uri": string,
                  "description": string
              }
            }
    }
  }
  …
  …
  …
}