【发布时间】:2021-01-14 21:25:17
【问题描述】:
我正在使用 Apple Pay 和 Stripe,当没有可用的送货时它可以正常工作。
When there is a shipping address selected it always gives invalid address error. (适用于 Stripe Sandbox Key)
我正在使用 STKPaymentContext API 并按照以下链接中的步骤操作。
https://stripe.com/docs/mobile/ios/basic
在配置中,我写了这个。
let config = STPPaymentConfiguration.shared()
config.requiredShippingAddressFields = [.postalAddress, .phoneNumber,.name]
不知道这里出了什么问题。
这是它的外观。
这是我的代码
extension CheckoutTableViewController:STPPaymentContextDelegate{
func paymentContext(_ paymentContext: STPPaymentContext, didUpdateShippingAddress address: STPAddress, completion: @escaping STPShippingMethodsCompletionBlock) {
guard
let buyerPostalCode = address.postalCode,
let buyerCountry = address.country,
let productId = self.productDetailsData?.productId
else{
completion(.invalid, nil, nil, nil)
return
}
guard let phone = address.phone, phone.count > 0 else {
completion(.invalid,RatesError.phoneNumberRequired,[],nil)
return
}
var shipmentItem:[String:Any] = [:]
shipmentItem["order_amount"] = self.productCost
shipmentItem["actual_weight"] = 8
shipmentItem["height"] = 7
shipmentItem["width"] = 10
shipmentItem["length"] = 13
shipmentItem["currency"] = "USD"
shipmentItem["destination_postal_code"] = buyerPostalCode
shipmentItem["destination_country_code"] = buyerCountry
shipmentItem["product_id"] = productId
shipmentItem["category"] = "fashion"
enum RatesError:Error,LocalizedError{
case NoDeliveryOptionsFound
case phoneNumberRequired
public var errorDescription: String? {
switch self {
case .NoDeliveryOptionsFound:
return "No couriers are available at the address.\nPlease try with different address."
case .phoneNumberRequired:
return "Please enter phone number."
}
}
}
fetchShippingOptions(forItem: shipmentItem, completionSuccess: {[weak self] (response) in
guard let self = `self` else {
return
}
if
let responseValue = response as? [String:Any],
let rates = responseValue["rates"] as? [[String:Any]]{
self.shippingRates = []
for rate in rates{
if let fullName = rate["courier_display_name"] as? String,
let identifier = rate["courier_id"] as? String,
let amount = rate["shipment_charge_total"] as? Double,
let detail = rate["full_description"] as? String
{
let method = PKShippingMethod()
method.amount = NSDecimalNumber.init(value: amount.currency)
method.identifier = identifier
method.label = fullName
method.detail = detail.replacingOccurrences(of: fullName, with: "")
self.shippingRates.append(method)
}
}
completion(.valid, nil, self.shippingRates, self.shippingRates.first)
}else{
completion(.invalid,RatesError.NoDeliveryOptionsFound,[],nil)
}
}) { (error) in
completion(.invalid,error,[],nil)
}
}
func paymentContextDidChange(_ paymentContext: STPPaymentContext) {
if let paymentOption = paymentContext.selectedPaymentOption {
self.lblPaymentMethod.text = paymentOption.label
} else {
self.lblPaymentMethod.text = "Select Payment"
}
if let shippingMethod = paymentContext.selectedShippingMethod {
if let selectedRate = self.shippingRates.first(where: { (method) -> Bool in
guard let leftValue = method.identifier, let rightValue = shippingMethod.identifier else{
return false
}
return leftValue == rightValue
}){
self.lblAddress.text = selectedRate.label
self.shippingCharges = Double(truncating: selectedRate.amount).currency
self.lblShippingCharges.text = "$\(shippingCharges)"
self.getStripeFees(forAmount: self.productCost + self.shippingCharges)
}
} else {
self.lblAddress.text = "Select Address"
}
self.updateTotalCost()
}
func paymentContext(_ paymentContext: STPPaymentContext, didFailToLoadWithError error: Error) {
let alertController = UIAlertController(
title: "Error",
message: error.localizedDescription,
preferredStyle: .alert
)
let cancel = UIAlertAction(title: "Cancel", style: .cancel, handler: { action in
// Need to assign to _ because optional binding loses @discardableResult value
// https://bugs.swift.org/browse/SR-1681
_ = self.navigationController?.popViewController(animated: true)
})
let retry = UIAlertAction(title: "Retry", style: .default, handler: { action in
self.paymentContext?.retryLoading()
})
alertController.addAction(cancel)
alertController.addAction(retry)
self.present(alertController, animated: true, completion: nil)
}
func paymentContext(_ paymentContext: STPPaymentContext, didCreatePaymentResult paymentResult: STPPaymentResult, completion: @escaping STPPaymentStatusBlock) {
self.callPaymentIntentAPI(paymentContext, didCreatePaymentResult: paymentResult, completion: completion)
}
func paymentContext(_ paymentContext: STPPaymentContext, didFinishWith status: STPPaymentStatus, error: Error?) {
OperationQueue.main.addOperation {
SVProgressHUD.dismiss()
}
let title: String
let message: String
switch status {
case .error:
title = "Error"
message = error?.localizedDescription ?? ""
UIAlertController.showAlert(withTitle: title, andMessage: message, andButtonTitles: ["Okay"]) {[weak self] (selectedIndex) in
OperationQueue.main.addOperation {
self?.navigationController?.popViewController(animated: true)
}
}
case .success:
title = "Success"
message = "Your purchase was successful!"
UIAlertController.showAlert(withTitle: title, andMessage: message, andButtonTitles: ["Okay"]) {[weak self] (selectedIndex) in
OperationQueue.main.addOperation {
self?.onPaymentCompletion?()
var isControllerFound:Bool = false
for controller in self?.navigationController?.viewControllers ?? []{
if (controller is ProductDetailsViewController) || (controller is ChatVC){
isControllerFound = true
self?.navigationController?.popToViewController(controller, animated: true)
break
}
}
if !isControllerFound{
self?.navigationController?.popViewController(animated: true)
}
}
}
case .userCancellation:
return()
@unknown default:
return()
}
}
}
【问题讨论】:
-
您是否可能在某处实现了此
didUpdateShippingAddress委托,即不调用完成块或使用status:.Invalid或其他方式调用它? stripe.dev/stripe-ios/docs/Protocols/…: -
是的,基于此,我将返回可用快递员列表,您可以在屏幕截图中看到选择了 USPS。
-
那么您可能应该共享该委托函数的代码,因为这可能就是问题所在。
-
代码共享@karllekko
标签: ios swift stripe-payments applepay