transactionReceipt已弃用.但我无法使用,
[[NSBundle mainBundle] appStoreReceiptURL].
Run Code Online (Sandbox Code Playgroud)
如果有收据,这应该返回收据的URL.但对我来说没有一个,因为这个值是零,而且据我所知,它不应该是.我在iOS 7上运行并且已经完成了一些应用内购买(设备上的沙箱).
谁能帮忙.
我们正在尝试使用StoreKit实现简单的应用程序内购买(不确定它是否与它有关)并且到目前为止一切顺利,但是我们面临一个特定问题:当我们退出应用程序时,iOS会永久询问我们登录:
只有在使用沙箱或TestFlight帐户登录时才会发生这种情况,但这非常令人讨厌.这背后有什么理由或我们不应该担心吗?我读过许多人面临类似的问题,并且一旦应用程序投入生产就会解决,但这似乎是一种处理它的hacky /不可预测的方式.
如果您需要,我准备提供更多信息.在这一点上,我只是不知道为什么会发生这种情况(我已将它与许多事情联系起来,但它们都没有真正证明是正确的......例如收据验证请求,付款队列中未完成的交易等. ).
我得到"这个应用程序购买已经被购买它将被免费恢复"但代表updatedTransactions没有被调用,没有任何反应,IAP没有执行.
我已经实现了恢复购买,它工作正常,但我如何阻止用户再次购买非消耗品?为什么没有调用委托updatedTransactions(SKPaymentTransactionState.Restored)?
即使在删除并重新安装应用程序后进行购买也会显示此弹出窗口.
这是我的代码.如果我做错了,请告诉我.谢谢
func makePaymentForProduct(product:SKProduct){
let payment = SKPayment.init(product: product)
SKPaymentQueue.defaultQueue().addPayment(payment)
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}
func restorePurchases(){
SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}
//MARK: SKProductsRequestDelegate
func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
self.delegate?.didGetProducts(response.products)
}
func request(request: SKRequest, didFailWithError error: NSError) {
self.delegate?.purchaseFailed(error.localizedDescription)
}
//MARK: SKPaymentTransactionObserver
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for (_, transaction) in transactions.enumerate() {
switch (transaction.transactionState) {
case SKPaymentTransactionState.Purchased:
self.completeTransaction(transaction)
break
case SKPaymentTransactionState.Restored:
self.restoreTransaction(transaction)
break
case SKPaymentTransactionState.Failed:
self.failedTransaction(transaction)
break
default:
break
}
}
}
func completeTransaction(transaction:SKPaymentTransaction){
self.delegate?.purchaseSuccessful()
SKPaymentQueue.defaultQueue().finishTransaction(transaction)
}
func …
Run Code Online (Sandbox Code Playgroud) 我正在iOS应用程序中进行自动更新订阅IAP.我打算在同一个订阅组中有3个不同的层.在我的测试中,我已经能够成功购买订阅,看到它在沙箱上更新了几次,然后在5或6次尝试后停止.这部分工作正常.但我想尝试从应用程序从一个层升级到更高层.这一次,当我尝试将带有新(升级)productID的SKPayment添加到支付队列时,我首先收到警告"你想要修改你的订阅......",然后我点击继续,我得到一个确认消息,但我也收到SKPaymentQueue: updatedTransactions
状态失败的回调.错误说:
"失败的事务错误=错误域= SKErrorDomain代码= 0"无法连接到iTunes Store"UserInfo = {NSLocalizedDescription =无法连接到iTunes Store}
任何想法为什么会发生这种情况,以及是否甚至可以从沙箱测试订阅组更新?如果没有,那你将如何进行测试呢?
我们有一个应用程序被苹果拒绝了几次,因为它无法完成自动续订 IAP 购买,并且如果尝试也无法恢复。我们最终通过添加一些额外的日志记录来缩小错误范围,并Payment added for transaction already in the SKPaymentQueue: ...
在日志中注意到。
在尝试重现时,我们启动了一段时间没有使用的手机,并注意到队列中有27 笔SKPaymentTransactionState.purchased
相同购买的交易,全部处于状态。我们SKPaymentTransactionObserver
会收到这些交易的通知,并且会进行拜访finishTransaction
。我假设有这么多交易,因为我们有每月订阅,沙盒中每 5 分钟自动续订一次,并且我们一直在另一部手机上使用相同的 App Store 帐户额外购买同一个 IAP - 所以现在,该手机将收到所有更新的通知。
奇怪的是,即使我们调用finishTransaction
这些交易,它们似乎仍未完成,这就是为什么我们在控制台中看到“为已在队列中的交易添加的付款”消息。
因此,为了调试这个,我实现了paymentQueue(_:removedTransactions:)
of SKPaymentTransactionObserver
,并注意到,即使我们调用了finishTransaction
如此多的事务,我们也只会看到一个被删除 - 而且似乎如果我们在应用程序中停留很长时间,只是什么也不做,那么更多的事务就会被删除。历时10多分钟。
在我的沮丧中,我继续做了这样的事情
public func paymentQueue(_ queue: SKPaymentQueue, removedTransactions transactions: [SKPaymentTransaction]) {
let remainingTransactions = queue.transactions
let hasRemainingTransactions = !remainingTransactions.isEmpty
if hasRemainingTransactions {
paymentQueue(queue, updatedTransactions: remainingTransactions)
}
}
Run Code Online (Sandbox Code Playgroud)
这当然是非常恶心的,但你难道不知道,对于 n 笔交易中的每笔交易,它们都被一笔一笔地删除——一次只删除一笔。
所以我的第一个想法是,嗯,这在现实世界中可能不太可能发生,因为你一次又一次地购买、更新得如此之快等,所以也许 SDK 并不期望一次完成这么多交易?我尝试了一些不那么恶心的东西,并paymentQueue(_:updatedTransactions:)
从这样的地方改变了我们的东西
public func …
Run Code Online (Sandbox Code Playgroud) 我正在按照测试中断的应用内购买的步骤进行操作,如 Apple 文档中“测试中断的购买”标题下的概述。我的问题从第 6 步开始,其中指出:
“在您的代码中,观察付款失败。付款队列收到状态为 SKPaymentTransactionState.failed 的更新交易。”
这对我有用,但失败状态会触发我的 UI 显示错误警报,指出付款失败,即使它只是准备显示条款和条件页面。
有没有办法检测事务何时实际失败,而不是暂停以让其他操作发生?我原以为这里的 SKPaymentTransactionState 状态是deferred
而不是failed
,因为这样可以更容易地进行适当处理。
在极少数情况下,我的一些用户似乎无法进行非消耗品购买.当他们尝试购买时,它不会激活"高级",并且当他们从当前安装恢复或未paymentQueue: updatedTransactions:
调用全新安装时.
我已经添加了大量日志记录,专门用于尝试确定还原未遵循预期流量的原因.在恢复失败期间,不会触发任何"RESTORE"类别事件.
仅供参考,[self success];
只显示内容视图,[self fail:]
并向用户显示错误消息.
也[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
被调用viewDidLoad
并[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];
按下按钮.
- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {
// COMPLETION POINT - RESTORE COMPLETE***
[MBProgressHUD hideHUDForView:self.view animated:TRUE];
if ([SKPaymentQueue defaultQueue].transactions.count == 0) {
[self.tracker send:[[GAIDictionaryBuilder createEventWithCategory:@"RESTORE"
action:@"failure_hard"
label:@"no_purchases"
value:nil] build]];
[self fail:@"There are no items available to restore at this time."];
} else {
[self success];
}
}
- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {
// COMPLETION POINT - RESTORE FAILED
[MBProgressHUD …
Run Code Online (Sandbox Code Playgroud) 我在 Swift 4/iOS 11 中恢复 IAP 时遇到问题。我的AppDelegate
实现SKPaymentTransactionObserver
. AppDelegate
我正在didFinishLaunchingWithOptions
打电话SKPaymentQueue.default().add(self)
。我paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction])
也在 AppDelegate 中实现了该功能。
我可以ViewController
像这样进行购买:
let payment = SKPayment(product: products.first!)
SKPaymentQueue.default().add(payment)
Run Code Online (Sandbox Code Playgroud)
购买成功完成 - 我在观察者中得到了updatedTransaction
with 状态。.purchased
paymentQueue
但是,当我从中调用以下内容ViewController
以恢复购买时:
SKPaymentQueue.default().restoreCompletedTransactions()
Run Code Online (Sandbox Code Playgroud)
该paymentQueue updatedTransactions
函数从未被调用。
看来我的沙箱用户等设置正确,因为初始购买正在运行。沙盒用户有能力恢复购买吗?restoreCompletedTransactions()
除了打电话恢复购买之外,我还需要做任何额外的工作吗?
更新,这是我的paymentQueue updatedTransactions
代码AppDelegate
:
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions{
switch transaction.transactionState{
case .purchased:
debugPrint("purchased it!")
menuDelegate?.unlockMenu()
//unlock …
Run Code Online (Sandbox Code Playgroud) 从iOS 13.4 开始,当行...
[[SKPaymentQueue defaultQueue] addPayment:payment];
Run Code Online (Sandbox Code Playgroud)
……被处决。
在iOS 13.4之前,用户确认购买时会弹出一个对话框,但现在什么都没有。有谁知道可能导致此问题的原因?
笔记:
objective-c objective-c++ in-app-purchase ios skpaymenttransaction
我正在我的 iOS 应用程序中实现自动续订订阅。我的事务处理看起来像这样的伪代码:
func paymentQueue(_queue: SKPaymentQueue, updatedTransactions transactions:[SKPaymentTransaction]) {
for (t in transactions) {
let data = Data(contentsOf: getReceiptUrl())
//this is actually async, but for simplicity here it's just a straight return
if verifyReceiptWithServer(data) == .success {
print("Verified receipt successfully!")
}
queue.finishTransaction(t)
}
}
Run Code Online (Sandbox Code Playgroud)
如果订阅在我的应用程序未处于活动状态时续订多次,则我可以在此处为每个产品获得不止一笔交易。有时,应用程序还会在重新安装时立即获取大量旧交易。我需要验证每笔交易吗?还是每人只做一个更好productIdentifier
?或者甚至可能每次调用一次paymentQueue:updatedTransactions:
?如果磁盘上的收据数据始终相同,那么我每次都会向服务器发送相同的二进制数据,有时可能会很多。
答案中的文档链接值得赞赏。