如何监听Stripe cardElement 的输入事件,判断卡片是不是无效并禁用按钮?
Posted
技术标签:
【中文标题】如何监听Stripe cardElement 的输入事件,判断卡片是不是无效并禁用按钮?【英文标题】:How to listen to the input event of the Stripe cardElement to determine if card is invalid and disable the button?如何监听Stripe cardElement 的输入事件,判断卡片是否无效并禁用按钮? 【发布时间】:2021-11-19 16:42:47 【问题描述】:当我的用户使用订单信息和客户详细信息填写表单时,我禁用了提交按钮,直到我的验证得到满足。我使用的库是 express-validate。
我想要做的也,是保持按钮禁用,首先,直到用户将信用卡信息输入到 Stripe 元素它实际上是一张有效的卡。 其次,在提交后,再次禁用该按钮,这样用户就无法继续点击该按钮。当成功或成功或错误通知返回时,我将重定向。
到目前为止,我还没有成功触发 cardElement.on() 方法,Stripe events。这就是我想要实现的目标,see client.js
这就是我目前所拥有的......
首页.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
);
...
编辑
在下面实现庞培的回答时,mounted() 中的监听器,这是 console.logs 的样子,直到信用卡输入完成...
【问题讨论】:
【参考方案1】:需要注意的重要一点是,要启用触发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
);
从我上面的 sn-p 可以看出,event
参数有一个 complete
属性,当卡片元素的值为“格式良好且可能完整”时,该属性设置为 true
[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 alllow for more attempts
else
// React to successful payment
);
[1]https://stripe.com/docs/js/element/events/on_change?type=cardElement#element_on_change-handler-complete
[2]https://stripe.com/docs/js/payment_intents/confirm_card_payment
【讨论】:
太棒了! Mounted() 实际上是监听 event.complete 属性的地方。我剩下的唯一问题是为什么在最初安装 DOM 节点按钮时必须附加侦听器?是不是因为在加载文档之前所有的监听器都需要在 window 对象上注册。以上是关于如何监听Stripe cardElement 的输入事件,判断卡片是不是无效并禁用按钮?的主要内容,如果未能解决你的问题,请参考以下文章
我可以在不使用 Stripe Card Element 的情况下使用 Stripe api
Stripe 取消 url 不会取消付款,因此 Stripe 不会发送取消付款意图