swiftstorekitstorekit2

The file “sandboxReceipt” couldn’t be opened because there is no such file


I am using StoreKit 2 described in this WWDC video https://developer.apple.com/videos/play/wwdc2021/10114/ of apple to handle transactions, however when I try to verify the receipt and go through all transactions I get the following error: 'The file “sandboxReceipt” couldn’t be opened because there is no such file'.

My code to retrieve the receipt: // Access the app's bundle let bundle = Bundle.main

    // Get the appStoreReceiptURL property, which points to the receipt file location
    guard let receiptURL = bundle.appStoreReceiptURL else {
        print("No receipt URL found.")
        return nil
    }
    
    do {
        // Read the data from the receipt file
        let receiptData = try Data(contentsOf: receiptURL)
        
        // Convert the receipt data to a base64-encoded string
        let base64Receipt = receiptData.base64EncodedString()
        
        // Return the base64-encoded receipt string
        return base64Receipt
    } catch {
        print("Error reading receipt data: \(error.localizedDescription)")
        return nil
    }

This happened after I migrated to StoreKit 2.


Solution

  • With StoreKit 2 it is recommended to use individual Transaction instead of the receipt. So the receipt is not loaded/refreshed in the StoreKit 2 implementation. To load/refresh the receipt do the following:

    public class ReceiptLoader: NSObject, SKPaymentTransactionObserver, SKRequestDelegate {
    
        public var paymentQueue = SKPaymentQueue.default()
        public static var shared = ReceiptLoader()
    
        
        // this is required to load the receipt
        public func initialize() {
            self.paymentQueue.add(self)
            let request = SKReceiptRefreshRequest()
            request.delegate = self
            request.start()
        }
        
        public func requestDidFinish(_ request: SKRequest) {
            self.paymentQueue.restoreCompletedTransactions()
        }
        
        public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
        }
        
        
    }