尝试使用具有有效购买令牌的 Java Google Play Developer API v3 检索应用内购买信息时出现错误请求(无效值)

Bad request (invalid value) when trying to retrieve in-app purchase info using the Java Google Play Developer API v3 with a valid purchase token

当使用 Java Google Play Developer API(版本 3)并请求有效购买令牌的购买信息时,出现以下异常。 API 使用以下消息调用 returns 400 错误请求响应。

{
  "code" : 400,
  "errors" : [ {
    "domain" : "global",
    "message" : "Invalid Value",
    "reason" : "invalid"
  } ],
  "message" : "Invalid Value"
}

很遗憾,没有进一步的信息。我不知道什么值是无效的。

首先,我们已就此联系 Google 支持。不幸的是,我们在 Google 的支持下来回奔波了将近 2 个月,他们甚至还没有表示他们正确理解了我们的问题所在。每次他们回复时,他们给我们的建议实际上与 Google Play Developer API 毫无关系,即使在多次彻底解释问题之后也是如此。这是我 20 年来最令人沮丧的支持体验。 Google 支持显然不会有任何帮助。

其次,我们已成功将我们的 Google Play 帐户与我们的后端链接起来。所有必要的配置都已完成并且可以正常工作。在我们的后端,每当进行 Android 应用内购买时,我们都会收到来自 Google Play 的通知,并且这些通知包含购买令牌。这需要付出一些努力,但我相信这一切现在都是正确的,我们的服务帐户配置正确,所有权限等都很好。

我能够成功调用 API 和 returns 可用的应用内购买产品列表。我得到了我们在 Google Play 中配置的完整且正确的产品列表,供用户在我们的应用程序中购买。为了进行此调用,我们必须提供凭据,我假设服务器在我们进行此调用时正在验证这些凭据。由于我可以成功进行此调用,因此我假设 "Invalid Value" 与我们的凭据无关。我们正在使用为特定服务帐户创建的 Google 生成的 JSON 文件(不使用 p12 文件)。

我搜索了 Whosebug,并在互联网的其余部分寻找有关此问题的信息。我发现许多页面都指出了相同或相似的问题,但使用的是 Google Play Developer API 的旧版本,这显然做了不同的事情。提供的解决方案似乎不适用于 v3 API。我已经搜索了好几个星期,并尝试了我遇到的各种解决方案,但都没有成功。

我已经在我的本地 PC 上 运行 编写了一个测试应用程序,它在我请求应用程序内产品列表时有效,但在请求给定购买令牌的购买详细信息时无效.我尝试过许多不同的购买代币。我读到测试令牌实际上不适用于这个特定的 API,所以我实际上发布了我们的应用程序构建,我可以用它进行真正的实际购买。我已经这样做了,被 Google 收费了,我们的后端已经从这些购买中收到了真实有效的购买令牌。

private static void testGooglePlayDevAPI_Purchase() throws Throwable {
    final String productIdSku = "[the_product_sku]";
    final String purchaseToken = "[a_valid_purchase_token]";
    final String packageName = "[our_app_id]";

    final File GOOGLE_PLAY_DEV_API_CREDENTIALS = 
            new File("path_to_file/google-api-credentials.json");

    final FileInputStream credentials = 
           new FileInputStream(GOOGLE_PLAY_DEV_API_CREDENTIALS);

    final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
    final HttpTransport TRANSPORT = 
            GoogleNetHttpTransport.newTrustedTransport();

    String scope = AndroidPublisherScopes.ANDROIDPUBLISHER;

    GoogleCredential credential = GoogleCredential
            .fromStream(credentials, TRANSPORT, JSON_FACTORY)
            .createScoped(Arrays.asList(scope));

    AndroidPublisher publisher = new AndroidPublisher
            .Builder(TRANSPORT, JSON_FACTORY, credential)
            .setApplicationName(packageName)
            .build();

    try {
        AndroidPublisher.Purchases purchases = publisher.purchases();

        AndroidPublisher.Purchases.Products products = purchases.products();
        AndroidPublisher.Purchases.Products.Get get = 
                products.get(packageName, productIdSku, purchaseToken);
        ProductPurchase product = get.execute();

        System.out.println(String.format(
                "Product purchase data found [developerPayload=%s]", 
                product.getDeveloperPayload()));
    } catch (Throwable t) {
        System.out.println(ExceptionSupport.getExceptionDetails(t));
    }
}

我希望上面的代码给我一个包含有效产品购买数据的响应(一个我可以查询和处理的有效 ProductPurchase 实例)。相反,我在这里得到的只是一个 400 Bad Request 响应,表明 SOME VALUE(我不知道是哪个)无效。实际响应是:

com.google.api.client.googleapis.json.GoogleJsonResponseException: 
400 Bad Request
{
  "code" : 400,
  "errors" : [ {
    "domain" : "global",
    "message" : "Invalid Value",
    "reason" : "invalid"
  } ],
  "message" : "Invalid Value"
}

更新:

我已经在下面提供了我自己对这个问题的回答。

我将在这里提供我自己的答案,因为我们终于找到了解决方法。事实证明 Java Google Play Developer API (v3) 客户端库中的某些内容无法正常工作。我不知道它是什么,但该客户端库的文档很糟糕,Google 没有提供使用它的示例。但是事实证明,我们直接使用HTTPS/JSON/OAuth2API是可以成功的,不需要通过Java客户端。我们已经使用这种方法实现了我们的服务器端解决方案,并将 OAuth2 令牌缓存在内存缓存中直到它们过期。

我仔细检查过,我们在 Google 支持下来回发送电子邮件 2 个月!!!他们一点帮助也没有。我发现这很了不起(以一种糟糕的方式)。