简体   繁体   中英

stripe.confirmCardPayment intent secret Returns Empty String

I'm trying to implement Stripe Elements Payment Intents into my React app using Netlify Functions. Submitting the payment form returns the error: Unhandled Rejection (IntegrationError): Invalid value for stripe.confirmCardPayment intent secret: value should be a client secret of the form ${id}_secret_${secret}. You specified: . Unhandled Rejection (IntegrationError): Invalid value for stripe.confirmCardPayment intent secret: value should be a client secret of the form ${id}_secret_${secret}. You specified: .

I can see the client_secret value in the paymentIntent object, so the serverless function is returning the client_secret, but I must not implementing it appropriate in the client. If I pass data.clientSecret as the parameter to stripe.confirmCardPayment , then my payment completes successfully, but the Elements form does not reset which indicates to me that there is a problem with this implementation.

Is setClientSecret not updating state on clientSecret?

Here's my Netlify function:

const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);

exports.handler = async (event) => {  
  const paymentObject = JSON.parse(event.body);
  const amount = paymentObject.amount;
  const donorName = paymentObject.metadata.donorName;
  const address = paymentObject.metadata.address;
  const city = paymentObject.metadata.city;
  const state = paymentObject.metadata.state;
  const zip = paymentObject.metadata.zip;
  const email = paymentObject.metadata.email

  try {
    const paymentIntent = await stripe.paymentIntents.create({
      amount,
      currency: 'usd',
      description: 'USS Idaho Donation',
      receipt_email: email,
      metadata: {
        donorName,
        address,
        city,
        state,
        zip,
        email,
      },
    });
    return {
      statusCode: 200,
      body: JSON.stringify({ 
        paymentIntent, 
        clientSecret: paymentIntent.client_secret
      })
    };
  } catch (error) {
    console.log({ error });

    return {
      statusCode: 400,
      body: JSON.stringify({ error }),
    };
  }
};

handleSubmit function:

const handleSubmit = async ev => {
    ev.preventDefault();
    setProcessing(true);

    window
      .fetch("/.netlify/functions/charge", {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          amount,
          receipt_email: email,
            metadata: {
             donorName: donorName,
             address: address,
             city: city,
             state: state,
             zip: zip,
             email: email
            }
          }
        )
      })
      .then(res => {
        return res.json();
        
      })
      .then(data => {
        setClientSecret(data.clientSecret)
        console.log(`clientSecret: ${clientSecret}`)
        
        const payload = stripe.confirmCardPayment(data.clientSecret, {
          payment_method: {
            card: elements.getElement(CardElement)
          }
        });
        
        if (payload.error) {
          setError(`Payment failed: ${payload.error.message}`);
          setProcessing(false);
        } else {
          setError(null);
          setProcessing(false);
          setSucceeded(true);
          reset();
        } 
        
      })
  };

The stripe.confirmCardPayment function returns a Promise, so you need wait for that Promise to resolve before updating your component state:

In your code, this would look something like:

const handleSubmit = async ev => {
    ev.preventDefault();
    setProcessing(true);

    window
      .fetch("/.netlify/functions/charge", {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify({
          amount,
          receipt_email: email,
            metadata: {
             donorName: donorName,
             address: address,
             city: city,
             state: state,
             zip: zip,
             email: email
            }
          }
        )
      })
      .then(res => {
        return res.json();
        
      })
      .then(data => {
        setClientSecret(data.clientSecret);
        
        return stripe.confirmCardPayment(data.clientSecret, {
          payment_method: {
            card: elements.getElement(CardElement)
          }
        });
      })
      .then((paymentResult) => {
        if (paymentResult.error) {
          setError(`Payment failed: ${payload.error.message}`);
          setProcessing(false);
        } else {
          if (paymentResult.paymentIntent.status === 'succeeded') {
            setError(null);
            setProcessing(false);
            setSucceeded(true);
            reset();
          }
        }
      });
  };

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM