世博会react-native-iap E_IAP_NOT_AVAILABLE

问题描述 投票:0回答:1

您好,我正在尝试在我的react-native expo应用程序中使用react-native-iap,无论我尝试什么,我都会收到错误“E_IAP_NOT_AVAILABLE”,在进行一些挖掘后,这是由于StokeKit不可用(1或2)。我将react-native-iap添加到app.json中的插件中。我还缺少什么其他设置步骤。我已经尝试过 expo go(我听说它在那里不起作用,但我尝试过)并通过导出到 testflight 然后从那里尝试。我不知道还能尝试什么。下面我添加了我的包和大部分尝试设置 iap 并导致错误的代码。

编辑:我创建了一个显示错误的小吃(不确定react-native-iap是否可以在小吃中工作,但只是想提供帮助): https://snack.expo.dev/@tristan-neateworks/expo-react-native-iap-e_iap_not_available

套餐:

"dependencies": {
    "@expo/vector-icons": "^14.0.0",
    "@expo/metro-runtime": "~3.2.1",
    "@react-native-community/slider": "4.5.2",
    "@react-native-picker/picker": "2.7.5",
    "@shopify/react-native-skia": "1.2.3",
    "expo-asset": "~10.0.8",
    "expo-constants": "~16.0.2",
    "expo-image": "~1.12.11",
    "expo-linear-gradient": "~13.0.2",
    "expo-linking": "~6.3.1",
    "expo-router": "~3.5.16",
    "expo-secure-store": "~13.0.1",
    "expo-status-bar": "~1.12.1",
    "react-native-bouncy-checkbox": "^4.0.1",
    "react-native-dialog": "^9.3.0",
    "react-native-gesture-handler": "~2.16.1",
    "react-native-gifted-charts": "^1.4.10",
    "react-native-iap": "^12.13.2",
    "react-native-reanimated": "~3.10.1",
    "react-native-safe-area-context": "4.10.1",
    "react-native-screens": "3.31.1",
    "react-native-svg": "15.2.0",
    "expo-dev-client": "~4.0.16",
    "react-native-linear-gradient": "*"
  },

iap 设置

import React from "react-native";
import {View} from "react-native";
import {
    withIAPContext, setup,
    initConnection,
    purchaseErrorListener,
    purchaseUpdatedListener,
    flushFailedPurchasesCachedAsPendingAndroid, finishTransaction,
} from 'react-native-iap';
import {useEffect} from "react";
import {api, getUser} from "../../be";
import * as SecureStore from "expo-secure-store";

function Listener({children}) {
    // eslint-disable-next-line no-unused-vars
    let purchaseUpdateSubscription = null;
    // eslint-disable-next-line no-unused-vars
    let purchaseErrorSubscription = null;
    useEffect(() => {
        void (async () => {

            console.log('t2')
            await initConnection().then(() => {
                // we make sure that "ghost" pending payment are removed
                // (ghost = failed pending payment that are still marked as pending in Google's native Vending module cache)
                console.log('t3')
                flushFailedPurchasesCachedAsPendingAndroid()
                    .catch(() => {
                        console.log('t4')
                        // exception can happen here if:
                        // - there are pending purchases that are still pending (we can't consume a pending purchase)
                        // in any case, you might not want to do anything special with the error
                    })
                    .then(() => {
                        console.log('t5')
                        purchaseUpdateSubscription = purchaseUpdatedListener(
                            (purchase) => {
                                console.log('purchaseUpdatedListener', purchase);
                                const receipt = purchase.transactionReceipt;
                                if (receipt) {
                                    console.log(receipt)
                                    api('iap/receipt/', 'POST', purchase.transactionReceipt)
                                        .then(async (deliveryResult) => {
                                            if (deliveryResult.success === true) {
                                                // Tell the store that you have delivered what has been paid for.
                                                // Failure to do this will result in the purchase being refunded on Android and
                                                // the purchase event will reappear on every relaunch of the app until you succeed
                                                // in doing the below. It will also be impossible for the user to purchase consumables
                                                // again until you do this.

                                                // If consumable (can be purchased again)
                                                // await finishTransaction({purchase, isConsumable: true});
                                                // If not consumable
                                                await finishTransaction({purchase, isConsumable: false});
                                                // mark subscription as active
                                            } else {
                                                // Retry / conclude the purchase is fraudulent, etc...
                                            }
                                        });
                                }
                            },
                        );

                        purchaseErrorSubscription = purchaseErrorListener(
                            (error) => {
                                console.log('t6')
                                console.warn('purchaseErrorListener', error);
                            },
                        );
                    });
            }).catch((e) => {
                console.log('t10')
                console.log(e)
                // exception can happen here if:
                // - there are pending purchases that are still pending (we can't consume a pending purchase)
                // in any case, you might not want to do anything special with the error
            });
        })()
    }, [])

    useEffect(() => {
        return () => {
            console.log('t7')
            // Anything in here is fired on component unmount.
            if (purchaseUpdateSubscription) {
                purchaseUpdateSubscription.remove();
                purchaseUpdateSubscription = null;
            }

            if (purchaseErrorSubscription) {
                purchaseErrorSubscription.remove();
                purchaseErrorSubscription = null;
            }
            console.log('t7.5')
        }
    }, [])
    return <View>{children}</View>
}

console.log('t1')
setup({storekitMode: 'STOREKIT2_MODE'})
export default withIAPContext(Listener)
react-native expo react-native-iap
1个回答
0
投票

删除ios文件夹,然后npx expo run:ios

© www.soinside.com 2019 - 2024. All rights reserved.