Webhook Signature
For security reasons, every Webhook sent from Reveni includes a signed header. Thus you can make sure that the event is sent by us and not by an unknown third party. For verifying those signatures, you will need the provided REVENI_API_KEY
that you use for Authentication.
Webhook requests use the POST
method and include a header for the signature: X-REVENI-SIGNATURE
. It contains the event timestamp and the computed signature. The timestamp is prefixed by t=
, and the signature is prefixed by a scheme. Schemes start with v
, then followed by an integer. The current valid signature scheme is v1
.
Example:
X-REVENI-SIGNATURE:t=1654594965.749773,v1=e1676b8d4c23dc90d3729035a2c2eaecaa4fa7ffd1ad7696a4bbbed6bb8522ec
The signature is generated using a hash-based message authentication code (HMAC) with SHA-256. To prevent downgrade attacks, you should ignore all schemes that are not v1.
For verifying the provided signatures, you can do the following:
Step 1. Extract the timestamp and signature from the header
Step 2. Generate the verification payload
string
- The timestamp in
string
format (e.g.1654594965.749773
) - The character
.
- The request payload (i.e. the request body in raw format):
{"id": "c6927a921708466da5ed2b4ebadf0bdf", "event": "return.created", "created": 1661518366, "data": {"amount": "76.4800","status": "incomplete","currency": "EUR","resource": "return","resource_id": "4e26c9f08f2a468fabc16af12ae0209b","object": {...}}}
Step 3. Compute an HMAC with the SHA256 hash function
Use the REVENI_API_KEY
as the key, and use the generated payload
string as the message.
Step 4. Compare the signatures
Compare the computed signature with the one extracted from the header, these must match. Also, check the timestamp with the current time and decide whether that difference is within your tolerance.
Reference snippet
Use the following Python snippet for reference. The computed signature must match the signature extracted from the Webhook header.
import hashlib
import hmac
# Use the timestamp extracted from the header and the request body as received
payload = f"{timestamp}.{request.json()}".encode()
# Use the REVENI API key
key = reveni_api_key.encode()
hash = hmac.new(
key,
payload,
hashlib.sha256,
)
signature = hash.hexdigest()
Basic Authentication
Reveni Webhooks support the Basic Authentication schema, which is based on a user
and password
. To create a Webhook with basic authentication, include the user and password credentials to the URL (e.g. https://user:[email protected]
). Reveni will honor these parameters and will send the appropriate header in the request. Then you can authenticate these requests upon received in your platform.