集成应用的后端

本部分介绍了使用 Google Cloud Marketplace 集成应用后端的步骤。通过此集成,您可以管理用户的帐号和权益,这表明用户已从 Google Cloud Marketplace 购买了您的产品。如果您选择了基于用量的价格模式,则还会集成后端以向 Google 报告使用情况。

如需了解有关将基本应用与 Google Cloud Marketplace 集成的示例以及示例代码演示,请参阅代码实验室来集成托管式服务

如需代码实验室中使用的示例代码,请参阅 GitHub 代码库

准备工作

  • 设置对 Cloud Commerce Partner Procurement API 的访问权限,如集成应用:设置中所述。
  • 如果您选择了基于用量的价格方案,请验证您的合作伙伴工程师是否已创建您可以据以报告使用情况的服务。 此服务会显示在 Producer Portal 的 Billing Integration(结算集成)部分Service domain(服务网域)字段中。

创建服务帐号

要将您的产品与 Google Cloud 集成,您必须在用于产品的项目中创建服务帐号。您的应用使用此服务帐号与 Google Cloud Marketplace Partner API 交互,并获取有关用户购买的信息。

我们建议您使用 Producer Portal 创建并关联服务帐号

如果您使用的是合作伙伴门户,那么您的合作伙伴工程师会向此服务帐号授予 Pub/Sub 订阅者角色。如需了解创建服务帐号的详细步骤,请参阅创建和管理服务帐号

使用 Producer Portal 集成应用的后端

如需访问从一个位置将应用的后端与 Google Cloud Marketplace 集成在一起的所有信息(例如您的服务帐号和方案级标识符),您可以使用 Producer Portal 的 BILLING INTEGRATION(结算集成)部分。

Producer Portal 的直接链接是:

https://console.cloud.google.com/producer-portal?project=YOUR_PROJECT_ID

要访问 BILLING INTEGRATION(结算集成)部分,请执行以下操作:

  1. 在产品列表中,点击您的产品的名称。

  2. 在您产品的概览页面上,转到技术集成部分,然后点击结算集成

在 Producer Portal 中创建和关联服务帐号

您可以使用 Producer Portal 的 BILLING INTEGRATION(结算集成)部分来创建并关联用于与 Partner API 互动以及获取有关用户购买的信息的服务帐号。

Producer Portal 的直接链接是:

https://console.cloud.google.com/producer-portal?project=YOUR_PROJECT_ID

在以下步骤中,您可以使用现有服务帐号,也可以创建新的服务帐号。如果您要创建新的服务帐号,请在 Service account name(服务帐号名称)字段中指定服务帐号的名称,并在 Service account ID(服务帐号 ID)字段中指定服务帐号 ID ,然后点击 CREATE AND LINK(创建和链接)。

如需关联您的服务帐号,请执行以下操作:

  1. 在产品列表中,点击您的产品的名称。

  2. 在您产品的概览页面上,转到技术集成部分,然后点击结算集成

  3. 如需与 Partner Procurement API 集成,请点击Link a service account to call Procurement API(关联服务帐号以调用 Procurement API)下方的 ADD SERVICE ACCOUNT(添加服务帐号)。您可以在字段中输入现有的服务帐号,也可以创建新的服务帐号。

  4. 要与 Pub/Sub 集成,请在 Link a service account to subscribe to Pub/Sub topic(关联服务帐号以订阅 Pub/Sub 主题)下,点击 ADD SERVICE ACCOUNT(添加服务帐号)。您可以在字段中输入现有的服务帐号,也可以创建新的服务帐号。

  5. 如需与 Service Control API 集成,请点击向服务帐号添加 roles/servicemanagement.serviceController 下的ADD SERVICE ACCOUNT(添加服务帐号)。您可以在字段中输入现有的服务帐号,也可以创建新的服务帐号。

用户帐号任务

