React+react-stripe-elements向Stripe传递额外数据失败求助
Hey there, let's break down why your metadata and owner data aren't showing up in the Payment Intent webhook response, and walk through how to fix it.
What's the Root Issue?
Your current workflow mixes two different Stripe API patterns, which is why the data isn't transferring:
- You're calling
createSource()in the frontend with metadata/owner details, but this creates a standalone Source object (an older Stripe API pattern). - You're then using a
client_secretfrom a backend-created Payment Intent to callconfirmIdealPayment(). These two objects (Source and Payment Intent) aren't linked by default, so the data from your Source never makes it to the Payment Intent that triggers the webhook.
Stripe's modern best practice is to build payments entirely around the Payment Intent API—no need for createSource() when using iDEAL with confirmIdealPayment().
Step-by-Step Fix
1. Pass Metadata/Customer Data to Your Backend First
Instead of adding metadata/owner info to createSource(), send this data to your backend when you request to create the Payment Intent. This way, your backend can attach it directly to the Payment Intent.
Updated Frontend Code (before calling confirmIdealPayment):
// First, send customer/metadata data to your backend to create the Payment Intent const paymentIntentResponse = await fetch('/payment-stripe/', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ amount: this.props.event.stock[0].price * 100, currency: 'eur', // Send your custom metadata metadata: { stock_type: this.props.event.stock[0].id, event: this.props.event.id, }, // Send customer details (for both metadata and billing info) customerDetails: { first_name: this.first_name.value, last_name: this.last_name.value, phonenumber: this.phonenumber.value, email: this.email.value } }) }); const content = await paymentIntentResponse.json();
2. Attach Data to the Payment Intent in Your Backend
Modify your backend code to receive the data from the frontend and include it in the PaymentIntent.create() call. Here's an example using Python's Stripe SDK (adjust for your backend language):
import stripe from flask import request, jsonify stripe.api_key = "YOUR_STRIPE_SECRET_KEY" @app.route('/payment-stripe/', methods=['POST']) def create_payment_intent(): request_data = request.get_json() # Create Payment Intent with attached metadata and customer info intent = stripe.PaymentIntent.create( amount=request_data['amount'], currency=request_data['currency'], payment_method_types=['ideal'], # Attach your custom metadata here metadata={ "event_id": request_data['metadata']['event'], "stock_type": request_data['metadata']['stock_type'], "first_name": request_data['customerDetails']['first_name'], "last_name": request_data['customerDetails']['last_name'], "phonenumber": request_data['customerDetails']['phonenumber'], "email": request_data['customerDetails']['email'] } ) return jsonify(client_secret=intent.client_secret)
3. Update Frontend Confirmation to Include Billing Details (Optional but Recommended)
While metadata will cover your backend verification needs, you can also attach customer details to the payment method itself using billing_details in confirmIdealPayment(). This makes the info accessible in the Payment Intent's payment_method object too:
this.props.stripe.confirmIdealPayment(content.client_secret, { payment_method: { ideal: idealBank, billing_details: { name: `${this.first_name.value} ${this.last_name.value}`, email: this.email.value, phone: this.phonenumber.value } }, return_url: 'http://127.0.0.1:3000/payment-succeeded/', })
4. Remove the Unnecessary createSource() Call
Since confirmIdealPayment() handles creating and attaching the iDEAL payment method to the Payment Intent automatically, you can delete the entire createSource() block from your code—it's no longer needed.
What to Verify After Changes
- Trigger a test payment, then check your Stripe Dashboard's Payment Intents tab: the metadata section should now show your custom data.
- Check the webhook response again—you'll see the
metadatafield populated with the data your backend added, and customer details will be inpayment_method.billing_details(if you added that step).
内容的提问来源于stack exchange,提问作者Tony

