Bug: Rounding error is causing pre-authorization amount to be less than final amount and Stripe Payment Error
Stripe version 6.7.14
I was getting the following error on an event registration:
Stripe Payment Error: This PaymentIntent's amount could not be updated because it has a status of requires_capture. You may only update the amount of a PaymentIntent with one of the following statuses: requires_payment_method, requires_confirmation, requires_action.
I discovered the source of the problem here: https://lab.civicrm.org/extensions/stripe/-/blob/master/js/civicrmStripe.js#L275
- The actual unrounded amount returned by
CRM.payment.getTotalAmount()
was : 200.50 * 1.15 = 230.575 - The pre-authorization amount calculated with
CRM.payment.getTotalAmount().toFixed(2)
was 230.57
When the final charge was being made for 230.58, it was greater than the pre-authorization amount and it was causing the error above.
The solution was to use ((Math.round((CRM.payment.getTotalAmount())*100))/100).toFixed(2)
instead of CRM.payment.getTotalAmount().toFixed(2)
.
I'm not submitting a patch because I am not familiar enough with the extension and I notice the use of .toFixed(2)
in several places.
This is where I replaced it:
https://lab.civicrm.org/extensions/stripe/-/blob/master/js/civicrmStripe.js#L275
CRM.api3('StripePaymentintent', 'Process', {
amount: CRM.payment.getTotalAmount().toFixed(2), // FIXME
currency: CRM.payment.getCurrency(CRM.vars[script.name].currency),
payment_processor_id: CRM.vars[script.name].id,
description: document.title,
csrfToken: CRM.vars[script.name].csrfToken,
captcha: script.getReCAPTCHAToken()
})