如何增加 apple Pay 操作的失败超时?

How can I increase the failure timeout of an apple Pay operation?

在目前的实施中,我的付款在某些情况下需要很长时间。用户经常会遇到类似 "Apple pay not completed" 的错误。 question 说在 iOS 11 这发生在 15-20 秒后,我可以增加这个时间吗,如果可以,如何?如果这段时间内付款有时间处理,则apple pay付款成功。

不幸的是,据我所知和发现,这是不可能的, onpaymentauthorized 方法必须在 30 秒内调用,否则付款将被拒绝。参考这个,大多数情况下你最多只有30秒。

https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778020-onpaymentauthorized

虽然更改失败超时是不可能的,但仍有一种解决方法可以避免出现 "Apple pay not completed" 消息,例如,您的 API呼叫处理付款已延长超时。 (在写这个答案的时候,在 iOS 13,ApplePay 对话框会在大约 30 秒内超时)。

诀窍是设置一个一次性计时器,它会在决定放弃之前关闭 ApplePay 对话框。当然,您的应用程序必须始终在购买过程结束时向用户提供适当的反馈(无论是成功还是失败),因为 ApplePay 对话框在您关闭后将无法显示任何内容。

示例计时器:

_ = Timer.scheduledTimer(withTimeInterval: 25, repeats: false) { _ in
    guard self.applePayBeingProcessed == true else { return }
    if let applePayVC = AppUtil.shared.topMostController() as? PKPaymentAuthorizationViewController {
        self.applePayHasTimeouted = true
        applePayVC.dismiss(animated: true)
    }
}

*applePayBeingProcessedpaymentAuthorizationViewController(_:didAuthorizePayment:handler:) 中设置为 true 并在调用 handler(PKPaymentAuthorizationResult(status: paymentStatus, errors: [error])) 后立即设置回 false - 这样计时器调用的例程当通过 paymentAuthorizationViewControllerDidFinish(_:)

以正常方式关闭 ApplePay 时将被跳过

** applePayHasTimeouted 稍后会在您的付款处理 API 调用完成后进行检查,如果 true 则意味着我们需要执行通常应该执行的操作在 paymentAuthorizationViewControllerDidFinish(_:) 里面(因为后者在手动关闭 ApplePay 对话框后永远不会被调用)

*** topMostController() 方法从层次结构的顶部查找控制器。如何做到这一点超出了当前问题的范围,有很多方法可以做到这一点,我最喜欢的方法是 this answer.