查询购买令牌返回无效值

我正在尝试设置一项网络服务来查询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开发人员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
    }
    

    现在,我想获得有关购买的信息。 我有这样的购买信息:

    {  
    "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,因为手动创建请求更清晰。

    感谢您的帮助和答复


    首先,我想与大家分享什么是400错误请求 ,发生错误的真正原因是什么?

    Ans:表示查询无效。 例如,家长标识缺失或所请求的维度或指标组合无效。

    建议的操作:您需要对API查询进行更改才能使其工作。

    资源链接:标准错误响应

    你的问题:

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

    根本原因:

    对于刷新令牌,响应始终包含一个新的访问令牌。 答案如下所示:

    {
      "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可以是访问令牌或刷新令牌。 如果令牌是访问令牌并且它具有相应的刷新令牌,则刷新令牌也将被撤销。

    注意:如果吊销被成功处理,则响应的状态码为200.对于错误条件,将返回状态码400和错误码。

    资源链接:

  • 离线访问,使用刷新令牌和撤销令牌

  • 当我使用静态响应进行测试时,这发生在我身上,即使用保留的产品ID进行测试(如android.test.purchased )。 SkyWalker的解决方案在这种情况下没有帮助。

    然后,我使用真实的产品ID,将我的应用发布为Google play的alpha版本,并将发布apk加载到我的设备中,现在一切正常。

    请务必仔细阅读在Google文档中设置测试购买的章节,以准备好您的应用和帐户以进行测试。

    链接地址: http://www.djcxy.com/p/47945.html

    上一篇: Query purchase token returns Invalid Value

    下一篇: what's the point of refresh token?