在 Google Play 结算系统之外进行营利的后端集成指南

Google Play Developer API 现在包含其他功能,可用于报告来自替代结算系统外部优惠系统的交易。本指南介绍了如何报告替代结算系统或外部优惠交易。

处理来自后端的 In-app 购买可能需要一些组件。要构建这些组件,您需要按照配置 Google Play Developer API中的说明设置后端集成。对于不特定于替代结算系统或外部优惠 API 的所有开发者后端功能,Google Play 结算系统文档中的说明均适用。

向 Google Play 报告新的外部交易

Externaltransactions API 集成,以报告在受支持的国家/地区发生的 Google Play 结算系统之外的交易,包括免费试用购买导致的 $0 交易。替代结算系统或外部优惠系统的交易只能在替代结算系统外部优惠计划允许的合格用户国家/地区启动和报告,否则 API 调用将被拒绝。这适用于所有交易,包括新购买、续订、充值、升级、降级等。

外部交易报告

通过替代结算系统或外部优惠系统授权付款后,您应调用 Externaltransactions API 来报告外部交易。这适用于所有交易,包括初始扣费、续订、退款等。所有交易都必须在交易发生后的 24 小时内报告。

每笔外部交易都通过一个外部交易 ID 进行报告。对于周期性购买(例如自动续订订阅),您需要将与周期性购买中第一笔交易关联的外部交易 ID 作为后续任何交易(包括退款)的参数发送。这将记录该购买的一系列交易。当产品发生变化(例如升级或降级),或者周期性交易被取消或过期且稍后再次购买相同产品时,您将为购买发送新的外部交易 ID。您不得将任何个人身份信息、专有或机密信息作为此外部交易 ID 的一部分。

报告新购买

每次在替代结算系统或外部优惠系统中成功进行新购买时,都需要调用 Externaltransactions API。对于这些新购买,您需要提供一个唯一externalTransactionId,作为查询参数,它与您后端中的购买相关联。此 externalTransactionId 不能在同一应用的软件包 ID 中重复使用。

通过 UserChoiceBillingListenerAlternativeBillingOnlyReportingDetailsListenerExternalOfferReportingDetailsListener 回调在应用中收到的 externalTransactionToken 也需要作为一次性购买和周期性购买(例如订阅)中的首次交易的请求正文的一部分。在任何一种情况下,这都被称为初始交易。初始交易后,externalTransactionToken 不再需要,您可以通过提供新的唯一 externalTransactionId 来报告后续交易(例如订阅续订)。有关如何报告后续交易的更多详细信息,请参阅报告购买的后续交易

示例:

  1. 开发者在其应用中配置并启用替代结算系统。
  2. 用户 1 位于韩国(受支持的国家/地区),正尝试购买 product1,价格为 12634.10 KRW/月,含一个月的免费试用优惠。
  3. 应用使用 product1ProductDetails 和用户选择的优惠启动购买流程。
  4. 用户 1 选择开发者的替代结算系统。
  5. UserChoiceBillingListener 接收到 my_token 作为 externalTransactionToken 的值。
  6. 开发者随后将相关信息发送到他们的后端(externalTransactionToken 值和正在购买的产品)。然后,他们在替代结算系统中启动 product1 的购买流程。此交易在开发者端分配了一个唯一的交易 ID,用于将其报告给 Google Play:123-456-789。即使用户获得了免费试用,交易 ID 也是必需的。
  7. 在替代结算系统中发生购买交易后,开发者通过以下请求向 Google Play 报告该交易。由于用户获得了免费一个月,初始报告为零美元交易。
POST /androidpublisher/v3/applications/com.myapp.android/externalTransactions?externalTransactionId=123-456-789

Body
 {
"originalPreTaxAmount" : {
   "priceMicros": "0",
   "currency": "KRW"
 },
 "originalTaxAmount" : {
   "priceMicros": "0",
   "currency": "KRW"
 },
"transactionTime" : "2022-02-22T12:45:00Z",
 "recurringTransaction" : {
   "externalTransactionToken": "my_token",
   "externalSubscription" {
     "subscriptionType": "RECURRING"
   }
 },
 "userTaxAddress" : {
   "regionCode": "KR"
 }
}

如果与居住在印度且税收因其行政区域(如邦或省)而异的用户进行交易,请务必在 userTaxAddress 下包含该区域。请参阅 API 参考指南中适用的行政区域的预定义字符串列表。

POST /androidpublisher/v3/applications/com.myapp.android/externalTransactions?externalTransactionId=123-456-789

Body
 {
"originalPreTaxAmount" : {
   "priceMicros": "0",
   "currency": "INR"
 },
 "originalTaxAmount" : {
   "priceMicros": "0",
   "currency": "INR"
 },
"transactionTime" : "2023-11-01T12:45:00Z",
 "recurringTransaction" : {
   "externalTransactionToken": "my_token",
   "externalSubscription" {
     "subscriptionType": "RECURRING"
   }
 },
 "userTaxAddress" : {
   # Tax varies in India based on state, so include that information in
   # administrativeArea
   "regionCode": "IN"
   "administrativeArea": "KERALA"
 }
}

报告购买的后续交易

