Thanks for the response @martinbean. The error message is indeed self explanatory, but I believe I'm using the test API keys appropriately in the code. And, when receiving the paymentIntent, i'm seeing a successful request on the API dashboard. It is only the handleCardSetup method that errors out, when passing the clientSecret.
Here's the relevant part of the Vue component (I took out javascript methods that weren't relevant). You'll see on mount, I retrieve the clientSecret from the server, which is passed to the handleCardSetup(). Any other suggestions are appreciated:
<template>
<aside class="header-subscription">
<div v-show="showAddPayment">
<label>Name
<input id="card-holder-name" type="text" v-model="cardHolderName">
</label>
<!-- Stripe Elements Placeholder -->
<label>Credit Card
<div id="card-element"></div>
</label>
<button id="card-button" class="button" @click="handleCardSetup">
{{ addPaymentText }}
</button>
</div>
</aside>
</template>
<script>
let stripe;
export default {
name: "main-subscription.vue",
props: ['name','subscription'],
data: function() {
return {
clientSecret: '',
showAddPayment: false,
cardElement:false,
cardHolderName:''
}
},
methods: {
handleCardSetup: async function() {
const { setupIntent, error } = await stripe.handleCardSetup(
this.clientSecret, this.cardElement, {
payment_method_data: {
billing_details: { name: this.cardHolderName }
}
}
);
if (error) {
console.log(error);
} else {
// The card has been verified successfully...
this.updatePaymentMethod(setupIntent.paymentMethod);
}
},
updatePaymentMethod(paymentMethod) {
console.log('updating payment method');
}
},
mounted: function() {
let self = this;
this.showAddPayment = this.subscription.type === 'Basic';
const loadStripeFields = function() {
stripe = Stripe('stripe-public-key');
const elements = stripe.elements();
self.cardElement = elements.create('card');
self.cardElement.mount('#card-element');
};
if (! document.getElementById('stripe-sdk')) {
console.log('load stripe');
const stripeScript = document.createElement('script');
stripeScript.setAttribute('id', 'stripe-sdk');
stripeScript.setAttribute('src', 'https://js.stripe.com/v3/');
stripeScript.setAttribute('async', 'false');
stripeScript.onreadystatechange = loadStripeFields;
stripeScript.onload = loadStripeFields;
document.head.appendChild(stripeScript);
} else
loadStripeFields();
self = this;
//get client secret from server
axios.get('/subscription/stripe-intent')
.then(function (response) {
self.clientSecret = response.data.client_secret;
})
.catch(function (error) {console.log(error);})
}
}
</script>