It depends on why it fails. Is it a transient error that you believe you can overcome then try again later and notify your client of the result. Until that time you shouldn’t call finish() on the transaction. If it is a permanent error then notify the client and call iap.finish().
As long as you haven’t called iap.finish() the client will get a callback when you do iap.set_listener() with the details of the ongoing purchase.
You should call finish() in a case when you sure that everything is fine with delivering of your goods. Or in case if you are sure that this purchase is corrupted (cheater for example) or the order has previously been processed.
Thanks for the reply!
But, if the problem is permanent, such as the user not having received their virtual goods (eg. data lost due to some backend issues), in such a case I might want to avoid calling iap.finish() and instead notifying the client:
Something went wrong. But don’t worry, we haven’t taken your money. Try again soon!
Is that correct way of thinking?
Edit
I just saw your reply, @AGulev, which answered this follow up question.
Thanks!