1
votes

I am having trouble with license testing my in-app products. I have an app published to the Google Play beta channel, and I have my relevant Google account listed as a license tester in the dev console. (Meaning I can make "purchases" without actually paying for the item(s).)

When I visit the in-app store for the first time, everything works fine. However, upon "purchasing" an item, I receive a signature verification error in the purchase flow response. From that point forward, I also receive the same signature error when querying for the store inventory.

I need help with this part. I have seen posts stating that the method verifyPurchase within Security.java is to blame. Those other posts state the issue is with android.test.purchased returning an empty String for the signature. What I'm seeing is different. My call passes the isEmpty(signature) test, but then is rejected later in the code. Why is Google In-App Billing returning a signature that is invalid? I have included the relevant code below.

public class Security {

    // ...

    // This method is part of the trace from
    // IabHelper.queryInventory and IabHelper.onActivityResult
    public static boolean verifyPurchase(String base64PublicKey, String signedData,
            String signature) {
        if (TextUtils.isEmpty(signedData) || TextUtils.isEmpty(base64PublicKey) ||
                TextUtils.isEmpty(signature)) { // Most say their problem is here
            Log.e(TAG, "Purchase verification failed: missing data.");
            return false;
        }

        PublicKey key = Security.generatePublicKey(base64PublicKey);
        return Security.verify(key, signedData, signature); // My code gets here, but...
    }

    public static boolean verify(PublicKey publicKey, String signedData,
            String signature) {
        Signature sig;
        try {
             sig = Signature.getInstance(SIGNATURE_ALGORITHM);
             sig = initVerify(publicKey);
             sig.update(signedData.getBytes());
             if (!sig.verify(Base64.decode(signature))) {  // ...verify fails; return false
                 Log.e(TAG, "Signature verification failed.");
                 return false;
             }
             return true;
        } catch (NoSuchAlgorithmException e) {
            Log.e(TAG, "NoSuchAlgorithmException.");
        } catch (InvalidKeyException e) {
            Log.e(TAG, "Invalid key specification.");
        } catch (SignatureException e) {
            Log.e(TAG, "Signature exception.");
        } catch (Base64DecoderException e) {
            Log.e(TAG, "Base64 decoding failed.");
        }
        return false;
    }
}

Update: As I mentioned in my comment, I was running a signed APK, with the debuggable flag set to true. I have now tried making an actual purchase, with a real credit card; I saw the exact same results. Even though the Google Play purchase flow completed as expected, I did not actually receive my product. Upon returning to the store, Google Play did not return the in-app inventory.

1
The app you are testing has the same versionCode of the app in the beta dev console? Is it compiled in release? You cannot test inapp with debug app and the versionCode of the app you're using must be known to Google.Mimmo Grottoli
Oh...are you using an emulator or a real device? You need the google play updated app too!Mimmo Grottoli
I have met all those conditions. I was able to pinpoint the exact line because I am running a signed APK with the same version code as the Play Store beta, but with the debuggable flag set to true. I admit I may be somewhat grasping for straws, but I am seeing the same end result as I am when running the beta downloaded from the Play Store. Purchases do not complete as they should, and the inventory call fails after trying a purchase.Sean Beach

1 Answers

3
votes

My problem actually had nothing to do with the Google Play In-App Billing Java code. I was reading the wrong license key for my app. My project has several different flavors. When this particular flavor was added, the file that contains the license key was copied from a different flavor and never changed. Now that I have corrected the key, everything is working as intended.

TL;DR: Verify that your Google Play license key is correct.