Feb 7, 2019
0
Level 8
Stripe: multiple elements payment forms possible?
Hi everybody, I'm trying to have two payment forms in a single component, problem is I'm getting the following error:
Can only create one Element of type cardNumber
At first one of the forms will be hidden but the user can choose to make the other appear clicking a button to add a new source.
Is it possible to have more than one payment form in the same page?
This is my full component:
<template>
<div class="STRIPEform21_maincontainer">
<layout-title-4 :number="2" :text="'Elije tu forma de pago.'"></layout-title-4>
<form v-show="!showPaymentForm" id="payment-form" method="POST" class="STRIPEform21_form_maincontainer">
<div class="STRIPEform21_form_row_container">
<span class="STRIPEform21_form_row_label">Nombre del titular</span>
<input class="STRIPEform21_form_row_input" type="text">
</div>
<div class="STRIPEform21_form_row_container">
<span class="STRIPEform21_form_row_label">Número de tarjeta</span>
<div id="card-number-element" class="STRIPEform21_form_row_input"></div>
</div>
<div class="STRIPEform21_form_row_container">
<span class="STRIPEform21_form_row_label">Fecha de caducidad</span>
<div id="card-expiry-element" class="STRIPEform21_form_row_input"></div>
</div>
<div class="STRIPEform21_form_row_container">
<span class="STRIPEform21_form_row_label">CVC</span>
<div id="card-cvc-element" class="STRIPEform21_form_row_input"></div>
</div>
<button class="STRIPEform21_form_button_container" type="submit" @click="addSource();">
<span class="STRIPEform21_form_button_text">Añadir</span>
</button>
</form>
<div class="STRIPEform21_column_container">
<div class="STRIPEform21_select_row_container">
<span class="STRIPEform21_select_row_label">Elije tu forma de pago:</span>
<select class="STRIPEform21_select_row_input">
<option class="STRIPEform21_select_row_option" >✱✱✱✱ ✱✱✱✱ ✱✱✱✱ 4242 - 05/22</option>
</select>
</div>
<div class="STRIPEform21_column_center_container">
<span class="STRIPEform21_column_text">O elije otra opción:</span>
<button class="STRIPEform21_column_button_container" @click="showPaymentForm = true">
<i class="STRIPEform21_column_button_icon fa fa-plus"></i>
<img class="STRIPEform21_column_button_image" src="/img/misc/credit-cards/rectangle-generic.svg">
<span class="STRIPEform21_column_button_text">Añadir otra tarjeta de credito</span>
</button>
</div>
</div>
<div v-show="showPaymentForm" class="STRIPEform21_tab_container">
<i class="STRIPEform21_close fa fa-times" @click="showPaymentForm = false;"></i>
<form id="payment-form" method="POST" class="STRIPEform21_form_maincontainer">
<div class="STRIPEform21_form_row_container">
<span class="STRIPEform21_form_row_label">Nombre del titular</span>
<input class="STRIPEform21_form_row_input" type="text">
</div>
<div class="STRIPEform21_form_row_container">
<span class="STRIPEform21_form_row_label">Número de tarjeta</span>
<div id="card-number-element-2" class="STRIPEform21_form_row_input"></div>
</div>
<div class="STRIPEform21_form_row_container">
<span class="STRIPEform21_form_row_label">Fecha de caducidad</span>
<div id="card-expiry-element-2" class="STRIPEform21_form_row_input"></div>
</div>
<div class="STRIPEform21_form_row_container">
<span class="STRIPEform21_form_row_label">CVC</span>
<div id="card-cvc-element-2" class="STRIPEform21_form_row_input"></div>
</div>
<button class="STRIPEform21_form_button_container" type="submit" @click="addSource();">
<span class="STRIPEform21_form_button_text">Añadir</span>
</button>
</form>
</div>
</div>
</template>
<!--SCRIPTS-->
<script>
import { stripePK } from '../../config/stripe.js';
import { mapState, mapActions } from 'vuex';
export default {
name: 'STRIPEform31',
computed:{
...mapState('Stripe', ['customer', 'customerSources', 'loadingStatus', 'errors']),
},
data: function () {
return {
showPaymentForm: false,
stripePK: stripePK,
}
},
props: {
globals: {required:true}
},
mounted() {
console.log(this.$options.name + ' component succesfully mounted');
this.getCustomerSources();
let stripe = Stripe(this.stripePK);
let elements = stripe.elements();
// Custom styling can be passed to options when creating an Element.
let style = {
base: {
color: 'rgba(0,0,0,0.7)',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: 'rgba(0,0,0,0.7)'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
// Create an instance of the card Element.
//let card = elements.create('card', {style: style});
//card.mount('#card-element');
let cardNumberElement = elements.create('cardNumber', {style: style});
cardNumberElement.mount('#card-number-element');
let cardExpiryElement = elements.create('cardExpiry', {style: style});
cardExpiryElement.mount('#card-expiry-element');
let cardCvcElement = elements.create('cardCvc', {style: style});
cardCvcElement.mount('#card-cvc-element');
let cardNumberElement2 = elements.create('cardNumber', {style: style});
cardNumberElement2.mount('#card-number-element2');
let cardExpiryElement2 = elements.create('cardExpiry', {style: style});
cardExpiryElement2.mount('#card-expiry-element-2');
let cardCvcElement2 = elements.create('cardCvc', {style: style});
cardCvcElement2.mount('#card-cvc-element-2');
// Handle real-time validation errors from the card Element.
cardNumberElement.addEventListener('change', function(event) {
if (event.error) {
$('#card-errors').text(event.error.message);
}
else {
$('#card-errors').text('');
}
});
// Handle form submission.
$('#stripe_form').submit(function(e) {
e.preventDefault();
stripe.createSource(cardNumberElement).then(function(result) {//or card
if (result.error) {
// Inform the user if there was an error.
$('.card-errors').text(result.error.message);
}
else {
// Send the source to your server.
stripeSourceHandler(result.source);
}
});
});
// Submit the form with the source ID.
function stripeSourceHandler(source) {
// Insert the source ID into the form so it gets submitted to the server
let form = $('#stripe_form');
$('<input>').attr({
type: 'hidden',
name: 'stripeSource',
value: source.id,
}).appendTo('form');
// Submit the form
form.submit();
}
},
methods: {
...mapActions('Stripe', ['addSource', 'getCustomerSources']),
openPaymentTab: function(){
this.paymentTab = true;
},
closePaymentTab: function(){
this.paymentTab = true;
}
}
};
</script>
<!--STYLES-->
<style scoped>
</style>
Please or to participate in this conversation.