Verificación de recibos de Java y AppStore

Estoy tratando de verificar un recibo de pago en el lado del server. {"status":21002, "exception":"java.lang.IllegalArgumentException"} un {"status":21002, "exception":"java.lang.IllegalArgumentException"} a cambio

Aquí está el código:

 private final static String _sandboxUriStr = "https://sandbox.itunes.apple.com/verifyReceipt"; public static void processPayment(final String receipt) throws SystemException { final BASE64Encoder encoder = new BASE64Encoder(); final String receiptData = encoder.encode(receipt.getBytes()); final String jsonData = "{\"receipt-data\" : \"" + receiptData + "\"}"; System.out.println(receipt); System.out.println(jsonData); try { final URL url = new URL(_sandboxUriStr); final HttpURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setRequestMethod("POST"); conn.setDoOutput(true); final OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream()); wr.write(jsonData); wr.flush(); // Get the response final BuffenetworkingReader rd = new BuffenetworkingReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = rd.readLine()) != null) { System.out.println(line); } wr.close(); rd.close(); } catch (IOException e) { throw new SystemException("Error when trying to send request to '%s', %s", _sandboxUriStr, e.getMessage()); } } 

Mi recibo se ve así:

 {\n\t"signature" = "[exactly_1320_characters]";\n\t"purchase-info" = "[exactly_868_characters]";\n\t"environment" = "Sandbox";\n\t"pod" = "100";\n\t"signing-status" = "0";\n} 

Los datos de recibo con un recibo codificado en BASE64 tienen este aspecto:

 {"receipt-data" : "[Block_of_chars_76x40+44=3084_chars_total]"} 

¿Alguien tiene una idea, o código de ejemplo, cómo puedo get de la cadena de recibo para responder a JSON, que se menciona aquí ?

21002: El problema estaba en la encoding de Base64 dentro de Java. Cuando hago la encoding dentro de iOS y la uso como la request del server sin ninguna encoding en Java, funcionó.

 switch (status) { case 21000: msg = "The App Store could not read the JSON object you provided"; logger.info("\n 21000 : The App Store could not read the JSON object you provided. "); break; case 21002: msg = "The data in the receipt-data property was malformed."; logger.info("\n 21002 : The data in the receipt-data property was malformed.. "); break; case 21003: msg = "The data in the receipt-data property was malformed."; logger.info("\n 21003 : The receipt could not be authenticated. "); break; case 21004: msg = "TThe shanetworking secret you provided does not match the shanetworking secret on file for your account."; logger.info("\n 21004 : The shanetworking secret you provided does not match the shanetworking secret on file for your account. "); break; case 21005: msg = "The receipt server is not currently available."; logger.info("\n 21005 : The receipt server is not currently available. "); break; case 21006: msg = "This receipt is valid but the subscription has expinetworking. When this status code is returned to your server, the receipt data is also decoded and returned as part of the response."; logger.info("\n 21006 : This receipt is valid but the subscription has expinetworking. When this status code is returned to your server, the receipt data is also decoded and returned as part of the response. "); break; case 21007: msg = "This receipt is a sandbox receipt, but it was sent to the production service for verification."; logger.info("\n 21007 : This receipt is a sandbox receipt, but it was sent to the production service for verification. "); break; case 21008: msg = "This receipt is a production receipt, but it was sent to the sandbox service for verification."; logger.info("\n 21008 : This receipt is a production receipt, but it was sent to the sandbox service for verification. "); break; default: msg = "Active subscription."; logger.info("\n 0 : valid ....Active subscription. "); break; } 

No estoy familiarizado con ese service, pero he visto errores similares con otros services cuando el tipo de contenido o los encabezados de aceptación no se configuran correctamente.

Intente algo como

  con.setRequestProperty("Content-Type", "application/json"); con.setRequestProperty("Accept", "application/json"); 

(O lo que sea que estén esperando. Estoy asumiendo json)

 CloseableHttpClient client = HttpClients.createDefault(); JSONObject requestData = new JSONObject(); requestData.put("receipt-data", recept); requestData.put("password", password); HttpPost httpPost = new HttpPost("https://sandbox.itunes.apple.com/verifyReceipt"); StringEntity entity = new StringEntity(requestData.toString()); httpPost.setEntity(entity); httpPost.setHeader("Content-type", "application/x-www-form-urlencoded"); CloseableHttpResponse response = client.execute(httpPost); BuffenetworkingReader rd = new BuffenetworkingReader(new InputStreamReader(response.getEntity().getContent())); StringBuffer result = new StringBuffer(); String line = ""; while ((line = rd.readLine()) != null) { result.append(line); } System.out.println(result.toString()); response.close();