diff --git a/eopayment/__init__.py b/eopayment/__init__.py index a0d7328..e818d2a 100644 --- a/eopayment/__init__.py +++ b/eopayment/__init__.py @@ -228,3 +228,7 @@ class Payment(object): continue res.append(param) return res + + @property + def has_free_transaction_id(self): + return self.backend.has_free_transaction_id diff --git a/eopayment/common.py b/eopayment/common.py index b027837..5c4870e 100644 --- a/eopayment/common.py +++ b/eopayment/common.py @@ -140,6 +140,8 @@ class PaymentResponse(object): class PaymentCommon(object): + has_free_transaction_id = False + PATH = '/tmp' BANK_ID = '__bank_id' diff --git a/eopayment/systempayv2.py b/eopayment/systempayv2.py index ed5da47..f503976 100644 --- a/eopayment/systempayv2.py +++ b/eopayment/systempayv2.py @@ -54,6 +54,7 @@ VADS_TRANS_ID = 'vads_trans_id' SIGNATURE = 'signature' VADS_CTX_MODE = 'vads_ctx_mode' VADS_EFFECTIVE_CREATION_DATE = 'vads_effective_creation_date' +VADS_EOPAYMENT_TRANS_ID = 'vads_ext_info_eopayment_trans_id' def isonow(): @@ -179,6 +180,7 @@ PARAMETERS = [ PARAMETER_MAP = dict(((parameter.name, parameter) for parameter in PARAMETERS)) + def add_vads(kwargs): new_vargs = {} for k, v in kwargs.items(): @@ -222,6 +224,7 @@ class Payment(PaymentCommon): 'vads_return_mode': 'NONE'}) ''' + has_free_transaction_id = True service_url = "https://paiement.systempay.fr/vads-payment/" signature_algo = 'sha1' @@ -312,7 +315,7 @@ class Payment(PaymentCommon): def request(self, amount, name=None, first_name=None, last_name=None, address=None, email=None, phone=None, orderid=None, info1=None, info2=None, info3=None, next_url=None, manual_validation=None, - **kwargs): + transaction_id=None, **kwargs): ''' Create the URL string to send a request to SystemPay ''' @@ -385,9 +388,12 @@ class Payment(PaymentCommon): if manual_validation: fields['vads_validation_mode'] = '1' check_vads(fields) + if transaction_id: + fields[VADS_EOPAYMENT_TRANS_ID] = transaction_id + else: + transaction_id = '%s_%s' % (fields[VADS_TRANS_DATE], vads_trans_id) 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], vads_trans_id) self.logger.debug('%s transaction id: %s', __name__, transaction_id) form = Form( url=self.service_url, @@ -487,7 +493,10 @@ class Payment(PaymentCommon): message += ' signature invalide.' test = fields[VADS_CTX_MODE] == 'TEST' - transaction_id = '%s_%s' % (copy[VADS_TRANS_DATE], copy[VADS_TRANS_ID]) + if VADS_EOPAYMENT_TRANS_ID in fields: + transaction_id = fields[VADS_EOPAYMENT_TRANS_ID] + else: + transaction_id = '%s_%s' % (copy[VADS_TRANS_DATE], copy[VADS_TRANS_ID]) # the VADS_AUTH_NUMBER is the number to match payment in bank logs copy[self.BANK_ID] = copy.get(VADS_AUTH_NUMBER, '') transaction_date = None @@ -498,7 +507,7 @@ class Payment(PaymentCommon): signed=signature_result, bank_data=copy, order_id=transaction_id, - transaction_id=copy.get(VADS_AUTH_NUMBER), + transaction_id=transaction_id, bank_status=message, transaction_date=transaction_date, test=test) diff --git a/tests/test_systempayv2.py b/tests/test_systempayv2.py index 3b64f60..353e190 100644 --- a/tests/test_systempayv2.py +++ b/tests/test_systempayv2.py @@ -35,6 +35,11 @@ PARAMS = { } +@pytest.fixture +def backend(): + return eopayment.Payment('systempayv2', PARAMS) + + def get_field(form, field_name): for field in form.fields: if field['name'] == field_name: @@ -167,3 +172,24 @@ def test_manual_validation(): data['manual_validation'] = False transaction_id, f, form = backend.request(**data.copy()) assert get_field(form, 'vads_validation_mode')['value'] == '' + +FIXED_TRANSACTION_ID = '1234' + +def test_transaction_id_request(backend): + transaction_id, kind, form = backend.request(10.0, transaction_id=FIXED_TRANSACTION_ID) + assert transaction_id == FIXED_TRANSACTION_ID + found = None + for field in form.fields: + if field['name'] == 'vads_ext_info_eopayment_trans_id': + found = field + break + assert found + assert found['value'] == FIXED_TRANSACTION_ID + + +def test_transaction_id_response(backend, caplog): + caplog.set_level(0) + response = '''vads_amount=1000&vads_auth_mode=FULL&vads_auth_number=3fcdd2&vads_auth_result=00&vads_capture_delay=0&vads_card_brand=CB&vads_card_number=597010XXXXXX0018&vads_payment_certificate=4db13859ab429cb6b9bae7546952846efd190e3a&vads_ctx_mode=TEST&vads_currency=978&vads_effective_amount=1000&vads_effective_currency=978&vads_site_id=51438584&vads_trans_date=20201027212030&vads_trans_id=sDJJeQ&vads_trans_uuid=368ef4d0822448e3a2e7413c4e9f8be8&vads_validation_mode=0&vads_version=V2&vads_warranty_result=&vads_payment_src=EC&vads_cust_country=FR&vads_contrib=eopayment&vads_tid=001&vads_sequence_number=1&vads_contract_used=2334410&vads_trans_status=AUTHORISED&vads_expiry_month=6&vads_expiry_year=2021&vads_bank_label=Banque+de+d%C3%A9mo+et+de+l%27innovation&vads_bank_product=MCW&vads_pays_ip=FR&vads_presentation_date=20201027212031&vads_effective_creation_date=20201027212031&vads_operation_type=DEBIT&vads_result=00&vads_extra_result=&vads_card_country=FR&vads_language=fr&vads_brand_management=%7B%22userChoice%22%3Afalse%2C%22brandList%22%3A%22CB%7CMASTERCARD%22%2C%22brand%22%3A%22CB%22%7D&vads_action_mode=INTERACTIVE&vads_payment_config=SINGLE&vads_page_action=PAYMENT&vads_ext_info_eopayment_trans_id=1234&vads_threeds_enrolled=Y&vads_threeds_auth_type=CHALLENGE&vads_threeds_eci=02&vads_threeds_xid=bVpsTUhLSWpodnJjdXJVdE5rb0g%3D&vads_threeds_cavvAlgorithm=2&vads_threeds_status=Y&vads_threeds_sign_valid=1&vads_threeds_error_code=&vads_threeds_exit_status=10&vads_threeds_cavv=jG26AYSjvclBARFYSf%2FtXRmjGXM%3D&signature=fBGbFQPlUiyrL0yVgQzbhokMt6cqG24hOr%2BYsXKr/b8=''' + result = backend.response(response) + assert result.signed + assert result.transaction_id == FIXED_TRANSACTION_ID