Reputation: 303
Ok so I'm trying to confirm a SetupIntent so I can save a card for later payments. I have Laravel on the backend and Nuxt on the front end. I'm just trying to have Vue save my card. My system is set up that I save the clientSecret in the database when I make a new account. Then when I'm trying to add a card to the client's account, I use axios to retrieve the clientSecret and use it in the confirmCardSetup method as described here. When I try to actually save the card, it's returning an error. I think it may be that I'm writing the Vue code wrong. This is how I do it:
import {mapGetters} from 'vuex'
import Message from '~/components/Message'
export default {
middleware: 'auth',
name: 'account',
data(){
return {
userData: {},
error: null,
success: null,
intent: '',
clientSecret: '',
elements: null,
card: null,
};
},
components: {
Message,
},
computed: {
...mapGetters(['loggedInUser'])
},
mounted(){
this.elements = this.$stripe.import().elements()
this.card = this.elements.create('card', {})
this.card.mount(this.$refs.card)
console.log(this.elements)
console.log(this.card)
this.getIntent()
},
methods: {
paymentIntent(){
//evt.preventDefault()
self.$stripe.import().confirmCardSetup(
this.intent,
{
payment_method: {
card: this.elements,
billing_details: {
name: this.$auth.$state.user.name,
},
},
}
)
.then(
res => {
if (res.error){
console.log(res.error)
}
else {
console.log(res)
}
}
)
},
async getIntent(){
self = this
self.$axios.get(`account/setup-intent/${self.$auth.$state.user.id}`,
{
header: {
'Authorization': self.$auth.getToken('local')
}
}
)
.then(
res => {
self.intent = res.data.intent
}
)
.catch(error => console.log(error))
},...
This is the object I get back:
code: "parameter_unknown"
doc_url: "https://stripe.com/docs/error-codes/parameter-unknown"
message: "Received unknown parameters: _elements, _id, _timings, _controller, _pendingFonts, _commonOptions"
param: "payment_method_data[card][_elements]"
setup_intent: {id: "seti_1HlLvp2sfYHW6zV6gKlH4wRg", object: "setup_intent", cancellation_reason: null, client_secret: "seti_1HlLvp2sfYHW6zV6gKlH4wRg_secret_IM43ctpYc92lw7x7qgXIehrMVNOjML8", created: 1604872817, …}
type: "invalid_request_error"
__proto__: Object
Finally, this is how I have my card:
<!-- card -->
<p class="mt-4 mb-4 text-gray-800 border-b border-black font-medium">Payment information</p>
<div ref="card"></div>
<button
type="submit"
id="card-button"
@click="paymentIntent"
>Add Card
</button>
What am I doing wrong?
Upvotes: 0
Views: 2703
Reputation: 303
I was using the nuxt-stripe library from WilliamDaSilva. I'm sure it was a great library, but apparently Stripe updates caused a lot of things to break. Putting Stripe in the header (nuxt.config.js file) and then following the setupIntent docs solved it for me rather quickly. Should've just went with the first-party solution first.
import {mapGetters} from 'vuex'
import Message from '~/components/Message'
export default {
middleware: 'auth',
name: 'account',
data(){
return {
userData: {},
error: null,
success: null,
clientSecret: '',
card: null,
stripe: Stripe(process.env.PUB_KEY),
};
},
components: {
Message,
},
computed: {
...mapGetters(['loggedInUser'])
},
mounted(){
var elements = this.stripe.elements()
this.card = elements.create('card')
this.card.mount(this.$refs.cardelement)
this.getIntent()
},
methods: {
setupIntent(){
this.stripe.confirmCardSetup(
this.clientSecret,
{
payment_method: {
card: this.card,
billing_details: {
name: this.$auth.$state.user.name,
},
},
}
)
.then(
res => {
if (res.error){
console.log(res.error)
}
else {
console.log(res)
}
}
)
},
...
Upvotes: 0
Reputation: 8737
You should be using this.card
not this.elements
here:
self.$stripe.import().confirmCardSetup(
this.intent,
{
payment_method: {
card: this.elements,
billing_details: {
name: this.$auth.$state.user.name,
},
},
}
)
Upvotes: 1