React 和 Stripe 集成 - Stripe 返回的客户端密钥无法被 React 识别

问题描述 投票:0回答:1

我正在将 Stripe 集成到我的 React SPA 中

我在前端创建了一个 Checkout 组件:

export default function Checkout() {

  const fetchClientSecret = useCallback(() => {
    // Create a Checkout Session
    fetch("/create-checkout-session", {
      method: "POST",
    })
      .then((res) => res.json())
      .then((data) => data.clientSecret);
  }, []);


  // Define options being passed to Stripe
  const options = {fetchClientSecret};
    
  return (
    <div>
      <EmbeddedCheckoutProvider stripe={stripePromise} options={options}>
        <EmbeddedCheckout />
      </EmbeddedCheckoutProvider>
    </div>
  );
}

以及我的 Express 后端中相应的 create-checkout-session 端点

app.post('/create-checkout-session', async (req, res) => {

  const session = await stripe.checkout.sessions.create({
    ui_mode: 'embedded',
    line_items: [
      {
        price: 'price_1Oxtf42MrIfdvsrao10PzNxF',
        quantity: 1,
      },
    ],
    mode: 'payment',
    return_url: `${YOUR_DOMAIN}/thankyou?session_id={CHECKOUT_SESSION_ID}`,
  });

  console.log(session.client_secret);
  
  res.send({clientSecret: session.client_secret});
});

我传递给 stripe.checkout.sessions.create 的价格 ID 是正确的。我的 console.log 调用确认后端正确生成了客户端密钥。

我的问题是,当我调用 Checkout 组件时,Stripe 返回此信息:

Uncaught (in promise) IntegrationError: fetchClientSecret failed with error "The fetchClientSecret function should always resolve with a client secret as a string. The function that was provided resolved with a value type of undefined."

谁能帮忙解释一下为什么会发生这种情况吗?

javascript reactjs node.js stripe-payments
1个回答
0
投票

这里的问题是异步 API 调用。目前,

fetchClientSecret
函数正在返回
undefined
,因为没有返回语句,也没有等待API响应。

您可以使用

async
关键字和
await
来声明函数以获取 API 响应。

最好的方法是使用状态变量并在成功响应后使用客户端密钥设置它。

const [clientSecret, setClientSecret] = useState("");

const fetchClientSecret = useCallback(async () => {
    try{
        // Create a Checkout Session
        const res = await fetch("/create-checkout-session", {
            method: "POST",
        })

        const responseBody = await res.json();
        setClientSecret(responseBody.clientSecret)
    } catch(err => {
        console.log(err);
    })

}, []);


 return (
    <div>
      {clientSecret?<EmbeddedCheckoutProvider stripe={stripePromise} options={{clientSecret: clientSecret}}>
        <EmbeddedCheckout />
      </EmbeddedCheckoutProvider>
      : <div>LOADING...</div>}
    </div>
  );
© www.soinside.com 2019 - 2024. All rights reserved.