skip to Main Content

Hello I am am trying to utilize react-native-iap in my react-native expo app and no matter what I try I am getting the error "E_IAP_NOT_AVAILABLE" which after doing some digging is being cause by StokeKit not being available (1 or 2). I added react-native-iap to my plugins in app.json. What other setup step am I missing. I have tried through both expo go (i hear it wont work there but I tried) and by exporting to testflight and then trying from there. I don’t know what else to try. Below I have added my packages and the bulk of my code that tries to setup iap and causes the error.

Edit: I created a snack showing the error (not sure if react-native-iap would even work in a snack, but just trying to be helpful):
https://snack.expo.dev/@tristan-neateworks/expo-react-native-iap-e_iap_not_available

Packages:

"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 setup

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)

2

Answers


  1. Delete the ios folder, then npx expo run:ios

    Login or Signup to reply.
  2. Were you able to solve it? I am interested in

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search