No More Posting New Topics!

If you have a question or an issue, please start a thread in our Github Discussions Forum.
This forum is closed for new threads/ topics.

Navigation

    Quasar Framework

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search

    Stripe integration with quasar q-field

    Show & Tell
    3
    3
    1117
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • zspine
      zspine last edited by

      Hi,

      I am new to quasar and vue and it took me some time to figure out implementing stripe elements with quasar components. I hope it maybe helpful to someone. (it’s not perfect but gives you the basic idea)

      <!-- StripeForm.vue -->
      <template>
        <div id="payment-form">
      
          <div class="q-mt-md q-mb-md text-negative" v-if="submissionError">
            <div id="card-errors" role="alert">{{ submissionError }}</div>
          </div>
      
          <q-field label="Card Number"
                   stack-label
                   class="q-mb-md"
                   :error-message="errors['cardNumber']"
                   :error="!isCardNumberValid">
      
            <template v-slot:control>
              <div class="self-center full-width no-outline">
                <div id="cardNumber" ref="cardNumber"></div>
              </div>
            </template>
      
          </q-field>
      
          <div class="row q-col-gutter-lg">
            <div class="col-6">
              <q-field label="Card Expiry"
                       stack-label
                       class="q-mb-md"
                       :error-message="errors['cardExpiry']"
                       :error="!isCardExpiryValid">
      
                <template v-slot:control>
                  <div class="self-center full-width no-outline">
                    <div id="cardExpiry" ref="cardExpiry"></div>
                  </div>
                </template>
      
              </q-field>
            </div>
            <div class="col-6">
              <q-field label="Card CVC"
                       stack-label
                       class="q-mb-md"
                       :error-message="errors['cardCvc']"
                       :error="!isCardCvcValid">
      
                <template v-slot:control>
                  <div class="self-center full-width no-outline">
                    <div id="cardCvc" ref="cardCvc"></div>
                  </div>
                </template>
      
              </q-field>
            </div>
          </div>
      
          <q-btn
            unelevated
            color="accent"
            label="Make Payment"
            :loading="loading"
            @click="submitForm"/>
      
        </div>
      </template>
      
      <script>
      // https://github.com/stripe/stripe-js
      import {loadStripe} from '@stripe/stripe-js/pure';
      
      export default {
        props: {
          data: {type: Object, required: false, default: () => {}}
        },
      
        data() {
          return {
            loading: false,
            stripe: null,
            elements: null,
            card: {
              cardNumber: null,
              cardExpiry: null,
              cardCvc: null
            },
            errors: {
              cardNumber: '',
              cardExpiry: '',
              cardCvc: ''
            },
            submissionError: null
          }
        },
      
        computed: {
          isCardNumberValid() {
            return this.isValid('cardNumber');
          },
          isCardExpiryValid() {
            return this.isValid('cardExpiry');
          },
          isCardCvcValid() {
            return this.isValid('cardCvc');
          }
        },
      
        methods: {
          async submitForm(e) {
            e.preventDefault();
      
            try {
              this.loading = true;
              this.submissionError = null;
              const { token, error } = await this.stripe.createToken(this.card['cardNumber']);
              console.log(error);
              if(error) {
                this.submissionError = error.message;
                this.$emit('failed', error);
              } else {
                this.resetForm();
                this.$emit('success', token);
              }
            } catch (error) {
              this.$emit('failed', error);
            } finally {
              this.loading = false;
            }
          },
      
          resetForm() {
            for (const [elementType, item] of Object.entries(this.card)) {
              this.card[elementType].clear();
            }
          },
      
          updated(e) {
            const elementType = e['elementType'];
            const error = e['error'];
      
            if (error) {
              this.errors[elementType] = e['error']['message'];
              return null;
            } else {
              if (this.errors[elementType]) {
                this.errors[elementType] = '';
              }
            }
          },
      
          isValid(elementType) {
            return this.errors[elementType] === '';
          },
      
          errorMessage(elementType) {
            return this.isValid(elementType) ? this.errors[elementType] : false;
          }
        },
      
        async mounted() {
      
          const style = {
            base: {
              fontFamily: '"Roboto", "-apple-system", "Helvetica Neue", Helvetica, Arial, sans-serif',
              '::placeholder': {
                color: '#CFD7E0',
              },
            },
          };
      
          if (!this.stripe) {
            this.stripe = await loadStripe('STRIPE_PUBLIC_KEY_HERE'); //REPLACE THE KEY
          }
      
          if (!this.elements) {
            const cardElements = ['cardNumber', 'cardExpiry', 'cardCvc']
      
            this.elements = this.stripe.elements();
            cardElements.forEach(element => {
              this.card[element] = this.elements.create(element, {style: style});
              this.card[element].mount('#' + element);
              this.card[element].addEventListener('change', (e) => this.updated(e));
            });
          }
        }
      }
      </script>
      
      <style scoped lang="scss">
      .StripeElement--invalid {
        border-color: transparent
      }
      </style>
      
      
      1 Reply Last reply Reply Quote 6
      • P
        pazarbasifatih last edited by pazarbasifatih

        It will be very helpful to me, once I deal with every other issue in the backend 😃
        Thanks a lot. This will be my first time implementing stripe. I’ll write about the news.

        1 Reply Last reply Reply Quote 1
        • G
          gs86 last edited by

          This worked perfect, have used in one of my projects now.

          Thanks a lot.

          1 Reply Last reply Reply Quote 1
          • First post
            Last post