2016-10-14 2 views
3

Я хочу проверить Android IAP через API Google на моем центральном игровом сервере.Проверка на Java-серверах Android IAP

Существует много частичной информации об этом, и это дует мне на ум. Я не заплатил € 25, чтобы стать разработчиком Google, потому что я не уверен, смогу ли я заставить его работать.

Когда выполняется IAP, возвращается объект JSON. Этот объект содержит несколько полей, таких как purchaseToken и productId (source).

Я нашел, что вы можете запросить информацию о купленном продукте с помощью следующего запроса GET: GET https://www.googleapis.com/androidpublisher/v2/applications/packageName/purchases/products/productId/tokens/token.

Я мог бы запрограммировать это без проблем, но вам необходимо авторизоваться: «Для этого запроса необходимо авторизироваться со следующей областью». (source). Здесь я начал путаться.

  1. Вам необходимо создать своего рода токен входа через консоль Dev (Link). Я не знаю, какой тип. OAuth или учетная запись службы?
  2. Этот токен недолговечен. Вы должны обновить его.

В Интернете есть несколько огромных фрагментов кода, которые могут работать или не работать, но все они частичные и не очень хорошо документированы.

Я нашел API-интерфейс API Google для Java: link. Этот API, похоже, сделан для устранения всех этих проблем с помощью OAuth и токенов для вас. Однако я не могу понять, как заставить этот API работать.

Возможно, это не так сложно, но есть много разных способов сделать это, и я не могу найти никаких ясных примеров.

TL; Мне нужно проверить серверы Google Play IAP. Для этого я хочу использовать API-интерфейс Googles.

РЕДАКТИРОВАТЬ: ЭТО МОЖЕТ БЫТЬ ПУТЬ ПРОСТОТА РЕШЕНИЯ. Передача исходного JSON плюс JSON на сервер может быть проще, потому что я могу просто проверить асимметричную серверную подпись.

+0

Это должно помочь: https://stackoverflow.com/questions/35127086/android-inapp-purchase-receipt-validation-google-play/35138885#35138885 –

+0

Я попытался выполнить его, но их интерфейс API изменено ПОЛНОСТЬЮ. И это не включает решение проблемы обновления токена. – kwantuM

ответ

2

Я сделал это в Scala, но, используя стандартную библиотеку Java, довольно просто преобразовать этот код в Java.

  • Прежде всего, вам нужна учетная запись службы. Вы можете создать это через консоль Google Dev. Это в основном дает вам обратно созданную электронную почту, которую вы будете использовать для аутентификации вашего бэкэнд-сервиса и создания токенов.

  • С созданной учетной записью вы можете скачать секретный ключ. Это нужно, чтобы подписать JWT.

  • Вы должны создать JWT в том формате, который определяет Google. См: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatingjwt

  • затем, с JWT, вы можете запросить доступ токенов

  • С маркером доступа, вы можете делать запросы, чтобы подтвердить ваши покупки

    /** Generate JWT(JSON Web Token) to request access token 
        * How to generate JWT: https://developers.google.com/identity/protocols/OAuth2ServiceAccount#creatingjwt 
        * 
        * If we need to generate a new Service Account in the Google Developer Console, 
        * we are going to receive a .p12 file as the private key. We need to convert it to .der. 
        * That way the standard Java library can handle that. 
        * 
        * Covert the .p12 file to .pem with the following command: 
        * openssl pkcs12 -in <FILENAME>.p12 -out <FILENAME>.pem -nodes 
        * 
        * Convert the .pem file to .der with the following command: 
        * openssl pkcs8 -topk8 -inform PEM -outform DER -in <FILENAME>.pem -out <FILENAME>.der -nocrypt 
        * 
        * */ 
        private def generateJWT(): String = { 
    
        // Generating the Header 
        val header = Json.obj("alg" -> "RS256", "typ" -> "JWT").toString() 
    
        // Generating the Claim Set 
        val currentDate = DateTime.now(DateTimeZone.UTC) 
        val claimSet =Json.obj(
         "iss" -> "<YOUR_SERVICE_ACCOUNT_EMAIL>", 
         "scope" -> "https://www.googleapis.com/auth/androidpublisher", 
         "aud" -> "https://www.googleapis.com/oauth2/v4/token", 
         "exp" -> currentDate.plusMinutes(5).getMillis/1000, 
         "iat" -> currentDate.getMillis/1000 
        ).toString() 
    
        // Base64URL encoded body 
        val encodedHeader = Base64.getEncoder.encodeToString(header.getBytes(StandardCharsets.UTF_8)) 
        val encodedClaimSet = Base64.getEncoder.encodeToString(claimSet.getBytes(StandardCharsets.UTF_8)) 
    
        // use header and claim set as input for signature in the following format: 
        // {Base64url encoded JSON header}.{Base64url encoded JSON claim set} 
        val jwtSignatureInput = s"$encodedHeader.$encodedClaimSet" 
        // use private key generated by Google Developer console to sign the content 
        val keyFile = Paths.get("<path_to_google_play_store_api.der>"); 
        val keyBytes = Files.readAllBytes(keyFile); 
    
        val keyFactory = KeyFactory.getInstance("RSA") 
        val keySpec = new PKCS8EncodedKeySpec(keyBytes) 
        val privateKey = keyFactory.generatePrivate(keySpec) 
    
        // Sign payload using the private key 
        val sign = Signature.getInstance("SHA256withRSA") 
        sign.initSign(privateKey) 
        sign.update(jwtSignatureInput.getBytes(StandardCharsets.UTF_8)) 
        val signatureByteArray = sign.sign() 
        val signature = Base64.getEncoder.encodeToString(signatureByteArray) 
    
        // Generate the JWT in the following format: 
        // {Base64url encoded JSON header}.{Base64url encoded JSON claim set}.{Base64url encoded signature} 
        s"$encodedHeader.$encodedClaimSet.$signature" 
        } 
    

