React-native-iap: 无法获得一系列产品/订阅

创建于 2019-08-19  ·  31评论  ·  资料来源: dooboolab/react-native-iap

版本的react-native-iap

3.3.9

本机版本

0.59.9

您遇到错误的平台(IOS或Android还是两者兼有?)

iOS和Android

预期行为

我希望能够获得在Play控制台和Appstore中创建的一系列产品和订阅。

实际行为

函数RNIap.getProductsRNIap.getSubscriptions总是返回空数组。

经过测试的环境(仿真器?真实设备?)

iOS模拟器,Android模拟器和Android真实设备

重现行为的步骤

  1. 在Google Play控制台和Apple Appstore Connect中添加产品
  2. 我使用了示例文件夹中的代码
  3. 我更改了产品/订阅ID

我确实等待了超过24小时。 我还在Google Play控制台中创建了Internal和Alpha版本,但是我仍然只得到空数组。

我想我应该何时确切开始工作尚不清楚。 例如,当我的Alpha测试推出仍在Google Play控制台中待发布时,这是否意味着react-native-iap不起作用? 我必须等到该应用发布后才能试用吗?

我也知道我什至无法在模拟器/仿真器上进行测试购买,但是getProducts / getSubscriptions在仿真器上工作还是我需要真实的设备进行测试?

const itemSkus = Platform.select({
    ios: ['product_1'],
    android: ['1', '2']
});

const itemSubs = Platform.select({
    ios: ['subscription_1'],
    android: ['subscription_1', 'subscription_2']
});

let purchaseUpdateSubscription;
let purchaseErrorSubscription;

class App extends Component {
    constructor(props) {
        super(props);

        this.state = {
            productList: [],
            receipt: '',
            availableItemsMessage: ''
        };
    }

    async componentDidMount() {
        SplashScreen.hide();
        try {
            const result = await RNIap.initConnection();
            await RNIap.consumeAllItemsAndroid();
            console.log('result', result);
        } catch (err) {
            console.warn(err.code, err.message);
        }

        purchaseUpdateSubscription = purchaseUpdatedListener(async purchase => {
            console.log('purchaseUpdatedListener', purchase);
            if (purchase.purchaseStateAndroid === 1 && !purchase.isAcknowledgedAndroid) {
                try {
                    const ackResult = await acknowledgePurchaseAndroid(purchase.purchaseToken);
                    console.log('ackResult', ackResult);
                } catch (ackErr) {
                    console.warn('ackErr', ackErr);
                }
            }
            this.setState({ receipt: purchase.transactionReceipt }, () => this.goNext());
        });

        purchaseErrorSubscription = purchaseErrorListener(error => {
            console.log('purchaseErrorListener', error);
            Alert.alert('purchase error', JSON.stringify(error));
        });
    }

    componentWillMount() {
        if (purchaseUpdateSubscription) {
            purchaseUpdateSubscription.remove();
            purchaseUpdateSubscription = null;
        }
        if (purchaseErrorSubscription) {
            purchaseErrorSubscription.remove();
            purchaseErrorSubscription = null;
        }
    }

    goNext = () => {
        Alert.alert('Receipt', this.state.receipt);
    };

    getItems = async () => {
        try {
            const products = await RNIap.getProducts(itemSkus);            
            console.log('Products', products);
            this.setState({ productList: products });
        } catch (err) {
            console.warn(err.code, err.message);
        }
    };

    getSubscriptions = async () => {
        try {
            const products = await RNIap.getSubscriptions(itemSubs);
            console.log('Products', products);
            this.setState({ productList: products });
        } catch (err) {
            console.warn(err.code, err.message);
        }
    };

    getAvailablePurchases = async () => {
        try {
            console.info('Get available purchases (non-consumable or unconsumed consumable)');
            const purchases = await RNIap.getAvailablePurchases();
            console.info('Available purchases :: ', purchases);
            if (purchases && purchases.length > 0) {
                this.setState({
                    availableItemsMessage: `Got ${purchases.length} items.`,
                    receipt: purchases[0].transactionReceipt
                });
            }
        } catch (err) {
            console.warn(err.code, err.message);
            Alert.alert(err.message);
        }
    };

