stripe.confirmCardPayment intent secret Возвращает пустую строку

#javascript #reactjs #stripe-payments #netlify #netlify-function

#javascript #reactjs #stripe-платежи #netlify #netlify-функция

Вопрос:

Я пытаюсь внедрить платежные намерения Stripe Elements в свое приложение React, используя функции Netlify. Отправка формы оплаты возвращает ошибку: Unhandled Rejection (IntegrationError): Invalid value for stripe.confirmCardPayment intent secret: value should be a client secret of the form ${id}_secret_${secret}. You specified: .

Я вижу значение client_secret в объекте PaymentIntent, поэтому бессерверная функция возвращает client_secret, но я не должен реализовывать его соответствующим образом в клиенте. Если я передаю data.clientSecret в качестве параметра в stripe.confirmCardPayment , то мой платеж завершается успешно, но форма элементов не сбрасывается, что указывает мне на наличие проблемы с этой реализацией.

setClientSecret не обновляет состояние clientSecret?

Вот моя функция Netlify:

 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:

 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();
        } 
        
      })
  };
  

Ответ №1:

stripe.confirmCardPayment Функция возвращает обещание, поэтому вам нужно дождаться разрешения этого обещания, прежде чем обновлять состояние вашего компонента:

В вашем коде это будет выглядеть примерно так:

 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();
          }
        }
      });
  };