# Calling iap.finish() on failed verification

**URL:** <https://forum.defold.com/t/calling-iap-finish-on-failed-verification/41211>\
**Category:** Questions\
**Created:** [January 22, 2019, 10:24am UTC](https://forum.defold.com/t/calling-iap-finish-on-failed-verification/41211 "2019-01-22T10:24:21Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![sjirenius](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/sjirenius/32/13177_2.png) [@sjirenius](https://forum.defold.com/u/sjirenius)\
**Post date:** [January 22, 2019, 10:24am UTC](https://forum.defold.com/t/calling-iap-finish-on-failed-verification/41211/1 "2019-01-22T10:24:21Z")

</div>

In the example for [iap.buy()](https://www.defold.com/ref/iap/#iap.buy:id--options-) , we have the code:

```lua
if (transaction.state == iap.TRANS_STATE_PURCHASED) then
    -- do server-side verification of purchase here..
    iap.finish(transaction)
end

```

What if my server-side verification fails, what is the correct way to act?

Should I simply not call `iap.finish(transaction)`, or is there some other way to explicitly cancel the transaction?

---

<div class="post-metadata">

**Author:** ![britzl](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/britzl/32/23_2.png) [@britzl](https://forum.defold.com/u/britzl)\
**Post date:** [January 22, 2019, 10:30am UTC](https://forum.defold.com/t/calling-iap-finish-on-failed-verification/41211/2 "2019-01-22T10:30:45Z")

</div>

> [@sjirenius](#):
>
> What if my server-side verification fails, what is the correct way to act?
> 
> Should I simply not call `iap.finish(transaction)` , or is there some other way to explicitly cancel the transaction?

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.

---

<div class="post-metadata">

**Author:** ![AGulev](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/agulev/32/4541_2.png) [@AGulev](https://forum.defold.com/u/AGulev)\
**Post date:** [January 22, 2019, 10:37am UTC](https://forum.defold.com/t/calling-iap-finish-on-failed-verification/41211/3 "2019-01-22T10:37:10Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![sjirenius](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/sjirenius/32/13177_2.png) [@sjirenius](https://forum.defold.com/u/sjirenius)\
**Post date:** [January 22, 2019, 10:53am UTC](https://forum.defold.com/t/calling-iap-finish-on-failed-verification/41211/4 "2019-01-22T10:53:41Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![britzl](https://forum-defold.b-cdn.net/user_avatar/forum.defold.com/britzl/32/23_2.png) [@britzl](https://forum.defold.com/u/britzl)\
**Post date:** [January 22, 2019, 11:06am UTC](https://forum.defold.com/t/calling-iap-finish-on-failed-verification/41211/5 "2019-01-22T11:06:28Z")

</div>

> [@sjirenius](#):
>
> 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()`

Exactly, don’t call iap.finish() until the virtual goods have been awarded.

> [@sjirenius](#):
>
> > Something went wrong. But don’t worry, we haven’t taken your money. Try again soon!

Well, you have actually taken their money 🙂 The Google/Apple purchase flow has been completed and the money has been withdrawn.

You shouldn’t ask the user to do retries. You should retry in the background.
