IAP receipt validation fails with status code: 21002

I have implemented IAP. The purchases are successful. The refresh receipt is working fine, which then calls the requestDidFinish(_ request: SKRequest) delegate. I'm fetching the receipt url through 'Bundle.main.appStoreReceiptURL'. When I convert the receipt data in base64 string and send it to app store's sandbox api and try to validate the receipt, it fails giving status code : 21002.

I was trying with the mentioned solutions. But every time it gives me 21002 code for receipt validation. even with curl command same output. This is my code -

func refreshReceipt() {
    ReceiptRefresher.shared.refresh { result in
                        switch result {
                        case .success(let receiptData):
                            let receiptString = receiptData.base64EncodedString(options: .endLineWithCarriageReturn)
                            self.validateReceipt(receiptString: receiptString)
                        case .failure(let error):
                            print(" Receipt refresh failed: \(error)")
                        }
                    }
}


func validateReceipt(receiptString: String) {
    let requestDict: [String: Any] = [
        "receipt-data": receiptString,
        "password": "8fbc59b791104907a3ad418597854d50"
    ]
    let requestData = try! JSONSerialization.data(withJSONObject: requestDict, options: [])

    var request = URLRequest(url: URL(string: "https://sandbox.itunes.apple.com/verifyReceipt")!)
    request.httpMethod = "POST"
    request.httpBody = requestData
    request.addValue("application/json", forHTTPHeaderField: "Content-Type")

    URLSession.shared.dataTask(with: request) { data, response, error in
        guard let data = data else { return }
        let json = try? JSONSerialization.jsonObject(with: data, options: [])
        print(json!)
    }.resume()

}

class ReceiptRefresher: NSObject, SKRequestDelegate { static let shared = ReceiptRefresher()

var completion: ((Result<Data, Error>) -> Void)?

func refresh(completion: @escaping (Result<Data, Error>) -> Void) {
    self.completion = completion
    let request = SKReceiptRefreshRequest()
    request.delegate = self
    request.start()
}

func requestDidFinish(_ request: SKRequest) {        
    guard let url = Bundle.main.appStoreReceiptURL else {
        print("❌ No receipt URL")
        completion?(.failure(NSError(domain: "NoReceiptURL", code: 1)))
        return
    }

    print("📍 Receipt URL: \(url.path)")

    do {
        let data = try Data(contentsOf: url, options: .alwaysMapped)
        print("✅ Receipt fetched. Size: \(data.count) bytes")
        print("Raw receipt data (hex): \(data as NSData)")
        completion?(.success(data))
    } catch {
        print("❌ Failed to read receipt: \(error.localizedDescription)")
        completion?(.failure(error))
    }

}

func request(_ request: SKRequest, didFailWithError error: Error) {
    completion?(.failure(error))
}

}

IAP receipt validation fails with status code: 21002
 
 
Q