    requestPurchase = async sku => {
        try {
            RNIap.requestPurchase(sku);
        } catch (err) {
            console.warn(err.code, err.message);
        }
    };

    requestSubscription = async sku => {
        try {
            RNIap.requestSubscription(sku);
        } catch (err) {
            Alert.alert(err.message);
        }
    };

    render() {
        const { productList, receipt, availableItemsMessage } = this.state;
        const receipt100 = receipt.substring(0, 100);

        return (
            <View style={styles.container}>
                <View style={styles.header}>
                    <Text style={styles.headerTxt}>react-native-iap V3</Text>
                </View>
                <View style={styles.content}>
                    <ScrollView style={{ alignSelf: 'stretch' }}>
                        <View style={{ height: 50 }} />
                        <NativeButton
                            onPress={this.getAvailablePurchases}
                            activeOpacity={0.5}
                            style={styles.btn}
                            textStyle={styles.txt}
                        >
                            Get available purchases
                        </NativeButton>

                        <Text style={{ margin: 5, fontSize: 15, alignSelf: 'center' }}>
                            {availableItemsMessage}
                        </Text>

                        <Text style={{ margin: 5, fontSize: 9, alignSelf: 'center' }}>
                            {receipt100}
                        </Text>

                        <NativeButton
                            onPress={() => this.getItems()}
                            activeOpacity={0.5}
                            style={styles.btn}
                            textStyle={styles.txt}
                        >
                            Get Products ({productList.length})
                        </NativeButton>
                        {productList.map((product, i) => {
                            return (
                                <View
                                    key={i}
                                    style={{
                                        flexDirection: 'column'
                                    }}
                                >
                                    <Text
                                        style={{
                                            marginTop: 20,
                                            fontSize: 12,
                                            color: 'black',
                                            minHeight: 100,
                                            alignSelf: 'center',
                                            paddingHorizontal: 20
                                        }}
                                    >
                                        {JSON.stringify(product)}
                                    </Text>
                                    <NativeButton
                                        // onPress={() => this.requestPurchase(product.productId)}
                                        onPress={() => this.requestSubscription(product.productId)}
                                        // onPress={() => this.buyItem(product.productId)}
                                        // onPress={() => this.buySubscribeItem(product.productId)}
                                        activeOpacity={0.5}
                                        style={styles.btn}
                                        textStyle={styles.txt}
                                    >
                                        Request purchase for above product
                                    </NativeButton>
                                </View>
                            );
                        })}
                    </ScrollView>
                </View>
            </View>
        );
    }
}
📱 iOS 🙏 help wanted 🚶🏻 stale 🤖 android

最有用的评论

当然。在Google Play商店发布后,我会在这里确认

更新

我的应用在Google Play商店上发布后,购买交易就可以进行了。 批准需要3天。 感谢@jvandenaardweg

更新2

如果模拟器具有Google Play商店支持,则react-native-iap可以在android模拟器上运行。

所有31条评论

您不需要real device即可在ios getProducts / getSubscription ios进行测试,而在android不需要。 对于android您需要购买真实的设备。

对于Google,请翻阅我的指南以解决您的问题。
您实际上不必将应用程序发布到Playstore进行测试,但是您需要上传签名的APK。

我也有这个问题,我已经在Apple中创建了一个产品,但似乎无法访问它。

const itemSkus = Platform.select({
  ios: [
    'product1'
  ],
  android: []
});

RNIap.getProducts(itemSkus).then((products) => {
      console.log(products);  //<< returns empty array
}).catch((error) => console.log(error))

产品是否需要时间来体现您的体验?

协议,税收和银行业务均处于活动状态
“ react-native-iap”:“ ^ 3.4.0”,
应用内已经处于“准备提交”状态

@nateblog您创造了什么样的产品? 订阅还是其他?

