How to handle pending purchases from Google Play
Asked Answered
C

3

23

Most of our purchases keep getting canceled after 3 days 30 minutes exactly, which I presume is the result of pending purchase state. However, there is so little documentation about how to handle pending purchases exactly. And, for some reason, even though I am a tester myself, I cannot test it because there is no "Slow card" option on purchase methods. Also, we do not have a backend server to well, back us up.

This is the explanation I've found from the official documentation:

void handlePurchase(Purchase purchase) {
    if (purchase.getPurchaseState() == PurchaseState.PURCHASED) {
        // Acknowledge purchase and grant the item to the user
    } else if (purchase.getPurchaseState() == PurchaseState.PENDING) {
        // Here you can confirm to the user that they've started the pending
        // purchase, and to complete it, they should follow instructions that
        // are given to them. You can also choose to remind the user in the
        // future to complete the purchase if you detect that it is still
        // pending.
    }
}

Look at the explanation on the PENDING state. What does "To complete the purchase, they should follow instructions that are given to them" mean? What are these instructions exactly? Do we need to redirect the user to Google Play or what? It is not specific about what to do and is bugging me out because purchases are getting cancelled for no reason, or for this reason. How does one complete a pending purchase? There is nothing about it, or I cannot find it, hence I ended up here.

I hope you can help me figure this out. Thanks.

Certiorari answered 8/10, 2019 at 13:3 Comment(1)
it's 2023, still struggling to make it work because of their poor documentationAlburga
E
31

I agree the documentation is poor, especially since the one time you want to know exactly what's happening is when you're handling other people's money!

It looks like a 'slow card' transaction is actually a 'pending purchase', something Google have been rolling out in 2019. Here's the probable flow...

  • In your app the user taps 'Buy now'
  • They see the Google checkout overlay
  • They choose "Pay at Freddina's Grocery, Accra" (a local store that's signed up to deal with Google pending purchases)
  • Google checkout displays a code to show to Freddina
  • User pays Freddina in cash and Freddina processes the payment using that code
  • 10 mins or so later, the purchase update will land in your app

As for handling unpredictably timed update events, we have an app with a handlePurchaseUpdated method listening out from the moment the app starts, and makes changes based on the Purchase object that comes with it. Here's an example flow:

  • We listen for purchase updates as soon as the app starts up
  • User makes a slow purchase
  • We get a purchase update
  • The passed Purchase object has purchase state PENDING
  • We tell the user that we'll notify them when the purchase is complete
  • At some point in the future (e.g. next day after an app restart) the purchase update comes in
  • If the purchase state is now PURCHASED we finalise the purchase and tell the user

Note: Ours is a ReactNative app, not native java, but the flow should be the same.

It's complicated to implement because you have to pick your time to make your purchase changes and display the purchase result at a time that makes sense, not necessarily when the purchase update arrives 5 secs after startup (or any other weird time). And it gets more complicated if there are errors during your grant-entitlement or acknowledgement steps, urgh.

Also, you might not be seeing the 'slow card' tester option because you didn't allow it?


Update for 2022: Personally I feel the documentation is still so poor, and the complexity so great, that I would recommend using a service like IAPHUB to manage iaps and subscriptions.

Extender answered 1/11, 2019 at 13:20 Comment(3)
I'm not sure what you mean by "allowing it" but I believe the issue we're experiencing is not related to pending purchases at all. I thought we needed to redirect the user first, then wait for a response from the app itself, but if they use a service such as "Pay at Freddina's Grocery, Accra" then the user should know that the purchase will be delayed. If "onPurchasesUpdated" or "queryPurchases" returns the updated value already, then there should be no problems. Thanks for your answer, though, I'm accepting it.Certiorari
As you explain above, it may be the case that user purchase using physical store, so transaction went to pending. It keeps pending for few days, in that time if user does not purchase it using that code from physical store, then at the end transaction may got cancelled ? I think most of users are doing this to play with it.Sherman
This was a great explanation and roadmap. But the reason his purchases were being cancelled was for not acknowledge the purchases as @RossCampaign pointed out in her answer.Kiwi
J
9

It sounds like you are not acknowledging the purchase. See below from the Google Play Billing documentation:

If you use the Google Play Billing Library version 2.0 or newer, you must acknowledge all purchases within three days. Failure to properly acknowledge purchases results in those purchases being refunded.

Jazminejazz answered 25/11, 2019 at 15:38 Comment(2)
You can't acknowledge pending purchases, you'll get an exception if you try to do so.Carmina
@HeysemKatibi That is objectively true. BUT I believe it's misleading in this situation. The original author never mentioned that they were even attempting to acknowledge the payment. As well, the documentation here seems to imply that pending purchases need to be ENABLED. It's possible that the OP never even enabled pending purchases and shouldn't have to deal with them: From documentation: ``` Call enablePendingPurchases() as part of initializing the BillingClient to enable pending transactions for your app. ```Edwinedwina
P
0

According to Google's documentation (https://developer.android.com/google/play/billing/integrate#pending), you need to call enablePendingPurchases() and then your PurchasesUpdatedListener will be notified when the state changes from PENDING to PURCHASED.

Protrusion answered 10/10, 2022 at 22:36 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.