[FIX] payment: float consistency enforcement in access_token generation
Steps to reproduce: - install sales, ecommerce and payment_authorize - setup authorize.net (test mode) - go to sales and select the quotation S00007 (demo data) or create a quotation with multiple items that add up to a float - select action > generate a payment link > go to the link > select pay with authorize - you are redirected to authorize.net use 4111 1111 1111 1111 as card number and 1223 as expiration date > pay - you are redirected to the odoo payment process page - wait for the result Previous behavior: the user is returned to a 404 error page but the payment went trough Current behavior: access_token generation is consistent and will not fail because of float representation the user is returned to the "payment confirmed" page WARNINGS: - watching the values in vscode prevents bug reproduction - when setting up authorize.net, do not forget to add your test url to the account's allowed return urls - use https for authorize.net connection opw-2223135 closes odoo/odoo#50633 X-original-commit: 0fe7fa0f95b7393d8829ba4b216d6c41d0c0dc3d Signed-off-by: mightyjol <jhk-odoo@users.noreply.github.com>
This commit is contained in:
@@ -11,6 +11,7 @@ import werkzeug
|
||||
from odoo import http, _
|
||||
from odoo.http import request
|
||||
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, consteq, ustr
|
||||
from odoo.tools.float_utils import float_repr
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
@@ -262,7 +263,7 @@ class WebsitePayment(http.Controller):
|
||||
values['reference'] = request.env['payment.transaction']._compute_reference(values=reference_values, prefix=reference)
|
||||
tx = request.env['payment.transaction'].sudo().with_context(lang=None).create(values)
|
||||
secret = request.env['ir.config_parameter'].sudo().get_param('database.secret')
|
||||
token_str = '%s%s%s' % (tx.id, tx.reference, tx.amount)
|
||||
token_str = '%s%s%s' % (tx.id, tx.reference, float_repr(tx.amount, precision_digits=tx.currency_id.decimal_places))
|
||||
token = hmac.new(secret.encode('utf-8'), token_str.encode('utf-8'), hashlib.sha256).hexdigest()
|
||||
tx.return_url = '/website_payment/confirm?tx_id=%d&access_token=%s' % (tx.id, token)
|
||||
|
||||
@@ -304,7 +305,7 @@ class WebsitePayment(http.Controller):
|
||||
try:
|
||||
tx.s2s_do_transaction()
|
||||
secret = request.env['ir.config_parameter'].sudo().get_param('database.secret')
|
||||
token_str = '%s%s%s' % (tx.id, tx.reference, tx.amount)
|
||||
token_str = '%s%s%s' % (tx.id, tx.reference, float_repr(tx.amount, precision_digits=tx.currency_id.decimal_places))
|
||||
token = hmac.new(secret.encode('utf-8'), token_str.encode('utf-8'), hashlib.sha256).hexdigest()
|
||||
tx.return_url = return_url or '/website_payment/confirm?tx_id=%d&access_token=%s' % (tx.id, token)
|
||||
except Exception as e:
|
||||
@@ -319,7 +320,7 @@ class WebsitePayment(http.Controller):
|
||||
if access_token:
|
||||
tx = request.env['payment.transaction'].sudo().browse(tx_id)
|
||||
secret = request.env['ir.config_parameter'].sudo().get_param('database.secret')
|
||||
valid_token_str = '%s%s%s' % (tx.id, tx.reference, tx.amount)
|
||||
valid_token_str = '%s%s%s' % (tx.id, tx.reference, float_repr(tx.amount, precision_digits=tx.currency_id.decimal_places))
|
||||
valid_token = hmac.new(secret.encode('utf-8'), valid_token_str.encode('utf-8'), hashlib.sha256).hexdigest()
|
||||
if not consteq(ustr(valid_token), access_token):
|
||||
raise werkzeug.exceptions.NotFound
|
||||
|
||||
Reference in New Issue
Block a user