【问题标题】: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 的样子,直到信用卡输入完成...

【问题讨论】:

    标签: javascript html forms vue.js stripe-payments


    【解决方案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 对象上注册。
    猜你喜欢
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    • 2016-09-03
    • 2013-03-11
    • 2023-01-23
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    相关资源
    最近更新 更多