配置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时出现错误,大概率是以下原因:
- Ephemeral Key获取失败:检查你的Firebase Function是否正确返回了Ephemeral Key,确保传递的Customer ID是正确的(从Firebase数据库读取的用户对应的Stripe Customer ID)
- MYAPIClient未正确实现协议方法:确认
createCustomerKey方法里的回调是否正确传递了Key或者错误信息 - 用户未登录:确保在初始化CustomerContext前,用户已经完成Firebase登录,能获取到正确的用户ID和对应的Customer ID
- 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
相关产品推荐
相关产品推荐

