Our API generates a signed request header using the webhook URL, POST, key, secret and the webhook data:
http_method = "POST" headers = generate_signed_request_headers(url, http_method, credential.key, credential.secret, data)
generate_signed_request_headers() includes the method (POST), webhook URL, the current date, a generated UUID, a content hash (using SHA1 encoded to UTF-8) and the content type (application/json) to build an access token:
paymentservice_contenthash = calculate_content_hash(json.dumps(data).encode(‘utf-8’))
original_access_token_string = build_access_token_context( http_method=http_method, http_path=http_path, paymentservice_date=paymentservice_date, paymentservice_nonce=paymentservice_nonce, paymentservice_contenthash=paymentservice_contenthash, content_type=content_type )
build_access_token_context() builds a token string by appending the method path, content type, content hash, date and nonce.
access_token_string = f"{http_method}\n" access_token_string += f"{http_path}\n" access_token_string += f"{content_type}\n" access_token_string += f"paymentservice-contenthash:{paymentservice_contenthash}\n" access_token_string += f"paymentservice-date:{paymentservice_date}\n" access_token_string += f"paymentservice-nonce:{paymentservice_nonce}" return access_token_string
This access_token_string, encoded to UTF-8, along with secret, is used to calculate the access token.
access_token = calculate_signature_hash(secret, original_access_token_string.encode("utf-8")) calculate_signature_hash(key: str, message: bytes) access_token = calculate_signature_hash(secret, original_access_token_string.encode("utf-8"))
The key is encoded to UTF-8, the message is hashed and it’s encoded to base 64:
hmac_hash = hmac.new(key.encode("utf-8"), message, hashlib.sha256) signature = base64.b64encode(hmac_hash.digest()) return signature.decode("utf-8")
The authorization header is the key and access token:
message = f"Signature {key}:{access_token}"