英文:
Prevent Stripe confirmPayment from redirecting when custom input field is invalid
问题
我在同一结账页面上使用了自定义字段来填写姓名和电子邮件,与Stripe的支付元素一起。我已将这些字段与支付元素的表单关联,使用了form
属性:
<input type="text" form="payment-form" id="name" ... required>
<input type="email" form="payment-form" id="email" ... required>
我在表单上设置了novalidate
以禁用默认浏览器验证,并启用Bootstrap自己的验证:
<div class="stripe-container">
<form id="payment-form" novalidate>
{{csrf_field()}}
<div id="payment-element">
<!-- Stripe.js injects the Payment Element here-->
</div>
<div class="loading-spinner"></div>
<button id="submit">
<div class="spinner hidden" id="spinner"></div>
<span id="button-text">Pay now</span>
</button>
<div id="payment-message" class="hidden"></div>
</form>
</div>
并修改了支付元素的JS以在单击“Pay now”时触发验证:
async function handleSubmit(e) {
e.preventDefault();
setLoading(true);
// Added JS to trigger Bootstrap validation for custom fields
paymentInputs = document.querySelectorAll(".payment-input");
Array.prototype.slice.call(paymentInputs).forEach(function (paymentInput) {
paymentInput.classList.remove("is-invalid");
if (!paymentInput.checkValidity()) {
paymentInput.classList.add("is-invalid");
setLoading(false);
}
});
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: process.env.MIX_APP_URL + "/success",
},
});
// ...
}
所有这些都完美地用于显示我的自定义字段的验证错误,甚至在Stripe字段之一未通过验证时阻止提交。问题是,当所有Stripe字段都有效时,单击付款按钮会触发我的自定义字段的验证失败,如预期的那样,但几秒钟后会简单地重定向到return_url
,这可能是因为confirmPayment成功解决。
如何防止confirmPayment在我的自定义字段验证失败时解决?我确定这与异步函数和Promise的工作方式有关,但我对它们不够熟悉,不知道该怎么做。
英文:
I have custom fields for name and email on the same checkout page as Stripe's Payment Element. I've linked these fields to the form for the Payment Element using the form
attribute:
<input type="text" form="payment-form" id="name" ... required>
<input type="email" form="payment-form" id="email" ... required>
I set novalidate
on the form to disable default browser validation and enable Bootstrap's own validation:
<div class="stripe-container">
<form id="payment-form" novalidate>
{{csrf_field()}}
<div id="payment-element">
<!-- Stripe.js injects the Payment Element here-->
</div>
<div class="loading-spinner"></div>
<button id="submit">
<div class="spinner hidden" id="spinner"></div>
<span id="button-text">Pay now</span>
</button>
<div id="payment-message" class="hidden"></div>
</form>
</div>
And modified the Payment Element's JS to trigger the validation when "Pay now" is clicked:
async function handleSubmit(e) {
e.preventDefault();
setLoading(true);
// Added JS to trigger Bootstrap validation for custom fields
paymentInputs = document.querySelectorAll(".payment-input");
Array.prototype.slice.call(paymentInputs).forEach(function (paymentInput) {
paymentInput.classList.remove("is-invalid");
if (!paymentInput.checkValidity()) {
paymentInput.classList.add("is-invalid");
setLoading(false);
}
});
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: process.env.MIX_APP_URL + "/success",
},
});
...
All this works perfectly to show validation errors for my custom fields, and even prevent the submit when one of the Stripe fields fails validation. The problem is when all of the Stripe fields are valid, clicking the payment button triggers the failed validation for my custom fields as expected, but a few seconds later simply redirects to the return_url
, likely because of confirmPayment resolving successfully.
How do I prevent confirmPayment from resolving when my custom fields fail validation? I'm sure this has something to do with how asynchronous functions and Promises work, but I'm not familiar enough with them to know what.
答案1
得分: 2
你可以避免调用 stripe.confirmPayment 如果你的附加输入字段无效。
let isInvalid = false;
Array.prototype.slice.call(paymentInputs).forEach(function (paymentInput) {
paymentInput.classList.remove("is-invalid");
if (!paymentInput.checkValidity()) {
paymentInput.classList.add("is-invalid");
setLoading(false);
isInvalid = true;
}
});
if (isInvalid) {
return;
}
// Only gets here if other inputs are valid
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: process.env.MIX_APP_URL + "/success",
},
});
英文:
You can avoid calling stripe.confirmPayment if your additional input fields are invalid.
let isInvalid = false;
Array.prototype.slice.call(paymentInputs).forEach(function (paymentInput) {
paymentInput.classList.remove("is-invalid");
if (!paymentInput.checkValidity()) {
paymentInput.classList.add("is-invalid");
setLoading(false);
isInvalid = true;
}
});
if (isInvalid) {
return;
}
// Only gets here if other inputs are valid
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: process.env.MIX_APP_URL + "/success",
},
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论