react-native-iap": "^2.3.17
的iOS
仅应在调用finishTransaction
时付款
添加信用卡等付款方式后,系统会检测到该金额。
但是达到了RNIap.buyProductWithoutFinishTransaction(sku)
方法。
真实设备-iPhone 6s
ComponentDidMount(){
await RNIap.initConnection();
await RNIap.consumeAllItems();
const prod = await RNIap.getProducts(product);
}
async componentWillUnmount() {
RNIap.endConnection()
}
buyProduct(sku){
await RNIap.clearTransaction();
RNIap.buyProductWithoutFinishTransaction(sku)
.then(purchase => {
// not reached
if(calltoserverisSuccess){
RNIap.finishTransaction();
}
})
.catch(error => {
// code enters catch case if ever
}}
抱歉,您的代码似乎有很多语法错误。 请参考我们仓库中的示例项目,然后与您的代码进行比较。
@dooboolab
感谢您的答复,此处发布的代码仅作为示例,这与实际应用程序中使用的并不完全相同。
我会尽力解释问题所在
RNIap.initConnection();
启动连接RNIap.getProducts(product)
获取产品并将其存储在状态中当用户点击购买按钮时
RNIap.clearTransaction();
只是为了确保没有剩余的未决交易。RNIap.buyProductWithoutFinishTransaction(sku)
如果服务器成功,则触发对应用程序服务器的调用,然后调用RNIap.finishTransaction();
以完成付款。componentWillUnmount()
RNIap.endConnection()
终止连接。如果用户已经添加了付款方式,则此过程可以正常进行。 如果用户未添加付款方式,则需要添加付款方式页面,并在达到RNIap.finishTransaction();
之前向您收取费用
谢谢你的细节。 您的问题现在看起来很清楚。 cc @JJMoon
@JJMoon
@ zohaibahmed-22这是沙盒测试用例吗?
@JJMoon不,这是一个真实的环境案例。
我知道当用户处于注销状态或没有信用卡信息时会发生此错误。
如果这些方法工作正常,则此错误的原因可能在其他地方。
我们需要准备此操作,该操作将使应用程序,viewDidDisappear等退出。
在沙盒模式下,此症状发生的方式有所不同。
当我创建一个新的沙箱帐户时,第一次购买不起作用。
在第二次,该设备已登录状态,并且工作正常。
我没有这个错误的线索。
@dooboolab @JJMoon看看这个
https://forums.developer.apple.com/thread/6431
https://forums.developer.apple.com/thread/64489
我还认为@dooboolab和@JJMoon在通过我们的iOS代码时发现了问题。 在updatedTransactions方法中,当我们在SKPaymentTransactionStateDeferred
或SKPaymentTransactionStateFailed
收到失败消息时,我们不假定为finishTransaction
。
由于在许多情况下, SKPaymentTransactionStateFailed
结果后跟有上面线程6431中提到的SKPaymentTransactionStatePurchased
。 我不确定Objective-C代码,因此请检查并确认是否在失败时清除事务。
@anandwahed我同意你的看法。 我的错。 抱歉
我将研究Apple的线程并解决该问题。
@anandwahed我想这是失败时通往finish transaction
的正确方法。 请查找此线程。 https://stackoverflow.com/questions/11008636/inapp-purchase-skpaymentqueue-finish-transaction-doesnt-work
当它失败时,将没有收据,因此您不会应用所购买的产品。 完成交易并不总是意味着“购买”。
同时,我将研究线程6431。
我刚刚阅读了6431线程(https://forums.developer.apple.com/thread/6431#14562)
底线。 自2015年以来未解决问题。哇..
有两种不同的方法来处理这种“存储套件流程”效果。
我学到了两件事。
答:失败时,我们必须finishTransaction
。 (我猜总是有或没有选项)
B. Storekit流程使成功和失败都有收据。 (这不好)
我建议大家阅读此主题,然后再回到此问题。
我猜,您选择哪种方式(1或2)取决于您自己。
我们可能需要回电以进行故障响应。
@JJMoon表示我们不应该使用buyProductWithoutFinishTransaction吗?
@ maxs15我不是那个意思。 抱歉造成混淆。
StoreKit流可以在任何购买时发生。 这是iOS问题,而不是此模块。
就目前而言,我也没有任何线索。 这件事发生在任何本机iOS应用程序中。 正确的?
我们将在空闲时间中挖掘更多的东西。
今天,我尝试调试此问题,因为我已经产生了此问题。 付款方式finishTransanction
已完成,但在payMethod更改时未获得callback
。 我尝试调试一些console.log
但无法在dev
环境中测试真实的帐单。 有人可以建议我如何调试此过程,以便我可以以real purchase
debug
为此real purchase
吗? 我是否应该在sandbox
模式下使用它? 它在沙箱中运行良好,所以我不知道如何调试它。 这是很不情愿的。
让我们收集一些想法,因为我认为这很重要。
当我尝试与非沙箱用户一起购买时,总是出现此错误。
@hyochan如果连接真实服务器(您的服务器),则是处于调试模式还是释放模式都无关紧要。 我想您有2个选择。
@JJMoon是的,我已经知道了,但是仍然无法在ios中进行实时购买测试。 这个stackoverflow是真的吗? 那我该如何解决呢? 我们必须测试现场购买。
面对此问题的任何人,我都可以肯定,请给我们一个有关如何解决此问题的想法。 in-app purchase fail when payment method added live
,如问题标题中所述。 我该如何调试? @anandwahed您是否曾就此问题联系过Apple?
@hyochan不,我们没有联系Apple支持。
我认为我们需要为此联系apple
,这看起来真的很糟糕,因为有一个不同的测试用例在sandbox
环境中是不可复制的。 对于那些想了解问题的人,我已经记录了屏幕,您可以在这里查看@anandwahed您还可以联系苹果吗? 因为我知道他们并不是那么支持,所以最好让更多的人与他们联系。 让我们共同解决这个问题。
今天我们收到了苹果的答复。 failure
之后可能再次返回回调。 我们正在研究#348中的解决方法,但恐怕这会很讨厌。
我已发布到2.4.0-beta1
,以尝试解决此问题。 PR
#348已添加到此版本,您还可以查看此功能的自述文件。 请注意,这正在测试中。
我已经在现场购买中对此进行了测试,并且似乎可以正常工作。 但是,请记住,仅应在发生故障时添加侦听器,否则它可能会被复制并产生成功的结果。
伙计们,谢谢您在这个问题上投入时间! 🙏
我认为当前文档需要更清楚地了解addAdditionalSuccessPurchaseListenerIOS
的用法。 这就是我试图在#414上解决的问题。
但是我也认为这为改进API留下了空间。 你们愿意讨论API的更改以更好地适应所谓的“存储套件流程”吗? 可能使用RxJS,例如:
const observable = RNIap.buyProduct('com.example.coins100')
.subscribe(
purchase => console.log(purchase), // successful payment
err => console.log(err) // err.code and err.message are available
)
还是可以更好地隐藏iOS的其他订阅的其他内容?
@Edgpaez太好了,但这将改变在android
完成的购买行为。 我希望我可以调查version 3
在此模块中的2019
。
您好@hyochan ,AFAICT,我们不需要更改程序包的内部行为,只需更改面向公众的界面即可。 我们可以保持buyItemByType方法解析诺言,并在index.js之上简单地添加一点Rx。
例如,我们将在index.js中包含以下内容:
export const buyProduct = (sku) => Platform.select({
android: () => Observable.of(RNIapModule.buyItemByType(ANDROID_ITEM_TYPE_IAP, sku, null, 0)), // returns an observable that emits when the RNIapModule.buyItemByType promise resolves
ios: ... // ios would do the same but taking into account the usage of addAdditionalSuccessPurchaseListenerIOS
})();
我的目标不是此特定实现,而是隐藏“存储套件流程”特定的细节。
您认为这是个好主意吗?
您对PR感兴趣吗?
@Edgpaez好的。 我现在了解细节了。 但是,我觉得添加RxJS
对于实现feature
有点太多,因为我认为没有它就可以解决。
另外,我觉得以下内容会有所不同。
RNIap.buyProduct('com.example.coins100')
.subscribe(
purchase => console.log(purchase), // successful payment
err => console.log(err) // err.code and err.message are available
)
如果您buyProduct
以下两个项目调用
RNIap.buyProduct('com.example.coins100');
RNIap.buyProduct('com.example.coins200');
我们不能保证哪个会先完成,所以我认为我们应该以本机处理sendEvent
到JS
。
我觉得实现应该看起来像
RNIap.buyProduct('com.example.coins100');
RNIap.buyProduct('com.example.coins200');
// receiving events
const subs = RNIap.purchaseUpdateListener(purchase => {
...
});
请告诉我是否有错过的事情。
让我们处理#423中的更多问题
最有用的评论
我认为我们需要为此联系
apple
,这看起来真的很糟糕,因为有一个不同的测试用例在sandbox
环境中是不可复制的。 对于那些想了解问题的人,我已经记录了屏幕,您可以在这里查看@anandwahed您还可以联系苹果吗? 因为我知道他们并不是那么支持,所以最好让更多的人与他们联系。 让我们共同解决这个问题。