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

Expo In App Purchase失效,我的代码哪里出问题了?

问题分析与修复方案

针对你使用Expo In App Purchase时遇到的「购买成功后指定代码未触发」问题,核心原因和修复方式如下:

核心问题:purchaseItemAsync的异步逻辑误解

Expo IAP的purchaseItemAsync在iOS平台下不会通过await直接返回购买结果,而是依赖purchaseUpdatedListener事件回调来通知购买状态。你的代码直接用await等待返回值,导致购买流程完成后,后续的console.log无法触发。

具体修复步骤

1. 添加购买状态监听器

在组件挂载时注册监听器,统一处理双平台的购买结果:

import { useEffect } from 'react';
import * as InAppPurchases from 'expo-in-app-purchases';
import { Alert } from 'react-native';

// 组件内部逻辑
useEffect(() => {
  const purchaseListener = InAppPurchases.purchaseUpdatedListener(({ responseCode, results }) => {
    if (responseCode === InAppPurchases.IAPResponseCode.OK) {
      results.forEach(purchase => {
        if (purchase.transactionState === InAppPurchases.IAPTransactionState.PURCHASED) {
          // 这里执行购买成功后的逻辑
          console.log('Purchase successful');
          console.log('Purchase:', purchase);
          // 手动结束交易,避免重复计费
          InAppPurchases.finishTransactionAsync(purchase, true);
        }
      });
    } else {
      Alert.alert('错误', '购买状态异常', [{ text: '确定' }]);
    }
  });

  // 组件卸载时移除监听器,避免内存泄漏
  return () => purchaseListener.remove();
}, []);

2. 调整handlePurchase的购买触发逻辑

移除await purchaseItemAsync后的直接处理代码,改为仅触发购买请求:

const handlePurchase = async (productId) => {
  try {
    setPressedItemId(productId);
    const items = [productId]; // 无需Platform.select,参数格式双平台通用
    const { responseCode, results } = await InAppPurchases.getProductsAsync(items);

    console.log('Get products response:', responseCode);
    console.log('Products:', results[0]?.productId); // 加可选链避免空值报错

    if (responseCode === InAppPurchases.IAPResponseCode.OK && results.length > 0) {
      const { productId } = results[0];
      // 触发购买,无需await返回结果,由监听器处理后续逻辑
      await InAppPurchases.purchaseItemAsync(productId, null, null, false);
      // 第四个参数设为false,避免自动结束交易导致监听器无法捕获状态
    } else {
      console.log('Failed to get product information:', responseCode);
      Alert.alert('错误', '无法购买商品', [{ text: '确定' }]);
    }
  } catch (error) {
    console.log('Failed to purchase:', error);
    Alert.alert('错误', '无法购买商品', [{ text: '确定' }]);
  } finally {
    setPressedItemId('');
  }
};

额外注意事项

  • iOS端需确保测试设备登录沙盒测试账号,且开发者后台已正确配置内购商品
  • Android端purchaseItemAsync可通过await返回结果,但统一用监听器处理能实现双平台逻辑一致
  • 必须调用finishTransactionAsync结束交易,否则会导致用户重复收到计费提示

内容的提问来源于stack exchange,提问作者Wilson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:22:52