Saturday, December 18, 2021


Tags

Mac App Store Receipt Verification Failures

In the run up to Christmas it stops working, I think I know why and how to solve it.

Saturday, December 18, 2021 - Sam Rowlands



On the 13th of December, a post appeared in the Xojo forum MAS: app rejected because of faulty receipt-validation. "Thomas Roemert" said he's had the problem since late November 2021. Several App Wrapper customers had also mentioned it, however App Review still accepted their app. In this case, Carlo, can't even test their receipt verification code. I launched into action as I've been maintaining Thomas Templemann's receipt validation code for some time now.

The problem

When a Mac app can't validate the receipt, it calls exit( 173 ), the macOS then refreshes the receipt, relaunches the app and off we go. Except now we're seeing a nondescript, unhelpful generic error message that the application is damaged and must be re-downloaded from the App Store. Ergh.

Console logs some clues about com.apple.commerce failing.

default 12:35:04.481080+0800 storeuid (com.apple.commerce) Fetching missing receipt for sandbox app /Applications/Notched Up.app default 12:35:04.707374+0800 storelegacy (com.apple.commerce) StoreLegacy: Failed to perform in-line receipt renewal for application at path /Applications/Notched Up.app : 'Error Domain=com.apple.commerce.client Code=500 "(null)"'

How should it work

According to Apple's receipt validation documentation

  • macOS: call exit with a status of 173. This exit status notifies the system that your application has determined that its receipt is invalid. At this point, the system attempts to obtain a valid receipt. If the system successfully obtains a valid receipt, it relaunches the application. Otherwise, it displays an error message to the user, explaining the problem.

Pretty much how we've been doing it since 2011 then. Jolly good.

Enter SKReceiptRefreshRequest

Wait, how did you end up there? A clue is in the log data ("storelegacy"), while t'other is simply from doing this for a while. I've watched how Mac idioms and functionality have been replaced by iOS idioms and functionality, so on a whim I followed the iOS instructions at Apple's receipt validation documentation. It works, even on Mac OS X 10.13.

Instead of calling exit(173) instigate a SKReceiptRefreshRequest and call [SKReceiptRefreshRequest start] with a delegate set-up to handle the responses. SKReceiptRefreshRequest is asynchronous, so you'll need to redesign your flow for receipt checking.

For those developing with Xojo, you can download OWStoreKitBridge from https://ohanaware.com/storeKitBridge/

So there's a bug and either it's with Apple's documentation, Apple's "Store" frameworks in the macOS or over at Apple's "Store" servers that interact with the Mac. What's annoying is that Apple haven't said anything, just letting Mac developers flounder and flop around. https://developer.apple.com/forums/thread/696546.