You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 16:31:10