Question

iOS - How to handle pending transactions?

  • 5 December 2022
  • 3 replies
  • 507 views

Badge +1

I might be misunderstanding how RevenueCat is supposed to work, but... We used to use SwiftyStoreKit to handle our pending transactions. RevenueCat states that:

Remove the SwiftyStoreKit completeTransactions() method, and replace it with the Purchases SDK configure()method.

 

Our workflow is: User makes a purchase, after the purchase is confirmed we call our backend to inform that this user has unlocked a product, then after a successful confirmation, we manually invoke the complete transaction, so that the user can be billed.

If there were any transactions that were not successfully communicated to the backend, they would be retried in the background.

Given the description above, provided by the documentation, it seems like there is no way to handle this.

What are we missing here? How can we ensure that purchases are only finished once our backend is informed?

 

Thank you


3 replies

Userlevel 4
Badge +8

Our workflow is: User makes a purchase, after the purchase is confirmed we call our backend to inform that this user has unlocked a product, then after a successful confirmation, we manually invoke the complete transaction, so that the user can be billed.

 

If there were any transactions that were not successfully communicated to the backend, they would be retried in the background.

You have a good understanding of what is happening – this is pretty much exactly what RevenueCat does, just substitute "RevenueCat" for "backend".

 

What are we missing here? How can we ensure that purchases are only finished once our backend is informed?

 Since RevenueCat is finishing transactions for you, there are two ways to inform your backend:

  1. webhooks (paid feature) - RevenueCat validates the receipt against Apple's servers, if successful a webhook event is sent to your backend, so you can be sure that webhook = valid purchase
  2. (free way) - Once the SDK sends the receipt to RevenueCat and receives a successful response, the SDK will let your app know via callback that the purchase went through without any errors. At that point your app can ping your backend letting it know to make a request to RevenueCat to check if the purchase is on the user's profile.
Badge +1

Hello. Thank you for your reply, but I still have a concern with the second workflow you mentioned:

(free way) - Once the SDK sends the receipt to RevenueCat and receives a successful response, the SDK will let your app know via callback that the purchase went through without any errors. At that point your app can ping your backend letting it know to make a request to RevenueCat to check if the purchase is on the user's profile.

 

If for some reason the app fails to communicate with the backend, even if we have a retry mechanism, doesn’t it mean that the user got billed and does not have access to what he/she was billed for (since we control product lock / unlock via our backend)?

The manual transaction finishing was preventing this, since we only finished the transaction after our backend was informed that it would need to unlock the items associated with that purchase.

 

Thank you for the clarification.

Userlevel 4
Badge +8

Yes, because of how you have implemented this, the user would not get access to what they are billed for. In the case that the app fails to communicate with the backend that a purchase has happened, you need to implement a way to record the failed request so you can retry sending it.

In the case that the app can’t send the receipt to RevenueCat, then the app won’t finish the StoreKit transaction and will retry until RevenueCat gets the receipt, at which point the SDK finishes the StoreKit transaction.

Reply