Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"No value for developerPayload" BillingError on Promo Code use #156

Closed
kanetik opened this issue Feb 22, 2016 · 19 comments · Fixed by #295
Closed

"No value for developerPayload" BillingError on Promo Code use #156

kanetik opened this issue Feb 22, 2016 · 19 comments · Fixed by #295
Labels

Comments

@kanetik
Copy link

kanetik commented Feb 22, 2016

I am testing adding Promo Code support into my app, and while I can make a normal payment for an in-app purchase, I run into problems when I try using a promo code. The response comes back with this error:

E/iabv3: org.json.JSONException: No value for developerPayload

I am working around the problem at the moment by doing this:

if (errorCode == Constants.BILLING_ERROR_OTHER_ERROR && _billingProcessor.loadOwnedPurchasesFromGoogle() && _billingProcessor.isPurchased(SKU))

The result of that is usually true, which proves that the purchase DID succeed, just the response was lacking the developerPayload that the library expects.

@balachandarlinks
Copy link

I ran into this same issue when I tried to purchase items with a promo code.

@MrEko
Copy link

MrEko commented Mar 3, 2016

Same issue here

@ghost
Copy link

ghost commented Mar 26, 2016

I have the same issue

@loki666
Copy link

loki666 commented Mar 31, 2016

Same issue here...

I dont understand why this lib bother with developerPayload.

This is really something useful when you have a backend that process the purchases responses, and the check is done on the backend (both signature and developerPayload)

@ItsCalebJones
Copy link

Have there been any updates on this? Wanting to use promo codes with my customers.

@ernell
Copy link

ernell commented May 19, 2016

Same here. Using the above workaround for now.

@serggl
Copy link
Member

serggl commented Nov 7, 2016

Can anyone paste a full stack trace for this problem? From the line above it seem like some error from billing service, not from the library itself.
Also, I've tried to redeem a promo code from Google Play menu, and it seem to work well

@ravivghl
Copy link

ravivghl commented Nov 9, 2016

how to use this lib with promotional or redeem code? i am try with direct add item but google in i can see add item success but in code not get success. how to solve it for redeem code. @serggl

@serggl
Copy link
Member

serggl commented Nov 11, 2016

Does anybody know if there is some additional setup needed in order to be able to enter promo codes directly on the purchase dialog? and not at the Google Play's redeem promo code section?

@Thomas-Vos
Copy link
Contributor

@serggl Promo codes work when entered in Google Play > menu > redeem, but only if you don't use a payload. Other method by entering in the purchase dialog, gives an error. When trying to purchase again, it gives an error it is already purchased, but isPurchased(...) still returns false.

https://developer.android.com/google/play/billing/billing_promotions.html#workflow

The user can enter the promo code as part of the app's ordinary purchase flow, as described in Implementing In-app Billing. As far as the app is concerned, this is just like an ordinary purchase, except that the user makes payment with a promo code instead of with money.

In my tests, eventually the promo code will become "active", but takes some time.

@serggl
Copy link
Member

serggl commented Dec 8, 2016

@SuperThomasLab seem like you are good in this context, can you help me testing code from feature/better-promo-support branch? I still can not see an option for entering promo codes on the purchase dialog, so there must be something with my setup...

@Thomas-Vos
Copy link
Contributor

Thomas-Vos commented Dec 8, 2016

@serggl I checked out the feature/better-promo-support branch, and think it should fix the empty payload issue. (have not tested yet). Wouldn't it be a security risk, though? A malicious app could just return an empty payload and it would be accepted. I think it's best to just leave the payload null if you want promo code support, and leave the code as it is. (or make it optional).

About the purchase dialog:
When the dialog opens you should be able to change the payment method to "Redeem". (Tap the little arrow below the title). Let me know if you need a screenshot.

If we just leave the payload as it is, there's still one problem with promo codes: Entering it through the purchase dialog. After you enter a promo code, and tap buy, onBillingError(...) is called. If you need any logs, please let me know.

BTW: The following URL opens Google Play and automatically enters the promo code: https://play.google.com/redeem?code=YOURPROMOCODE. Might be useful for something. I currently use this with a custom redeem dialog to prevent users entering it in the purchase dialog.

@serggl
Copy link
Member

serggl commented Dec 9, 2016

