react-native-iap
react-native-iap copied to clipboard
getAvailablePurchases returns also expired purchases on iOS. So, how can I get a user's current active subscription in iOS?
Please use the Discussion board if you want to get some help. Please use issues to report bugs.
Description
getAvailablePurchases returns also expired purchases on iOS. So, how can I get a user's current active subscription in iOS?
Expected Behavior
Like Android, getAvailablePurchases must return only the active purchases.
Environment:
- react-native-iap: ^12.10.5
- react-native: 0.70.10
- Platforms (iOS): 16.3.1
Sadly it's always been quite cumbersome on iOS.
Easiest way is to send off a receipt to your server, then have it ask Apple if it's expired or not. Today you would use the App Store Server API, and the endpoint /v1/transactions/{transactionId} The old API is deprecated.
You could also validate it in-app, by decrypting the receipt, but that's not exactly easy. At least I have no clue how to do it: https://developer.apple.com/documentation/appstorereceipts/validating_receipts_on_the_device
But now that Storekit2 is implemented in react-native-iap, you can look at transaction.expirationDate via transactionListener and do a simple epoch comparison. And maybe for good measure validate it on your server too.
Also maybe see https://react-native-iap.dooboolab.com/docs/guides/receipts if you haven't.
Writing all this hoping someone can prove me wrong. Would kill for something easy like Android's purchaseState.
@Robiullah2244 Have you tried this?
purchases = await RNIap.getAvailablePurchases({
onlyIncludeActiveItems: true,
})
@Robiullah2244 Have you tried this?
purchases = await RNIap.getAvailablePurchases({ onlyIncludeActiveItems: true, })
Hi @bitfabrikken, Thanks and yes, I already tried it. Also, the parameter is by default true. No luck.
This code really works but only with StoreKit 2. If you are using Storekit 1 ... you are well ... we can call it unlucky ( ͡° ʖ̯ ͡° ).
const activeSubscription = await getAvailablePurchases({onlyIncludeActiveItems: true})
To get it work you have to configure at start that you want to use it only with Storekit 2:
setup({storekitMode: 'STOREKIT2_MODE'})
and declare your app supports only iOS 15+ in your project.pbxproj
-> IPHONEOS_DEPLOYMENT_TARGET = 15.0;
.
Don't support Storekit 1 (iOS <15) and your life will be much much easier.
If your app is already in your production -> The major task is also to convince your product team. Tip how to do that is: if you are using Firebase Analytics -> list how many of your users are using old iOS, I can expect it will be minority, iOS users are generally good at keeping their phone up-to-date.
@cervebar This doesn't appear to be an option yet in the SDK? Is there a pending release this flag will be included in?
Please disregard. This is an option in the bae SDK getAvailablePurchases()
method but NOT in the one returned by the useIAP()
hook.
I don't know if this is the best approach, but I'm fetching the purchase history, sorting by date, then trying to verify the most recent subscription id on the server
I also don't know the difference between purchaseHistory
and availablePurchases
so if anyone has any details please share 😅
getAvailablePurchases
we don't use the hook version (from useIap.ts
), because it doesn't pass this parameter, but call directly (from file iap.ts
)
import {
getAvailablePurchases
} from 'react-native-iap'