This repository was archived by the owner on Oct 16, 2025. It is now read-only.
Commit 8972aeb
authored
fix: skip upgraded transactions during subscription upgrade (#20)
## Problem
When upgrading from a monthly subscription to a yearly subscription
(within the same subscription group), `onPurchaseSuccess` was emitting
old purchase objects first, and the correct upgraded transaction arrived
only after 3-4 minutes in iOS Sandbox.
- Related hyochan/react-native-iap#3054
### Root Cause
StoreKit 2's `Transaction.updates` emits **upgraded transactions** (with
`isUpgraded = true`) during subscription upgrades, in addition to the
new subscription transaction. These old transactions should be filtered
out.
## Solution
Added filtering logic to skip both revoked and upgraded transactions in
`startTransactionListener()`:
```swift
// Skip revoked or upgraded transactions (happens during subscription upgrades)
if transaction.revocationDate != nil || transaction.isUpgraded {
OpenIapLog.debug("⏭️ Skipping revoked/upgraded transaction: \(transactionId)")
continue
}
```
This follows Apple's official StoreKit 2 best practices from [WWDC 2021
- Meet StoreKit
2](https://developer.apple.com/videos/play/wwdc2021/10114/):
> When checking if a product is purchased, ensure that the transaction's
`revocationDate` equals nil (to exclude refunded transactions) and that
subscriptions where a customer has upgraded don't have the `isUpgraded`
flag set to true.
**Apple Documentation:**
-
[`Transaction.isUpgraded`](https://developer.apple.com/documentation/storekit/transaction/3812954-isupgraded)
- A Boolean that indicates whether the user upgraded to another
subscription
-
[`Transaction.revocationDate`](https://developer.apple.com/documentation/storekit/transaction/3818605-revocationdate)
- The date that the App Store refunded the transaction
## Changes
- Added `transaction.isUpgraded` check in `startTransactionListener()`
- Combined with existing `revocationDate` check for comprehensive
filtering
- Added debug logging for skipped transactions
## Testing
- ✅ All unit tests passing (10 tests)
- ✅ Swift build successful
- ✅ Maintains existing functionality (subscription renewals, duplicate
prevention)1 parent 65f150f commit 8972aeb
1 file changed
+3
-3
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
838 | 838 | | |
839 | 839 | | |
840 | 840 | | |
841 | | - | |
842 | | - | |
843 | | - | |
| 841 | + | |
| 842 | + | |
| 843 | + | |
844 | 844 | | |
845 | 845 | | |
846 | 846 | | |
| |||
0 commit comments