Java和AppStore收据validation

我正在尝试validation服务器端的付款收据。 我得到了一个{"status":21002, "exception":"java.lang.IllegalArgumentException"}作为回报

这里是代码:

 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 BufferedReader rd = new BufferedReader(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()); } } 

我的收据是这样的:

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

用BASE64编码收据接收数据如下所示:

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

有人有一个想法,或示例代码我怎么能从收据string回复JSON,在这里提到?

21002:问题出在Java内部的Base64编码。 当我在IOS内部进行编码,并将其用作Java中没有任何编码的服务器的请求时,它就起作用了。

 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 shared secret you provided does not match the shared secret on file for your account."; logger.info("\n 21004 : The shared secret you provided does not match the shared 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 expired. 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 expired. 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; } 
 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); BufferedReader rd = new BufferedReader(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(); 

我不熟悉该服务,但是当内容types或接受的标头设置不当时,我发现与其他服务有类似的错误。

尝试类似

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

(或者他们所期待的,我假设json)