5

The app I'm currently working on has a mix of non consumable products and auto renewable subscriptions. Looks like after one or two days, purchased non consumable products are removed from the Sandbox receipt. Upon restore the products are provided by StoreKit observer callbacks, but they are still missing from the receipt.

I've tried both local validation and parsing via OpenSSL and the remote validation via Apple servers and the results match: those products are always missing. Note that this never happens with subscriptions, both expired and valid ones are always present in the receipt. Another funny detail: products don't go missing all at once, they progressively disappear following the purchase order, as the sandbox test user was being "cleaned up".

Since Apple docs state here that "Non-consumables, auto-renewing subscription items, and non-renewing subscription items remain in the receipt indefinitely" I would expect them to be there.

Does anybody know if this is an expected sandbox behaviour? Is there any official Apple resource stating that it's going to be ok once the app is in production?

EDIT: Found the exact same issue posted by somebody in the dev forums here.

  • Just ran into the issue as well. Non-consumable disappeared from receipt in sandbox environment. But they are in the callbacks of the queue. – vomi Jun 10 '20 at 09:19

2 Answers2

1

Non-consumable transactions are not returned in the JSON response from iTunes server validation.

However, they are present in the receipt and you can see them parsing it locally.

Matteo Gobbi
  • 17,697
  • 3
  • 27
  • 41
0

Massimo! Are you sure your products are non-consumables? Because consumable products disappear from the receipt.

Here is an example of how validating receipt can be done via Apple servers:

func validateReceipt(){
    guard let receiptUrl = Bundle.main.appStoreReceiptURL else {
            return
    }

    #if DEBUG
        let urlString = "https://sandbox.itunes.apple.com/verifyReceipt"
    #else 
        let urlString = "https://buy.itunes.apple.com/verifyReceipt"
    #endif
    let receiptData = try? Data(contentsOf: receiptUrl).base64EncodedString()
    let requestData = ["receipt-data" : receiptData ?? "", "password" : "YOUR_SHARED_SECRET", "exclude-old-transactions" : false] as [String : Any]
    var request = URLRequest(url: URL(string: urlString)!)
    request.httpMethod = "POST"
    request.setValue("Application/json", forHTTPHeaderField: "Content-Type")
    let httpBody = try? JSONSerialization.data(withJSONObject: requestData, options: [])
    request.httpBody = httpBody
    URLSession.shared.dataTask(with: request)  { (data, response, error) in
      // view your transactions here
    }.resume()        
}

We are the platform that manages subscriptions, including receipt validation, and we have a big experience in this area – but we never had the problem as you talk about.

Please double check that you are using non-consumables and would be great if you provide more details, screenshots, code, etc.

apphud
  • 625
  • 4
  • 8
  • 1
    Thanks for your quick reply, I'm 100% sure they are non consumables. :) I'm perfectly aware of the fact that consumables will not be present in the receipt once the transaction is closed. Moreover they disappear after 1-2 days. EDIT: Also, they are returned by the observer callbacks upon restore, so yeah, they are non consumable. :) – Massimo Cesaraccio Oct 15 '19 at 12:35
  • @MassimoCesaraccio have you found the solution to the problem? I'm experiencing the same issue at the moment – Alex Aug 25 '20 at 13:00
  • Same issue..those transactions are present in the receipt if you parse it locally.. – Matteo Gobbi Nov 27 '20 at 08:28