另外,您是否在App Store Connect中为产品/订阅添加了本地化? 如果是这样,请尝试添加您在设备或模拟器上有效的本地化版本。 我记得以前有一些麻烦。 我的模拟器和设备的语言环境是英语,所以我只为订阅添加了“英语(美国)”本地化。

@jvandenaardweg-谢谢您的答复,是的,我已经添加了本地化,因为如果我跳过本地化,应用内状态将不会设置为“准备提交”。 我将本地化设置为“英语(美国)”,因为我正在使用的设备使用英语,是的,该产品是订阅的。

更新

我已经确定我启用了功能下的应用程序内并将包降级为2.4.0,但结果仍然相同。 。 我无法获得产品,它只是返回空数组。

我还手动链接了软件包,因为其他帖子建议不要使用react-native链接,但结果仍然相同。 我正在使用模拟器和真实设备。

抱歉,现在已解决,问题是我的xcode中的包ID,我使用了错误的包ID,现在一切正常

我有一个类似的东西,我只需要手动执行库的链接过程。 (ios)

我遇到了同样的问题,没有从Itunes Connect加载任何产品,而且我不确定从哪里开始寻找问题。 该应用使用的是RN的旧版本:0.43.4。 我已经尝试了RN-IAP的3.3.7和2.5.5版本。 我应该在旧版本的React-Native上使用旧版本的库吗?

由于没有错误消息,也没有数据,因此似乎很难解决问题。

抱歉,现在已解决,问题是我的xcode中的包ID,我使用了错误的包ID,现在一切正常

嘿,@ nateblog! 我面临着一个类似的问题:我得到了用于产品和订阅的空数组,并且在App Store Connect中创建了2个订阅项目。 您能否详细说明您的捆绑销售商品ID有什么问题? 我认为我没有提交正确的商品SKU,因为我找不到关于它们的构造或形式的任何参考-它们是[捆绑标识符]。[购买商品的ProductId]还是[ProductId]购买商品]?

另外,我想补充一下,我的发布和调试方案的捆绑标识符略有不同:

  • 发布-'domain.appName';
  • 调试-'domain.appName.dev';
    我创建的应用程序内购买项目与应用程序的生产(即发布)版本有关。 这是否意味着我无法从应用程序的开发版本访问这些项目?

任何建议将不胜感激。

我有一个类似的东西,我只需要手动执行库的链接过程。 (ios)

你救了我的一天!

我已经整合了react-native-iap并将我签名的apk上传到Play商店的Beta版本,并且还添加了一个订阅计划。 我试图在调试模式下按订阅ID获取订阅列表,该模式始终返回一个空数组。 我可以实际在调试模式下测试订阅吗?

