Skip to content
Browse files

[FIX] payment_authorize: always send an amount with the correct decimals

We cannot assume reading the value of a monetary field has the
decimals specified by the currency in decimal_places.

Right after creating a record with a monetary field it may have a
different amount of decimals.

To reproduce this:

>>> tx = env['payment.transaction'].create({
   'amount': 10.87,
   'acquirer_id': env['payment.acquirer'].search([], limit=1).id,
   'currency_id': env.ref('base.USD').id,
   'reference': 'test'
>>> tx.amount

<Restart odoo>
>>> env['payment.transaction'].browse(130).amount

Authorize requires us to send a correctly rounded amount. The
following response is returned when sending 10.870000000000001:

{'messages': {'message': [{'code': 'E00027',
                           'text': 'The transaction was unsuccessful.'}],
              'resultCode': 'Error'},
 'transactionResponse': {'SupplementalDataQualificationIndicator': 0,
                         'accountNumber': '',
                         'accountType': '',
                         'authCode': '',
                         'avsResultCode': 'P',
                         'cavvResultCode': '',
                         'cvvResultCode': '',
                         'errors': [{'errorCode': '5',
                                     'errorText': 'A valid amount is '
                         'refTransID': '',
                         'responseCode': '3',
                         'testRequest': '0',
                         'transHash': '',
                         'transHashSha2': '',
                         'transId': '0'}}

To work around the issue always round when we read amount.

Lower level solutions were considered in #45248 but for now we'll
stick with this higher level and lower risk patch.


X-original-commit: 7485927
  • Loading branch information
jorenvo committed Feb 13, 2020
1 parent 2942826 commit 936bed3451227815177f0c9f313b4ef89ec05eac
Showing with 3 additions and 3 deletions.
  1. +3 −3 addons/payment_authorize/models/
@@ -253,15 +253,15 @@ def authorize_s2s_do_transaction(self, **data):
'Please make sure the token has a valid acquirer reference.'))

if not self.acquirer_id.capture_manually:
res = transaction.auth_and_capture(self.payment_token_id, self.amount, self.reference)
res = transaction.auth_and_capture(self.payment_token_id, round(self.amount, self.currency_id.decimal_places), self.reference)
res = transaction.authorize(self.payment_token_id, self.amount, self.reference)
res = transaction.authorize(self.payment_token_id, round(self.amount, self.currency_id.decimal_places), self.reference)
return self._authorize_s2s_validate_tree(res)

def authorize_s2s_capture_transaction(self):
transaction = AuthorizeAPI(self.acquirer_id)
tree = transaction.capture(self.acquirer_reference or '', self.amount)
tree = transaction.capture(self.acquirer_reference or '', round(self.amount, self.currency_id.decimal_places))
return self._authorize_s2s_validate_tree(tree)

def authorize_s2s_void_transaction(self):

0 comments on commit 936bed3

Please sign in to comment.
You can’t perform that action at this time.