Validating receipt comes back with status code 21002

Problem I'm having when validating auto-renewable receipt

Status code: status code 21002


Apple said:

The data in the receipt-data property was malformed or missing.


Trying to validate receipt server side to prevent hacks. In app purchases for auto-renewable subscription. I had converted this code from Swift 1 to Swift 3 so maybe the code is old and apple changed its ways so maybe someone can help me.

Every time I run the

validateReceipt()
function in
viewDidLoad
and before I show my content. The
validateReceipt()
is supposed to update a isValidated bool to true when correct and false to when not validated, to continue to MainController.


Using the sandbox url

https://sandbox.itunes.apple.com/verifyReceipt


Here is the

validateReceipt()
function


func validateReceipt() {
    
        let receiptUrl = Bundle.main.appStoreReceiptURL
        
        do {
            let receipt: Data = try Data(contentsOf:receiptUrl!)
            let receiptdata: NSString = receipt.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0)) as NSString
            let request = NSMutableURLRequest(url: NSURL(string: "https://example.com/ss/verifyiReceipt.php")! as URL)
            let session = URLSession.shared
            request.httpMethod = "POST"
            
                request.httpBody = receiptdata.data(using: String.Encoding.ascii.rawValue)
        
                let task = session.dataTask(with: request as URLRequest, completionHandler: {(data, response, error) in
                   
                    do {
                        let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSDictionary
            
                        if(error != nil) {
                    
                            print(error!.localizedDescription)
                            print("ERROR when validating!")
                
                        } else {
                    
                            if let parseJSON = json {
                                print("Receipt \(parseJSON)")
                                print("Validated!.. I think..")
                        
                            } else {
                                print("Receipt ERROR!")
                            }
                        }  
                    } catch {
                        print("Error: (Receipt to JSON)")
                    }
                })
            task.resume()
        } catch {
            print("Error: (Receipt URL)")
        }
    }


And this is the PHP Code


<?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.'","password":"cb9dexample3287"}'; 
$info = getReceiptData($new); 
?>
Validating receipt comes back with status code 21002
 
 
Q