如何监听Stripe cardElement 的input 事件判断card 是否无效并禁用按钮?
How to listen to the input event of the Stripe cardElement to determine if card is invalid and disable the button?
当我的用户填写带有订单信息和客户详细信息的表单时,我禁用了提交按钮,直到我的验证得到满足。我使用的库是 express-validate。
我想做的也是让按钮保持禁用状态,首先直到用户将信用卡信息输入到 Stripe 元素中,它实际上是一张有效的卡。 其次,提交后,再次禁用该按钮,这样用户就无法继续点击该按钮。当成功或成功或错误通知返回时,我将重定向。
到目前为止,我没有成功触发 cardElement.on() 方法,Stripe events. And this was the example of what I am trying to achieve,see client.js
这是我目前所拥有的...
Home.vue
<form
id="order-info"
class="form-container"
@submit.prevent="createOrder"
>
...
<div class="stripe-container">
<div id="stripe-element-card" ref="card">
<!-- Stripe.js injects the Card Element -->
</div>
</div>
<p id="card-error" role="alert" />
<p class="result-message hidden">
Payment succeeded
</p>
<button
v-if="toggleUserInfo"
id="submit"
class="stripe"
:disabled="$v.$invalid" // this is based on current form validations
type="submit"
// I want to disable also until card is valid and then disable again
// after user clicks to prevent additional clicking until success/error returns
>
<div
id="spinner"
class="spinner"
:class="{ hidden: !isLoading }"
></div>
<span id="button-text" :class="{ hidden: isLoading }">Pay now</span>
<script>
async mounted() {
stripe = await loadStripe(process.env.VUE_APP_STRIPE_PK);
elements = stripe.elements();
card = elements.create("card", { style: style });
card.mount("#stripe-element-card");
},
...
createOrder 方法
async createOrder(event) {
console.log(event.target);
this.loading(true);
this.$v.$touch();
if (!this.$v.$invalid) {
// gather order and user details, superfluous code
const cardElement = elements.getElement("card");
const billingDetails = {
name: user.name,
address: {
city: user.city,
line1: user.street,
state: "NY"
},
phone: user.phone
};
try {
cardElement.on("change", event => {
console.log("LOGGING THE CARD ELEMENT EVENT", event);
// NOT SEEING ANYTHING HERE
// disable button until valid card is inputted
});
...
编辑
在下面实现 Pompey 的回答时,mounted() 中的侦听器,这就是 console.logs 在信用卡输入完成之前的样子...
需要注意的一件重要事情是,想要启用触发 createOrder
的按钮的 change
处理程序位于 createOrder
方法本身。我会将处理程序代码移动到卡元素安装在 Home.vue:
之后
card.mount("#stripe-element-card");
cardElement.on("change", event => {
console.log("LOGGING THE CARD ELEMENT EVENT", event);
if (event.complete) {
// enable payment button
} else if (event.error) {
// show event.error.message to customer
}
});
正如您从我上面的代码片段中看到的那样,event
参数有一个 complete
属性,当卡片元素的值为“格式良好且可能完整”[1],因此当它为真时,您可以启用您的按钮。检查 change
处理程序中的 event.error
也是值得的,如果存在,则向用户显示 event.error.message
.
同样,要根据付款成功重定向客户或重新启用按钮,您可以使用 then
方法从 confirmCardPayment
获取指示成功或失败的响应[2] :
stripe.confirmCardPayment('{PAYMENT_INTENT_CLIENT_SECRET}', {
...
})
.then(function(result) {
if(result.error)
{
// Display result.error.message and re-enable button to allow for more attempts
}
else
{
// React to successful payment
}
});
[2]https://stripe.com/docs/js/payment_intents/confirm_card_payment
当我的用户填写带有订单信息和客户详细信息的表单时,我禁用了提交按钮,直到我的验证得到满足。我使用的库是 express-validate。
我想做的也是让按钮保持禁用状态,首先直到用户将信用卡信息输入到 Stripe 元素中,它实际上是一张有效的卡。 其次,提交后,再次禁用该按钮,这样用户就无法继续点击该按钮。当成功或成功或错误通知返回时,我将重定向。
到目前为止,我没有成功触发 cardElement.on() 方法,Stripe events. And this was the example of what I am trying to achieve,see client.js
这是我目前所拥有的...
Home.vue
<form
id="order-info"
class="form-container"
@submit.prevent="createOrder"
>
...
<div class="stripe-container">
<div id="stripe-element-card" ref="card">
<!-- Stripe.js injects the Card Element -->
</div>
</div>
<p id="card-error" role="alert" />
<p class="result-message hidden">
Payment succeeded
</p>
<button
v-if="toggleUserInfo"
id="submit"
class="stripe"
:disabled="$v.$invalid" // this is based on current form validations
type="submit"
// I want to disable also until card is valid and then disable again
// after user clicks to prevent additional clicking until success/error returns
>
<div
id="spinner"
class="spinner"
:class="{ hidden: !isLoading }"
></div>
<span id="button-text" :class="{ hidden: isLoading }">Pay now</span>
<script>
async mounted() {
stripe = await loadStripe(process.env.VUE_APP_STRIPE_PK);
elements = stripe.elements();
card = elements.create("card", { style: style });
card.mount("#stripe-element-card");
},
...
createOrder 方法
async createOrder(event) {
console.log(event.target);
this.loading(true);
this.$v.$touch();
if (!this.$v.$invalid) {
// gather order and user details, superfluous code
const cardElement = elements.getElement("card");
const billingDetails = {
name: user.name,
address: {
city: user.city,
line1: user.street,
state: "NY"
},
phone: user.phone
};
try {
cardElement.on("change", event => {
console.log("LOGGING THE CARD ELEMENT EVENT", event);
// NOT SEEING ANYTHING HERE
// disable button until valid card is inputted
});
...
编辑
在下面实现 Pompey 的回答时,mounted() 中的侦听器,这就是 console.logs 在信用卡输入完成之前的样子...
需要注意的一件重要事情是,想要启用触发 createOrder
的按钮的 change
处理程序位于 createOrder
方法本身。我会将处理程序代码移动到卡元素安装在 Home.vue:
card.mount("#stripe-element-card");
cardElement.on("change", event => {
console.log("LOGGING THE CARD ELEMENT EVENT", event);
if (event.complete) {
// enable payment button
} else if (event.error) {
// show event.error.message to customer
}
});
正如您从我上面的代码片段中看到的那样,event
参数有一个 complete
属性,当卡片元素的值为“格式良好且可能完整”[1],因此当它为真时,您可以启用您的按钮。检查 change
处理程序中的 event.error
也是值得的,如果存在,则向用户显示 event.error.message
.
同样,要根据付款成功重定向客户或重新启用按钮,您可以使用 then
方法从 confirmCardPayment
获取指示成功或失败的响应[2] :
stripe.confirmCardPayment('{PAYMENT_INTENT_CLIENT_SECRET}', {
...
})
.then(function(result) {
if(result.error)
{
// Display result.error.message and re-enable button to allow for more attempts
}
else
{
// React to successful payment
}
});
[2]https://stripe.com/docs/js/payment_intents/confirm_card_payment