You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift集成Stripe后支付状态显示requires_payment_method原因排查

Stripe支付状态一直为requires_payment_method且无Charges的排查方案

问题背景

Swift项目集成Stripe的流程:

  • 点击支付按钮调用request_payment接口获取Payment Intent数据
  • 弹出Stripe卡片输入界面,输入卡号、有效期和CVV后得到paymentMethodId
  • 在didCreatePaymentMethod方法中调用save_payment接口

但Stripe控制台显示支付状态为requires_payment_method,且无Charges数据,需排查问题根源。

客户端代码

import UIKit
import Stripe
class NewBuyRequestPaymentVC: UIViewController, STPAddCardViewControllerDelegate{

@IBAction func payButton(_ sender: UIButton) {
    
    let param: [String: Any] = [
        "description": descriptionTextField.text ?? "No description",
        "amount": amountTextField.text ?? "0.0",
        "enquiry_id": enqrId ?? "",
    ]
    
    APIReqeustManager.sharedInstance.serviceCall(param: param, method: .post, url: CommonUrl.request_payment){ [weak self] (resp) in
        
        self?.makePayment = PaymentNewBuyModel(dictionary: resp.dict as NSDictionary? ?? NSDictionary())
        
        self?.paymentIntentClientSecret = self?.makePayment?.result?.intent?.client_secret
        paymentIntentId = makePayment?.result?.intent?.id
        
        // 弹出Stripe卡片输入界面
        let config = STPPaymentConfiguration.shared
        config.requiredBillingAddressFields = .none
        let viewController = STPAddCardViewController(configuration: config, theme: STPTheme.defaultTheme)
        viewController.delegate = self
        let navigationController = UINavigationController(rootViewController: viewController)
        self?.present(navigationController, animated: true, completion: nil)
    }
}

func addCardViewControllerDidCancel(_ addCardViewController: STPAddCardViewController) {
    dismiss(animated: true, completion: nil)}

@objc
func addCardViewController(_ addCardViewController: STPAddCardViewController, didCreatePaymentMethod paymentMethod: STPPaymentMethod, completion: @escaping STPErrorBlock) {
    paymentMethodId = paymentMethod.stripeId
    print("payment method id \(paymentMethodId ?? "")")
    savePaymentServiceCall()
    dismiss(animated: true, completion: nil)
}

func savePaymentServiceCall(){
    
    print("payment transaction and method id \(String(describing: paymentIntentId)), \(String(describing: paymentMethodId))")
    
    let param = ["term_id" : makePayment?.result?.term_id?.description ?? "",
                 "payment_method" : paymentMethodId ?? "",
                 "intent_id" : paymentIntentId ?? ""
    ] as [String : Any]
    APIReqeustManager.sharedInstance.serviceCall(param: param as [String : Any], method: .post, url: CommonUrl.save_payment) { [weak self] (resp) in
        
    }
}
}

Stripe控制台返回数据

{
"id": "pi_3LWMATIAbhwaLb1OenxVAI",
"object": "payment_intent",
"livemode": false,
"status": "requires_payment_method",
"amount": 1170,
"amount_received": 0,
"charges": {
    "object": "list",
    "data": []
}
}

排查修复要点

1. 缺失Payment Intent确认流程

当前代码仅创建Payment Method并调用后端接口,但未完成Stripe支付的核心确认步骤。需在didCreatePaymentMethod中调用Stripe SDK的支付确认方法:

@objc
func addCardViewController(_ addCardViewController: STPAddCardViewController, didCreatePaymentMethod paymentMethod: STPPaymentMethod, completion: @escaping STPErrorBlock) {
    guard let clientSecret = self.paymentIntentClientSecret else {
        completion(NSError(domain: "PaymentError", code: -1, userInfo: [NSLocalizedDescriptionKey: "缺少Payment Intent Client Secret"]))
        return
    }
    
    let paymentParams = STPPaymentIntentParams(clientSecret: clientSecret)
    paymentParams.paymentMethodId = paymentMethod.stripeId
    
    STPPaymentHandler.shared().confirmPayment(withParams: paymentParams, authenticationContext: self) { [weak self] status, intent, error in
        switch status {
        case .succeeded:
            // 支付成功后再调用后端接口记录状态
            self?.paymentMethodId = paymentMethod.stripeId
            self?.savePaymentServiceCall()
            completion(nil)
            self?.dismiss(animated: true, completion: nil)
        case .failed:
            completion(error)
            self?.dismiss(animated: true, completion: nil)
        case .canceled:
            completion(NSError(domain: "PaymentError", code: -2, userInfo: [NSLocalizedDescriptionKey: "用户取消支付"]))
            self?.dismiss(animated: true, completion: nil)
        @unknown default:
            completion(NSError(domain: "PaymentError", code: -3, userInfo: [NSLocalizedDescriptionKey: "未知状态"]))
            self?.dismiss(animated: true, completion: nil)
        }
    }
}

2. 后端save_payment接口逻辑缺失

若后端仅存储数据,未调用Stripe API将Payment Method关联到Payment Intent并完成确认,会导致状态一直停留在requires_payment_method。需检查后端:

  • 是否调用Stripe的PaymentIntent confirm或update + confirm接口,传入Payment Intent ID和Payment Method ID
  • 确保使用正确的API密钥,且处理卡片验证失败、金额不匹配等异常情况

3. 检查Payment Intent创建参数

确认request_payment接口创建Payment Intent时:

  • amount是否为最小单位(如1170代表11.70元)
  • 是否设置了正确的currency参数
  • payment_method_types是否包含card类型

4. 未处理支付状态回调

原代码直接关闭界面,无法感知支付是否成功。必须依赖STPPaymentHandler的回调结果,再执行后续业务逻辑。

内容的提问来源于stack exchange,提问作者Swift iOS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 13:39:40