python-redsys 1.1.1__py3-none-any.whl → 1.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python_redsys-1.1.1.dist-info → python_redsys-1.2.1.dist-info}/METADATA +14 -9
- python_redsys-1.2.1.dist-info/RECORD +13 -0
- {python_redsys-1.1.1.dist-info → python_redsys-1.2.1.dist-info}/WHEEL +1 -1
- redsys/__init__.py +2 -5
- redsys/client.py +8 -14
- redsys/request.py +17 -8
- redsys/response.py +9 -10
- redsys/tests/test_client.py +10 -17
- redsys/tests/test_request.py +16 -12
- redsys/tests/test_response.py +11 -4
- python_redsys-1.1.1.dist-info/RECORD +0 -13
- {python_redsys-1.1.1.dist-info → python_redsys-1.2.1.dist-info/licenses}/LICENSE +0 -0
|
@@ -1,21 +1,26 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: python-redsys
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.1
|
|
4
4
|
Summary: A simple, clean and less dependant client to handle payments through Redsys.
|
|
5
|
-
Home-page: https://github.com/systemallica/python-redsys
|
|
6
5
|
License: MIT
|
|
7
|
-
|
|
8
|
-
Author
|
|
9
|
-
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Author: David Díaz
|
|
8
|
+
Author-email: d.diazp@gmail.com
|
|
9
|
+
Requires-Python: >=3.8,<4.0
|
|
10
10
|
Classifier: Intended Audience :: Developers
|
|
11
11
|
Classifier: License :: OSI Approved :: MIT License
|
|
12
12
|
Classifier: Operating System :: OS Independent
|
|
13
13
|
Classifier: Programming Language :: Python :: 3
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
16
14
|
Classifier: Programming Language :: Python :: 3.8
|
|
17
15
|
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
-
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.15
|
|
22
|
+
Requires-Dist: pycryptodome (>=3.19.0,<4.0.0)
|
|
23
|
+
Project-URL: Homepage, https://github.com/ddiazpinto/python-redsys
|
|
19
24
|
Description-Content-Type: text/markdown
|
|
20
25
|
|
|
21
26
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
redsys/__init__.py,sha256=kRuS8epm885TJGvdrjNc9xwT70glq_h9x71_bUgT68s,138
|
|
2
|
+
redsys/client.py,sha256=ervLX4FbzDfWjh_SO2SFyY9IT0PZ5aIcVZdYy4mUO7Q,3937
|
|
3
|
+
redsys/constants.py,sha256=lJYgbmikxh0b9iVM4M5XFWBWVvdFY27OkcXSLluHSsQ,2497
|
|
4
|
+
redsys/request.py,sha256=IEzlRi34JgDBRRyaBHtIrAZ38fADL977RdBFaeWDdbY,5304
|
|
5
|
+
redsys/response.py,sha256=leDhlDlnVLGeruxlN2_3DQ-V56xAbIiFkvoqYDmz9S0,5430
|
|
6
|
+
redsys/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
redsys/tests/test_client.py,sha256=oND8W9y6O6MkDLNxnBpd8UDShwKWoAW3SgKmWDOXHrw,3858
|
|
8
|
+
redsys/tests/test_request.py,sha256=FONigjMNdaug2DwillYKCLPK-gzIYZSVUZmcm9QkCms,3110
|
|
9
|
+
redsys/tests/test_response.py,sha256=V8WdZ1oR4Ed5ZKmi2R-Hpgnr3AyYZy-jFH1yn2S0lA4,1220
|
|
10
|
+
python_redsys-1.2.1.dist-info/METADATA,sha256=Wn6Z7SG3HtRu0PIaxBwEzsDomMFzxO_BH9M4NpFu-uA,4631
|
|
11
|
+
python_redsys-1.2.1.dist-info/WHEEL,sha256=L-WvLdSBvJWHXv5zrQxDvNRnIgoBzLUpcbuiw19KCuQ,88
|
|
12
|
+
python_redsys-1.2.1.dist-info/licenses/LICENSE,sha256=Ku6mJcUOcHd2aZ4o2Jh4Tjkx1oZT-iT0VCyUNvm2IXU,1257
|
|
13
|
+
python_redsys-1.2.1.dist-info/RECORD,,
|
redsys/__init__.py
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
__version__ = "1.
|
|
2
|
-
__version_info__ = tuple(
|
|
3
|
-
int(num) if num.isdigit() else num
|
|
4
|
-
for num in __version__.replace("-", ".", 1).split(".")
|
|
5
|
-
)
|
|
1
|
+
__version__ = "1.2.1"
|
|
2
|
+
__version_info__ = tuple(int(num) if num.isdigit() else num for num in __version__.replace("-", ".", 1).split("."))
|
redsys/client.py
CHANGED
|
@@ -3,8 +3,10 @@ import hashlib
|
|
|
3
3
|
import hmac
|
|
4
4
|
import json
|
|
5
5
|
import re
|
|
6
|
-
from abc import ABC
|
|
7
|
-
from
|
|
6
|
+
from abc import ABC
|
|
7
|
+
from abc import abstractmethod
|
|
8
|
+
from typing import Any
|
|
9
|
+
from typing import Dict
|
|
8
10
|
|
|
9
11
|
from Crypto.Cipher import DES3
|
|
10
12
|
|
|
@@ -51,16 +53,12 @@ class Client(ABC):
|
|
|
51
53
|
Generates the encrypted signature using the 3DES-encrypted order
|
|
52
54
|
and base64-encoded merchant parameters
|
|
53
55
|
"""
|
|
54
|
-
signature = hmac.new(
|
|
55
|
-
encrypted_order, merchant_parameters, hashlib.sha256
|
|
56
|
-
).digest()
|
|
56
|
+
signature = hmac.new(encrypted_order, merchant_parameters, hashlib.sha256).digest()
|
|
57
57
|
return base64.b64encode(signature)
|
|
58
58
|
|
|
59
59
|
def encrypt_3DES(self, order: str) -> bytes:
|
|
60
60
|
"""Encrypts(3DES algorithm) the payment order using the secret key"""
|
|
61
|
-
cipher = DES3.new(
|
|
62
|
-
base64.b64decode(self.secret_key), DES3.MODE_CBC, IV=b"\0\0\0\0\0\0\0\0"
|
|
63
|
-
)
|
|
61
|
+
cipher = DES3.new(base64.b64decode(self.secret_key), DES3.MODE_CBC, IV=b"\0\0\0\0\0\0\0\0")
|
|
64
62
|
# the cipher needs to be passed 16 bytes,
|
|
65
63
|
# so "order" must be 16 bytes long,
|
|
66
64
|
# therefore we left-justify adding ceros
|
|
@@ -96,16 +94,12 @@ class RedirectClient(Client):
|
|
|
96
94
|
"""
|
|
97
95
|
decoded_parameters = self.decode_parameters(merchant_parameters.encode())
|
|
98
96
|
response = Response(decoded_parameters)
|
|
99
|
-
calculated_signature = self.generate_signature(
|
|
100
|
-
response.order, merchant_parameters.encode()
|
|
101
|
-
)
|
|
97
|
+
calculated_signature = self.generate_signature(response.order, merchant_parameters.encode())
|
|
102
98
|
# Remove any non-alphanumeric characters from the signature
|
|
103
99
|
not_alphanumeric = re.compile("[^a-zA-Z0-9]")
|
|
104
100
|
safe_signature = re.sub(not_alphanumeric, "", signature)
|
|
105
101
|
|
|
106
|
-
safe_calculated_signature = re.sub(
|
|
107
|
-
not_alphanumeric, "", calculated_signature.decode()
|
|
108
|
-
)
|
|
102
|
+
safe_calculated_signature = re.sub(not_alphanumeric, "", calculated_signature.decode())
|
|
109
103
|
if safe_signature != safe_calculated_signature:
|
|
110
104
|
raise ValueError("The provided signature is not valid.")
|
|
111
105
|
return response
|
redsys/request.py
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import re
|
|
2
2
|
from decimal import Decimal
|
|
3
|
-
from typing import Any
|
|
3
|
+
from typing import Any
|
|
4
|
+
from typing import Dict
|
|
4
5
|
|
|
5
|
-
from redsys.constants import CURRENCIES
|
|
6
|
+
from redsys.constants import CURRENCIES
|
|
7
|
+
from redsys.constants import LANGUAGES
|
|
8
|
+
from redsys.constants import TRANSACTIONS
|
|
6
9
|
|
|
7
10
|
# General parameters
|
|
8
11
|
MERCHANT_CODE = "Ds_Merchant_MerchantCode"
|
|
@@ -36,6 +39,10 @@ PAN = "Ds_Merchant_Pan"
|
|
|
36
39
|
EXPIRY_DATE = "Ds_Merchant_ExpiryDate"
|
|
37
40
|
CVV2 = "Ds_Merchant_Cvv2"
|
|
38
41
|
|
|
42
|
+
# BIZUM PAYMENT parameters
|
|
43
|
+
MOBILE_NUMBER = "Ds_Merchant_Bizum_MobileNumber"
|
|
44
|
+
PAYMENT_METHOD = "Ds_Merchant_PayMethods"
|
|
45
|
+
|
|
39
46
|
MERCHANT_PARAMETERS_MAP = {
|
|
40
47
|
"merchant_code": MERCHANT_CODE,
|
|
41
48
|
"terminal": TERMINAL,
|
|
@@ -59,6 +66,8 @@ MERCHANT_PARAMETERS_MAP = {
|
|
|
59
66
|
"pan": PAN,
|
|
60
67
|
"expiry_date": EXPIRY_DATE,
|
|
61
68
|
"cvv2": CVV2,
|
|
69
|
+
"mobile_number": MOBILE_NUMBER,
|
|
70
|
+
"payment_method": PAYMENT_METHOD,
|
|
62
71
|
}
|
|
63
72
|
|
|
64
73
|
|
|
@@ -68,9 +77,11 @@ class Request:
|
|
|
68
77
|
their values according to the platform specifications
|
|
69
78
|
"""
|
|
70
79
|
|
|
71
|
-
_parameters: Dict[str, Any]
|
|
80
|
+
_parameters: Dict[str, Any]
|
|
72
81
|
|
|
73
82
|
def __init__(self, parameters: Dict[str, Any]) -> None:
|
|
83
|
+
# __setattr__ only handles merchant parameters, so the per-instance store is set directly.
|
|
84
|
+
object.__setattr__(self, "_parameters", {})
|
|
74
85
|
for key, value in parameters.items():
|
|
75
86
|
if key in MERCHANT_PARAMETERS_MAP:
|
|
76
87
|
if check := getattr(self, f"check_{str(key)}", None):
|
|
@@ -81,7 +92,7 @@ class Request:
|
|
|
81
92
|
|
|
82
93
|
def __getattr__(self, item: str) -> Any:
|
|
83
94
|
if item in MERCHANT_PARAMETERS_MAP:
|
|
84
|
-
return self._parameters
|
|
95
|
+
return self._parameters.get(item)
|
|
85
96
|
|
|
86
97
|
def __setattr__(self, key, value):
|
|
87
98
|
if key in MERCHANT_PARAMETERS_MAP:
|
|
@@ -93,9 +104,7 @@ class Request:
|
|
|
93
104
|
parameters = {}
|
|
94
105
|
for key, value in self._parameters.items():
|
|
95
106
|
prepare = getattr(self, "prepare_%s" % key, None)
|
|
96
|
-
parameters[MERCHANT_PARAMETERS_MAP[key]] = (
|
|
97
|
-
prepare(value) if prepare else value
|
|
98
|
-
)
|
|
107
|
+
parameters[MERCHANT_PARAMETERS_MAP[key]] = prepare(value) if prepare else value
|
|
99
108
|
return parameters
|
|
100
109
|
|
|
101
110
|
@staticmethod
|
|
@@ -108,7 +117,7 @@ class Request:
|
|
|
108
117
|
|
|
109
118
|
@staticmethod
|
|
110
119
|
def check_order(value):
|
|
111
|
-
if not re.match(r"[0-9]{4}[a-zA-Z0-9]{
|
|
120
|
+
if not re.match(r"[0-9]{4}[a-zA-Z0-9]{8}$", value):
|
|
112
121
|
raise ValueError("order format is not valid.")
|
|
113
122
|
|
|
114
123
|
@staticmethod
|
redsys/response.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from decimal import Decimal
|
|
2
|
-
from typing import Any
|
|
2
|
+
from typing import Any
|
|
3
|
+
from typing import Dict
|
|
3
4
|
|
|
4
5
|
RESPONSE = "Ds_Response"
|
|
5
6
|
DATE = "Ds_Date"
|
|
@@ -92,12 +93,12 @@ class Response:
|
|
|
92
93
|
Defines a response
|
|
93
94
|
"""
|
|
94
95
|
|
|
95
|
-
_parameters: Dict[str, Any]
|
|
96
|
+
_parameters: Dict[str, Any]
|
|
96
97
|
|
|
97
98
|
def __init__(self, parameters: Dict[str, Any]):
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}
|
|
99
|
+
# __setattr__ only handles merchant parameters, so the per-instance store is set directly.
|
|
100
|
+
object.__setattr__(self, "_parameters", {})
|
|
101
|
+
MERCHANT_PARAMETERS_MAP_REVERSE = {value: key for key, value in MERCHANT_PARAMETERS_MAP.items()}
|
|
101
102
|
for key, value in parameters.items():
|
|
102
103
|
reversed_parameter = MERCHANT_PARAMETERS_MAP_REVERSE.get(key, key)
|
|
103
104
|
clean = getattr(self, "clean_%s" % reversed_parameter, None)
|
|
@@ -105,14 +106,12 @@ class Response:
|
|
|
105
106
|
|
|
106
107
|
def __getattr__(self, item: str) -> Any:
|
|
107
108
|
if item in MERCHANT_PARAMETERS_MAP:
|
|
108
|
-
return self._parameters
|
|
109
|
+
return self._parameters.get(item)
|
|
109
110
|
|
|
110
111
|
def __setattr__(self, key: str, value: Any):
|
|
111
112
|
if key in MERCHANT_PARAMETERS_MAP:
|
|
112
113
|
clean = getattr(self, "clean_%s" % MERCHANT_PARAMETERS_MAP[key], None)
|
|
113
|
-
self._parameters[MERCHANT_PARAMETERS_MAP[key]] = (
|
|
114
|
-
clean(value) if clean else value
|
|
115
|
-
)
|
|
114
|
+
self._parameters[MERCHANT_PARAMETERS_MAP[key]] = clean(value) if clean else value
|
|
116
115
|
|
|
117
116
|
@property
|
|
118
117
|
def is_authorized(self):
|
|
@@ -144,4 +143,4 @@ class Response:
|
|
|
144
143
|
|
|
145
144
|
@staticmethod
|
|
146
145
|
def clean_amount(value):
|
|
147
|
-
return Decimal("{
|
|
146
|
+
return Decimal(f"{str(value)[:-2]}.{str(value)[-2:]}")
|
redsys/tests/test_client.py
CHANGED
|
@@ -4,7 +4,8 @@ from decimal import Decimal as D
|
|
|
4
4
|
import pytest
|
|
5
5
|
|
|
6
6
|
from redsys.client import RedirectClient
|
|
7
|
-
from redsys.constants import EUR
|
|
7
|
+
from redsys.constants import EUR
|
|
8
|
+
from redsys.constants import STANDARD_PAYMENT
|
|
8
9
|
from redsys.request import Request
|
|
9
10
|
|
|
10
11
|
|
|
@@ -18,7 +19,7 @@ class TestRedirectClient:
|
|
|
18
19
|
"terminal": "1",
|
|
19
20
|
"transaction_type": STANDARD_PAYMENT,
|
|
20
21
|
"currency": EUR,
|
|
21
|
-
"order": "
|
|
22
|
+
"order": "000000000001",
|
|
22
23
|
"amount": D("10.56489").quantize(D(".01"), ROUND_HALF_UP),
|
|
23
24
|
"merchant_data": "test merchant data",
|
|
24
25
|
"merchant_name": "Example Commerce",
|
|
@@ -33,7 +34,7 @@ class TestRedirectClient:
|
|
|
33
34
|
encoded_params = self.client.encode_parameters(self.merchant_params)
|
|
34
35
|
encoded_params_str = encoded_params.decode("UTF-8")
|
|
35
36
|
assert encoded_params_str.endswith("ZWRzeXMvcmVzcG9uc2UifQ==")
|
|
36
|
-
assert len(encoded_params_str) ==
|
|
37
|
+
assert len(encoded_params_str) == 628
|
|
37
38
|
|
|
38
39
|
def test_decode_parameters(self):
|
|
39
40
|
encoded_params = self.client.encode_parameters(self.merchant_params)
|
|
@@ -43,24 +44,18 @@ class TestRedirectClient:
|
|
|
43
44
|
def test_encrypt_3DES(self):
|
|
44
45
|
encrypted_order = self.client.encrypt_3DES(self.request.order)
|
|
45
46
|
assert len(encrypted_order) == 16
|
|
46
|
-
assert (
|
|
47
|
-
str(encrypted_order)
|
|
48
|
-
== 'b"/\\x17\\\\6\\n\\x1aY\\xf3\\xb7\\\\\\xde\'d\\xa5\\x03\\xb7"'
|
|
49
|
-
)
|
|
47
|
+
assert str(encrypted_order) == "b'/\\x17\\\\6\\n\\x1aY\\xf3\\xd7\\xa5\\x97\\xb9\\xb6\\xe0\\x8dH'"
|
|
50
48
|
|
|
51
49
|
def test_sign_hmac256(self):
|
|
52
50
|
encrypted_order = self.client.encrypt_3DES(self.request.order)
|
|
53
51
|
encoded_params = self.client.encode_parameters(self.merchant_params)
|
|
54
52
|
signature = self.client.sign_hmac256(encrypted_order, encoded_params)
|
|
55
|
-
assert signature == b"
|
|
53
|
+
assert signature == b"a2F05DwuH5aXu5vD1IdjQ+NxaR0lPsRwksW1nr2Nzuw="
|
|
56
54
|
|
|
57
55
|
def test_prepare_request(self):
|
|
58
56
|
prepared_request = self.client.prepare_request(self.parameters)
|
|
59
57
|
assert len(prepared_request.keys()) == 3
|
|
60
|
-
assert (
|
|
61
|
-
prepared_request.get("Ds_Signature")
|
|
62
|
-
== b"eEW4YN7/kkNHRO0/HhXy9TppzHwF38+eZApKAagDI9A="
|
|
63
|
-
)
|
|
58
|
+
assert prepared_request.get("Ds_Signature") == b"a2F05DwuH5aXu5vD1IdjQ+NxaR0lPsRwksW1nr2Nzuw="
|
|
64
59
|
pass
|
|
65
60
|
|
|
66
61
|
def test_create_response_valid(self):
|
|
@@ -69,15 +64,13 @@ class TestRedirectClient:
|
|
|
69
64
|
"Ds_Terminal": "1",
|
|
70
65
|
"Ds_TransactionType": "0",
|
|
71
66
|
"Ds_Currency": 978,
|
|
72
|
-
"Ds_Order": "
|
|
67
|
+
"Ds_Order": "000000000001",
|
|
73
68
|
"Ds_Amount": 1056,
|
|
74
69
|
"Ds_MerchantData": "test merchant data",
|
|
75
70
|
}
|
|
76
71
|
encoded_params = self.client.encode_parameters(merchant_parameters)
|
|
77
72
|
signature = self.client.generate_signature(self.request.order, encoded_params)
|
|
78
|
-
response = self.client.create_response(
|
|
79
|
-
signature.decode(), encoded_params.decode()
|
|
80
|
-
)
|
|
73
|
+
response = self.client.create_response(signature.decode(), encoded_params.decode())
|
|
81
74
|
assert response._parameters.get("order") == merchant_parameters.get("Ds_Order")
|
|
82
75
|
|
|
83
76
|
def test_create_response_invalid(self):
|
|
@@ -86,7 +79,7 @@ class TestRedirectClient:
|
|
|
86
79
|
"Ds_Terminal": "1",
|
|
87
80
|
"Ds_TransactionType": "0",
|
|
88
81
|
"Ds_Currency": 978,
|
|
89
|
-
"Ds_Order": "
|
|
82
|
+
"Ds_Order": "000000000001",
|
|
90
83
|
"Ds_Amount": 1056,
|
|
91
84
|
"Ds_MerchantData": "test merchant data",
|
|
92
85
|
}
|
redsys/tests/test_request.py
CHANGED
|
@@ -4,7 +4,8 @@ from random import choice
|
|
|
4
4
|
|
|
5
5
|
import pytest
|
|
6
6
|
|
|
7
|
-
from redsys.constants import EUR
|
|
7
|
+
from redsys.constants import EUR
|
|
8
|
+
from redsys.constants import STANDARD_PAYMENT
|
|
8
9
|
from redsys.request import Request
|
|
9
10
|
|
|
10
11
|
|
|
@@ -15,7 +16,7 @@ class TestRequest:
|
|
|
15
16
|
"terminal": "1",
|
|
16
17
|
"transaction_type": STANDARD_PAYMENT,
|
|
17
18
|
"currency": EUR,
|
|
18
|
-
"order": "
|
|
19
|
+
"order": "000000000001",
|
|
19
20
|
"amount": D("10.56489").quantize(D(".01"), ROUND_HALF_UP),
|
|
20
21
|
"merchant_data": "test merchant data",
|
|
21
22
|
"merchant_name": "Example Commerce",
|
|
@@ -41,7 +42,7 @@ class TestRequest:
|
|
|
41
42
|
"terminal": "1",
|
|
42
43
|
"transaction_type": STANDARD_PAYMENT,
|
|
43
44
|
"currency": EUR,
|
|
44
|
-
"order": "
|
|
45
|
+
"order": "000000000001",
|
|
45
46
|
"amount": D("10.56489").quantize(D(".01"), ROUND_HALF_UP),
|
|
46
47
|
"merchant_data": "test merchant data",
|
|
47
48
|
"merchant_name": "Example Commerce",
|
|
@@ -51,20 +52,23 @@ class TestRequest:
|
|
|
51
52
|
}
|
|
52
53
|
prepared_parameters = Request(parameters).prepare_parameters()
|
|
53
54
|
assert len(prepared_parameters.keys()) == 11
|
|
54
|
-
assert (
|
|
55
|
-
prepared_parameters.get("Ds_Merchant_MerchantData") == "test merchant data"
|
|
56
|
-
)
|
|
55
|
+
assert prepared_parameters.get("Ds_Merchant_MerchantData") == "test merchant data"
|
|
57
56
|
|
|
58
57
|
def test_super_long_merchant_data_throws_error(self):
|
|
59
|
-
merchant_data = "".join(
|
|
60
|
-
choice("abcdefghijklmnopqrtsuvwxyz-0123456789") for _ in range(1025)
|
|
61
|
-
)
|
|
58
|
+
merchant_data = "".join(choice("abcdefghijklmnopqrtsuvwxyz-0123456789") for _ in range(1025))
|
|
62
59
|
with pytest.raises(ValueError):
|
|
63
60
|
assert Request.check_merchant_data(merchant_data)
|
|
64
61
|
|
|
65
62
|
def test_super_long_merchant_url_throws_error(self):
|
|
66
|
-
merchant_url = "".join(
|
|
67
|
-
choice("abcdefghijklmnopqrtsuvwxyz-0123456789") for _ in range(251)
|
|
68
|
-
)
|
|
63
|
+
merchant_url = "".join(choice("abcdefghijklmnopqrtsuvwxyz-0123456789") for _ in range(251))
|
|
69
64
|
with pytest.raises(ValueError):
|
|
70
65
|
assert Request.check_merchant_url(merchant_url)
|
|
66
|
+
|
|
67
|
+
def test_requests_do_not_share_parameters(self):
|
|
68
|
+
first = Request(
|
|
69
|
+
{"order": "000000000001", "amount": D("1.00"), "currency": EUR, "mobile_number": "+34700000000"}
|
|
70
|
+
)
|
|
71
|
+
second = Request({"order": "000000000002", "amount": D("2.00"), "currency": EUR})
|
|
72
|
+
assert "Ds_Merchant_Bizum_MobileNumber" not in second.prepare_parameters()
|
|
73
|
+
assert second.mobile_number is None
|
|
74
|
+
assert first.prepare_parameters()["Ds_Merchant_Bizum_MobileNumber"] == "+34700000000"
|
redsys/tests/test_response.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from decimal import Decimal
|
|
2
|
+
|
|
1
3
|
from redsys.response import Response
|
|
2
4
|
|
|
3
5
|
|
|
@@ -8,18 +10,23 @@ class TestResponse:
|
|
|
8
10
|
"Ds_MerchantCode": "1056",
|
|
9
11
|
"Ds_Terminal": "1",
|
|
10
12
|
"Ds_TransactionType": "1",
|
|
11
|
-
"Ds_Order": "
|
|
13
|
+
"Ds_Order": "000000000001",
|
|
12
14
|
"Ds_Amount": "10054",
|
|
13
15
|
"Ds_MerchantData": "test merchant data",
|
|
14
16
|
"Ds_Currency": 978,
|
|
15
17
|
}
|
|
16
18
|
response = Response(parameters)
|
|
17
19
|
assert response.code == 90
|
|
18
|
-
assert
|
|
19
|
-
response.message == "Transacción autorizada para pagos y preautorizaciones"
|
|
20
|
-
)
|
|
20
|
+
assert response.message == "Transacción autorizada para pagos y preautorizaciones"
|
|
21
21
|
assert len(response._parameters.keys()) == 8
|
|
22
22
|
assert response.is_authorized is True
|
|
23
23
|
assert response.is_paid is True
|
|
24
24
|
assert response.is_canceled is False
|
|
25
25
|
assert response.is_refunded is False
|
|
26
|
+
|
|
27
|
+
def test_responses_do_not_share_parameters(self):
|
|
28
|
+
first = Response({"Ds_Response": "0000", "Ds_Order": "000000000001", "Ds_Amount": "100"})
|
|
29
|
+
second = Response({"Ds_Response": "0190", "Ds_Order": "000000000002"})
|
|
30
|
+
assert "amount" not in second.parameters
|
|
31
|
+
assert second.amount is None
|
|
32
|
+
assert first.amount == Decimal("1.00")
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
redsys/__init__.py,sha256=isoYrgHz945c1Cgxa2CY6lzHZXM3NV2r_KSvgTWKD6k,148
|
|
2
|
-
redsys/client.py,sha256=-wFN9XpKqa-Y3R4InWj-mq_Jtt4-IhO0nbaf4TiQsZM,3992
|
|
3
|
-
redsys/constants.py,sha256=lJYgbmikxh0b9iVM4M5XFWBWVvdFY27OkcXSLluHSsQ,2497
|
|
4
|
-
redsys/request.py,sha256=NuOH-ReP2xw23rtBS5vE1L9lk0BCr7qR4A6SPGJcEqc,4919
|
|
5
|
-
redsys/response.py,sha256=Yz7BvnsHY9UBencH1dO27di5MkVtrZ9SbTBE4QNNP78,5326
|
|
6
|
-
redsys/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
redsys/tests/test_client.py,sha256=7Ra-xYx0dZcSbe8ReszzEM1jD7CW6XDMTqOULtnAnvg,3911
|
|
8
|
-
redsys/tests/test_request.py,sha256=p0zstJwi4_-PL70tQXgNFskp7P5VBCxlDf9ZAaWAOe8,2635
|
|
9
|
-
redsys/tests/test_response.py,sha256=pi-iyAZ2Vc7MF4IUMM8Idztk7d5qD0C7GTkVbX4jrIo,847
|
|
10
|
-
python_redsys-1.1.1.dist-info/LICENSE,sha256=Ku6mJcUOcHd2aZ4o2Jh4Tjkx1oZT-iT0VCyUNvm2IXU,1257
|
|
11
|
-
python_redsys-1.1.1.dist-info/WHEEL,sha256=y3eDiaFVSNTPbgzfNn0nYn5tEn1cX6WrdetDlQM4xWw,83
|
|
12
|
-
python_redsys-1.1.1.dist-info/METADATA,sha256=ym0S75ZhTxDrbFdrKDjg74AziZ5Sd_dJevIeaWThvXs,4412
|
|
13
|
-
python_redsys-1.1.1.dist-info/RECORD,,
|
|
File without changes
|