@ShridharCodewave我面临着同样的问题。 请让我知道您是否可以解决问题:(

react-native-iap:3.3.2

我在Android模拟器上面临着同样的问题。 我将apk上传到Google Play商店到Beta频道并添加了产品。

image

首先,连接初始化,然后我尝试获取产品,但console.warn上没有任何显示
这里没有结果
这里没有错误

@ismetsezer Android的整个In App结算在模拟器中均不起作用:

您不能使用模拟器来测试Google Play结算; 您必须在设备上安装应用程序才能测试Google Play结算。
https://developer.android.com/google/play/billing/billing_testing

您需要一个真正的设备。

在iOS中,您可以在模拟器中获取订阅数据。 但是您不能购买它,因为您还需要一个真实的设备。

对于上面的其他意见:还要确保versionNameversionCodeandroid/app/build.gradle相同或更高的一个在谷歌上传游戏控制台。

由于Android的新审核政策,您还需要在非生产轨道上运行的经过审核的应用程序:

以前,您可以通过上传未发布的“草稿”版本来测试应用。 不再支持此功能。 相反,您必须将您的应用发布到封闭或开放的测试轨道。 有关更多信息,请参见不再支持草稿应用程序。
https://developer.android.com/google/play/billing/billing_testing

封闭/开放测试轨道中的“发布”意味着它需要经历Google Play的新审核流程。 新应用可能需要几天的时间,而现有应用则可能需要几个小时。

我不知道我执行的确切步骤,但是对我来说,它可以在Android设备上本地工作。 因此,这可能不是不是react-native-iap软件包问题,而是更多的配置问题。

如果有人可以确认上述内容,那么更新有关此更改的自述文件可能是一件好事。 因为这是自上个月以来的新事物。

感谢@jvandenaardweg,当我切换到真实设备时,是的,它可以正常工作并且连接成功,但是正如您所说,根据链接,由于产品数组为空,我必须等待测试应用程序在Beta通道上发布

高兴听到

当然。在Google Play商店发布后,我会在这里确认

更新

我的应用在Google Play商店上发布后,购买交易就可以进行了。 批准需要3天。 感谢@jvandenaardweg

更新2

如果模拟器具有Google Play商店支持,则react-native-iap可以在android模拟器上运行。

@kesepara在将新的订阅计划添加到Play商店后,我不得不等待几个小时才能显示在设备上。

@ismetsezer@kesepara
非常感谢您对您的开发流程的投入,因为我仍然不清楚。
我已经为iOS设置了RN IAP,并且现在可以正常工作。
我现在开始做Android部分,在这里我发现我们必须使用(至少)在“封闭轨道”上上传的已签名APK,才能测试付款功能。
但是在您的评论中,您说的是您已经能够在Android模拟器上对其进行测试,对吗?
此外,如果我们必须在商店上使用签名的APK,该如何调试?
您的帮助将不胜感激。

@beeremy谢谢您的

@ismetsezer ,您好,感谢您的反馈。

对于可能有用的任何人,我都可以按照以下建议进行调试配置: https :

我可以确认为@ismetsezer ,在Google Play控制台中发布应用后,订阅和产品将在android中运行。 当应用尚未发布时,尝试获取订阅/产品将不适用于android。

在iOS上,订阅和产品无需发布该应用即可正常运行。

嘿,看来这个问题最近没有任何活动。 问题是否已解决,还是仍然需要社区的关注? 如果没有其他活动,则可能已关闭此问题。 您也可以将此问题标记为“供讨论”或“良好的第一期”,我将其保留为开放状态。 感谢你的贡献。

此处Android开发人员的RN 0.59.1,我正在使用IAP版本4.4.1

我的构建当前处于Alpha轨道上。 之后,我在平台上的调试模式下在Platform.select({})上像往常一样在机器上进行了重建。我在Play控制台上指定了订阅ID,并调用了getSubscriptions(),但是收到一个空数组。 这是因为它在Alpha中吗? 有任何想法吗?

@edgaralienfoe您是否在Google Play控制台中激活了订阅?

@acostalima应该被激活。 我以为这样做可能要花几天时间,但还是没有运气。

我问@edgaralienfoe是因为我记得有一个选项可以在Google Play控制台上显式激活订阅,如果该订阅未处于活动状态,则该订阅将不会显示在您的应用中。 但是,如果您这样说,那么可能还有其他问题。

@edgaralienfoe您找到解决方案了吗? 也许您的应用版本需要高于Alpha跟踪版本

@edgaralienfoe您找到解决方案了吗? 也许您的应用版本需要高于Alpha跟踪版本

Alpha轨道工作正常。 我已经使用IAP部署到Alpha且没有问题,已经测试了IAP相当长时间。 另一方面,内部轨道不起作用。

对于每个可能在这里遇到麻烦的人,iOS上对我而言,窍门是按照@ Kuhne1的建议手动链接项目-在清理了build文件夹并手动安装Pods之后,它也起作用了,希望它对任何人

嘿,看来这个问题最近没有任何活动。 问题是否已解决,还是仍然需要社区的关注? 如果没有其他活动,则可能已关闭此问题。 您也可以将此问题标记为“供讨论”或“良好的第一期”,我将其保留为开放状态。 感谢你的贡献。

长时间不活动后结束此问题。 如果此问题在最新版本中仍然存在,请随时创建具有最新信息的新问题。

此页面是否有帮助?
0 / 5 - 0 等级