Android-inapp-billing-v3: Payment Success But onProductPurchased is not called secont time it calls

Created on 11 Jun 2015  Â·  54Comments  Â·  Source: anjlab/android-inapp-billing-v3

When making an in app purchase (Test purchase) Payment is working plus Payment success is printed but onProductPurchased() is not called at that time when trying to order the same item it gets called.
Any reason or help on this

Thanks

question

Most helpful comment

I had same issue. It was resolved by using app specific Licence Key. Go to google play publisher console, open particular app, go to Services & APIs and use Base64-encoded RSA public key.

All 54 comments

I don't understand architectural reason but they are calling onActivityResult when purchase is successful.

in your activity you need to override this method and it will be called once payment is successful

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);

}

I'm using test payment to test this criteria and when doing that payment successful message pops up but onProductPurchased is not called at that time.
But when I click to pay it again it get called the function suddenly.
Thanks

Make sure your Activity which is making the purchase has overridden onActivityResult method.
It has to look like this:

    @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (!bp.handleActivityResult(requestCode, resultCode, data))
            super.onActivityResult(requestCode, resultCode, data);
    }

Once you correctly override onActivityResult  onProductPurchased will be called first time you make a purchase. 


Check sample app for more detailed exampled and how it overrides onActivityResult:
https://github.com/anjlab/android-inapp-billing-v3/blob/master/sample/src/com/anjlab/android/iab/v3/sample2/MainActivity.java

I have the same problem, handleActivityResult returns true, but onProductPurchased is called only after triggering purchase method the second time. But on my other app exactly same code works fine and onProductPurchased called right after purchase.

Well, onActivityResult not called at all. When you making purchase for a first time, library calls startIntentSenderForResult of activity and there is no result.
When you making purchase for a second time, library immediately calls onProductPurchased.
Have no idea how to fix it

Ok, there is error 102 on first purchasing. So, my solution is to call .purchase() with null activity inside onBillingError:
public void onBillingError(int i, Throwable throwable)
{
if (i == 102)
billingProcessor.purchase(null, ITEM_ID);
}

