即使检索到 clientSecret,Apple Pay 支付也无法通过
Apple Pay Payment not going through even though clientSecret was retrieved
我们的目标是成功完成 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 sheet 出现时,我称之为正确。打印语句工作正常,检索到 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 sheet 中显示成功消息。这是我在 didCompleteWithStatus
方法中的内容:
func applePayContext(_ context: STPApplePayContext, didCompleteWith status: STPPaymentStatus, error: Error?) {
guard status == .success else {
print("Payment couldn't go through")
return
}
}
所以奇怪的是,第一种方法最终成功,费用显示在 API 调用日志中,但 didCompleteWith...
方法总是以错误结束状态和 Apple 上的“付款未完成”sheet,对于我来说,我无法理解为什么。
我认为问题在于您在这一行中创建了一个错误:
let error = NSError(domain: backendUrl, code: 400, userInfo: [NSLocalizedDescriptionKey: "The payment cannot go through for some reason!"])
然后将该错误输入此处的 completion
处理程序:
completion(paymentIntentClient, error)
这导致 Apple Pay 中显示“付款未完成”错误 sheet。
completion
处理程序的想法是向其提供支付意向的客户端密码 或者 如果您无法向其提供客户端密码,则会出现错误,而不是两个都。 The documentation 对此进行了解释:
Call this with the PaymentIntent’s client secret, or the error that occurred creating the PaymentIntent.
如果您在没有 error
的情况下调用 completion
,您应该已经准备就绪。
我们的目标是成功完成 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 sheet 出现时,我称之为正确。打印语句工作正常,检索到 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 sheet 中显示成功消息。这是我在 didCompleteWithStatus
方法中的内容:
func applePayContext(_ context: STPApplePayContext, didCompleteWith status: STPPaymentStatus, error: Error?) {
guard status == .success else {
print("Payment couldn't go through")
return
}
}
所以奇怪的是,第一种方法最终成功,费用显示在 API 调用日志中,但 didCompleteWith...
方法总是以错误结束状态和 Apple 上的“付款未完成”sheet,对于我来说,我无法理解为什么。
我认为问题在于您在这一行中创建了一个错误:
let error = NSError(domain: backendUrl, code: 400, userInfo: [NSLocalizedDescriptionKey: "The payment cannot go through for some reason!"])
然后将该错误输入此处的 completion
处理程序:
completion(paymentIntentClient, error)
这导致 Apple Pay 中显示“付款未完成”错误 sheet。
completion
处理程序的想法是向其提供支付意向的客户端密码 或者 如果您无法向其提供客户端密码,则会出现错误,而不是两个都。 The documentation 对此进行了解释:
Call this with the PaymentIntent’s client secret, or the error that occurred creating the PaymentIntent.
如果您在没有 error
的情况下调用 completion
,您应该已经准备就绪。