@SuperThomasLab I only have an option to change the payment method, not to redeem a promo code, really dont know why (maybe because my test app was never released from alpha to production mode).
Yes, I tried that link previously, thats a quite different flow, which I believe works.
Also I agree on a security concern, my original plan was to inspect the data returning with a purchase here https://github.com/anjlab/android-inapp-billing-v3/blob/master/library/src/main/java/com/anjlab/android/iab/v3/BillingProcessor.java#L470. Maybe there are some promo-code specific fields there. Can you try that?

@Thomas-Vos
Copy link
Contributor

@serggl This is the code I used:

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

    Bundle bundle = data.getExtras();
    if (bundle != null) {
        StringBuilder stringBuilder = new StringBuilder();
        for (String key : bundle.keySet()) {
            Object value = bundle.get(key);
            stringBuilder.append("Item: ").append(key).append(" | ");

            if (value != null) {
                stringBuilder.append(value).append(" (").append(value.getClass().getName()).append(")");
            } else {
                stringBuilder.append("No value");
            }

            stringBuilder.append("\n");
        }
        
        // This just shares text with an Intent, nothing special
        IntentHelper.shareString(mActivity, stringBuilder.toString(), "onActivityResult");
    }
    
    if (!bp.handleActivityResult(requestCode, resultCode, data)) {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

This is the output of a normal purchase:

Item: INAPP_PURCHASE_DATA | {"packageName":"com.my.packagename","productId":"donate_option_1","purchaseTime":1481302139187,"purchaseState":0,"developerPayload":"inapp:donate_option_1:some_random_text","purchaseToken":"some_random_text"} (java.lang.String)
Item: INAPP_DATA_SIGNATURE | some_random_text (java.lang.String)
Item: RESPONSE_CODE | 0 (java.lang.Integer)

This is the output when using a promo code in purchase dialog:

Item: INAPP_PURCHASE_DATA | {"packageName":"com.my.packagename","productId":"donate_option_1","purchaseTime":1481302370156,"purchaseState":0,"purchaseToken":"some_random_text"} (java.lang.String)
Item: INAPP_DATA_SIGNATURE | some_random_text (java.lang.String)
Item: RESPONSE_CODE | 0 (java.lang.Integer)

As you can see, there's no developer payload. (And the method onBillingError(...) is called). The purchase becomes "active" when trying to purchase again. (I think because BillingProcessor checks again if an item is purchased). Maybe we should create something to disable the payload completely.

Here are some screenshots of the purchase dialog: http://imgur.com/a/2yGfe

@serggl
Copy link
Member

serggl commented Dec 10, 2016

@SuperThomasLab this seem like a known issue already: https://github.com/googlesamples/android-play-billing/issues/7
In this light, not really sure what we can do here

@Thomas-Vos
Copy link
Contributor

Thomas-Vos commented Dec 10, 2016

@serggl There are two options:

  1. We could add a note in the readme to not use a payload if you want promo code support. Then it should work through the Google Play app. The redeem URL can be used to prevent users entering it in the purchase dialog, but instead in a custom dialog that opens Google Play.

  2. Second option is to use this workaround:

     if (errorCode == Constants.BILLING_ERROR_OTHER_ERROR && _billingProcessor.loadOwnedPurchasesFromGoogle() && _billingProcessor.isPurchased(SKU))
    

    But it needs to be improved, because I don't think it's very good to call loadOwnedPurchasesFromGoogle() every time there is an error. Any ideas how we could solve this?

@serggl
Copy link
Member

serggl commented Dec 12, 2016

@SuperThomasLab I agreed on your options, with some notes:

  1. Yes, we could just add a method the with disable payload checks at all, so the developers will have a control on it at their own risk

  2. That is an also good option, we could document this workaround in README, and also change the error code. I believe it should be a new error code, something like BILLING_ERROR_INVALID_PAYLOAD

Not sure what the best option would be. Anyone else reading this thread? Thoughts?

@matpag
Copy link

matpag commented Jun 1, 2017

There is an official (not so good) answer finally on this topic https://github.com/googlesamples/android-play-billing/issues/7#issuecomment-305316583

@serggl
Copy link
Member

serggl commented Aug 4, 2017

well, why not good? at least it is now officially documented behaviour which we can deal with

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants