From a6030560299fa619485664e5e859a873c3361801 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Sat, 10 Oct 2020 12:36:57 +0200 Subject: [PATCH] systempayv2: do not use filesystem for unique vads_trans_id (#47534) vads_trans_id character space is larger than what we use, using 6 alphanumeric characters probability of collision on a day is small, 1 on 2*10^9. https://paiement.systempay.fr/doc/fr-FR/form-payment/reference/vads-trans-id.html --- eopayment/systempayv2.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/eopayment/systempayv2.py b/eopayment/systempayv2.py index 6f6b869..055d5a7 100644 --- a/eopayment/systempayv2.py +++ b/eopayment/systempayv2.py @@ -20,7 +20,9 @@ import pytz import datetime as dt import hashlib import hmac +import random import string +import six from six.moves.urllib import parse as urlparse import warnings from gettext import gettext as _ @@ -156,7 +158,8 @@ PARAMETERS = [ Parameter('vads_theme_config', 'ans', 32, max_length=255), Parameter(VADS_TRANS_DATE, 'n', 4, length=14, needed=True, default=isonow), - Parameter('vads_trans_id', 'n', 3, length=6, needed=True), + # https://paiement.systempay.fr/doc/fr-FR/form-payment/reference/vads-trans-id.html + Parameter('vads_trans_id', 'an', 3, length=6, needed=True), Parameter('vads_validation_mode', 'n', 5, max_length=1, choices=('', '0', '1'), default=''), Parameter('vads_version', 'an', 1, default='V2', needed=True, @@ -314,6 +317,21 @@ class Payment(PaymentCommon): options = add_vads(options) self.options = options + def make_vads_trans_id(self): + # vads_trans_id must be 6 alphanumeric characters, + # trans_id starting with 9 are reserved for the systempay backoffice + # https://paiement.systempay.fr/doc/fr-FR/form-payment/reference/vads-trans-id.html + gen = random.SystemRandom() + if six.PY3: + alphabet = string.ascii_letters + string.digits + else: + alphabet = string.letters + string.digits + first_letter_alphabet = alphabet.replace('9', '') + vads_trans_id = ( + gen.choice(first_letter_alphabet) + + ''.join(gen.choice(alphabet) for i in range(5)) + ) + return vads_trans_id def request(self, amount, name=None, first_name=None, last_name=None, address=None, email=None, phone=None, orderid=None, info1=None, @@ -368,9 +386,8 @@ class Payment(PaymentCommon): '%s value %s is not of the type %s' % (name, orderid, ptype)) kwargs[name] = orderid - transaction_id = self.transaction_id(6, string.digits, 'systempay', - self.options[VADS_SITE_ID]) - kwargs[VADS_TRANS_ID] = force_text(transaction_id) + vads_trans_id = self.make_vads_trans_id() + kwargs[VADS_TRANS_ID] = vads_trans_id fields = kwargs for parameter in PARAMETERS: name = parameter.name @@ -392,7 +409,7 @@ class Payment(PaymentCommon): check_vads(fields) fields[SIGNATURE] = force_text(self.signature(fields)) self.logger.debug('%s request contains fields: %s', __name__, fields) - transaction_id = '%s_%s' % (fields[VADS_TRANS_DATE], transaction_id) + transaction_id = '%s_%s' % (fields[VADS_TRANS_DATE], vads_trans_id) self.logger.debug('%s transaction id: %s', __name__, transaction_id) form = Form( url=self.service_url, -- 2.28.0