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
This commit is contained in:
Benjamin Dauvergne 2020-10-10 12:36:57 +02:00
parent b0ca39636a
commit b1ebd698b3
1 changed files with 23 additions and 4 deletions

View File

@ -20,7 +20,10 @@ import pytz
import datetime as dt
import hashlib
import hmac
import random
import re
import string
import six
from six.moves.urllib import parse as urlparse
import warnings
from gettext import gettext as _
@ -315,6 +318,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,
@ -369,9 +387,10 @@ 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()
assert re.match(r'^[0-9a-zA-Z]{6}$', vads_trans_id)
kwargs[VADS_TRANS_ID] = vads_trans_id
fields = kwargs
for parameter in PARAMETERS:
name = parameter.name
@ -393,7 +412,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,