概括来讲,您的应用必须应对以下情景:

  1. 用户在 Google Cloud Marketplace 中发出请求或进行更改,例如注册您的产品。

  2. Google Cloud Marketplace 通过 Pub/Sub 向您的应用发送通知,其中的 eventType 中包含有关请求的信息。例如,如果用户更改其权益,则 eventTypeENTITLEMENT_PLAN_CHANGED

    请参阅可用的 eventType 的完整列表。

  3. 为了批准该请求,您的应用会向 Partner Procurement API 发送一个 HTTP POST 请求。

以下部分介绍了用户可以发出的请求类型,以及应用为处理请求而必须执行的操作。

对于本部分中介绍的 API 调用,请使用此端点:

https://cloudcommerceprocurement.googleapis.com/

为新用户创建帐号

用户首次购买您的产品时,Google Cloud Marketplace 会创建一个帐号资源来跟踪用户与您的关系。创建帐号资源后,您将通过系统为您创建的 Pub/Sub 主题获得通知。Pub/Sub 消息格式如下:

{
  "eventId": "...",
  "providerId": "YOUR_PARTNER_ID",
  "account": {
    "id": "USER_ACCOUNT_ID",
    "updateTime": "..."
  }
}

其中 USER_ACCOUNT_ID 是由 Google Cloud Marketplace 创建的帐号 ID,YOUR_PARTNER_ID 是合作伙伴工程师向您授予 Partner Procurement API 的访问权限时分配给您的 ID。

同时,用户会被定向到您的注册页面,并通过该页面在您的系统中创建帐号。如需了解如何创建注册页面,请参阅集成应用的前端

在用户成功注册后,您的应用必须调用 Partner Procurement API 并指明该帐号已获得批准。帐号在创建时处于 ACCOUNT_ACTIVE 状态,但是它们在 approvals 字段中有一个名为 signupPENDING 条目,表示用户尚未注册。要在用户注册后批准该帐号,请使用以下 HTTP POST 请求:

POST v1/providers/YOUR_PARTNER_ID/accounts/USER_ACCOUNT_ID:approve {'approvalName': 'signup'}

要检查关联帐号的状态,请使用以下 HTTP GET 请求:

GET v1/providers/YOUR_PARTNER_ID/accounts/USER_ACCOUNT_ID

响应的格式如下:

{
  "name": "providers/YOUR_PARTNER_ID/accounts/USER_ACCOUNT_ID",
  "provider": "acme-services",
  "state": "ACCOUNT_ACTIVE",
  "approvals": [{
    "name": "signup",
    "state": "APPROVED",
    "updateTime": "...",
  }],
  "updateTime": "...",
  "createTime": "..."
}

有关可用帐号状态的列表,请参阅 providers.accounts API 参考

管理权益

当客户选择您的软件的某个价格方案时,Google 会创建一项权益,表明客户已从 Google Cloud Marketplace 购买了您的产品。本部分将介绍如何使用 Partner Procurement API 为您的客户创建和管理权益。

如需详细了解如何管理许可,请访问参考文档

批准或拒绝权益

当客户选择价格方案时,Google Cloud Marketplace 会创建权益,并将以下 Pub/Sub 消息发送到您的应用:

{
  "eventId": "...",
  "eventType": "ENTITLEMENT_CREATION_REQUESTED",
  "providerId": "YOUR_PARTNER_ID",
  "entitlement": {
    "id": "ENTITLEMENT_ID",
    "updateTime": "...",
    "newOfferDuration": "P2Y3M",   // Contract duration for offer-based entitlements
  },
}

其中 ENTITLEMENT_ID 是由 Google Cloud Marketplace 创建的 ID。 如果优惠指定了时长,则以年和月为单位提供该时长。如果优惠指定了结束日期(而不是持续时间),则表示时长的字段为空。

在您的系统中,更新用户的帐号以反映他们购买了方案。然后,要批准权利,请向 Partner Procurement API 发出 HTTP POST 请求,并发送您要批准的 ENTITLEMENT_ID

POST v1/providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID:approve

如需拒绝权益,请在 HTTP POST 请求中改用 reject 方法:

POST v1/providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID:reject

更改权益方案

根据您设置的价格方案,客户可能可以更改其方案。如果客户选择新的价格方案,您将收到以下格式的 Pub/Sub 消息:

{
  "eventId": "...",
  "eventType": "ENTITLEMENT_PLAN_CHANGE_REQUESTED",
  "providerId": "YOUR_PARTNER_ID",
  "entitlement": {
    "id": "ENTITLEMENT_ID",
    "newPlan": "ultimate",   // New plan
    "updateTime": "...",
    "newOfferDuration": "P2Y3M",   // Contract duration for the new offer, for offer-based entitlements
  },
}

如果优惠指定了时长,则以年和月为单位提供该时长。如果优惠指定了结束日期(而不是持续时间),则表示时长的字段为空。

要批准方案更改,请向 Partner Procurement API 发出以下 HTTP POST 请求:

POST v1/providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID:approvePlanChange

请求正文必须具有正在批准的方案:

{
  "pendingPlanName": PLAN_NAME
}

更改获得批准后,您将在更改生效时收到另一则 Pub/Sub 消息。在消息中,eventType 字段更改为 ENTITLEMENT_PLAN_CHANGED。要检查方案的状态,请向 Partner Procurement API 发出以下 HTTP GET 请求。

GET v1/providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID

响应类似于以下内容,其中 state 字段指示新方案已经生效,还是方案更改仍处待处理:

{
  "name": "providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID",
  "provider": "YOUR_PARTNER_ID",
  "account": "USER_ACCOUNT_ID",
  "product": "example-server",
  "plan": "pro",
  "state": "ENTITLEMENT_PENDING_PLAN_CHANGE",
  "newPendingPlan": "ultimate",
  ...
}

向用户发送状态消息

如果用户选择价格方案与您的后端批准权益之间相差几个小时或更长时间,建议您向用户提供状态消息。在此消息中,指明批准的进度,以及指明预计完成批准的时间(如果可行)。

要提供状态消息,请向 Procurement API 发出以下 HTTP POST 请求:

POST v1/providers/your-partner-id/entitlements/entitlement_id:updateUserMessage

在请求正文中,提供消息的文本,类似于以下示例:

{
  "message": "Approval expected in 2 days"
}

取消权益

如果用户决定取消其权益,您将收到一条 Pub/Sub 通知。与更改方案类似,实际取消可能会在当前结算周期结束时生效。

通知格式如下:

{
  "eventId": "...",
  // If the entitlement is canceled at the end of the month,
  // eventType is ENTITLEMENT_PENDING_CANCELLATION
  "eventType": "ENTITLEMENT_CANCELLED",
  "providerId": "YOUR_PARTNER_ID",
  "entitlement": {
    "id": "ENTITLEMENT_ID",
    "cancellationDate": "...",
    "updateTime": "..."
  },
}

删除权益

如果用户向 Google 支持团队发出直接请求,或者如果他们离开 Google 平台,则他们的权益会被立即取消,并且他们的权益和帐号会在 60 天宽限期后被删除。为了保护用户的隐私,您必须在收到通知后从服务器中删除用户的数据。

在用户权益被取消以及用户帐号被删除后,您会收到类似以下内容的通知:

{
  "eventId": "...",
  "eventType": "ENTITLEMENT_DELETED",
  "providerId": "YOUR_PARTNER_ID",
  "entitlement": {
    "id": "ENTITLEMENT_ID",
    "updateTime": "...",
  },
}
{
  "eventId": "...",
  "eventType": "ACCOUNT_DELETED",
  "providerId": "YOUR_PARTNER_ID",
  "account": {
    "id": "USER_ACCOUNT_ID",
    "updateTime": "...",
  },
}

帐号任务的事件类型列表

以下是您的应用可能在 Pub/Sub 消息中收到的 eventType 列表:

