Swift iOS应用Stripe支付:card_令牌无法保存至客户问题
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
didCreatePaymentResulthandler 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 indidCreatePaymentResult—they can't be reused later.
内容的提问来源于stack exchange,提问作者DevWithZachary

