EDIT: since some people are still checking out this thread, I want to mention that this is highly obsolete, because it is about v2 in app purchase, which is now deprecated. Please check out the latest (currently v3) documentation, it is pretty straightforward
There are loads of threads about this issue, and I think I understand the problem, however, at the moment I cannot test with real purchases, since I don't currently have a valid credit card, what Google accepts, only a Maestro, which is not accepted. This is why I ask for help (not purchase verification, but verifying that my thought process is good).
First, the problem comes from the new verifyPurchase
method. The new method checks for signatures, which should be fine. However, Google does not provide any signature for test ids, such as android.test.purchased
. This causes the method below to always fail, and it will always return false on the verification, even if the fake purchase has been completed, and I had a confirmation dialog, that the purchase is indeed succesful. The method:
public static boolean verifyPurchase(String base64PublicKey, String signedData, String signature) {
//if(BuildConfig.DEBUG) return true;
if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey) ||
TextUtils.isEmpty(signature)) {
Log.e(TAG, "Purchase verification failed: missing data.");
return false;
}
PublicKey key = Security.generatePublicKey(base64PublicKey);
return Security.verify(key, signedData, signature);
}
The problem comes from the TextUtils.isEmpty()
checks, since the signature will be empty, the code will return false. My temporary, testing workaround is in the code, commented out. If I add the if(BuildConfig.DEBUG) return true;
at the beginning of the method for testing, everything is working fine, the user gets the premium features up and running, so the problem is indeed about signatures.
Another problem is, if I purchase android.test.purchased
, I cannot query the inventory of the user, so I cannot be sure, that my checker method, which checks if the user has purchased the premium feature, works.
My two questions:
If I remove the if(BuildConfig.DEBUG) return true;
line from verifyPurchase
, and replace the android.test.purchased
id with the real id of the real SKU I am offering, can I be sure everything will work correctly in my case? I repeat, with the added debug functionality everything is working fine. If you need to see any more code, let me know!
The method below checks if the user has purchased the premium feature, if he/she has, then it sets the corresponding preferences, otherwise, if anything goes south, it leaves everything as it is. Is this method correct? I am doing this in the Application
class, on every app start up, to prevent tinkering.
private void checkPremium()
{
//get the helper up and running
final IabHelper helper=new IabHelper(INSTANCE, getBase64Key());
helper.startSetup(new IabHelper.OnIabSetupFinishedListener()
{
@Override
public void onIabSetupFinished(IabResult result)
{
//if the helper is in a correct state, check the inventory
if(result.isSuccess())
{
helper.queryInventoryAsync(new IabHelper.QueryInventoryFinishedListener()
{
@Override
public void onQueryInventoryFinished(IabResult result, Inventory inv)
{
//if the inventory is reachable, check if we got the premium
if(result.isSuccess())
{
setPremium(inv.hasPurchase(ActWidgetSearch.SKU));
}
}
});
}
}
});
}
Thanks in advance!