I have a consumable IAP in an app. The app has users and login/ logout functionality to switch between them. The amount of the consumable product associated with an user is stored on a server. So when the purchase is made a call to the server is made to "inform" it to update with the new amount of product. This call could potentially fail. From what I read what I should do there is to retry in background until it succeeds. I wonder how to handle the following cases:
1. The user logs out and kills the app. Then on start of the app SKPaymentTransactionObserver is called with SKPaymentTransactionStatePurchased because the transactions has not been finished. How do I know for which user of the app this transaction is. Should I store transaction ID-s alongside some user specific information to continue retrying to update with the tokens for this user. Or is there a better approach?
2. The state of the transaction is SKPaymentTransactionStateDeferred. Similar scenario as in point 1. The user logs out and either doesn't log in or logs in with different user. SKPaymentTransactionStatePurchased is received at some point and the app should update the correct user with the purchased product. The app could also be restarted in the process. Should again the transaction id be saved alongside some user information to make the update to the backend? Or is there a better approach.
3. The user logs out. The user logs in the app on another device. SKPaymentTransactionStatePurchased probably won't be called and the user will receive nothing. Maybe I should just block the UI until the purchase is updated on the server also but I worry of some big delays. Also if the user kills the app in the waiting they will be charged but won't receive anything. So can I do something?
Probably there are cases I am missing here, but these are the ones that come to my mind. I don't see similar questions very often and some specific handling is not mentioned so I wonder if things are not easier than I make them to be. The transaction observer is added in didFinishLaunchingWithOptions in AppDelegate and removed in applicationWillTerminate in AppDelegate.