Your Event Companion
Technical
How to Verify an App Store Transaction Receipt in Java/Groovy?
Dec 13th
This post is knowingly quite technical. The journey towards creating a mobile application is filled with technical discoveries and struggles, and we thought it might be interesting to share our experiences. So if you are not a developer your self, it is likely that you won’t understand a lot in the Technical category of this blog. Hopefully it will make you feel like knowing more and you will join the tribe.
In the last few days, I’ve been playing with In-App Purchase on the iPhone and I’ve done some experiments with what they call the Server Product Model, that is a model in which your iPhone application is connected to a server that is responsible to provide commercial content.
There is something interesting with step 12. It happens after the mobile application has already talked with the App Store to process the payment. So you could think that all the server has to do next is to send the content and we’re good to go… But what if the mobile application was hacked and the payment was not really processed? What if the request was forged? Well, that’s what step 12 is all about. Basically, the mobile application sends some encoded data to the server. The server checks that it’s genuine and sends the content only if it is. Of course it only works if you have a server, and creating one for the sole purpose of checking transactions might not be a good idea. But since I’m using a server to download content from, why not use it to perform some authentication as well?
Now the next question is “How does my server check this transaction receipt with Apple’s app store?”. My server, ConferenceGuide server, is a Grails one. What is cool with Grails is that it comes with a couple of additional Java APIs that are very useful. So without further ado, let’s dive into some code:
void verifyReceipt(String productId, byte[] receipt) {
//This is the URL of the REST webservice in iTunes App Store
URL url = new URL("https://buy.itunes.apple.com/verifyReceipt");
//make connection, use post mode
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setDoOutput(true);
connection.setAllowUserInteraction(false);
//Encode the binary receipt data into Base 64
//Here I'm using org.apache.commons.codec.binary.Base64 as an encoder, since commons-codec is already in Grails classpath
Base64 encoder = new Base64();
String encodedReceipt = new String(encoder.encode(receipt));
//Create a JSON query object
//Here I'm using Grails' org.codehaus.groovy.grails.web.json.JSONObject
Map map = new HashMap();
map.put("receipt-data", encodedReceipt);
JSONObject jsonObject = new JSONObject(map);
//Write the JSON query object to the connection output stream
PrintStream ps = new PrintStream(connection.getOutputStream());
ps.print(jsonObject.toString());
ps.close();
//Call the service
BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream()));
//Extract response
String str;
StringBuffer sb = new StringBuffer();
while ((str = br.readLine()) != null) {
sb.append(str);
sb.append("\n");
}
br.close();
String response = sb.toString();
//Deserialize response
JSONObject result = new JSONObject(response);
int status = result.getInt("status");
if (status == 0) {
//provide content
} else {
//signal error, throw an exception, do your stuff honey!
}
}
That’s all there is to it… plus a few exception handlers here and there to make sure everything goes right for users when something goes wrong on your side. Note that this code works in Groovy and should work in Java as well, which means it’s probably not as short as it could be if it were realy groovified. But it works, for real. Enjoy!



