voltrue2 / in-app-purchase

A Node.js module for in-App-Purchase for iOS, Android, Amazon and Windows.
http://iap.gracenode.org
Other
1.04k stars 287 forks source link

Note: Always set ignoreCanceled: true for Apple, otherwise you might reject valid purchases (this is not obvious from current documentation!) #342

Open tkafka opened 3 years ago

tkafka commented 3 years ago

For Apple, purchases are sorted by purchase_date (latest one goes first) (here), and then deduplicated by original_transaction_id (here).

This might seem innocent enough, but when the user upgrades eg. from monthly subscription to yearly, Apple might add an extra cancelled monthly transaction (probably to end prematurely the line of monthly subscriptions), which happens after the just activated yearly subscription. In the end, the sorted list of purchases looks like this:

As these transactions have a same original_transaction_id, the first one will overwrite the following one's if you set ignoreCanceled: false. As a result, your user with yearly subscription will appear to have just one cancelled monthly transaction!

The fix? Set ignoreCanceled: true, so that cancelled transactions are filtered out before the deduplication. You will lose an evidence of cancelled payments, though.

dataxpress commented 2 years ago

Thank you for posting this and your analysis! I'm running into this issue as well - lots of users who switch from monthly to annual complaining of their subscription not working. However, I am setting ignoreCanceled: true:

let purchaseData = iap.getPurchaseData(validatedData, { ignoreCanceled: true, ignoreExpired: true });

I am continuing to dig into this, as I think there might be something else going on with the ordering / sorting / filtering of the transactions. Have you had yours continue to work with ignoreCanceled: true or was there another workaround you needed? I'm also wondering if ignoreExpired is somehow causing a problem. Will post more if I come across anything.

pierroo commented 1 year ago

More than a year later, but did you guys manage to find a solution? @dataxpress @tkafka

That would be super helpful, for managing subscriptions with ios and their ordering in the "in_app" array is a complete nightmare. For consumable one time purchase it's always the first item of this array that gives the right info, but when it comes to subscription it keeps being messed up...

Your help would be super appreciated.