您好,我正在尝试在我的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)
删除ios文件夹,然后npx expo run:ios