Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mac App Store Receipt Validation Code?

Wondering if anyone has a tutorial or working code for the new Mac App Store's receipt validation? About the only references I've been able to find so far are Apple's stellar documentation on the topic and one open source project which compiles but doesn't have a lot of inline comments so it's hard to understand unless you are a crypto whiz.

Apple docs for registered devs only:

https://developer.apple.com/devcenter/mac/documents/validating.html

Roddi's ValidateStoreReceipt (looks promising, but sparsely documented):

https://github.com/roddi/ValidateStoreReceipt

Also wondering why Apple does not just provide working code for validation?

Any other good references out there?

like image 726
Rei Avatar asked Nov 23 '10 21:11

Rei


People also ask

How do I validate my Apple receipt?

Use the production URL https://buy.itunes.apple.com/verifyReceipt when your app is live in the App Store. For more information on these endpoints, see verifyReceipt. Verify your receipt first with the production URL; then verify with the sandbox URL if you receive a 21007 status code.

How do I get a receipt for App Store purchase on Mac?

From the Account menu in the menu bar choose "View My Account..." Under Purchase History, click on "See All". Choose the desired date range at the top left. Find the order that you need the receipt for and click on the number next to "ORDER ID" in the top right of the block for the order.

What URL should I use to verify my receipt?

What url should I use to verify my receipt? Use the sandbox URL https://sandbox.itunes.apple.com/verifyReceipt while testing your application in the sandbox and while your application is in review. Use the production URL https://buy.itunes.apple.com/verifyReceipt once your application is live in the App Store.


1 Answers

It is hard to provide a generic solution for Mac App Store receipt validation, mainly because this is a very sensitive piece of code that must be hard to bypass (cf. Apple documentation).

These GitHub projects are very good starting points to learn about what steps must be performed in receipt validation:

  • NPReceiptVerification
  • ValidateStoreReceipt
  • AppReceiptParser

Once you have understood what must be done, here is some advice:

  • Don't use Objective-C classes or methods. Objective-C carries a lot of metadata, and its dynamic nature exposes it to runtime injection.
  • Only use C function calls. Even if you need more lines of code with the CoreFoundation framework, you can perfectly do what the Foundation framework can do (NSString, NSArray, NSDictionary, ...).
  • Don't link dynamically with the OpenSSL library as it has been deprecated in Mac OS X Lion. If you want to go with OpenSSL, link it statically to be sure to have the latest release.
  • Use system functions for cryptography. Mac OS X ships with equivalent functions since 10.5. For example, to compute a SHA-1 hash, you can use the CC_SHA1 function.
  • Don't put strings in plaintext in your code. Encode them or encrypt them. If you fail to do so, you give a hint about the location of your code.
  • Don't use numeric constants in your code. Compute them at runtime, with some simple operations (+, -, / or *). Again, if you fail to do so, you give a hint about the location of your code.
  • Avoid simple tests for validation by embedding your tests and the call to NSApplicationMain into a complex loop.
  • Avoid calling NSApplicationMain directly. Use a function pointer to hide the invocation. If you fail to do so, you give a hint about the location of your code.
  • For each release of your application, slightly modify the validation code so it is never the same.

Remember that receipt validation is necessary and is not simple as it seems. It can consume a lot of time that you may better spend on your application.

So I suggest you to take a look at this application: Receigen (Disclaimer: I am the developer of this application).

like image 190
Laurent Etiemble Avatar answered Oct 04 '22 13:10

Laurent Etiemble