You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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:
purchase date = 2021-02-17 09:55:00 monthly subscription, cancelled (newest, few hours after previous)
purchase date = 2021-02-17 07:12:00 yearly subscription, valid
purchase date = 2021-02-03 15:34:00 previous month's monthly subscription, valid
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.
The text was updated successfully, but these errors were encountered:
tkafka
changed the title
Note: Always set ignoreCanceled: true for Apple, otherwise you might reject valid purchases (this is not obvious from current documentation)!
Note: Always set ignoreCanceled: true for Apple, otherwise you might reject valid purchases (this is not obvious from current documentation!)
May 22, 2021
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.
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...
For Apple, purchases are sorted by
purchase_date
(latest one goes first) (here), and then deduplicated byoriginal_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:
purchase date = 2021-02-17 09:55:00
monthly subscription, cancelled (newest, few hours after previous)purchase date = 2021-02-17 07:12:00
yearly subscription, validpurchase date = 2021-02-03 15:34:00
previous month's monthly subscription, validAs these transactions have a same
original_transaction_id
, the first one will overwrite the following one's if you setignoreCanceled: 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.The text was updated successfully, but these errors were encountered: