user3857836
user3857836

Reputation: 39

Vue Component with Stripe JS v3

I am using Vue component for my checkout form.

The stripe js (v3) file was included in the header section.

The form was in Component

This component has two section. One is to get payment details from the user and another is to submit card details.

<template>

    <div class="payment_form">
       <div id="payment_details" v-if="showPaymentDetails">
        <!-- User input goes here. Like username phone email -->
       </div>
        <div id="stripe-form" v-if="showStripeForm">
            <form action="/charge" method="post" id="payment-form" @submit.prevent="createStripeToken()">
               <div class="form-row">
                    <label for="card-element">
                        Credit or debit card
                    </label>
                    <div id="card-element">
                        <!-- a Stripe Element will be inserted here. -->
                    </div>

                    <!-- Used to display Element errors -->
                    <div id="card-errors" role="alert"></div>
                </div>

                <button>Submit Payment</button>
            </form>
        </div>
    </div>

</template>
<script>
     import { Validator } from 'vee-validate';
        export default {

        data() {
            return {
                stripeToken: '',
                showPaymentDetails: true,
                showStripeForm: true,
            }
        },
        created() {
        },
        methods: {
            validateForm() {
                self = this;
                this.$validator.validateAll().then(result => {
                    if (result) {
                        // eslint-disable-next-line
                        alert('From Submitted!');
                        console.log(this.$data);
                        axios.post('/data',{
                            name:this.name,
                        })
                        .then(function (response) {
                            self.showStripeForm = true;
                            console.log(response);
                        })
                        .catch(function (error) {
                            console.log(error);
                        });
                        return;
                    }

                });
            },

            createStripeToken(){
                var form = document.getElementById('payment-form');
                form.addEventListener('submit', function(event) {
                    event.preventDefault();

                    window.stripe.createToken(card).then(function(result) {
                        if (result.error) {
                            // Inform the user if there was an error
                            var errorElement = document.getElementById('card-errors');
                            errorElement.textContent = result.error.message;
                        } else {
                            // Send the token to your server
                            console.log(result.token);
                        }
                    });
                });
            },
            initStripe(){
                window.stripe = Stripe('stripe_test_key_here');
                var elements = stripe.elements();
                var style = {
                    base: {
                        // Add your base input styles here. For example:
                        fontSize: '16px',
                        lineHeight: '24px'
                    }
                };

                // Create an instance of the card Element
                window.card = elements.create('card', {style: style});

                // Add an instance of the card Element into the `card-element` <div>
                window.card.mount('#card-element');

            }

        },
        mounted() {
            this.initStripe();
            setTimeout(function () {

                this.showStripeForm = false;
            },2000);
        }
    }
</script>

I try to load the stripe form on page load and try to disable the element via showStripeForm.

But vue unset the loaded stripe card form from the stripe server and saved the dom to its original state.

So i can't trigger the stripe form on the axios callback.

I don't want to user stripe checkout and stripe js v1(getting input on your own form is deprecated after this version).

Upvotes: 3

Views: 2915

Answers (1)

Ikbel
Ikbel

Reputation: 7851

In mounted. Change the setTimeout callback to an arrow function, otherwise, this will point to Window instead of Vue.

mounted() {
  setTimeout(() => {
     this.showStripeForm = false
  }, 2000)
}

Also, the way you access the DOM is not so Vue-ish. You could use ref on the DOM element you want to use in your code. For example:

<form action="/charge" method="post" ref="payment-form" @submit.prevent="createStripeToken()">

Then access it from $refs like this:

var form = this.$refs['payment-form']
/* 
  Same result as document.getElementById('payment-form')
  but without using an id attribute.
*/

Upvotes: 1

Related Questions