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

Swift iOS应用Stripe支付:card_令牌无法保存至客户问题

Fixing Stripe Apple Pay: Can't Save card_ Token to Customer

Hey there, let's break down why you're hitting this issue and how to fix it quickly.

The Root Problem

The stripeID you're pulling from paymentResult.source is a one-time payment method token (starting with card_). These tokens are temporary—they can only be used once to either create a charge or attach to a Stripe Customer. You can't save them directly to a Customer because they expire immediately after use, and Stripe doesn't allow storing them long-term.

Step-by-Step Solution

To save the Apple Pay payment method for future use, you need to:

  • Have an existing Stripe Customer ID for your user (create one if you don't have it yet—this should be done via your backend, not the client).
  • Send the temporary card_ token to your backend, then use Stripe's API to attach it to the Customer. This gives you a reusable payment method ID you can store.
  • Update your didCreatePaymentResult handler to trigger this backend flow instead of trying to use the token directly.

Modified Client-Side Code

Here's how to adjust your Swift method to work with a backend endpoint:

func paymentContext(_ paymentContext: STPPaymentContext, didCreatePaymentResult paymentResult: STPPaymentResult, completion: @escaping STPErrorBlock) {
    guard let customerId = yourAppCurrentUser.stripeCustomerId else {
        completion(NSError(domain: "YourApp", code: -1, userInfo: [NSLocalizedDescriptionKey: "No customer ID found for user"]))
        return
    }
    
    let temporaryCardToken = paymentResult.source.stripeID
    
    // Call your backend API to attach the token to the customer
    YourBackendService.shared.attachPaymentTokenToCustomer(token: temporaryCardToken, customerId: customerId) { result in
        switch result {
        case .success(let reusablePaymentMethodId):
            // Store this reusable ID for future payments
            self.orderToken = reusablePaymentMethodId
            completion(nil) // Signal Stripe the flow succeeded
        case .failure(let error):
            completion(error) // Pass the error back to Stripe to show to the user
        }
    }
}

Backend Example (Node.js)

This is what the backend endpoint would look like—remember, you must use your Stripe Secret Key here (never expose this client-side):

const stripe = require('stripe')('sk_your_secret_key_here');

app.post('/api/attach-payment-token', async (req, res) => {
    const { token, customerId } = req.body;
    
    try {
        // Attach the temporary card token to the customer
        const paymentMethod = await stripe.paymentMethods.attach(
            token,
            { customer: customerId }
        );
        
        res.status(200).json({ paymentMethodId: paymentMethod.id });
    } catch (error) {
        res.status(400).json({ error: error.message });
    }
});

Key Notes

  • Never handle Customer modifications client-side: The Stripe Publishable Key (used in your iOS app) doesn't have permission to modify Customers—this is a security risk, so all Customer operations need to happen on your backend.
  • Temporary tokens expire fast: Make sure you send the card_ token to your backend immediately after receiving it in didCreatePaymentResult—they can't be reused later.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:24:10