I'm trying to verify Android in-app purchases from my server using the Google Checkout API. As per this other query (App on Android market - HTTP notifications don't come), I get no callback so I'm using the polling API.
It's working fine, except that I'm getting a 5 or 6 minute delay before the polling receives the notifications about a purchase, even though all the information is already visible to the user logged in to the merchant account in a browser. Checking the API documentation, it implies it could take even longer, as it states "Using the Polling API, you can retrieve all notifications that are less than 180 days old and that are at least 30 minutes old".
Is this delay typical (I'm in the UK)? Is the polling API still the recommended way to verify an Android in-app purchase?
In my opinion, trying to validate GP LVL and/or IAB information via the Google Checkout Polling API on a server is not the best approach. There's a much better option available if you have a server anyway.
As mentioned in the article Securing Android LVL Applications, the best approach is to validate licence information on a trusted server. It goes like this:
com.android.vending.licensing
directly. Don't include your Google Developer Console app key with your app, you don't need it there.ILicensingService.checkLicense()
call. Your server supplies a secure random nonce to your app. Your app callsILicensingService.checkLicense()
with that nonce.ILicenseResultListener.verifyLicense()
, prodiving signed data and a signature. (Hint: The signed data contains the nonce, so not even a re-play attack is possible here.)With one difference, the same applies to IAB. Unfortunately, IAB V3 does not work with a nonce for
getPurchases()
. The reason is probably that the IAB Service itself (and not just the Google app-side reference code) uses caching extensively. Still, for purchases, you can pass adeveloperPayload
tocom.android.vending.billing.IInAppBillingService.getBuyIntent()
, which will be included in the signed data whichgetPurchases()
returns. So as long as you have either no expiration criteria or some kind of implicit (time-based) or server-managed explicit expiration criteria for in-app purchases, the API is still safe enough; the server would then ask the app to consume expired items and it's not even a problem if that fails because the server still knows it and can ask the app to consume the items again and again.I hope I could shed a bit of light on this topic.