条纹 CardElement 不呈现

Stripe CardElement not rendering

我正在尝试将 Stripe 集成到我的应用程序中,但是我在让 CardElement 在我的支付表单中呈现时遇到了问题。

这是我的付款表格代码:

import React from "react";
import { Typography, Button, Divider } from "@material-ui/core";
import {
  Elements,
  CardElement,
  ElementsConsumer,
} from "@stripe/react-stripe-js";
import { loadStripe } from "@stripe/stripe-js";

import Review from "./Review";

const stripePromise = loadStripe(process.env.REACT_APP_STRIPE_PUBLIC_KEY);

console.log(process.env.REACT_APP_STRIPE_PUBLIC_KEY);

const PaymentForm = ({
  checkoutToken,
  nextStep,
  backStep,
  shippingData,
  onCaptureCheckout,
}) => {
  const handleSubmit = async (event, elements, stripe) => {
    event.preventDefault();

    if (!stripe || !elements) return;

    const cardElement = elements.getElement(CardElement);

    const { error, paymentMethod } = await stripe.createPaymentMethod({
      type: "card",
      card: cardElement,
    });

    console.log("[Payment Method]", paymentMethod);

    if (error) {
      console.log("[error]", error);
    } else {
      const orderData = {
        line_items: checkoutToken.live.line_items,
        customer: {
          firstname: shippingData.firstName,
          lastname: shippingData.lastName,
          email: shippingData.email,
        },
        shipping: {
          name: "International",
          street: shippingData.address1,
          town_city: shippingData.city,
          county_state: shippingData.shippingSubdivision,
          postal_zip_code: shippingData.zip,
          country: shippingData.shippingCountry,
        },
        fulfillment: { shipping_method: shippingData.shippingOption },
        payment: {
          gateway: "stripe",
          stripe: {
            payment_method_id: paymentMethod.id,
          },
        },
      };

      onCaptureCheckout(checkoutToken.id, orderData);

      nextStep();
    }
  };

  return (
    <>
      <Review checkoutToken={checkoutToken} />
      <Divider />
      <Typography variant="h6" gutterBottom style={{ margin: "20px 0" }}>
        Payment method
      </Typography>
      <Elements stripe={stripePromise}>
        <ElementsConsumer>
          {({ elements, stripe }) => (
            <form onSubmit={(e) => handleSubmit(e, elements, stripe)}>
              <CardElement />
              <br /> <br />
              <div style={{ display: "flex", justifyContent: "space-between" }}>
                <Button variant="outlined" onClick={backStep}>
                  Back
                </Button>
                <Button
                  type="submit"
                  variant="contained"
                  disabled={!stripe}
                  color="primary"
                >
                  Pay {checkoutToken.live.subtotal.formatted_with_symbol}
                </Button>
              </div>
            </form>
          )}
        </ElementsConsumer>
      </Elements>
    </>
  );
};

export default PaymentForm;

Here 是目前付款表格的图片。请注意,CardElement 不存在。

我在控制台中没有收到任何与 Stripe 相关的错误消息或任何表明错误的消息。我什至为 CardElement 指定了一个 class 名称,并在 Inspector 中检查了它,发现它存在,但为空 Div。之后,我查看了 Stripe 关于此事的文档,但似乎我已经正确地遵循了所有内容。

如果有人知道发生了什么事并能指出正确的方向,我将不胜感激!

loadStripe() 是一个 returns 承诺的异步函数。 ElementsConsumer docs 的道具部分指出:

“请注意,如果您将 Promise 传递给 Elements 提供程序并且 Promise 尚未解析,则 stripe 和 elements 将为空。”

在你上面的代码中,你的承诺在你的组件呈现之前没有解决,这导致上面返回 null 并且你的 CardElement 没有安装。

要解决此问题,建议您调用 loadStripe() 并将 PaymentForm 组件包装在应用根目录下的 Elements 提供程序中,而不是在 [=12] 中=] 组件.

我终于弄明白了。显然 loadStripe() 在服务器环境中解析 null。由于我是我的应用程序的 运行 本地服务器,它返回 null,因此我的 CardElement 没有呈现。将应用程序部署到 AWS 后,它现在可以正常工作了。

感谢大家的帮助!