Swift中保存卡片获STPToken后,无法生成Stripe CustomerId求助
解决Swift中通过STPToken生成Stripe CustomerId的问题
嘿,我来帮你搞定这个问题!首先得明确一个关键点:你不能在iOS客户端直接创建Stripe Customer,因为这需要用到Stripe的Secret Key,这个密钥绝对不能暴露在客户端代码里(一旦被逆向破解,你的Stripe账户会面临被盗用的风险)。正确的流程是:客户端获取到STPToken后,把这个Token传给你的后端服务,由后端调用Stripe的官方API来创建Customer,再将生成的CustomerId返回给客户端。
下面是完整的实现步骤和代码示例,一步步来:
1. 完善客户端代码,获取STPToken并传给后端
你的代码只写到了初始化STPAddCardViewController,接下来需要给它设置代理,实现代理方法来拿到Token,然后传给后端:
// 记得让你的ViewController遵守STPAddCardViewControllerDelegate协议 class YourCardViewController: UIViewController, STPAddCardViewControllerDelegate { // 触发添加卡片流程的方法,比如按钮点击时调用 func showAddCardFlow() { let paymentConfig = STPPaymentConfiguration() paymentConfig.requiredBillingAddressFields = .none paymentConfig.publishableKey = "pk_test_whRD827lMXvFb1MtY9T7bRzW" let theme = STPTheme.default() let addCardVC = STPAddCardViewController(configuration: paymentConfig, theme: theme) addCardVC.delegate = self // 必须设置代理才能拿到Token // 用Stripe的导航控制器包裹卡片界面,这样自带返回、确认按钮 let navController = UINavigationController(rootViewController: addCardVC) present(navController, animated: true) } // MARK: - STPAddCardViewControllerDelegate // 用户取消添加卡片时的回调 func addCardViewControllerDidCancel(_ addCardViewController: STPAddCardViewController) { dismiss(animated: true) } // 用户成功添加卡片,拿到STPToken的回调 func addCardViewController(_ addCardViewController: STPAddCardViewController, didCreateToken token: STPToken, completion: @escaping STPErrorBlock) { // 关键:拿到token的id,这是要传给后端的核心内容 let tokenId = token.id // 调用你的后端API,把tokenId传过去 guard let apiUrl = URL(string: "https://your-backend-domain.com/create-stripe-customer") else { let invalidUrlError = NSError(domain: "YourAppDomain", code: -1, userInfo: [NSLocalizedDescriptionKey: "无效的API地址"]) completion(invalidUrlError) dismiss(animated: true) return } var request = URLRequest(url: apiUrl) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") // 构造请求参数 let params = ["stripe_token": tokenId] do { request.httpBody = try JSONSerialization.data(withJSONObject: params) } catch { completion(error) dismiss(animated: true) return } // 发起网络请求 URLSession.shared.dataTask(with: request) { data, response, error in DispatchQueue.main.async { if let err = error { // 网络请求失败,通知Stripe流程失败 completion(err) self.dismiss(animated: true) return } // 解析后端返回的CustomerId guard let responseData = data, let responseDict = try? JSONSerialization.jsonObject(with: responseData) as? [String: String], let customerId = responseDict["customer_id"] else { let parseError = NSError(domain: "YourAppDomain", code: -2, userInfo: [NSLocalizedDescriptionKey: "无法解析CustomerId"]) completion(parseError) self.dismiss(animated: true) return } // 成功拿到CustomerId,这里可以做你需要的后续处理 print("成功获取Stripe CustomerId: \(customerId)") completion(nil) // 通知Stripe流程成功 self.dismiss(animated: true) } }.resume() } }
2. 后端实现:调用Stripe API创建Customer
这里以Node.js为例(Stripe支持几乎所有主流后端语言的SDK,比如Python、Java、Ruby等,你可以根据自己的技术栈调整):
首先安装Stripe的Node.js SDK:
npm install stripe
然后编写API接口:
const stripe = require('stripe')('sk_test_your_secret_key_here'); // 替换成你的Stripe Secret Key const express = require('express'); const app = express(); app.use(express.json()); // 处理客户端传来的token,创建Customer的接口 app.post('/create-stripe-customer', async (req, res) => { try { const { stripe_token } = req.body; // 调用Stripe API创建Customer,并关联传入的token const customer = await stripe.customers.create({ source: stripe_token, // 这里传入客户端发来的tokenId // 可选:你可以添加用户邮箱、描述等额外信息 // email: "user@example.com", // description: "Customer for user@example.com" }); // 将生成的CustomerId返回给客户端 res.status(200).json({ customer_id: customer.id }); } catch (error) { // 处理错误,返回给客户端 res.status(500).json({ error: error.message }); } }); // 启动服务,这里端口可以根据你的需求调整 app.listen(3000, () => { console.log('后端服务运行在端口3000'); });
几个必须注意的点
- 绝对不要在客户端代码中使用Stripe的Secret Key:Secret Key只能放在后端服务器上,一旦泄露,攻击者可以用它操作你的Stripe账户,造成损失。
- 测试环境用测试密钥(
pk_test_和sk_test_开头),生产环境切换为正式密钥(pk_live_和sk_live_开头)。 - 确保后端的Stripe SDK是最新版本,避免出现API兼容性问题。
内容的提问来源于stack exchange,提问作者varun
相关产品推荐
相关产品推荐

