条纹 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 后,它现在可以正常工作了。
感谢大家的帮助!
我正在尝试将 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 后,它现在可以正常工作了。
感谢大家的帮助!