77import copy
88
99
10-
10+ # generates HMAC signature for the NotificationRequest object
1111def generate_notification_sig (dict_object , hmac_key ):
1212
1313 if not isinstance (dict_object , dict ):
@@ -36,7 +36,30 @@ def generate_notification_sig(dict_object, hmac_key):
3636 return base64 .b64encode (hm .digest ())
3737
3838
39+ # generates HMAC signature for the payload (bytes)
40+ def generate_payload_sig (payload , hmac_key ):
41+
42+ if not isinstance (payload , bytes ):
43+ raise ValueError ("Must Provide payload as bytes" )
44+
45+ hmac_key = binascii .a2b_hex (hmac_key )
46+
47+ hm = hmac .new (hmac_key , payload , hashlib .sha256 )
48+ return base64 .b64encode (hm .digest ())
49+
50+
3951def is_valid_hmac_notification (dict_object , hmac_key ):
52+ """
53+ validates the HMAC signature of the NotificationRequestItem object. Use for webhooks that provide the
54+ hmacSignature as part of the payload `AdditionalData` (i.e. Payments)
55+ Args:
56+ dict_object: object with a list of notificationItems
57+ hmac_key: HMAC key to generate the signature
58+
59+ Returns:
60+ boolean: true when HMAC signature is valid
61+ """
62+
4063 dict_object = copy .deepcopy (dict_object )
4164
4265 if 'notificationItems' in dict_object :
@@ -53,5 +76,24 @@ def is_valid_hmac_notification(dict_object, hmac_key):
5376 return hmac .compare_digest (merchant_sign_str , expected_sign )
5477
5578
79+ def is_valid_hmac_payload (hmac_signature , hmac_key , payload ):
80+ """
81+ validates the HMAC signature of a payload against an expected signature. Use for webhooks that provide the
82+ hmacSignature in the HTTP header (i.e. Banking, Management API)
83+ Args:
84+ hmac_signature: HMAC signature to validate
85+ hmac_key: HMAC key to generate the signature
86+ payload: webhook payload
87+
88+ Returns:
89+ boolean: true when HMAC signature is valid
90+ """
91+
92+ merchant_sign = generate_payload_sig (payload , hmac_key )
93+ merchant_sign_str = merchant_sign .decode ("utf-8" )
94+
95+ return hmac .compare_digest (merchant_sign_str , hmac_signature )
96+
97+
5698def get_query (query_parameters ):
5799 return '?' + '&' .join (["{}={}" .format (k , v ) for k , v in query_parameters .items ()])
0 commit comments