Android In-App Billing: Purchase state stays “purchased” after order cancelation

前端 未结 9 2358
余生分开走
余生分开走 2020-12-23 19:36

I\'m currently testing my InApp billing mechanism (using the InApp Billing version 3 API, therefore taking the TrivialDrive example as reference).

I have one managed

相关标签:
9条回答
  • 2020-12-23 19:54

    I know this is a year old, but none of the answers/tips presented helped me so I thought I would add my solution.

    First, I was experiencing the same issue. Namely, made a test purchase, cancelled it, still received a purchase state indicating valid purchase.

    What I forgot was that I recently switched the 'License Test Response' field on the settings pane of the Google Play Developer Console from 'RESPOND_NORMALLY' to 'LICENSED'

    After switching it back to 'RESPOND_NORMALLY', the purchase state of the cancelled purchase was correctly returned as such.

    So, you might want to check that before you try waiting for days

    0 讨论(0)
  • 2020-12-23 19:56

    if I see correctly the reference code in the trivialdrivesample is wrong, which would be a shame for the official reference project for in app billing.

    if purchase == null it just means it has never been purchased. To get the real information you have to call

    purchase.getPurchaseState()
    

    according to here

    purchaseState The purchase state of the order. Possible values are 0 (purchased), 1 (canceled), 2 (refunded), or 3 (expired, for subscription purchases only).

    0 讨论(0)
  • 2020-12-23 19:58

    It’s already well answered in the Google official docs. Copying the words here.

    When the user cancels a subscription, Google Play does not offer a refund for the current billing cycle. Instead, it allows the user to have access to the cancelled subscription until the end of the current billing cycle, at which time it terminates the subscription. For example, if a user purchases a monthly subscription and cancels it on the 15th day of the cycle, Google Play will consider the subscription valid until the end of the 30th day (or other day, depending on the month).

    That should explain it all. getPurchase() will still return the purchase data till the end of the current subscription cycle.

    0 讨论(0)
  • 2020-12-23 19:59

    I noticed the exact same thing:

    Making an in-app purchase with a test account -> refunding the purchase with removing access -> getPurchaseState still returns Purchased (even after relogin and restart) and thus the access to the premium features is not removed in my app.

    But when I tested the same thing with a real purchase:

    Customer made a real purchase -> a couple of weeks later I refunded it -> Customer did not have access to the premium features of my app anymore.

    So could it be, that this is only a problem for test purchases?

    0 讨论(0)
  • 2020-12-23 20:10

    This problem also occures when using the app on another device with the same account. The item is not received as purchased until the device is restarted, even after hours. If trying to purchase again, the google wallet dialog says "item already owned". The return code from the iabHelper still is "user cancelled" cause the real response from the purchase activity is not given back, just written in the debug log.

    else if (resultCode == Activity.RESULT_CANCELED) {
            logDebug("Purchase canceled - Response: " + getResponseDesc(responseCode));
            result = new IabResult(IABHELPER_USER_CANCELLED, "User canceled.");
            if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
        }
    

    So its not possible to react to this google billing dialog cause we are always getting the same result IABHELPER_USER_CANCELED, even if the dialog said "item already owned".

    Edit:

    I fix it with this:

    else if (resultCode == Activity.RESULT_CANCELED) {
            logDebug("Purchase canceled - Response: " + getResponseDesc(responseCode));
            if(responseCode == 7) 
                result = new IabResult(BILLING_RESPONSE_RESULT_ITEM_ALREADY_OWNED, "Item already owned.");
            else                                                                                             
                result = new IabResult(IABHELPER_USER_CANCELLED, "User canceled.");
            if (mPurchaseListener != null) mPurchaseListener.onIabPurchaseFinished(result, null);
        }
    

    So now if the response from the billing dialog is 7 as "Item already owned" i report it back to my listener.

    0 讨论(0)
  • 2020-12-23 20:13

    I found the following section in the documentation (IAB API v2), but I am not sure if this can be used for IAB API v3. The broadcast might still be sent though.

    "... your application can receive an IN_APP_NOTIFY broadcast intent when Google Play receives a refund notification from Google Wallet. In this case, Google Play sends an IN_APP_NOTIFY message to your application. Your application can handle this message the same way it handles responses from an application-initiated REQUEST_PURCHASE message so that ultimately your application receives a PURCHASE_STATE_CHANGED message that includes information about the item that has been refunded. The refund information is included in the JSON string that accompanies the PURCHASE_STATE_CHANGED broadcast intent. Also, the purchaseState field in the JSON string is set to 2."

    from: http://developer.android.com/google/play/billing/v2/api.html#billing-action-notify

    0 讨论(0)
提交回复
热议问题