eventType说明
ACCOUNT_CREATION_REQUESTED已弃用
ACCOUNT_ACTIVE表示已创建客户帐号。
ACCOUNT_DELETED表示该客户的帐号已从 Google Cloud 系统中删除。
ENTITLEMENT_CREATION_REQUESTED表示客户选择了您的一个定价方案。
ENTITLEMENT_ACTIVE表示客户选择的方案现在已经生效。
ENTITLEMENT_PLAN_CHANGE_REQUESTED表示客户选择了新方案。
ENTITLEMENT_PLAN_CHANGED表示客户的方案变更已获批准且变更已生效。
ENTITLEMENT_PLAN_CHANGE_CANCELLED表示客户的方案变更已被取消,原因是该方案变更未获批准,或者他们已换回原来的方案。
ENTITLEMENT_PENDING_CANCELLATION表示客户取消了他们的方案,并且取消操作直到结算周期结束为止都处于待处理状态。
ENTITLEMENT_CANCELLATION_REVERTED表示客户的处于待处理状态的取消操作已还原。请注意,取消操作在结束之后不可还原。
ENTITLEMENT_CANCELLED表示客户计划已取消。
ENTITLEMENT_CANCELLING表示客户的方案正在被取消。
ENTITLEMENT_RENEWED表示客户的授权续订了又一个期限。 您无需执行任何操作来完成续订。
ENTITLEMENT_OFFER_ENDED表示面向客户的非公开优惠已结束。如果客户的授权已取消,则会另行触发一个 ENTITLEMENT_CANCELLED 事件。如果客户的授权仍然有效,他们的方案将恢复为无折扣价。
ENTITLEMENT_DELETED表示有关客户方案的信息已从 Google Cloud Marketplace 中删除。

(对于基于用量的价格)向 Google 报告使用情况

如果您为产品选择基于用量的价格,则必须向 Service Control API 报告应用的使用情况。

如需了解 Service Control,请参阅入门指南

如果您可以访问 Producer Portal,我们建议您使用 Producer Portal 在 Producer Portal 中创建服务帐号来与 Service Control 搭配使用。

如果您无权访问 Producer Portal,您的合作伙伴工程师会创建与您的解决方案对应的服务,并为您的服务帐号提供访问权限以报告该服务的使用情况。

创建权益后,您必须使用以下 HTTP GET 请求调用 Partner Procurement API 来检索 usageReportingId

GET v1/providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID

响应包含有关权益的信息,格式如下:

{
  "name": "providers/YOUR_PARTNER_ID/entitlements/ENTITLEMENT_ID",
  "provider": "YOUR_PARTNER_ID",
  "account": "USER_ACCOUNT_ID",
  "product": "example-messaging-service",
  "plan": "pro",
  "usageReportingId": "USAGE_REPORTING_ID",
  "state": "ENTITLEMENT_ACTIVATION_REQUESTED",
  "updateTime": "...",
  "createTime": "..."
}

要报告使用情况,您必须首先进行 services.check API 调用,以检查服务的配置。在响应中,如果 checkErrors[] 对象为空,请进行 services.report API 调用以发送使用情况报告。

使用情况报告是一个 Service Control API Operation。以下举例说明了 example-messaging-service 的使用情况报告,该报告会发送有关客户正在使用的存储的信息:

POST https://servicecontrol.googleapis.com/v1/services/example-messaging-service.gcpmarketplace.example.com:report
{
  "operations": [{
    "operationId": "1234-example-operation-id-4567",
    "operationName": "Hourly Usage Report",
    "consumerId": "USAGE_REPORTING_ID",
    "startTime": "2019-02-06T12:00:00Z",
    "endTime": "2019-02-06T13:00:00Z",
    "metricValueSets": [{
      "metricName": "example-messaging-service/UsageInGiB",
      "metricValues": [{ "int64Value": "150" }]
    }],
    "userLabels": {
      "cloudmarketplace.googleapis.com/resource_name": "order_history_cache",
      "cloudmarketplace.googleapis.com/container_name": "storefront_prod",
      "environment": "prod",
      "region": "us-west2"
    }
  }]
}

其中:

  • operationId 是服务实例生成的唯一字符串。您应该为 checkreport 操作使用相同的 operationId

  • consumerId 与权益中的 usageReportingId 相同。

  • startTimeendTime 表示 report 操作的总时间间隔的开始时间和结束时间。在大多数情况下,report 操作的 startTime 的值应与上一个 report 操作的 endTime 相同。

    如果客户的服务在 report 操作的 startTime 之前停用,则 services.check API 调用会在 checkErrors[] 对象中发送错误,客户将不会被收取相应时段的费用。

  • MetricValueSet 包含一个或多个中间时间间隔以及相应的更新指标值。您可以在选择和提交价格模式时定义服务的指标。

    如果您可以访问 Producer Portal,则可以在 Producer Portal 的技术集成部分查看和引用指标的标识符。

  • userLabels 是用户创建的标签,定义为符合特定语法要求的键值对字符串。这些标签将转发到 Cloud Billing 费用管理工具以进行归因。如需了解推荐的标签规则,请参阅用量标签的最佳做法

如果 services.check API 返回以下一个或多个错误,我们建议您停止向客户提供服务,除非错误得到解决:

  • SERVICE_NOT_ACTIVATED
  • BILLING_DISABLED
  • PROJECT_DELETED

报告用量的最佳做法

在报告用量(例如用户操作或资源利用率)时,请注意以下信息,以确保正确地向客户收费。

在发生时报告用量

用量报告延迟会降低客户的费用管理体验,并且可能不会反映在合作伙伴报告中。服务提供商必须在产生用量的一小时内报告用量。

如果您需要更多时间来报告用量,请与合作伙伴工程师联系。

在取消权益后报告用量

如果您在取消权益后未报告用量,您仍然可以使用时间戳来报告它,该时间戳反映了产生使用的实际时间。时间戳必须在取消权益之前。请在一小时内报告此用量。权益结束后,不得将任何用量报告为新的用量。

在月底报告用量

一小时报告窗口适用于月末截止时间。为确保在当月的帐单上报告用量,请在次日凌晨 1 点(美国和加拿大太平洋时间(UTC-7 或 UTC-8))报告用量。

例如,对于 9 月的帐单,请在 10 月 1 日凌晨 1 点(美国和加拿大太平洋时间(UTC-7 或 UTC-8))之前报告用量。

如果用量在当天晚些时候报告,则可能不包含在当月帐单中。

针对在发生问题时阻止报告用量的客户操作的补救措施

如果您无法报告用量,或者服务或结算长时间停用,我们建议您为客户提供宽限期以恢复服务。我们建议不要超过 30 天。在此宽限期内,请考虑执行以下操作:

  • 将提供的服务降级。例如,将客户切换到免费层级或开始拒接来电。

  • 在服务停用期间继续收集用量日志。我们建议收集用量及费用明细(不超过一小时),以便在启用服务后重放。

启用该服务后,您必须将在该服务停用期间收集的用量报告为实际用量,并报告收集数据的时间。您还必须恢复正常的用量报告。

对于 Kubernetes 应用,如果用量报告在应用启动期间失败,我们建议应用自行停止,以便您的客户立即获得反馈并解决问题。

用量标签的最佳做法

对于基于用量的 SaaS 产品,用量归因于 usageReportingId 字段指定的单个项目。在某些情况下,SaaS 产品可能会在客户组织内广泛共享,并被用于许多客户项目。为了支持更具体的费用归属,我们建议基于使用情况的 SaaS 产品在其使用情况报告操作中包含可选的 userLabels 字段。

如果您的服务原生支持资源标签的概念,我们建议您在用量报告中转发这些标签。标签必须符合语法要求

Google Cloud Marketplace 保留以下标签。您可以使用这些标签来识别在原生服务平台中使用的其他上下文。我们建议您默认在使用情况报告中添加这些标签。

标签键标签值说明
cloudmarketplace.googleapis.com/resource_name USER_SUPPLIED 与使用情况指标关联的资源名称。
cloudmarketplace.googleapis.com/container_name USER_SUPPLIED 资源容器的名称。

标签会转发到 Cloud Billing 费用管理工具,包括费用报告结算导出

使用情况标签示例

在本例中,假设您的组织提供了一款名为 SaaS 存储解决方案的存储产品。

客户 Carl 为其 Google Cloud 项目“e-commerce-website”购买了存储空间产品,用于托管其电子商务网站的 user_profiles_dbproducts_db 数据库:

  • user_profiles_db 包含访问 Carl' 网站的用户的相关信息。
  • products_db 包含与小卡尔在其网站上销售的产品有关的信息。

如果您想要向 Carl 提供其使用量的详细费用明细,则可以使用 userLabels 键值对分别报告每个数据库的使用费用。

例如,如需报告 Carl' products_db 存储使用的费用,您可以发送以下报告,指明 Carl' products_db 存储花费了 100 个单位:

operation = {
  'operationId': '<UUID>',
  'operationName': 'db-total-storage',
  'consumerId': 'project:carl_website',
  'startTime': '<Timestamp>',
  'endTime': '<Timestamp>',
  'metricValues': [{
      'int64Value': 100,
  }],
  'userLabels': {
    'cloudmarketplace.googleapis.com/container_name': 'e-commerce-website',
    'cloudmarketplace.googleapis.com/resource_name': 'products_db'
  }
}

service.services().report(
  serviceName=service_name, body={
    'operations': [operation]
}).execute()

如需查看使用 userLabels 的更详细示例,您可以参阅 SaaS Codelab

(可选)将您的报告与 Virtual Private Cloud (VPC) 集成

如果要在产品服务的运行环境中使用 Virtual Private Cloud (VPC),则必须完成以下步骤,以便将 Google Cloud Marketplace 报告与 VPC 集成。默认情况下,VPC 中的 Compute Engine 虚拟机只能在内部进行通信。您必须配置其中一个虚拟机与外部通信,以便 VPC 中的其他虚拟机能够将其用于报告。

准备工作

设置专用 Google 访问通道

如需使您的产品的 Compute Engine 虚拟机 (VM) 能够与外部通信以进行报告,您必须设置专用 Google 访问通道。如需详细了解如何配置专用 Google 访问通道,请参阅配置专用 Google 访问通道

  1. 为您的服务环境启用专用 Google 访问通道

  2. 配置 DNS 以解析对 private.googleapis.com 的请求。

  3. 为 Google API 创建自定义路由

    • 对于名称,请指定 route-google-apis-services

    • 网络部分,选择您的 VPC。

    • 对于目标 IP 地址范围,指定 199.36.153.8/30

    • 对于 Priority(优先级),请指定 0

    • 对于实例标记,请指定 google-apis-services

    • 对于下一个跃点,选择默认互联网网关

  4. 创建 VPC 防火墙规则以使您的产品与 Google API 通信:

    • 对于名称,请指定 google-apis-services

    • 对于 Description,指定 Allow egress traffic to Google APIs and services

    • 启用防火墙规则日志记录

    • 网络部分,选择您的 VPC。

    • 对于流量方向,选择出站流量

    • 对于对匹配项执行的操作,选择允许

    • 对于名称,请指定 google-apis-services

    • 目标部分,选择 Specified target tags;然后在目标标记部分,指定 google-apis-services

    • 对于目标过滤条件,选择 IPv4 ranges;对于目标 IPv4 范围,指定 199.36.153.8/30

    • 对于协议和端口,选择 Allow all

  5. 在控制台中,选择要用于报告产品使用情况的虚拟机。在网络标记下,添加 google-apis-services,然后点击保存

  6. 网络接口下,找到您的 VPC 的网络接口。

  7. 子网列中,点击子网链接。在子网详情页面中,点击修改,然后将专用 Google 访问通道设置为开启

  8. 点击保存

(可选)将您的报告与 VPC Service Controls 集成

如果您想在产品服务的运行环境中使用 VPC Service Controls,则必须完成以下步骤,以便将 Google Cloud Marketplace 报告与 VPC Service Controls 集成:

  1. 在服务环境中设置您的 VPC Service Controls 的首选实现。如需详细了解如何设置 VPC Service Controls,请参阅使用 VPC Service Controls 设置服务边界

  2. 确保 VPC Service Controls 实现中的 servicecontrol.googleapis.com 服务不受限制。