2

当使用 Java Google Play Developer API(版本 3)并请求购买信息以获取有效的购买令牌时,我收到以下异常。API 调用返回带有以下消息的 400 Bad Request 响应。

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

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

首先,我们已就此联系了 Google 支持。不幸的是,我们在近 2 个月的时间里一直在与 Google 支持来回切换,但他们甚至还没有表示他们正确理解我们的问题是什么。每次他们回复时,他们都会给我们提供与 Google Play Developer API 毫无关系的建议,即使在多次彻底解释问题之后也是如此。这是我 20 年来最令人沮丧的支持体验。谷歌支持显然不会在这里提供任何帮助。

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

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

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

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

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 响应,表明一些值(我不知道哪个)是无效的。实际的反应是:

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

更新:

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

4

1 回答 1

3

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

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

于 2019-08-06T03:46:06.977 回答