play google example developer java google-play

java - example - API de desarrollador de Google Play: el token de compra de consulta devuelve un valor no vĂ¡lido



google play store api key (2)

Primero, quiero compartir con ustedes lo que es 400 solicitudes incorrectas y cuál es la verdadera causa de su ocurrencia.

Respuesta: Indica que la consulta no fue válida. Por ejemplo, faltaba la identificación de los padres o la combinación de dimensiones o métricas solicitadas no era válida.

Acción recomendada: debe realizar cambios en la consulta de la API para que funcione.

Enlace de recursos: respuestas de error estándar

Tu problema:

Su código se ejecutó correctamente y devolvió el archivo json relacionado como resultado. Pero después de un período, it is not working when you want to get information about purchase . Da mensaje de error "HTTP / 1.1 400 Bad Request"

Causa principal:

Para el token de actualización, la respuesta siempre incluye un nuevo token de acceso. A continuación se muestra una respuesta:

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

Entonces, el token de acceso tiene un tiempo de expiración. después de un tiempo de expiración, el token de acceso no funcionará.

También hay otra restricción. Hay límites en el número de tokens de actualización que se emitirán; un límite por combinación cliente / usuario y otro por usuario en todos los clientes.

Por lo tanto, en su caso, ya ha superado el límite de creación de token de actualización.

Solución:

Entonces, primero necesitas revocar el token. Luego guarde los tokens de actualización en el almacenamiento a largo plazo y continúe usándolos mientras sigan siendo válidos.

Como está utilizando el token de actualización, entonces necesita cambiar la solicitud de publicación http https://accounts.google.com/o/oauth2/token a https://www.googleapis.com/oauth2/v4/token

Por lo que su código se verá a continuación:

String refreshToken = "1/ljll6d9ME3Uc13jMrBweqXugV4g4timYcXXXXXXXXX"; HttpPost request = new HttpPost("https://www.googleapis.com/oauth2/v4/token"); List<NameValuePair> params = new ArrayList<NameValuePair>(); ............... ...............

Procedimiento de revocación:

Hay 2 formas de revocar.

  1. Un usuario puede revocar el acceso visitando Configuración de la cuenta
  2. También es posible que una aplicación revoque mediante programación el acceso que se le ha otorgado.

Para revocar mediante programación un token, su aplicación realiza una solicitud a https://accounts.google.com/o/oauth2/revoke e incluye el token como parámetro:

curl https://accounts.google.com/o/oauth2/revoke?token={token}

El token puede ser un token de acceso o un token de actualización. Si el token es un token de acceso y tiene un token de actualización correspondiente, el token de actualización también se revocará.

NB: si la revocación se procesa con éxito, el código de estado de la respuesta es 200. En caso de error, se devuelve un código de estado 400 junto con un código de error.

Enlace de recursos:

  1. Acceso sin conexión, usando token de actualización y revocar un token

Estoy intentando configurar un servicio web para consultar las compras de Google Play. Almacenamos la información del pedido para los clientes y este servicio llamaría a la API de Google Play para consultar los detalles de la suscripción.

Cada vez que intento consultar una compra, me da el error:

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

Esto es lo que intenté:

  • Creé un proyecto en https://console.developers.google.com habilitado "API de desarrollador de Android Google Play"
  • Creó un client_id oAuth 2.0 y client_secret para la aplicación web de tipo
  • Iniciado sesión como propietario de la cuenta, generé un refresh_token
  • En https://play.google.com/apps/publish fui a Configuración -> Acceso a la API y vinculé el proyecto a mi aplicación

En cuanto al código, usé refresh_token para obtener un 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");

El access_token de esto funciona porque puedo llamar a esta API con él y obtener la respuesta:

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...

Esto devuelve:

{ "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" }

Ahora, quiero informarme sobre una compra. Tengo una información de una compra como tal:

{ "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 }

Ahora, quiero informarme sobre una compra. Tengo una información de una compra como tal:

{ "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...

Dado que packageName / productId y access_token parecen funcionar para la primera llamada, y purchaseToken está directamente sacado de la información del pedido. ¿Qué es el error de valor no válido?

Cualquier ayuda apreciada, no estoy seguro de qué más probar. ¡Gracias!

ACTUALIZACIÓN: Revisé y validé todos los nombres de paquetes y la configuración de la cuenta. El problema real parecía ser el servicio que estaba atacando. Lo cambié a: https://www.googleapis.com/androidpublisher/v2/applications/packageName/purchases/subscriptions/subscriptionId/tokens/purchaseToken

También cambié para usar la API del cliente de Google, ya que tenía un aspecto mucho más limpio que la creación manual de solicitudes.

Gracias por la ayuda y respuestas


Esto me sucedió cuando estaba probando con respuestas estáticas, es decir, usando ID de producto reservadas para las pruebas (como android.test.purchased ). La solución de SkyWalker no ayudó en este caso.

Luego utilicé ID de productos reales, publiqué mi aplicación como alfa para google play y cargué lateralmente el apk de la versión en mi dispositivo y ahora todo funciona como se esperaba.

Asegúrese de leer detenidamente el capítulo Configuración de compras de prueba en Google docs para preparar su aplicación y cuenta adecuadamente para la prueba.