我有一个结帐页面,主要包含新的 Stripe Payment Element和一个 PayPal 支付按钮(来自 Standard Checkout 集成)。按钮加载速度足够快,但通过 XAMPP 在本地加载时,支付元素的信用卡表单需要超过 5 秒,我想如果 Google Pay 和 Apple Pay 按钮在测试模式下呈现,这同样适用于它们。我希望开发环境中的这种速度在快速连接上转化为至少 2-3 秒的生产环境,这仍然非常慢。
假设这种加载速度对于 Stripe Payment Element 来说是正常的,我是否可以使用任何策略来使其加载速度更快?
无论如何,我想至少通过添加一个微调器/预加载器来加快感知的加载速度,该微调器/预加载器在加载表单之前一直显示,这也可以最大程度地减少不和谐content jump当前在加载表单时发生(老实说,我很惊讶 Stripe 一开始就适合这个 UX)。我如何将这样的微调器集成到 Stripe 的客户端代码中?
这是 checkout.js 中有问题的客户端代码,仅从 Stripe 的 Quickstart guide 中略微改编而来:
const stripe = Stripe(<PK_TEST_KEY>);
const fonts = [
{
cssSrc:
"https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;600;700&display=swap",
},
];
const appearance = {
theme: "stripe",
labels: "floating",
variables: {
colorPrimary: "#000",
colorPrimaryText: "#fff",
colorText: "#fff",
fontFamily: "Open Sans, Segoe UI, sans-serif",
borderRadius: "4px",
fontSizeBase: "1em",
fontSizeXs: "0.7em",
fontWeightNormal: "400",
fontWeightMedium: "400",
fontWeightLight: "400",
},
};
let elements;
initialize();
checkStatus();
document
.querySelector("#payment-form")
.addEventListener("submit", handleSubmit);
// Fetches a payment intent and captures the client secret
async function initialize() {
const { clientSecret } = await fetch("/payment/stripe", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-TOKEN": document.querySelector('input[name="_token"]').value,
},
}).then((r) => r.json());
elements = stripe.elements({ fonts, appearance, clientSecret });
const paymentElement = elements.create("payment");
paymentElement.mount("#payment-element");
}
async function handleSubmit(e) {
e.preventDefault();
setLoading(true);
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
// Make sure to change this to your payment completion page
return_url: "http://localhost/success",
},
});
// This point will only be reached if there is an immediate error when
// confirming the payment. Otherwise, your customer will be redirected to
// your `return_url`. For some payment methods like iDEAL, your customer will
// be redirected to an intermediate site first to authorize the payment, then
// redirected to the `return_url`.
if (error.type === "card_error" || error.type === "validation_error") {
showMessage(error.message);
} else {
showMessage("An unexpected error occured.");
}
setLoading(false);
}
// Fetches the payment intent status after payment submission
async function checkStatus() {
const clientSecret = new URLSearchParams(window.location.search).get(
"payment_intent_client_secret"
);
if (!clientSecret) {
return;
}
const { paymentIntent } = await stripe.retrievePaymentIntent(clientSecret);
switch (paymentIntent.status) {
case "succeeded":
showMessage("Payment succeeded!");
break;
case "processing":
showMessage("Your payment is processing.");
break;
case "requires_payment_method":
showMessage("Your payment was not successful, please try again.");
break;
default:
showMessage("Something went wrong.");
break;
}
}
// ------- UI helpers -------
function showMessage(messageText) {
const messageContainer = document.querySelector("#payment-message");
messageContainer.classList.remove("hidden");
messageContainer.textContent = messageText;
setTimeout(function () {
messageContainer.classList.add("hidden");
messageText.textContent = "";
}, 10000);
}
// Show a spinner on payment submission
function setLoading(isLoading) {
if (isLoading) {
// Disable the button and show a spinner
document.querySelector("#submit").disabled = true;
document.querySelector("#spinner").classList.remove("hidden");
document.querySelector("#button-text").classList.add("hidden");
} else {
document.querySelector("#submit").disabled = false;
document.querySelector("#spinner").classList.add("hidden");
document.querySelector("#button-text").classList.remove("hidden");
}
}
最佳答案
实现加载微调器的主要方法是在 initialize()
函数开始时启动一个加载微调器的动画,然后监听 PaymentElement 的“就绪”事件以确定何时隐藏
Stripe 的示例代码有一个用于提交按钮的微调器,但不幸的是,当应用于其他 DOM 元素时它并没有真正起作用,因此您必须滚动自己的微调器而不是直接重新使用它。但这就是想法!
https://stripe.com/docs/js/element/events/on_ready
async function initialize() {
loaderOn(); // start showing a spinner and maybe apply `hidden` to the payment-element div
const response = await fetch("/create-payment-intent", {
...
...
const paymentElement = elements.create("payment");
paymentElement.on("ready", function(){
loaderOff(); // hide the spinner and maybe remove `hidden` from the payment-element div
})
paymentElement.mount("#payment-element");
关于javascript - Stripe Payment Element 加载时间慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71324848/