0

I am trying to use receipt validation using my server. but I get 21002 error "The data in the receipt-data property was malformed or missing."

I tried all php code that I found but no one works. I tried to connect direct to sandbox and it works fine but when I change it to my server this error appears.

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 Code side

<?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);
    ?>

Any suggestion? why is this code not working?


Edit 1:

I tried using postman and connect with sandbox.itunes.com and I got the same error

Postman Pic

I think now the problem is with this line of code

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

I am trying to solve it. Any suggestion?

LF00
  • 27,015
  • 29
  • 156
  • 295
  • [How to ask a good question](https://stackoverflow.com/help/how-to-ask) & [What topics can I ask about here?](https://stackoverflow.com/help/on-topic) – Trenton McKinney Aug 11 '19 at 04:24

1 Answers1

0

With php code, refer to my answer.

With post,just use the raw post data in json format.

In your php code, you shouldn't do the str_replace work, the data is already well base64 encoded, just use it.

In your post man, you should use json raw post data. Refer to What is the difference between form-data, x-www-form-urlencoded and raw in the Postman Chrome application?

enter image description here

LF00
  • 27,015
  • 29
  • 156
  • 295