【问题标题】:Java and AppStore receipt verificationJava 和 AppStore 收据验证
【发布时间】:2020-08-21 18:45:23
【问题描述】:

我正在尝试在服务器端验证付款收据。 我得到一个{"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]"}

有人有想法,或示例代码我如何从收据字符串中获取回复 JSON,提到here

【问题讨论】:

  • 根据this answer:the JSON Object that you have created to send for verification is not in correct format.

标签: java ios in-app-purchase


【解决方案1】:

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;
    }

【讨论】:

    【解决方案2】:
    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();
    

    【讨论】:

      【解决方案3】:

      我不熟悉该服务,但是当内容类型或接受未正确设置的标头时,我在其他服务中看到了类似的错误。

      试试类似的东西

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

      (或任何他们期望的。我假设是 json)

      【讨论】:

      • 谢谢,尝试添加这些,没有用。同样的错误:{"status":21002, "exception":"java.lang.IllegalArgumentException"}
      【解决方案4】:

      对于稍后到达这里的每个人,请确保在您的 JSONObject 上调用 toString()。因此,如果您使用的是 resTemplate,请使用:

          JSONObject jsonObject = new JSONObject();
          jsonObject.put("receipt-data", "your-receipt");
      
          // This will result in a response with status 21002 (https://developer.apple.com/documentation/appstorereceipts/status)
          HttpEntity<JSONObject> httpEntityRequest = new HttpEntity<>(jsonObject);
      
          // call toString() makes it work!
          HttpEntity<String> httpEntityRequest = new HttpEntity<>(jsonObject.toString());
      
          ResponseEntity<String> response = restTemplate.postForEntity(appleVerifyReceiptUrl, httpEntityRequest, String.class);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-01-24
        • 2016-07-31
        • 1970-01-01
        • 2014-07-19
        • 2016-03-08
        相关资源
        最近更新 更多