从服务器端检查谷歌Android订阅

时间:2012-09-26 15:25:18

标签: android api in-app-billing subscription

简而言之: 我是否可以从服务器端使用Google Play Android Developer API而无需在Play商店中提供任何应用程序?

背景: 我正在开发一个项目,为每月订阅提供应用程序。每个订阅的相应数据(购买令牌,日期等)存储在后端数据库中。 现在我想创建一个循环遍历每个数据集的cronjob。对于每个订阅,如果订阅仍然有效,我想联系Google API以检索信息,并更新与响应状态相对应的数据库

对于后端逻辑,我使用google-api-java-client library

要取消或验证订阅,我需要先使用OAuth2对自己进行身份验证。 去过那里,做到了。

new GoogleCredential.Builder()
    .setTransport(HTTP_TRANSPORT)
    .setJsonFactory(JSON_FACTORY)
    .setServiceAccountId(SERVICE_ACCOUNT_EMAIL)
    .setServiceAccountScopes("https://www.googleapis.com/auth/androidpublisher") // $1
    .setServiceAccountPrivateKeyFromP12File(new File(filePath))
    .setClientSecrets(CLIENT_ID, CLIENT_SECRET) // $2
    .build();

$ 1:我不知道给定的帐户范围是否有效。因为我只是在极少数示例中找到了这个值,但this overviewgoogle playground

都没有

$ 2我想这是必要的,尽管我发现很多例子没有提供这些信息。

但是,遗憾的是,当我提供无效数据(例如错误的电子邮件或私钥)时,我看不出任何差异。

问题

  • 如何验证GoogleCredential是否正确?
  • 我可以在接下来的步骤中看到它,例如联系ie androidpublisher API吗?

在下一步中,我尝试获取订阅的购买状态:

Androidpublisher publisher = new Androidpublisher.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential)
                               .setApplicationName(GOOGLE_PRODUCT_NAME) // $1                
                               .build();
Androidpublisher.Purchases purchases = publisher.purchases();
Androidpublisher.Purchases.Get get = purchases.get("android.test.purchased", "monthly001", "mytoken"); // $2
SubscriptionPurchase subscripcion = get.execute(); 

$ 1:来自API console -> API Access

的虚拟产品名称

$ 2:除了事实,androidpush API确实not allow contacting it via service accounts, but only via web server applications auth flow,我没有任何线索在get-方法的参数中插入什么。

这是API: https://developers.google.com/android-publisher/v1/purchases/get

问题

  • 什么是包名称以及此上下文中的subscriptionId是什么?
  • 我在哪里获取/设置这些值?

阅读this document后,我知道有办法处理假/静态响应。但是,如果这也适用于订阅,或者仅适用于移动设备上的应用内帐单,我无法在任何地方阅读。

我想知道为什么/如果有一个简单的方法用沙箱或s.th.开发。 simliar。

我仍然觉得我只是缺少很大的一部分来理解事情应该如何运作。 也许你们中的某个人可以给我一个如何在这个地方继续前进的提示,或者可以说我在哪里错了。

亲切的问候,

克里斯托弗

1 个答案:

答案 0 :(得分:4)

我现在可以弄清楚我以前的大部分理解问题。

= 1 =生成授权网址

String authorizeUrl = new GoogleAuthorizationCodeRequestUrl(googleClientId,callbackUrl,"https://www.googleapis.com/auth/androidpublisher").build()    
// See why: http://stackoverflow.com/questions/8433990/when-authenticating-with-oauth-and-youtube-always-get-error-invalid-grant-on
authorizeUrl += "&approval_prompt=force&access_type=offline"

= 2 = AUTHENTICATE

由于server-webflow不适用于androidpublisher API,客户现在必须手动调用(1)中生成的URL。

= 3 = CALLBACK

谷歌回调应该处理后续步骤。回调包含我们必须使用的参数“code”。

= 4 =请求AUTH-TOKEN

    // Build the HTTP parameter
    Map<String,String> params = [:]
    params.put("grant_type", "authorization_code")
    params.put("code", code.encodeAsURL())
    params.put("client_id", customer.googleClientId.encodeAsURL())
    params.put("client_secret", customer.googleClientSecret.encodeAsURL())
    params.put("redirect_uri", getCallbackUrl().encodeAsURL())

    // Send the POST request
    // This action might throw an exception in case any parameter were wrong, invalid or not specified.
    String result = HttpRequestHandler.sendRequest("https://accounts.google.com/o/oauth2/token", params);
    JSONElement jsonResult = JSON.parse(result)

    // Map result
    OAuth2Result oAuth2Result = new OAuth2Result()
    oAuth2Result.accessToken = jsonResult.getAt("access_token")
    oAuth2Result.refreshToken = jsonResult.getAt("refresh_token")
    oAuth2Result.ttlSeconds = Integer.parseInt(jsonResult.getAt("expires_in").toString())
    oAuth2Result.tokenType = jsonResult.getAt("token_type") 

= 5 =请求刷新令牌

    // Build the HTTP parameter
    Map<String,String> params = [:]
    params.put("grant_type", "refresh_token")
    params.put("refresh_token", this.customer.googleRefreshToken.encodeAsURL())
    params.put("client_id", customer.googleClientId.encodeAsURL())
    params.put("client_secret", customer.googleClientSecret.encodeAsURL())

    // Send the POST request
    // This action might throw an exception in case any parameter were wrong, invalid or not specified.
    String result = HttpRequestHandler.sendRequest("https://accounts.google.com/o/oauth2/token", params);
    JSONElement jsonResult = JSON.parse(result)

    // Map result
    OAuth2Result oAuth2Result = new OAuth2Result()
    oAuth2Result.accessToken = jsonResult.getAt("access_token")
    oAuth2Result.refreshToken = jsonResult.getAt("refresh_token")
    oAuth2Result.ttlSeconds = Integer.parseInt(jsonResult.getAt("expires_in").toString())
    oAuth2Result.tokenType = jsonResult.getAt("token_type")