【问题标题】:Apple Pay Payment not going through even though clientSecret was retrieved即使检索了 clientSecret,Apple Pay 付款也不会通过
【发布时间】:2021-06-23 15:14:09
【问题描述】:

我们的目标是成功完成 Apple Pay 付款并通过此 API 集成完成。 我确实处于成功的边缘,但我还有一个我无法弄清楚的错误。

func startApplePayCheckout() {
    let backendUrlForIntent = "https://us-central1-xxxxx-41f12.cloudfunctions.net/createPaymentIntent"
    guard let user = Auth.auth().currentUser else { return }
    getUsersStripeCustomerID { (customerid) in
        if let id = customerid {
            // Create a PaymentIntent as soon as the view loads
            let costAsAnInt = self.actualCostOfEvent.text?.replacingOccurrences(of: "$", with: "").replacingOccurrences(of: ".", with: "")
            let costForStripe = Int(costAsAnInt!)
            let url = URL(string: backendUrlForIntent)!
            let json: [String: Any] = [
                "amount": costForStripe! + (self.gothereFee * Int(self.stepperValue.value)),
                "currency": "CAD",
                "customer": id,
                "setup_future_usage": "on_session",
            ]
            var request = URLRequest(url: url)
            request.httpMethod = "POST"
            request.setValue("application/json", forHTTPHeaderField: "Content-Type")
            request.httpBody = try? JSONSerialization.data(withJSONObject: json)
            let task = URLSession.shared.dataTask(with: request, completionHandler: { [weak self] (data, response, error) in
                guard let response = response as? HTTPURLResponse,
                      response.statusCode == 200,
                      let data = data,
                      let json = try? JSONSerialization.jsonObject(with: data, options: []) as? [String : Any],
                      let clientSecret = json["clientSecret"] as? String else {
                    let message = error?.localizedDescription ?? "Failed to decode response from server."
                    self?.displayCancelledAlert(title: "Error Loading Page", message: message)
                    return
                }
                guard let paymentIntentID = json["paymentIntentID"] as? String else { return }
                
                self?.db.document("student_users/\(user.uid)/events_bought/\(self?.nameToUseInAPICall)").setData(["stripePaymentIntentID": paymentIntentID], merge: true, completion: { (error) in
                    if let error = error {
                        print("There was an error setting the paymentIntentID in the document: \(error)")
                    } else {
                        print("PaymentIntentID successfully stored!")
                    }
                })
                print("Created PaymentIntent")
                self?.paymentIntentClientSecret = clientSecret
            })
            task.resume()
        }
    }
    

当 Apple Pay 表出现时,我认为这是正确的。打印语句工作正常,clientSecret 被检索。现在当我实际尝试付款时,我仍然得到“付款未完成”,这是我在didCreatePaymentMethod 函数中的内容:

func applePayContext(_ context: STPApplePayContext, didCreatePaymentMethod paymentMethod: STPPaymentMethod, paymentInformation: PKPayment, completion: @escaping STPIntentClientSecretCompletionBlock) {
    guard let paymentIntentClient = paymentIntentClientSecret else {
        print("There is an issue with the clientSecret")
        return
    }
    
    let error = NSError(domain: backendUrl, code: 400, userInfo: [NSLocalizedDescriptionKey: "The payment cannot go through for some reason!"])
    
    let paymentIntentParams = STPPaymentIntentParams(clientSecret: paymentIntentClient)
    paymentIntentParams.paymentMethodId = paymentMethod.stripeId
    
    let paymentHandler = STPPaymentHandler.shared()
    paymentHandler.confirmPayment(paymentIntentParams, with: self) { (status, intent, error) in
        switch status {
        case .canceled:
            print("Payment Canceled")
            break
        case .failed:
            print("Payment Failed")
            break
        case .succeeded:
            print("Payment Succeeded")
            break
        default:
            break
        }
    }
    
    completion(paymentIntentClient, error)

}

编辑 因此,实施此操作后,当我检查日志时,付款实际上会收费,但对于实际的 Apple Pay 本身,它永远不会在 Apple Pay 表中显示成功消息。这是我在didCompleteWithStatus 方法中的内容:

 func applePayContext(_ context: STPApplePayContext, didCompleteWith status: STPPaymentStatus, error: Error?) {
    
    guard status == .success else {
        print("Payment couldn't go through")
        return
    }
}

所以奇怪的事情是,第一个方法最终成功并且费用显示在 API 调用日志中,但 didCompleteWith... 方法总是以错误状态和“付款未完成”结束在 Apple 表上,我这辈子都无法理解为什么。

【问题讨论】:

  • 完成此流程后,支付意图的状态如何?在开发人员 > 日志和开发人员 > 事件下的 Stripe 仪表板中是否有任何提示?
  • 等一下,让我编辑帖子,我添加了一些内容。 @贾斯汀迈克尔
  • 刚刚完成编辑,现在看看@Justin Michael
  • 在您的 applePayContext:didCompleteWithStatus:error: 委托方法中尝试同时记录 statuserror 并将详细信息添加到您的消息中。
  • 哦,等一下,我想我明白了。您正在创建一个实际的 error 并将其提供给 completion 处理程序。如果您删除 let error = NSError... 行,它会按预期工作吗?

标签: ios swift stripe-payments applepay passkit


【解决方案1】:

我认为问题在于您在此行上创建了一个错误:

let error = NSError(domain: backendUrl, code: 400, userInfo: [NSLocalizedDescriptionKey: "The payment cannot go through for some reason!"])

然后在此处将该错误输入completion 处理程序:

completion(paymentIntentClient, error)

这会导致 Apple Pay 表中显示“付款未完成”错误。

completion 处理程序的想法是为它提供一个支付意图的客户端密码如果你不能为它提供一个客户端密码,而不是两者都提供一个错误。 The documentation 对此进行了解释:

使用 PaymentIntent 的客户端密码或创建 PaymentIntent 时发生的错误调用此方法。

如果您在没有error 的情况下调用completion,您应该已准备就绪。

【讨论】:

  • 完成块中必须有两个参数。一个字符串,即 clientSecret,和一个错误数据类型。 @贾斯汀迈克尔
  • Nvm 只需设置 nil,现在效果很好。感谢过去一周左右的所有帮助,非常感谢。 @贾斯汀迈克尔
猜你喜欢
  • 2014-12-19
  • 2017-05-13
  • 2021-07-28
  • 2020-04-16
  • 2015-03-02
  • 2019-04-05
  • 2018-12-31
  • 1970-01-01
  • 2018-01-17
相关资源
最近更新 更多