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

配置Stripe的STPPaymentMethodsViewController时STPCustomerContext配置位置疑问

解决STPPaymentMethodsViewController中STPCustomerContext的配置问题

看起来你已经搞定了Firebase侧创建Stripe Customer的流程,现在卡在了iOS端STPCustomerContext的配置上对吧?我来一步步帮你理清这个问题:

一、STPCustomerContext的核心作用&正确配置位置

STPCustomerContext是Stripe iOS SDK用来桥接你的后端和客户端的关键类,它负责从你的后端获取Customer信息、同步支付方式等操作。最佳实践是:

  • 要么在需要使用支付相关功能的视图控制器里初始化(比如你展示STPPaymentMethodsViewController的那个VC)
  • 要么封装成全局单例(如果APP多个地方用到支付功能,推荐这种方式)

二、先确认你的MYAPIClient实现是否正确

你的MYAPIClient需要遵守STPCustomerContextDelegate协议,并且正确实现两个核心方法:获取Customer Ephemeral Key、创建Payment Method。这里给你补全标准实现(结合你的Firebase场景):

import Stripe

class MYAPIClient: NSObject, STPCustomerContextDelegate {
    static let shared = MYAPIClient() // 单例模式,方便全局调用
    
    func createCustomerKey(withAPIVersion apiVersion: String, completion: @escaping STPJSONResponseCompletionBlock) {
        // 这里调用你的Firebase Cloud Function或者后端接口,获取Customer的Ephemeral Key
        // 注意:要传递当前用户的Stripe Customer ID(从Firebase数据库获取)和Stripe API版本
        guard let currentUserID = Auth.auth().currentUser?.uid else {
            completion(nil, NSError(domain: "MYAPIClient", code: -1, userInfo: [NSLocalizedDescriptionKey: "用户未登录"]))
            return
        }
        
        // 示例:调用Firebase Functions获取Ephemeral Key
        let functions = Functions.functions()
        functions.httpsCallable("createEphemeralKey").call(["customerId": YOUR_CUSTOMER_ID_FROM_FIREBASE, "apiVersion": apiVersion]) { result, error in
            if let error = error {
                completion(nil, error as NSError)
                return
            }
            guard let key = result?.data as? [String: Any] else {
                completion(nil, NSError(domain: "MYAPIClient", code: -2, userInfo: [NSLocalizedDescriptionKey: "获取Ephemeral Key失败"]))
                return
            }
            completion(key, nil)
        }
    }
    
    // 如果需要创建Payment Method(可选,有些场景SDK会自动处理)
    func attachPaymentMethod(_ paymentMethod: STPPaymentMethod, completion: @escaping STPErrorBlock) {
        // 调用后端接口将Payment Method关联到Customer
        // 同样需要传递Customer ID和Payment Method ID
        let functions = Functions.functions()
        functions.httpsCallable("attachPaymentMethod").call(["customerId": YOUR_CUSTOMER_ID_FROM_FIREBASE, "paymentMethodId": paymentMethod.stripeId]) { result, error in
            completion(error)
        }
    }
}

三、在STPPaymentMethodsViewController所在VC中配置STPCustomerContext

现在你可以在要展示支付方式列表的VC里,初始化STPCustomerContext,然后传入STPPaymentMethodsViewController:

import Stripe

class PaymentMethodsVC: UIViewController {
    var customerContext: STPCustomerContext!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // 初始化CustomerContext,使用我们的MYAPIClient
        customerContext = STPCustomerContext(keyProvider: MYAPIClient.shared)
    }
    
    // 比如点击按钮展示支付方式列表
    @IBAction func showPaymentMethods(_ sender: UIButton) {
        let config = STPPaymentMethodsConfiguration()
        // 配置允许的支付方式类型,比如.card、.applePay等
        config.paymentMethodTypes = [.card]
        
        let paymentMethodsVC = STPPaymentMethodsViewController(configuration: config, customerContext: customerContext, delegate: self)
        // 用导航控制器push或者present
        navigationController?.pushViewController(paymentMethodsVC, animated: true)
    }
}

// 遵守STPPaymentMethodsViewControllerDelegate协议
extension PaymentMethodsVC: STPPaymentMethodsViewControllerDelegate {
    func paymentMethodsViewControllerDidCancel(_ controller: STPPaymentMethodsViewController) {
        controller.dismiss(animated: true)
    }
    
    func paymentMethodsViewController(_ controller: STPPaymentMethodsViewController, didSelect paymentMethod: STPPaymentMethod) {
        // 处理选中的支付方式,比如保存到本地或者用于后续支付
        print("选中的支付方式ID:\(paymentMethod.stripeId)")
        controller.dismiss(animated: true)
    }
    
    func paymentMethodsViewController(_ controller: STPPaymentMethodsViewController, didFailToLoadWithError error: Error) {
        // 处理加载失败的错误,比如提示用户
        print("加载支付方式失败:\(error.localizedDescription)")
        controller.dismiss(animated: true)
    }
}

四、常见错误排查(结合你遇到的加载错误)

如果加载STPPaymentMethodsViewController时出现错误,大概率是以下原因:

  1. Ephemeral Key获取失败:检查你的Firebase Function是否正确返回了Ephemeral Key,确保传递的Customer ID是正确的(从Firebase数据库读取的用户对应的Stripe Customer ID)
  2. MYAPIClient未正确实现协议方法:确认createCustomerKey方法里的回调是否正确传递了Key或者错误信息
  3. 用户未登录:确保在初始化CustomerContext前,用户已经完成Firebase登录,能获取到正确的用户ID和对应的Customer ID
  4. Stripe API版本不匹配:确保你的后端(Firebase Function)使用的Stripe API版本和iOS SDK的版本一致(可以在STPAPIClient.shared.apiVersion查看SDK的版本)

关键提醒

  • 不要硬编码Customer ID,一定要从Firebase数据库中读取当前登录用户对应的Stripe Customer ID
  • Ephemeral Key是短期有效的,每次打开支付方式列表时都会重新获取,所以不要缓存它

内容的提问来源于stack exchange,提问作者Omar Al-Eisa

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:09:09