vue-stripe-elementsを使っていて困ったこと
最初下記を使っていて、すごく使いやすかったのですが、複数ヶ所でstripe-elementを表示させようとするとエラーになってうまくできませんでした。
vue-stripe-elementsのissue
同じようなことで困ってる人がいるようで、issueみても解決してないみたいだったので、自作しました。
自作したやつ
ボタンが、vuetify仕様になっております。まだ、カード番号入力中に支払いボタンが一瞬アクティブになったりするし、ボタンクリック時にローディングまでのタイムラグが若干あったりと、改善点がありますが、上記問題は解決できました。
<template> <div> <div :class="stripeElementClass"></div> <div :class="errorClass">{{ errorMessage }}</div> <v-btn :color="btnColor" :large="btnSize === 'large'" class="stripe-element-btn" @click.prevent="createToken" :disabled="!complete" :loading="btnLoading" > <slot></slot> </v-btn> </div> </template> <script> export default { props: [ 'stripeKey', 'stripeOptions', 'btnColor', 'btnSize', 'cardClass', 'errorClass', 'btnLoading' ], data: () => ({ stripe: null, stripeElement: null, token: null, complete: false, errorMessage: '', newCardClass: null, }), created() { this.stripe = Stripe(this.stripeKey) this.newCardClass = this.cardClass + this._randomString(20) }, mounted() { this.createStripeElement() }, computed: { stripeElementClass: function() { return [this.cardClass, this.newCardClass] } }, methods: { async createToken() { try { if (!this.complete) return const result = await this.stripe.createToken(this.stripeElement) if (result.error) { this.errorMessage = result.error.message } else { this.$emit('token', result.token.id) } } catch (err) { this.errorMessage = err.message } }, createStripeElement() { const elements = this.stripe.elements(); this.stripeElement = elements.create('card', {style: this.stripeOptions, hidePostalCode: true}); this.stripeElement.mount('.' + this.newCardClass) this.stripeElement.addEventListener('change', event => { if (event.error) { this.complete = false this.errorMessage = event.error.message } else { this.errorMessage = '' this.complete = true } }) }, _randomString(len) { const str = "abcdefghijklmnopqrstuvwxyz0123456789"; let r = ''; for (let i = 0; i < len; i++) { r += str[Math.floor(Math.random() * str.length)]; } return r } } } </script>