Google Play Developer API 包含额外的功能,可报告来自结算和链接计划的交易。本指南介绍了如何报告这些结算计划产生的交易。
从后端处理外部交易时,可能需要用到一些组件。如需构建这些组件,您需要按照配置 Google Play Developer API 中的说明设置后端集成。如需构建并非特定于结算和链接计划的开发者后端功能,请参阅 Google Play 结算系统。
术语词汇表
本指南使用的惯用术语:
- 结算和链接计划:有助于在 Google Play 之外购买数字内容或下载应用的计划。这包括备选结算系统和外部内容计划。
- 外部交易 API:用于报告符合条件的结算和链接计划交易的 API。
- 外部交易:根据备选结算系统和外部内容计划的定义,在应用之外发生的符合条件的交易。
- 外部交易令牌:通过 Play 结算库向您提供的令牌,供您在用户完成外部交易时使用。此令牌用于通知 Google Play 有一笔外部交易已成功完成。
- 外部交易 ID:您生成的用于标识外部交易的唯一标识符。
向 Google Play 报告新的外部交易
集成 externaltransactions API,即可报告在支持的国家/地区发生在 Google Play 结算系统之外的交易,包括免费试用购买交易和应用安装产生的 0 美元交易。您仅可在备选结算系统、外部优惠或外部支付指南允许的范围内,针对符合条件的用户所在国家/地区启动和报告结算和链接计划的交易;否则,API 调用将被拒绝。此限制适用于所有交易,包括新的购买交易、续订、充值、升级、降级和应用下载。
外部交易报告
当通过结算和链接计划完成外部交易的支付授权后,您应调用 externaltransactions API 报告相关交易。这适用于所有交易,包括初始扣款、续订、退款等。如需了解报告要求,请参阅相应结算和链接计划的准则。
每笔外部交易均需通过外部交易 ID 进行报告。对于周期性购买交易(例如自动续订订阅),您需要将其首笔交易对应的外部交易 ID 作为参数,提交至所有后续交易(包括退款)的报告中,以此记录该购买交易相关的一系列交易。如果商品发生变化(例如升级或降级),或周期性交易已取消、过期后用户再次购买同一商品,则需要为该购买交易分配新的外部交易 ID。您不得在此外部交易 ID 中包含任何个人身份信息、专有信息或机密信息。
报告初始交易
每当结算和链接计划中发生新的购买交易或应用下载成功事件时,您都必须调用 externaltransactions API。
对于应用下载、一次性购买交易和周期性购买交易(例如订阅)的首笔交易,请求正文中必须包含应用通过 Google Play 结算库收到的 externalTransactionToken。这称为初始交易。完成初始交易后,您可以通过提供新的唯一 externalTransactionId 来报告后续交易(例如续订)。如需了解详情,请参阅报告购买交易的后续交易。
示例:
- 开发者在其应用中配置并启用备选结算系统。
- 用户 1 位于支持该功能的韩国,试图以每月 12,634.10 韩元的价格购买
product1,并享有 1 个月免费试用权益。 - 应用将加载
product1的ProductDetails以及用户选择的优惠,启动购买流程。 - 用户 1 选择开发者提供的备选结算系统。
UserChoiceBillingListener收到my_token作为externalTransactionToken的值。- 然后,开发者将相关信息(
externalTransactionToken值和所购商品)发送到其后端,接着在备选结算系统中启动product1的购买流程。此交易在开发者端获配一个唯一的交易 ID (123-456-789),用于向 Google Play 报告。即使用户正在免费试用商品,开发者也必须提供交易 ID。 - 在备选结算系统中发生购买交易后,开发者会使用以下请求向 Google Play 报告该交易。由于用户享有 1 个月免费权益,此交易初始报告为 0 美元交易。
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"
}
}
报告初始交易时,请注意以下事项:
subscriptionType可以是RECURRING(对于自动续订型订阅),也可以是PREPAID(对于预付费订阅)。OtherRecurringProduct必须用于表示需要多次支付或延迟支付的一次性购买交易。例如,预订可能先产生一笔 0 美元交易,待预订完成后,再产生一笔相应 SKU 价格的交易。如需详细了解如何报告后续交易,请参阅报告购买交易的后续交易。- 在报告初始外部优惠交易时,您必须提供
ExternalOfferDetails。后续交易不需要这样做。
如果与您交易的用户位于印度,且税费取决于其所在行政区(如邦或直辖区),请在 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"
}
}
外部优惠
如果所报告的交易属于外部优惠计划,对于一次性交易或周期性交易系列的首笔交易,必须设置 externalOfferDetails 字段:
- 报告应用下载交易时,请将
linkType设置为LINK_TO_APP_DOWNLOAD,并为installedAppPackage和installedAppCategory提供相应的值。如需了解详情,请参阅报告应用下载。 - 报告数字内容优惠交易时,请将
linkType设置为LINK_TO_DIGITAL_CONTENT_OFFER。 - 通过外部优惠计划安装外部应用后,您必须报告在该外部应用中进行的交易。报告这些交易时,请将这些交易与原始应用下载事件相关联:
- 提供应用下载事件对应的
externalTransactionToken。 - 在
externalOfferDetails字段中,将appDownloadEventExternalTransactionId设置为应用下载事件的externalTransactionId。externalOfferDetails中的其他字段不是必需字段。
- 提供应用下载事件对应的
通过外部优惠下载的外部应用中交易的请求示例:
POST /androidpublisher/v3/applications/com.myapp.android/externalTransactions?externalTransactionId=ABC-DEF-GHI
Body
{
"originalPreTaxAmount" : {
"priceMicros": "100000",
"currency": "EUR"
},
"originalTaxAmount" : {
"priceMicros": "10000",
"currency": "EUR"
},
"transactionTime" : "2025-11-22T12:45:00Z",
"oneTimeTransaction" : {
"externalTransactionToken": my_external_transaction_token_for_link_to_download_event"
},
"userTaxAddress" : {
"regionCode": "DE"
},
"externalOfferDetails" : {
"appDownloadEventExternalTransactionId": "my_external_transaction_id_for_link_to_download_event"
}
}
如需了解不同交易类型的 Play 服务费更新详情,请参阅面向欧洲经济区 (EEA) 用户的外部优惠计划的变更。
报告购买交易的后续交易
在某些情况下,同一外部购买交易有多笔相关联的用户支付,例如续订或预付费方案充值。
您可以在 Externaltransactions 中使用同一 API 报告这些后续交易。如报告新购买交易中所述,后续交易不需要 externalTransactionToken。不过,系统会为每笔续订或充值交易发送新的唯一 externalTransactionId 作为查询参数,并将初始交易的 ID 包含在 initialExternalTransactionId 字段中。
接着之前的示例:
- 用户 1 的首次续订发生在备选结算系统中。初始交易 ID 为 123-456-789。
- 开发者在报告该周期性交易时,需要在 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。这与报告新购买交易类似。
报告应用下载
如需报告外部优惠结算系统中的应用安装,必须调用 Externaltransactions.createexternaltransaction,并发送提供给应用的 externalTransactionToken。此类交易需要报告为零费用一次性交易,操作流程与报告初始交易类似。请务必在请求正文中添加 ExternalOfferDetails。
请求示例:
POST /androidpublisher/v3/applications/com.myapp.android/externalTransactions?externalTransactionId=123-456-789
Body
{
"originalPreTaxAmount" : {
"priceMicros": "0",
"currency": "USD"
},
"originalTaxAmount" : {
"priceMicros": "0",
"currency": "USD"
},
"transactionTime" : "2025-12-22T12:45:00Z",
"oneTimeTransaction" : {
"externalTransactionToken": "my_token",
},
"userTaxAddress" : {
"regionCode": "US"
}
"externalOfferDetails" : {
"linkType" : "LINK_TO_APP_DOWNLOAD",
"installedAppPackage" : "my.external.app",
"installedAppCategory" : "APP"
}
}
从备选结算系统交易手动报告方式迁移
如需迁移您在未启用自动报告功能的情况下提供备选结算系统期间开始的有效订阅,请使用 migratedTransactionProgram 字段(而不是指定 initialExternalTransactionId 或 externalTransactionToken)创建一笔新的零费用交易。将每项有效订阅的 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 媒体体验计划)的开发者在报告外部交易时必须提供 transaction_program_code。如果您是符合条件的开发者,请与您的业务发展经理联系,详细了解如何设置此字段。
向 Google Play 报告购买交易退款
与 externaltransactions API 集成后,您可报告在 Google Play 结算系统以外向用户退款的交易。为了让 Play 正确识别哪一笔交易已退款,您应将之前所报告交易的相应 externalTransactionId 添加为网址参数的一部分。
报告订阅购买交易的退款时,请引用被退款订阅的具体周期性交易的 externalTransactionId。
示例: 假设某项订阅包含以下交易:
外部交易 ID 为 ABC.1234-5678-9012-34567 的初始交易
外部交易 ID 为 ABC.1234-5678-9012-34567..0 的首笔周期性交易
外部交易 ID 为 ABC.1234-5678-9012-34567..1的第二笔周期性交易
如需报告该订阅所有交易的退款,您需要发出三个单独的退款请求:一个针对初始交易,两个针对后续交易。
此方法既接受全额退款(金额与用户在原始外部交易中支付的金额相同),又接受部分退款(金额小于用户在原始外部交易中支付的金额)。对于部分退款,您需要指定退还的税前金额。
API 配额
与 Google Play Developer API 的其他端点相同,Externaltransactions API 的所有调用均受 API 配额限制。
此外,Externaltransactions API 对 Externaltransactions.createexternaltransaction 或 Externaltransactions.refundexternaltransaction 的调用设有每分钟 1,200 次查询 (QPM) 的限制。对 Externaltransactions.getexternaltransaction 的调用不会计入此 1,200 QPM 的限额。