我正在尝试建立一个网络服务来查询Google Play购买的商品。我们为客户存储订单信息,该服务将调用Google Play API来查询订阅详细信息。

每次我尝试查询购买商品时,都会出现以下错误:

HTTP/1.1 400 Bad Request
{
   "error":{
      "errors":[
         {
            "domain":"global",
            "reason":"invalid",
            "message":"Invalid Value"
         }
      ],
      "code":400,
      "message":"Invalid Value"
   }
}

这是我尝试过的:
  • https://console.developers.google.com中创建了一个项目,并启用了“Google Play Android Developer API”
  • 为类型Web应用程序
  • 创建了oAuth 2.0 client_id和client_secret
  • 以帐户所有者身份登录,我生成了refresh_token
  • https://play.google.com/apps/publish中,我转到设置-> API访问并将项目链接到我的应用程序

  • 在代码方面,我使用refresh_token获取了access_token:
    String refreshToken = "1/ljll6d9ME3Uc13jMrBweqXugV4g4timYcXXXXXXXXX";
    HttpPost request = new HttpPost("https://accounts.google.com/o/oauth2/token");
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("client_id", client_id));
    params.add(new BasicNameValuePair("client_secret", client_secret));
    params.add(new BasicNameValuePair("refresh_token", refreshToken));
    params.add(new BasicNameValuePair("grant_type", "refresh_token"));
    request.setEntity(new UrlEncodedFormEntity(params));
    
    HttpResponse response = httpClient.execute(request);
    HttpEntity entity = response.getEntity();
    String body = EntityUtils.toString(entity);
    JSONObject json = new JSONObject(body);
    String accessToken = json.getString("access_token");
    

    之所以可以使用access_token是因为我可以用它调用此API并获取响应:
    String url = String.format("https://www.googleapis.com/androidpublisher/v2/applications/%s/inappproducts/%s", packageName, productId);
    HttpClient client = new DefaultHttpClient();
    HttpGet get = new HttpGet(url);
    get.setHeader("Authorization", "Bearer " + accessToken);
    HttpResponse response = client.execute(get);
    // parse response etc...
    

    返回:
    {
        "packageName":"com.my.app",
        "sku":"com.my.app.premium",
        "status":"active",
        "purchaseType":"subscription",
        "defaultPrice":{
        //...
    }
    },
        "listings":{
        "en-US":{
        "title":"My App Premium",
        "description":"My App"
    }
    },
        "defaultLanguage":"en-US",
        "subscriptionPeriod":"P1Y"
    }
    

    现在,我想获取有关购买的信息。我有这样的购买信息:
    {
    "orderId":"GPA.1111-1111-1111-11111",
    "packageName":"com.my.app",
    "productId":"com.my.app.premium",
    "purchaseTime":1452801843877,
    "purchaseState":0,
    "developerPayload":"XXXXXXXd9261023a407ae5bb6ab8XXXXXXX",
    "purchaseToken":"xxxxxxxxxxxxxx.YY-J123o12-xxxxxxxxxxxxxxxmYRk2itBkNdlXhyLMjXsxxxxxxxxxxxxLfBxabaAjKbeBC0PVhHnHd1DDbFkgZtbQxxk5pDIAH3xBHu8HrcWfRgewAYnFeW9xxxxxxxxxxxxxC5TDjcBL8fhf",
    "autoRenewing":true
    }
    
    String url = String.format("https://www.googleapis.com/androidpublisher/v2/applications/%s/purchases/products/%s/tokens/%s",packageName, productId, purchaseToken);
    HttpClient client = new DefaultHttpClient();
    HttpGet get = new HttpGet(url);
    get.setHeader("Authorization", "Bearer " + accessToken);
    HttpResponse response = client.execute(get);
    // parse response etc...
    

    由于packageName/productId和access_token似乎适用于第一次调用,并且purchaseToken就在订单信息之外。产生无效值错误的原因是什么?

    任何帮助表示赞赏-不知道还有什么尝试。谢谢!

    更新:
    我经历并验证了所有软件包名称和帐户设置
    真正的问题似乎是我要提供的服务。我将其切换为:
    https://www.googleapis.com/androidpublisher/v2/applications/packageName/purchases/subscriptions/subscriptionId/tokens/purchaseToken

    我还交换了使用Google Client API的方法,因为它看起来比手动创建请求要干净得多。

    感谢您的帮助和答复

    最佳答案



    回答:表示查询无效。例如,缺少父ID,或者所请求的维度或指标组合无效。

    推荐的操作:您需要对API查询进行更改以使其起作用。

    资源链接: Standard Error Responses

    你的问题:

    您的代码运行正常,并返回了相关的json文件作为输出。但是过了一段时间,it is not working when you want to get information about purchase。它给出错误消息“HTTP/1.1 400 Bad Request”

    根本原因:

    对于刷新 token ,响应始终包括新的访问 token 。响应如下所示:

    {
      "access_token":"1/fFBGRNJru1FQd44AzqT3ZgXXXXXX",
      "expires_in":3920,
      "token_type":"Bearer",
    }
    

    因此,访问 token 具有到期时间。到期后,访问 token 将不起作用。

    还有另一个限制。对将要发出的刷新 token 的数量有限制;每个客户/用户组合一个限制,所有客户中每个用户一个限制。

    因此,就您的情况而言(),您已经超出了创建刷新 token 的限制。

    解:

    因此,您首先需要撤销 token 。然后将刷新 token 保存在长期存储中,并在它们仍然有效的情况下继续使用它们。

    使用刷新 token 时,需要将http发布请求https://accounts.google.com/o/oauth2/token更改为https://www.googleapis.com/oauth2/v4/token
    因此,您的代码将如下所示:
    String refreshToken = "1/ljll6d9ME3Uc13jMrBweqXugV4g4timYcXXXXXXXXX";
    HttpPost request = new HttpPost("https://www.googleapis.com/oauth2/v4/token");
    List<NameValuePair> params = new ArrayList<NameValuePair>();
    ...............
    ...............
    

    撤销程序:

    撤销有2种方法。
  • 用户可以通过访问Account Settings
  • 撤消访问权限
  • 应用程序也有可能以编程方式撤消对它的访问。

  • 要以编程方式撤消 token ,您的应用程序会请求https://accounts.google.com/o/oauth2/revoke并将 token 作为参数包括在内:
    curl https://accounts.google.com/o/oauth2/revoke?token={token}
    
    token可以是访问 token 或刷新 token 。如果 token 是访问 token ,并且具有相应的刷新 token ,则刷新 token 也将被吊销。



    资源链接:
  • Offline access, Using refresh token and Revoke a token
  • 09-09 20:54
    查看更多