servicios services saldo play google detuvo descargar con comprar como celular app actualizar android in-app-purchase in-app-billing

android - services - play store apk



Verificación del lado del servidor de la compra de la versión 3 de facturación de Google Play en la aplicación (3)

Esta es una pregunta demasiado antigua, pero espero que mi respuesta pueda ayudar a alguien.

Debe validar la firma en el lado del cliente , y luego debe pasar purchaseToken al lado del servidor , y luego el servidor se pondrá en contacto con el servidor de Google y obtendrá toda la información necesaria sobre la compra, como purchaseState y el estado de consumptionState .

https://developers.google.com/android-publisher/api-ref/purchases/products

No puedo encontrar una respuesta directa sobre cómo verifico una compra de facturación en la aplicación en el servidor antes de poner contenido descargable a disposición del usuario.

Utilizo la aplicación en la versión de facturación 3. Compro productos administrados utilizando un código basado en la clase IabHelper del código de ejemplo TrivialDrive. Todo está bien y excelente y la compra se completó con éxito, recibí un objeto de Compra completo y los siguientes datos originales de JSON:

{ "orderId":"12999763169054705758.1364365967744519", "packageName":"my package name", "productId":"77", "purchaseTime":1366217534000, "purchaseState":0, "purchaseToken":"utfwimslnrrwvglktizikdcd.AO-J1OwZ4l5oXz_3d2SAWAAUgFE3QErKoyIX8WuSEnBW26ntsyDmlLgoUd5lshqIY2p2LnlV4tpH4NITB4mJMX98sCtZizH7wGf6Izw3tfW_GflJDKFyb-g" }

Como lo entiendo, necesito pasar el purchaseToken y algo que veo como una firma para el servidor. El servidor luego usa una clave privada para verificar la compra. ¿Es esto correcto? Si es así, ¿de dónde obtengo la firma y realmente no hay documentación decente sobre la verificación del lado del servidor de una compra?


Mi pequeña contribución para reducir el fraude en compras dentro de la aplicación.

Verificación de la firma en un servidor externo, en su código de Android:

verifySignatureOnServer ()

private boolean verifySignatureOnServer(String data, String signature) { String retFromServer = ""; URL url; HttpsURLConnection urlConnection = null; try { String urlStr = "https://www.example.com/verify.php?data=" + URLEncoder.encode(data, "UTF-8") + "&signature=" + URLEncoder.encode(signature, "UTF-8"); url = new URL(urlStr); urlConnection = (HttpsURLConnection) url.openConnection(); InputStream in = urlConnection.getInputStream(); InputStreamReader inRead = new InputStreamReader(in); retFromServer = convertStreamToString(inRead); } catch (IOException e) { e.printStackTrace(); } finally { if (urlConnection != null) { urlConnection.disconnect(); } } return retFromServer.equals("good"); }

convertStreamToString ()

private static String convertStreamToString(java.io.InputStreamReader is) { java.util.Scanner s = new java.util.Scanner(is).useDelimiter("//A"); return s.hasNext() ? s.next() : ""; }

Verify.php en el directorio raíz de alojamiento web

<?php // get data param $data = $_GET[''data'']; // get signature param $signature = $_GET[''signature'']; // get key $key_64 = ".... put here the base64 encoded pub key from google play console , all in one row !! ...."; $key = "-----BEGIN PUBLIC KEY-----/n". chunk_split($key_64, 64,"/n"). ''-----END PUBLIC KEY-----''; //using PHP to create an RSA key $key = openssl_get_publickey($key); // state whether signature is okay or not $ok = openssl_verify($data, base64_decode($signature), $key, OPENSSL_ALGO_SHA1); if ($ok == 1) { echo "good"; } elseif ($ok == 0) { echo "bad"; } else { die ("fault, error checking signature"); } // free the key from memory openssl_free_key($key); ?>

NOTAS:

  • Debería cifrar la URL en su código java, si no, la URL se puede encontrar fácilmente con una simple búsqueda de texto en su aplicación descomprimida apk

  • También es mejor cambiar el nombre del archivo php, los argumentos de url, las respuestas buenas / malas a algo sin sentido.

  • VerifySignatureOnServer () debe ejecutarse en un subproceso separado si no se lanzará una red en el subproceso principal.

Espero que ayude ...


where do I get the signature from ?

Echa un vistazo a los documentos oficiales ,

Dice que dentro del método onActivityResult() puede obtener los siguientes datos como se muestra en el ejemplo,

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 1001) { int responseCode = data.getIntExtra("RESPONSE_CODE", 0); String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA"); String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");//this is the signature which you want if (resultCode == RESULT_OK) { try { JSONObject jo = new JSONObject(purchaseData);//this is the JSONObject which you have included in Your Question right now String sku = jo.getString("productId"); String purchaseToken = jo.getString("purchaseToken"); //you need to send sku and purchaseToken to server for verification } catch (JSONException e) { alert("Failed to parse purchase data."); e.printStackTrace(); } } } }

Para la verificación en el extremo del servidor, Echa un vistazo a los documentos oficiales

Como se mencionó anteriormente, la aplicación cliente enviará sku y purchaseToken a la API del servidor. El servidor tendrá que recibir esos valores y tendrá que realizar una verificación con la API de publicación de Android para verificar la compra:

El servidor puede llamar a la siguiente solicitud GET agregando los parámetros necesarios:

https://www.googleapis.com/androidpublisher/v2/applications/ packageName / purchase / products / productId / tokens / token

aquí,
packageName = packageName de la aplicación cliente
productId = sku recibido de la aplicación cliente
token = purchaseToken recibido de la aplicación cliente

JSONObject en una respuesta JSONObject como el formato mencionado:

{ "kind": "androidpublisher#productPurchase", "purchaseTimeMillis": long, "purchaseState": integer, "consumptionState": integer, "developerPayload": string, "orderId": string, "purchaseType": integer }

aquí, purchaseState = 0 significa compra válida

Espero que sea util !!