Apple IAP 收据验证返回代码 21002

Dev*_*Ltd 5 httpclient in-app-purchase xamarin.ios ios xamarin

我试图提交到沙箱(和实时)verifyReceipt 端点,但我总是从 Apple 收到以下 JSON 响应......

{"status":21002, "exception":"java.lang.IllegalArgumentException"}
Run Code Online (Sandbox Code Playgroud)

这是邮递员截图

邮递员测试

我正在发布数据并设置标题(应用程序/json)

{"receipt-data":"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"}
Run Code Online (Sandbox Code Playgroud)

这是通过 TestFlight 内部测试部署从在 iOS 设备上运行的应用程序执行的。

我有点不确定 Base64 字符串是否格式不正确或其他东西 - 它确实有一些空格,但我现在删除了那些(因为我看到报告说它有帮助)。

这是我在移动应用程序中为捕获 base 64 编码所做的工作,请注意这是 Xamarin 代码(C#),但它非常接近地映射到您在 Objective-c / swift 中所做的......

String purchaseToken = null;
NSUrl receiptUrl = NSBundle.MainBundle.AppStoreReceiptUrl;
NSData receipt = null;

if (receiptUrl != null) {
    receipt = NSData.FromUrl (receiptUrl);
}

if (receipt == null) {
    // No local receipt -- handle the error
    // https://forums.xamarin.com/discussion/25304/how-do-i-exit-with-reason
    Environment.Exit (173);
} else {
    // http://stackoverflow.com/questions/37505020/example-of-parsing-a-receipt-for-an-in-app-purchase-using-ios-xamarin
    NSDictionary requestContents = NSDictionary.FromObjectAndKey ((NSString)receipt.GetBase64EncodedString (
                NSDataBase64EncodingOptions.None),
                (NSString)"receipt-data");
     string receiptData = (requestContents ["receipt-data"] as NSString).ToString ();

    purchaseToken = receiptData;
}

this.iapConsumableEvent.PurchaseToken = purchaseToken;
Run Code Online (Sandbox Code Playgroud)

服务器代码 (Java) 使用 HttpClient 将其传输给 Apple...

HttpClient client = HttpClientHelper.createHttpClient(new DefaultRedirectStrategy());
final HttpPost postRequest = new HttpPost(appleEnvironmentUrl);
StringEntity input = new StringEntity(receiptRequestJson);
input.setContentType("application/json");
postRequest.setEntity(input);
HttpResponse response = client.execute(postRequest);

String rawResponse = EntityUtils.toString(response.getEntity(), "UTF-8");
BasicDBObject appleJson = BasicDBObject.parse(rawResponse);

int statusCode = appleJson.getInt("status", 99999);

//ALWAYS RETURNING 21002 The data in the receipt-data property was malformed or missing.
Run Code Online (Sandbox Code Playgroud)

我感谢任何想法/答案!

jeh*_*jeh 8

我在试图通过邮递员让它工作时遇到了问题。

这在 node.js 中对我有用。我必须 JSON.stringify 在它起作用之前:

function createReceiptRequestJSON(base64String, secret) {
    return JSON.stringify({
        "receipt-data":base64String,
        password:secret
    });
}
Run Code Online (Sandbox Code Playgroud)

您可以通过 iTunes Connect 找到您的秘密,但我很确定您需要将其包含在请求中。

编辑:

和邮递员再看一眼。从这个答案苹果收据_数据样本中得到了收据。

在此处输入图片说明

似乎工作...


Dev*_*Ltd 0

事实证明,我使用 HTTP get 作为查询参数将令牌发送到服务器,一旦我将其添加到 POST 正文中,一切就正常了!