#Valentin Hinov
1 messages · Page 1 of 1 (latest)
Sounds to me like you're not calling confirmPayment via an event handler (i.e. button click). Can you share your code?
this.$store
.dispatch('createMessage', {
message: {
...this.message,
contribution_amount: intent?.amount || 0,
},
intent: intent,
progressListener: (progress: number) => {
this.uploadProgressPercentage = progress
},
})
.then(async (newMessage: ExistingMessage) => {
createdMessage = newMessage
if (intent && intent.amount > 0) {
if (this.stripe !== null) {
return await stripe.confirmPayment({
elements,
confirmParams: {
payment_method_data: {
billing_details,
},
return_url: paymentDetails.returnUrl,
},
redirect: 'if_required',
})
} else {
return Promise.reject()
}
} else {
return Promise.resolve()
}
})
roughly the important bits
yes, I am making a network request first to my own server before calling confirmPayment but I need to do that as I need to create the relevant object on my backend before making the payment
So the flow goes like this
Fill form (including Payment element) -> Click submit button -> Upload and make API call to my server -> Confirm Stripe Payment
Is this function called via an onClick handler?
confirmPayment has to be called via a event handler, that error implies it isn't
yes, it is
Can you share that part of the code that calls that dispatch fn?
it's from the submit method of a form
private async submit() {
if (this.submitting) {
return
}
this.submitting = true
// re-fetch thankbox to ensure it's not been locked while this form was being filled out
try {
await store.dispatch('thankbox/get', { id: this.thankbox.id, override: true })
if (this.thankbox.is_locked_for_messages) {
await this.showThankboxLockedForNewMessages()
return (this.submitting = false)
}
} catch {
this.$store.commit('alert/add', {
message: 'Could not submit message. Please try again.',
level: 'error',
timeout: 3000,
})
return (this.submitting = false)
}
const intent = this.intent
let createdMessage: ExistingMessage | null = null
this.$store
.dispatch('thankbox/createMessage', {
thankbox: this.thankbox,
message: {
...this.message,
contribution_amount: intent?.amount || 0,
},
intent: intent,
progressListener: (progress: number) => {
this.uploadProgressPercentage = progress
},
})
so it's just doing a few sanity and error checks before calling out to my API
I tested it and if my API operation is quick (aka, no file to upload, or very small one) it works.
But if I try to upload a bigger file (e.g. video or something), which can take more than few seconds then that dispatch can take a while before returning and calling confirmPayment. Then I get the error
I guess you'll need to account for that then. Perhaps you handle the upload separate to the payment, or do it post-payment
Right...yeah. I was wondering if instead I could do something with this https://stripe.com/docs/payments/accept-a-payment-deferred?platform=web&type=payment
?
Not sure how that would help your use case
That's generally a better flow for scenarios where the payment amount can change multiple times (i.e. a shopping cart)
right, I see
Is it important that you only upload the file after payment succeeds?
well no, I could change it so I upload the file after
and I guess that is the solution
Yeah if I was designing your system I'd do it async after payment, via a webhook
Let me know if you have any follow-ups