错误21002:使用服务器的IOS的收据验证

时间:2019-08-10 20:19:10

标签: php ios swift in-app-purchase payment

我正在尝试通过服务器使用收据验证。但出现21002错误“ receiving-data属性中的数据格式错误或丢失。”

我尝试了所有找到的php代码,但是没有人能用。我尝试直接连接到沙箱,但工作正常,但是当我将其更改为服务器时,会出现此错误。

private func validateReceipt(completion : @escaping (_ status : Bool) -> ())  {


        // Get receipt if available
        if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL,
            FileManager.default.fileExists(atPath: appStoreReceiptURL.path) {

            do {
                let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped)
                print(receiptData)

                let receiptdata = receiptData.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 00))



                let dict = ["receipt-data" : receiptdata]

                let jsonData = try! JSONSerialization.data(withJSONObject: dict, options: JSONSerialization.WritingOptions(rawValue: 0))

                let request = NSMutableURLRequest(url: NSURL(string: ReceiptURL.myServer.rawValue)! as URL)

                let session = URLSession.shared


                request.httpMethod = "POST"

                request.httpBody = jsonData

                let task = session.dataTask(with: request as URLRequest, completionHandler: { data, response, error  in

                    if let dataR = data
                    {

                        self.handleData(responseDatas: dataR as NSData, completion: { status in
                            completion(status)
                        })
                    } else {
                        completion(false)
                    }
                })

                task.resume()

            }
            catch { print("Couldn't read receipt data with error: " + error.localizedDescription) }
        }



    }


    private func handleData(responseDatas : NSData, completion : (_ status : Bool) -> ())
    {
        do {

            if let json = try JSONSerialization.jsonObject(with: responseDatas as Data, options: JSONSerialization.ReadingOptions.mutableLeaves) as? NSDictionary
            {

                if let value = json.value(forKeyPath: "status") as? Int
                {

                    if value == 0
                    {

                        completion(true)
                    }
                    else
                    {
                        completion(false)


                    }
                }
                else
                {
                    completion(false)
                }
            } 

        } catch {
            print(error.localizedDescription)
        }
    }

PHP代码端

<?php
    function getReceiptData($receipt)
    {
        $fh = fopen('showme.txt',w);
        fwrite($fh,$receipt);
        fclose($fh);
        $endpoint = 'https://sandbox.itunes.apple.com/verifyReceipt';

        $ch = curl_init($endpoint);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $receipt);
        $response = curl_exec($ch);
        $errno = curl_errno($ch);
        $errmsg = curl_error($ch);
        curl_close($ch);
        $msg = $response.' - '.$errno.' - '.$errmsg;
        echo $response;
    }

foreach ($_POST as $key=>$value){
    $newcontent .= $key.' '.$value;
}

$new = trim($newcontent);
$new = trim($newcontent);
$new = str_replace('_','+',$new);
$new = str_replace(' =','==',$new);

if (substr_count($new,'=') == 0){
if (strpos('=',$new) === false){
        $new .= '=';
}
}

$new = '{"receipt-data":"'.$new.'"}';
$info = getReceiptData($new);
    ?>

有什么建议吗? 为什么此代码不起作用?


编辑1:

我尝试使用邮递员并与sandbox.itunes.com连接,但遇到了相同的错误

Postman Pic

我认为现在问题出在这行代码上

let receiptdata = receiptData.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 00))

我正在尝试解决它。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

有关php代码,请参阅my answer

使用post时,只需使用json格式的原始post数据即可。

在您的php代码中,您不应该执行str_replace工作,因为数据已经使用base64进行了很好的编码,只需使用它即可。

在邮递员中,您应该使用json原始邮递数据。请参阅What is the difference between form-data, x-www-form-urlencoded and raw in the Postman Chrome application?

enter image description here