PAYATHON 2026

如何通过 Google Play Developer API 获取自动续订订单 orderId?

支付阿杰

明确结论

可以获取,但不同接口版本对应的字段不同:

  • 当前的 purchases.subscriptionsv2.get 会在响应的 latestOrderId 字段中返回最近一次成功订阅交易的订单号。
  • 旧版 purchases.subscriptions.get 使用的是 orderId 字段。
  • Google Play 不提供单独的通用 transactionId。后端一般用 purchaseToken 稳定标识订阅记录,orderId 则用于对账和定位某次扣款。

自动续订每次成功扣款都会生成新的订单号,所以不能把 orderId 作为整个订阅生命周期的唯一主键。

推荐使用 Subscriptions V2 API

客户端完成购买后,需要将以下信息提交给自己的后端:

  • packageName
  • productId
  • purchaseToken

后端通过服务账号或其他合法的 OAuth 2.0 凭据调用:

GET https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptionsv2/tokens/{purchaseToken}
Authorization: Bearer {accessToken}

请求使用以下 OAuth scope:

https://www.googleapis.com/auth/androidpublisher

示例:

curl \
  -H "Authorization: Bearer ACCESS_TOKEN" \
  "https://androidpublisher.googleapis.com/androidpublisher/v3/applications/com.example.app/purchases/subscriptionsv2/tokens/PURCHASE_TOKEN"

响应中主要关注这些字段:

{
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "latestOrderId": "GPA.1234-5678-9012-34567..1",
  "startTime": "2026-09-01T08:00:00Z",
  "lineItems": [
    {
      "productId": "premium_monthly",
      "expiryTime": "2026-11-01T08:00:00Z",
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ]
}

各字段的含义如下:

  • latestOrderId:最近一次成功交易的 Google Play 订单号。
  • subscriptionState:当前订阅状态。
  • lineItems[].expiryTime:对应订阅项目的到期时间。
  • lineItems[].autoRenewingPlan.autoRenewEnabled:是否仍启用自动续订。

具体字段是否出现,还要看订阅类型和当前状态。生产代码需要允许可选字段缺失。

Java 后端示例

以下示例使用 Google API Java Client:

AndroidPublisher androidPublisher = new AndroidPublisher.Builder(
        httpTransport,
        jsonFactory,
        credential
).setApplicationName("subscription-backend").build();

SubscriptionPurchaseV2 purchase =
        androidPublisher.purchases()
                .subscriptionsv2()
                .get(packageName, purchaseToken)
                .execute();

String latestOrderId = purchase.getLatestOrderId();
String subscriptionState = purchase.getSubscriptionState();

if (latestOrderId != null) {
    System.out.println("Latest order ID: " + latestOrderId);
}

实际使用时,还要检查 lineItems、expiryTime 和自动续订计划,不能只根据 latestOrderId 判断订阅是否有效。

如果仍在使用旧版接口

旧版接口的请求形式如下:

GET https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{purchaseToken}

响应对象 SubscriptionPurchase 中可能包含:

{
  "orderId": "GPA.1234-5678-9012-34567..1",
  "startTimeMillis": "1788249600000",
  "expiryTimeMillis": "1790928000000",
  "autoRenewing": true
}

Java 示例:

SubscriptionPurchase purchase =
        androidPublisher.purchases()
                .subscriptions()
                .get(packageName, subscriptionId, purchaseToken)
                .execute();

String orderId = purchase.getOrderId();

新接入或正在改造的系统应优先使用 purchases.subscriptionsv2.get。这个接口可以更完整地表达订阅状态、多商品和新的订阅模型。

自动续订订单号的变化规则

Google Play 的订阅订单号通常采用类似下面的格式:

GPA.1234-5678-9012-34567
GPA.1234-5678-9012-34567..0
GPA.1234-5678-9012-34567..1

续订后缀通常会随续订次数变化,但后端不应通过拆分字符串来推算交易次数,也不能假设所有订单号始终使用完全相同的格式。保存订单号时,应将其视为不透明字符串。

如果后端需要完整记录每一笔续订流水,只反复读取 latestOrderId 并不可靠,因为它只表示查询时最近关联的订单。更稳妥的处理流程是:

  1. 保存初始 purchaseToken。
  2. 接入 Real-time Developer Notifications。
  3. 收到订阅事件后,重新调用 Developer API。
  4. 保存当时返回的 latestOrderId、状态、到期时间和原始通知标识。
  5. 为 orderId 设置唯一约束,避免重复入账。

注意事项

  • purchaseToken 用于调用 Developer API,应由客户端安全地传给后端,不能用 orderId 代替。
  • orderId 适合用于对账、退款定位和关联某次扣款。内部订阅主键应使用自己的用户 ID、订阅记录 ID,并关联 purchaseToken。
  • 升级、降级或重新订阅时,Google Play 可能返回新的 token。此时可以通过 linkedPurchaseToken 关联前后的订阅关系。
  • 不要只相信客户端上传的订单号。后端应调用 Google Play Developer API,验证最终的订阅状态和订单信息。
  • 关闭自动续订不代表订阅立即失效。用户通常仍可使用到 expiryTime,因此需要同时检查订阅状态和到期时间。

备注:内容仅供参考。