react-native-iap取消订阅:无法监听退订结果的技术问题
解决react-native-iap退订操作无法监听结果的问题
因为退订操作是跳转至应用商店完成的,脱离了APP的控制范围,purchaseUpdatedListener只负责监听APP内发起的购买交易,所以退订不会触发它。要判断退订是否完成,核心思路是监听APP从后台返回前台的事件,主动查询用户当前的订阅状态。
具体实现方案
- 利用React Native自带的
AppState监听APP前后台切换 - 当APP从后台回到前台时,调用react-native-iap的API查询用户订阅状态
- 根据查询结果判断是否已完成退订
修改后的代码示例
import { AppState, Platform } from 'react-native'; import { initConnection, deepLinkToSubscriptionsAndroid, getAvailablePurchases, getSubscriptions, purchaseUpdatedListener } from 'react-native-iap'; import { useState, useEffect } from 'react'; // 订阅状态查询函数 const checkSubscriptionStatus = async (targetSku) => { try { const connection = await initConnection(); if (!connection) return false; if (Platform.OS === 'ios') { // iOS:获取当前有效购买项目,判断目标订阅是否存在 const purchases = await getAvailablePurchases(); const hasActiveSubscription = purchases.some(purchase => purchase.productId === targetSku && purchase.transactionState === 'purchased' ); return !hasActiveSubscription; // 无活跃订阅则视为已退订 } else { // Android:获取订阅详情,检查状态 const subscriptions = await getSubscriptions({ skus: [targetSku] }); const targetSub = subscriptions[0]; // 订阅状态为canceled或expired则视为已退订 return targetSub?.status === 'canceled' || targetSub?.status === 'expired'; } } catch (error) { console.error('查询订阅状态失败:', error); return false; } }; const CancelSubscriptionScreen = () => { const [isCanceling, setIsCanceling] = useState(false); const [appState, setAppState] = useState(AppState.currentState); const targetSku = '你的订阅SKU'; // 替换为实际的订阅SKU useEffect(() => { // 监听APP前后台切换 const appStateSubscription = AppState.addEventListener('change', async (nextAppState) => { // 从后台切回前台时触发状态查询 if (appState.match(/inactive|background/) && nextAppState === 'active') { const isUnsubscribed = await checkSubscriptionStatus(targetSku); if (isUnsubscribed) { // 这里处理退订完成后的逻辑,比如提示用户、更新页面状态 console.log('退订已完成'); } } setAppState(nextAppState); }); // 保留原有的购买监听(仅用于购买场景) const purchaseSubscription = purchaseUpdatedListener(async (purchase) => { const receipt = purchase.transactionReceipt; console.log('receipt', receipt); }); return () => { appStateSubscription.remove(); purchaseSubscription.remove(); }; }, [appState, targetSku]); const unsubscribe = async () => { setIsCanceling(true); const connection = await initConnection(); if (connection) { if (Platform.OS === 'ios') { await Linking.openURL('https://buy.itunes.apple.com/WebObjects/MZFinance.woa/wa/manageSubscriptions'); } else { await deepLinkToSubscriptionsAndroid({ sku: targetSku }); } } setIsCanceling(false); }; // 页面渲染逻辑... return ( // 你的页面布局 <></> ); }; export default CancelSubscriptionScreen;
补充说明
- iOS的
getAvailablePurchases返回当前有效的订阅交易记录,若找不到目标SKU的活跃交易,说明已退订 - Android的
getSubscriptions会返回订阅的实时状态,canceled代表用户主动取消,expired代表订阅到期 - 若需要更高的准确性,可以结合苹果/谷歌的服务器端收据验证,避免本地缓存延迟导致的状态偏差
内容的提问来源于stack exchange,提问作者Guilherme
相关产品推荐
相关产品推荐

