[FIX] payment_authorize: use SHA-512 instead of MD5 as not supported
Authorize.Net is phasing out the MD5 based hash use for transaction response verification in favor of the SHA-512 based hash utilizing a Signature Key. Instead of hashing with md5 the transaction key, it is now required to hash the signature key (binary format) with SHA-512. Support for MD5 will be dropped the 7th March 2019 for sandbox environment and the 28th March 2019 for production environment, initially planned for the 14th. Note that as of February 11, 2019 authorize removed the ability to configure or update MD5 Hash setting in the Merchant Interface. Merchants who had this setting configured have been emailed/contacted. opw-1943030 Usefull links: https://developer.authorize.net/support/hash_upgrade/ https://support.authorize.net/s/article/What-is-a-Signature-Key https://support.authorize.net/s/article/MD5-Hash-End-of-Life-Signature-Key-Replacement https://support.authorize.net/s/article/Do-I-need-to-upgrade-my-transaction-fingerprint-from-HMAC-MD5-to-HMAC-SHA512-and-how closes odoo/odoo#31642 Signed-off-by: Romain Derie (rde) <rde@odoo.com>
This commit is contained in:
@@ -5,6 +5,7 @@ from datetime import datetime
|
||||
import hashlib
|
||||
import hmac
|
||||
import logging
|
||||
import string
|
||||
import time
|
||||
import urlparse
|
||||
|
||||
@@ -54,7 +55,15 @@ class PaymentAcquirerAuthorize(models.Model):
|
||||
values['x_fp_timestamp'],
|
||||
values['x_amount'],
|
||||
values['x_currency_code']])
|
||||
return hmac.new(str(values['x_trans_key']), data, hashlib.md5).hexdigest()
|
||||
|
||||
# [BACKWARD COMPATIBILITY] Check that the merchant did update his transaction
|
||||
# key to signature key (end of MD5 support from Authorize.net)
|
||||
# The signature key is now '128-character hexadecimal format', while the
|
||||
# transaction key was only 16-character.
|
||||
if len(values['x_trans_key']) == 128:
|
||||
return hmac.new(values['x_trans_key'].decode("hex"), data, hashlib.sha512).hexdigest().upper()
|
||||
else:
|
||||
return hmac.new(str(values['x_trans_key']), data, hashlib.md5).hexdigest()
|
||||
|
||||
@api.multi
|
||||
def authorize_form_generate_values(self, values):
|
||||
@@ -172,7 +181,7 @@ class TxAuthorize(models.Model):
|
||||
def _authorize_form_get_tx_from_data(self, data):
|
||||
""" Given a data dict coming from authorize, verify it and find the related
|
||||
transaction record. """
|
||||
reference, trans_id, fingerprint = data.get('x_invoice_num'), data.get('x_trans_id'), data.get('x_MD5_Hash')
|
||||
reference, trans_id, fingerprint = data.get('x_invoice_num'), data.get('x_trans_id'), data.get('x_SHA2_Hash') or data.get('x_MD5_Hash')
|
||||
if not reference or not trans_id or not fingerprint:
|
||||
error_msg = _('Authorize: received data with missing reference (%s) or trans_id (%s) or fingerprint (%s)') % (reference, trans_id, fingerprint)
|
||||
_logger.info(error_msg)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import hashlib
|
||||
import hmac
|
||||
import time
|
||||
import urlparse
|
||||
import unittest
|
||||
@@ -32,15 +30,6 @@ class AuthorizeCommon(PaymentAcquirerCommon):
|
||||
@odoo.tests.common.post_install(True)
|
||||
class AuthorizeForm(AuthorizeCommon):
|
||||
|
||||
def _authorize_generate_hashing(self, values):
|
||||
data = '^'.join([
|
||||
values['x_login'],
|
||||
values['x_fp_sequence'],
|
||||
values['x_fp_timestamp'],
|
||||
values['x_amount'],
|
||||
]) + '^'
|
||||
return hmac.new(str(values['x_trans_key']), data, hashlib.md5).hexdigest()
|
||||
|
||||
def test_10_Authorize_form_render(self):
|
||||
self.assertEqual(self.authorize.environment, 'test', 'test without test environment')
|
||||
|
||||
@@ -84,7 +73,7 @@ class AuthorizeForm(AuthorizeCommon):
|
||||
'x_ship_to_state': None,
|
||||
}
|
||||
|
||||
form_values['x_fp_hash'] = self._authorize_generate_hashing(form_values)
|
||||
form_values['x_fp_hash'] = self.env['payment.acquirer']._authorize_generate_hashing(form_values)
|
||||
# render the button
|
||||
res = self.authorize.render('SO004', 320.0, self.currency_usd.id, values=self.buyer_values)
|
||||
# check form result
|
||||
@@ -108,7 +97,9 @@ class AuthorizeForm(AuthorizeCommon):
|
||||
# typical data posted by authorize after client has successfully paid
|
||||
authorize_post_data = {
|
||||
'return_url': u'/shop/payment/validate',
|
||||
# x_MD5_Hash will be empty starting the 28th March 2019
|
||||
'x_MD5_Hash': u'7934485E1C105940BE854208D10FAB4F',
|
||||
'x_SHA2_Hash': u'7D3AC844BE8CA3F649AB885A90D22CFE35B850338EC91D1A5ADD819A85FF948A3D777334A18CDE36821DC8F2B42A6E1950C1FF96B52B60F23201483A656195FB',
|
||||
'x_account_number': u'XXXX0027',
|
||||
'x_address': u'Huge Street 2/543',
|
||||
'x_amount': u'320.00',
|
||||
|
||||
Reference in New Issue
Block a user