I settled on this approach:
If the DoRecovery API returns with a status code of 2, the subscription in question is still in recovery, I set up a timer and begin polling getAllPurchases so that my app can know when/if the subscription comes out of recovery.
I use exponential back-off with the timer to keep from spamming Roku's API servers.
I have push-notifications set up with my back-end servers, but that only helps if I poll my servers instead of Roku's getAllPurchases, and there are security concerns with that; how do I authenticate the requests to make sure the right account is asking about a transaction they own?
I can do that by forcing the user to log in with their app account, i.e. non-Roku account, but instead of doing that I opted for polling getAllPurchases.
My workflow is:
- At app startup, getAllPurchases is pinged
- If there are any subscriptions in recovery, I call the DoRecovery API at the appropriate place so that they are prompted to update their payment info.
- Upon the DoRecovery API completing, if the user didn't cancel the payment info dialog, I check the return status:
- If it's 1, we're all good (payment info was updated and processed).
- If it's 2, we assume they entered the payment info but that it hasn't had time to be processed (subscriptions are still in recovery).
- Begin polling getAllPurchases as described above (with exponential back-off).
- When the subscription in question comes out of recovery, turn off timer.
- If it's 3, the user cancelled the subscription. Update the internal logic of the app accordingly.
At any rate, this is the approach I've settled on for now. I'm still testing and have not submitted the app for certification, so we'll see if this passes muster with Roku then.