I have the same Problem :(((((((((((((

onProductPurchased just called if i press my purchase Button at the second time.
At the second Time no Purchase windows appear but onProductPurchased is called this time correctly

if you could show your code then I could review it.
I have followed example code and it is working for me

I read the source code to get tomorrow information about the error code

    public static final int BILLING_ERROR_INVALID_SIGNATURE = 102;

So it can be a Signature problem...

Log.e(LOG_TAG, "Public key signature doesn't match!");
if (eventHandler != null) eventHandler.onBillingError(Constants.BILLING_ERROR_INVALID_SIGNATURE, null);
}
} else {
Log.e(LOG_TAG, String.format("Payload mismatch: %s != %s", purchasePayload, developerPayload));
if (eventHandler != null)
eventHandler.onBillingError(Constants.BILLING_ERROR_INVALID_SIGNATURE, null);
}

I get this Code from BillingProcessor.java from the source code

Im sure the problem is on the Method: public boolean handleActivityResult(int requestCode, int resultCode, Intent data) { in the BillingProcessor.java

As you pointed out it is invalid signature error code. Try looking at this page how to get a valid license key:
https://support.google.com/googleplay/android-developer/answer/186113?hl=en

You can also provide null as license key for testing. But you will only be able to purchase test products (
'android.test.purchased', etc)

No my License key is valid i even checked it up i think that the method handleActivityResult(int requestCode, int resultCode, Intent data) { in the BillingProcessor.java contains an error or the if else structure on this method is a little bit buggy,

My license key is also copied from Developer Console, so it's valid. But my solution with calling .purchase(null, ITEM_ID) on 102 error code still works well.

@Radiokot are you sure it works with a null activity? why not use "this" instead of null if i use this it will be the same action when the user touch the purchase button the second time

@mustii82 anyway at the second time onActyvityResult will not be called, so it does not matter which activity you gonna use there. For me, "null" is just for clarity.

@Radiokot Okay Thank you :) did you read the source code to explain the issue or do you understand why it gets to this wrong BILLING_ERROR_INVALID_SIGNATURE error ? and are you sure that the error code can only be 102 at our issue?

@mustii82 I watched BillingProcessor code to get shure that onActyvityResult will not be called when the item is already purchased. But I don't know if it is another way to get 102 error. I found that 102 refers to connection refused: http://stackoverflow.com/questions/27728970/android-inapp-purchases-error-code-102

I don't think so 102 is declared in the library code to an different issue The Guy on stack overflow talk about error 102 from the android market if you can't download a app from the play store thats a different problem and had nothing to to with this Library

look at the code number 102 is declared as a variable and have an different explanation

I'm also facing this issue. However, I'm just in a "testing phase" which I set up in my developer console. When I made my 1st purchase, everything was ok. Then I cancelled subscription in Google Play and tried to purchase it again and an error 102 popped up.
Tried your hack with null Activity but it gave me error 103.

Finally, I think that it's just a bug of Google Play Store which is not able to accept and revoke those subscriptions in that short time.

After a while of digging I found the problem
It's a bug of the library - when subscription is purchased onActivityResult is called and it is passed to library. Data provided by Google are correct.

The problematic line is line 339 in BillingProcessor.java
if(purchasePayload.equals(developerPayload)) {
Every time i get here false cause purchasePayload and developerPayload are never equal and error 102 is fired.

DeveloperPayload is generated by Google and when you want to re-subscribe it differs from original developerPayload, purchasePayload is generated by library and it still the same.

Permanent solution:
When onActivityResult is called do not call

if (!billingProcessor.handleActivityResult(requestCode, resultCode, data)) {
            super.onActivityResult(requestCode, resultCode, data);
}

and handle it by yourself

Can you fix it on the code and commit it ? Please take a workaround on the source code :)

@mroczis please build a pull request :)

@Radiokot your solutions doesent work for me :(

Solved :+1:
there is error 102 on first purchasing. and then second time in-app purchase work properly.

if you are using PRODUCT_ID = "android.test.purchase"
then use LICENSE_KEY = null

because 102 error says "Invalid DigitalKey".
see here,
http://help.wodify.com/knowledgebase/articles/173603-billing-error-messages

@Radiokot says its error 104 @chiragsheta says its error 102 on first purchasing Nobody knows what causes this errors :/ can someone make a pull request with an bugfix ? this bug is the most appearing on this library

I am also having the same issue. For me, onBillingError() is not being called so the trick with calling purchase() is not going to work.

My setup is being called from a Fragment and I do have onActivityResult() in place.

Anyone one else also not getting onBillingError on first purchase? I'll start digging deeper for my scenario.

@mustii82 Maybe everyone has a different issue but its acting the same. More comments from you saying to make a pull request isn't going to solve anything.

Ok well I think I have a working fix for me. It was mainly due to onActivitiyResult() not being called in the fragment due to startIntentSenderforResult(). I'm not too deep into it but there is a known issue with that and passing to a fragment. I'm sure there is probably a cleaner fix but basically I just told the activity to pass onActivityResult over to the fragments:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
for (Fragment fragment : getSupportFragmentManager().getFragments())
{
if (fragment != null)
{
fragment.onActivityResult(requestCode, resultCode, data);
}
}
}

It's not necessarily a problem. The returned billing public key is NOT the real public key. Thus the signature verification fails for test transactions. Simply initialize BillingProcessor with an empty public key when testing and the signature verification will pass. I do the following, good to go.

private static boolean TESTING = false;
public static final String IN_APP_BILLING_KEY = TESTING ? "" : REAL_KEY;
public static String DONATION_PRODUCT_ID = TESTING ? "android.test.purchased" : PRODUCT_ID;

maybe we should start to look for similaritys between these different problems and errors i think all these problems are the responds from one little bug all these problems share the similarity that we need to call 2 times to get it working so by counting similaritys we are maybe able to find the root of this problem

Generally the Library works great. It's just when using android.test.purchased the real Billing Key is not returned from the server response. The only difference between my solution above and a "better" solution is to add a boolean to the lib that represents testing mode; testing mode will bypass the return response signature check, which is exactly what happens when you pass an empty APP_BILLING_KEY during initialization.

See line 418 of BillingProcessor. When the billing key is null the signature check passes :+1:

@nseidm1 many people get this error even with real billing keys without testing anything so its a bigger problem i think even my release apps have this problem

If you look at the code the only reason the onProductPurchased isn't called is the verifyPurchaseSignature() method on line 418 in BillingProcessor. That's it. No magic.

I personally think the current implementation is decent. Works fine in production and debug testing for me. Just use the below logic for managing your billing key.

private static boolean TESTING = false;
public static final String IN_APP_BILLING_KEY = TESTING ? "" : REAL_KEY;
public static String DONATION_PRODUCT_ID = TESTING ? "android.test.purchased" : PRODUCT_ID;

And just use APP_BILLING_KEY in the BillingProcessor constructor.

Has this ever been resolved because I am still seeing the same thing. I do not get a completed purchase (onProductPurchased or onActivityResult) callback when I call bp.purchase. When I call it a second time, it works. Is this the best I am going to get with this lib?

Also, when I use the test approach described above it works the same except that the Google Play Store service crashes.

Any ideas?

onProductPurchase is not firing in first purchase. Still same problem.

onProductPurchase is not firing in first purchase. Any ideas???

"android.test.purchased" and key "" ---- onProductPurchase working correct

with real billing key and PRODUCT_ID ---- onProductPurchase working when you making purchase for a second time

I never got it to work and gave up on it a long time ago. There are some
bugs in there that were never fixed. If you get it to work I would like to
hear what you did.

On Fri, Jul 1, 2016 at 7:06 PM, Viktor [email protected] wrote:

onProductPurchase is not firing in first purchase. Any ideas???

—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/anjlab/android-inapp-billing-v3/issues/100#issuecomment-230065473,
or mute the thread
https://github.com/notifications/unsubscribe/AF0rInXJyQew0eby5CZ2S2XrVLPKpQZrks5qRZ2SgaJpZM4E_hpG
.

I do face the exact same issue and can't use the library.
My previous implementation was never failing on this.

The security check is failing with the following exception catched : java.security.spec.InvalidKeySpecException: java.lang.RuntimeException: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag.

The security check is called in BillingProcessor l.495 : Security.verifyPurchase(productId, signatureBase64, purchaseData, dataSignature)

Any idea ?

Still Struggling with this.

I had same issue. It was resolved by using app specific Licence Key. Go to google play publisher console, open particular app, go to Services & APIs and use Base64-encoded RSA public key.

Still getting same Issue 👎 👎

My all problems with this is connected with super.onActivityResult - must be called for proper working.

When payment successful receiving an error BILLING_ERROR_INVALID_SIGNATURE.
Is there any fix for this?
iab version 1.0.38

Please read thread above

Error:(71, 0) Could not get unknown property 'sonatypeRepo' for object of type org.gradle.api.publication.maven.internal.deployer.DefaultGroovyMavenDeployer.
Open File

I had issue with subscriptions.
After succesfull subscribion i had error 102.
My fix was add this permission to the Manifest:

<uses-permission android:name="com.android.vending.CHECK_LICENSE" />

according to Play Console documentation:
https://developer.android.com/google/play/licensing/adding-licensing

@pkarolis you solution worked for me

I am using this with Fragments, and when i call purchase it gets purchased successfully in test as well as in production, first time onProductPurchased() method is not being called after Purchase Successful, when we click second time on purchase it works.

i added this code to my main activity as @cmendes0101 sugested:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        for (Fragment fragment : getSupportFragmentManager().getFragments())
        {
            if (fragment != null)
            {
                fragment.onActivityResult(requestCode, resultCode, data);
            }
        }
    }

and everything works fine now.

did any one solve the issue i am facing the same problem....?

Same Problem, it's affecting react-native-billing as well :(

@Boomcollective on 22 Sep 2016 is completely right! It was all about a wrong API key.

I'm currently using @pkarolis work around as I had to push to production ASAP.
But I know it's not a very nice move as you might take untended actions when an actual 102 error occurs.

After using breakpoints I discovered that result code in onActivityResult is - 1 and the handleActivityResult method is false..

I haven't tried using App specific license key but I would do that to see if it would work.

BTW, I haven't tested with an actual card as I have been using the Google play test payment, I don't know if that might be part of the issue.

i added this code to my main activity as @cmendes0101 sugested:

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        for (Fragment fragment : getSupportFragmentManager().getFragments())
        {
            if (fragment != null)
            {
                fragment.onActivityResult(requestCode, resultCode, data);
            }
        }
    }

and everything works fine now.

Thank you so much, my head was going around in circles to figure how to solve this problem

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mahirozdin picture mahirozdin  Â·  3Comments

kriti-1 picture kriti-1  Â·  7Comments

mattiaferigutti picture mattiaferigutti  Â·  6Comments

RishabhTayal picture RishabhTayal  Â·  3Comments

RajatVaghani picture RajatVaghani  Â·  8Comments