在某些情况下,同一外部购买与多个用户付款相关联(例如,订阅续订或预付计划充值)。您可以使用 Externaltransactions 中相同的 API 来报告这些后续交易。如报告新购买中所述,后续交易不需要 externalTransactionToken。相反,为每次续订或充值交易发送新的唯一 externalTransactionId 作为查询参数,并在 initialExternalTransactionId 字段中包含初始交易的 ID。

沿用之前的示例

  1. 用户 1 的第一次续订发生在替代结算系统上。初始交易 ID 为 123-456-789
  2. 开发者在 URL 查询参数中报告交易周期性作为此新交易的外部交易 ID,同时在 initialExternalTransactionId 字段中引用初始交易的外部交易 ID。

示例请求:

POST /androidpublisher/v3/applications/com.myapp.android/externalTransactions?externalTransactionId=abc-def-ghi

Body
 {
"originalPreTaxAmount" : {
   "priceMicros": "12634000000",
   "currency": "KRW"
 },
 "originalTaxAmount" : {
   "priceMicros": "1263000000",
   "currency": "KRW"
 },
"transactionTime" : "2022-02-22T12:45:00Z",
 "recurringTransaction" : {
   "initialExternalTransactionId": "123-456-789",

   "externalSubscription" {
     "subscriptionType": "RECURRING"
   }
 },
 "userTaxAddress" : {
   "regionCode": "KR"
 }
}

报告升级或降级

要报告用户在替代结算系统拥有订阅时的升级或降级,您可以使用 Externaltransactions API 中的相同端点和功能,发送提供给应用用于升级或降级交易的 externalTransactionToken。这与报告新购买类似。

从替代结算交易的手动报告迁移

要迁移在您提供未自动化报告的替代结算系统时启动的有效订阅,请使用 migratedTransactionProgram 字段创建新的零费用交易,而不是指定 initialExternalTransactionIdexternalTransactionToken。将 transactionTime 设置为用户最初为每个有效订阅注册的时间。之后,通过 API 正常报告这些订阅的每笔后续交易,提供用于创建续订交易的上述 initialExternalTransactionId。订阅迁移后,如果通过本页描述的自动化方法进行报告,您将不再需要手动报告该订阅的后续交易。

在迁移订阅时,请注意配额限制,以确保迁移不会导致配额耗尽。如果需要迁移大量订阅,请将它们分散到多天进行,或申请增加配额

migratedTransactionProgram 字段只能在从手动报告迁移时使用。手动报告不再受支持时,该字段将被弃用。

示例请求:

# Note that the externalTransactionId specified here will used to report subsequent
# transactions.

POST /androidpublisher/v3/applications/com.myapp.android/externalTransactions?externalTransactionId=abc-def-ghi

Body
 {
 # Be sure to set the price to 0 for this transaction since it does not reflect
 # an actual subscription renewal.
 "originalPreTaxAmount" : {
   "priceMicros": "0",
   "currency": "KRW"
 },
 "originalTaxAmount" : {
   "priceMicros": "0",
   "currency": "KRW"
 },

 # The transaction time should be set to when the user signed up for this
 # subscription.
 "transactionTime" : "2022-02-22T12:45:00Z",
  "recurringTransaction" : {
    "migratedTransactionProgram": "USER_CHOICE_BILLING",

    "externalSubscription" {
      "subscriptionType": "RECURRING"
    }
  },
 "userTaxAddress" : {
   "regionCode": "KR"
 }
}

报告 Play 合作伙伴计划

参与合作伙伴计划(例如Play Media Experience Program)的开发者在报告外部交易时必须提供transaction_program_code。如果您是符合条件的开发者,请联系您的业务发展经理,了解如何设置此字段的更多信息。

向 Google Play 报告购买退款

Externaltransactions API 集成,以报告退款给用户的 Google Play 结算系统之外的交易。为了让 Play 正确识别哪些交易已退款,您应将之前报告的交易的相应 externalTransactionId 作为 URL 参数的一部分包含在内。

报告订阅购买的退款时,请引用正在退款的订阅特定周期性交易的 externalTransactionId

示例:假设某个订阅有以下交易

  • 初始交易,外部交易 ID 为 ABC.1234-5678-9012-34567
  • 第一次周期性交易,外部交易 ID 为 ABC.1234-5678-9012-34567..0
  • 第二次周期性交易,外部交易 ID 为 ABC.1234-5678-9012-34567..1

要报告该订阅所有交易的退款,您需要进行三次单独的退款请求:一次是针对初始交易,两次是针对后续交易。

此方法接受全额退款(金额与用户在原始外部交易中支付的金额相同)和部分退款(金额小于用户在原始外部交易中支付的金额)。对于部分退款,您需要指定已退还的税前金额。

API 配额

Externaltransactions API 与 Google Play Developer API 中的任何其他端点一样,都受到每日 API 配额的限制。

此外,Externaltransactions API 对 Externaltransactions.createexternaltransactionExternaltransactions.refundexternaltransaction 的调用设置了每分钟 1200 次查询 (QPM) 的限制。Externaltransactions.getexternaltransaction 的调用不计入此 1200 QPM 限制。