44import hmac
55import json
66import re
7- from abc import ABCMeta , abstractmethod
7+ from abc import ABC , abstractmethod
8+ from typing import Any , Dict
89
910from Crypto .Cipher import DES3
1011
1819DEFAULT_SIGNATURE_VERSION = "HMAC_SHA256_V1"
1920
2021
21- class Client (object ):
22- __metaclass__ = ABCMeta
22+ class Client (ABC ):
23+ """
24+ Abstract class from which RedirectClient inherits.
25+ It implements methods that may be used in future clients(i.e. rest).
26+ """
2327
24- def __init__ (self , secret_key = None ):
28+ def __init__ (self , secret_key : str = None ):
2529 self .secret_key = secret_key
2630
2731 @abstractmethod
@@ -34,15 +38,28 @@ def create_response(
3438 def prepare_request (self , request ):
3539 raise NotImplementedError
3640
37- def encode_parameters (self , parameters ):
41+ @staticmethod
42+ def encode_parameters (parameters : Dict [str , Any ]) -> bytes :
3843 """Encodes the merchant parameters in base64"""
3944 return base64 .b64encode (json .dumps (parameters ).encode ())
4045
41- def decode_parameters (self , parameters ):
46+ @staticmethod
47+ def decode_parameters (parameters : bytes ) -> Dict [str , Any ]:
4248 """Decodes the merchant parameters from base64"""
4349 return json .loads (base64 .b64decode (parameters ).decode ())
4450
45- def encrypt_3DES (self , order ):
51+ @staticmethod
52+ def sign_hmac256 (encrypted_order : bytes , merchant_parameters : bytes ) -> bytes :
53+ """
54+ Generates the encrypted signature using the 3DES-encrypted order
55+ and base64-encoded merchant parameters
56+ """
57+ signature = hmac .new (
58+ encrypted_order , merchant_parameters , hashlib .sha256
59+ ).digest ()
60+ return base64 .b64encode (signature )
61+
62+ def encrypt_3DES (self , order : str ) -> bytes :
4663 """Encrypts(3DES algorithm) the payment order using the secret key"""
4764 cipher = DES3 .new (
4865 base64 .b64decode (self .secret_key ), DES3 .MODE_CBC , IV = b"\0 \0 \0 \0 \0 \0 \0 \0 "
@@ -52,22 +69,12 @@ def encrypt_3DES(self, order):
5269 # therefore we left-justify adding ceros
5370 return cipher .encrypt (order .encode ().ljust (16 , b"\0 " ))
5471
55- def sign_hmac256 (self , encrypted_order , merchant_parameters ):
56- """
57- Generates the encrypted signature using the encrypted order
58- and merchant parameters
59- """
60- signature = hmac .new (
61- encrypted_order , merchant_parameters , hashlib .sha256
62- ).digest ()
63- return base64 .b64encode (signature )
64-
65- def generate_signature (self , order , merchant_parameters ):
72+ def generate_signature (self , order : str , merchant_parameters : bytes ) -> bytes :
6673 return self .sign_hmac256 (self .encrypt_3DES (order ), merchant_parameters )
6774
6875
6976class RedirectClient (Client ):
70- def prepare_request (self , parameters ) :
77+ def prepare_request (self , parameters : Dict [ str , Any ]) -> Dict [ str , Any ] :
7178 """Takes the merchant parameters and returns the necessary parameters
7279 to make the POST request to Redsys"""
7380 request = Request (parameters )
@@ -81,14 +88,14 @@ def prepare_request(self, parameters):
8188
8289 def create_response (
8390 self ,
84- signature ,
85- merchant_parameters ,
86- ):
91+ signature : str ,
92+ merchant_parameters : str ,
93+ ) -> Response :
8794 """
8895 Decodes the Redsys response to check for validity.
8996 Checks if the received signature corresponds to the sent signature.
9097
91- Both the signature and merchant parameters are plain strings, not bytes.
98+ Both the ` signature` and ` merchant parameters` are plain strings, not bytes.
9299 """
93100 decoded_parameters = self .decode_parameters (merchant_parameters )
94101 response = Response (decoded_parameters )
0 commit comments