我正在尝试设置网络服务来查询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"
}
}
以下是我的尝试:
代码方面,我使用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
}
现在,我希望获得有关购买的信息。我有购买的信息:
{
"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客户端API,因为手动创建请求更加清晰。
感谢您的帮助和回复
答案 0 :(得分:10)
首先,我想与您分享 400错误请求以及什么是 发生它的真正原因是什么?
Ans:表示查询无效。例如,缺少父ID或请求的维度或指标的组合无效。
推荐的操作:您需要对API查询进行更改才能使其正常工作。
资源链接: Standard Error Responses
您的代码运行正常并返回相关的json
文件作为输出。但过了一段时间,it is not working when you want to get information about purchase
。它提供错误消息&#34; HTTP / 1.1 400错误请求&#34;
对于刷新令牌,响应始终包含新的访问令牌。回复如下所示:
{
"access_token":"1/fFBGRNJru1FQd44AzqT3ZgXXXXXX",
"expires_in":3920,
"token_type":"Bearer",
}
因此,访问令牌有一个到期时间。在到期时间之后,访问令牌将无法工作。
还有另一个限制。将发布的刷新令牌数量有限制;每个客户端/用户组合一个限制,以及所有客户端的每个用户另一个限制。
因此,在您的情况下,您已经超越了创建刷新令牌的限制。
因此,您首先需要撤消令牌。然后在长期存储中保存刷新令牌,并继续使用它们,只要它们仍然有效。
当您使用刷新令牌时,您需要将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>();
...............
...............
有两种方法可以撤销。
要以编程方式撤消令牌,您的应用程序会向https://accounts.google.com/o/oauth2/revoke
发出请求,并将令牌作为参数包含在内:
curl https://accounts.google.com/o/oauth2/revoke?token={token}
token
可以是访问令牌或刷新令牌。如果令牌是访问令牌并且它具有相应的刷新令牌,则刷新令牌也将被撤销。
N.B:如果成功处理了吊销,则状态代码 响应的响应是200.对于错误条件,状态代码400是 返回错误代码。
答案 1 :(得分:2)
This happened to me when I was testing with Static Responses, i.e. using reserved product IDs for testing (like android.test.purchased
). SkyWalker's solution did not help in this case.
Then I used real product IDs, published my app as alpha to google play and side-loaded the release apk into my device and now everything works as expected.
Be sure to read carefully chapter Setting Up for Test Purchases in google docs to prepare your app and account properly for testing.
答案 2 :(得分:0)
对实时数据调用此方法以查看API请求和响应。在API Explorer
方面需要帮助API: https://www.googleapis.com/androidpublisher/v1.1/applications/packageName/subscriptions/subscriptionId/purchases/token
请求参数:
packageName:PACKAGE_NAME
subscriptionId:SUBSCRIPTION_ID
令牌:PURCHASE_TOKEN