stripe.confirmCardPayment 意图机密 Returns 空字符串

stripe.confirmCardPayment intent secret Returns Empty String

我正在尝试使用 Netlify 函数将 Stripe Elements Payment Intents 实施到我的 React 应用程序中。提交付款表格 returns 错误:Unhandled Rejection (IntegrationError): Invalid value for stripe.confirmCardPayment intent secret: value should be a client secret of the form ${id}_secret_${secret}. You specified: .

我可以在 paymentIntent 对象中看到 client_secret 值,因此无服务器函数返回 client_secret,但我不能在客户端中适当地实现它。如果我将 data.clientSecret 作为参数传递给 stripe.confirmCardPayment,那么我的付款会成功完成,但 Elements 表单不会重置,这表明此实施存在问题。

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

处理提交函数:

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

stripe.confirmCardPayment 函数 returns 一个 Promise,因此您需要等待 Promise 解决后再更新您的组件状态:

在您的代码中,这类似于:

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