сейчас что у вас есть сгенерированный JWT, вы можете запросить у access token следующее:

/** Request the Google Play access token */ 
     private def getAccessToken(): Future[String] = { 

     ws.url("https://www.googleapis.com/oauth2/v4/token") 
      .withHeaders("Content-Type" -> "application/x-www-form-urlencoded") 
      .post(
      Map(
       "grant_type" -> Seq("urn:ietf:params:oauth:grant-type:jwt-bearer"), 
       "assertion" -> Seq(generateJWT())) 
     ).map { 
      response => 
      try { 
       (response.json \ "access_token").as[String] 
      } catch { 
       case ex: Exception => throw new IllegalArgumentException("GooglePlayAPI - Invalid response: ", ex) 
      } 
     } 

     } 

С помощью токена доступа на ваших руках, вы можете подтвердить свои покупки.

Надеюсь, что это поможет.

+1

Спасибо за внимание, но этот вопрос почти год назад. – kwantuM

+2

. Вы правы, но мне это нужно неделю назад, и я не мог найти твердого ответа. Это может помочь кому-то другому;) –

1

Следуя приведенному выше замечанию, менеджер Google API изменился в дизайне, но процедура все тот же. Вы хотите создать учетную запись службы , после создания вы можете загрузить JSON Web token, это простой JSON-файл с учетными данными, необходимыми для аутентификации. У учетной записи службы должен быть доступ к API разработчика Google Play. Вам необходимо предоставить доступ к Финансы в консоли разработчика Google Play> Настройки> Доступ к API.

Вы можете использовать Google APIs Client Library for Java для аутентификации и оформления запросов к API разработчика Google Play. Следуйте документам OAuth2 Service accounts, чтобы настроить их. Существует примечание к Data store, в котором описывается, как обрабатывается токен обновления.

Существуют также документы о том, как использовать Google Play Developer API Client Library for Java.

Что касается проверки подлинности подписки на покупку JSON, в ответе на покупку намерения покупки есть INAPP_DATA_SIGNATURE. Дополнительную информацию о том, как его получить, см. В документах Purchasing an Item. Вы можете проверить INAPP_PURCHASE_DATA на base64, декодируя подпись и проверив ее с помощью вашего лицензионного ключа, найденного в API-интерфейсе разработчика Google Play> Все приложения> [Имя приложения]> Сервисы &. Убедитесь, что INAPP_PURCHASE_DATA нетронутым, иначе вы получите this problem.

Надеюсь, что это поможет.

Смежные вопросы