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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:37:20