First steps
There are few things before you get started...
Prerequisites for integrating ZealiD:
- Have ZealiD app
- Receive your client_id and client_secret
- use HMAC_STRING generator to be able to generate hmac_string for Authentication header in your requests
- use HMAC_REQUEST to generate and send an authenticated request
Below you can find a couple of different scripts for generating hmac_string or for sending hmac requests
#!/bin/bash
if [ $# -eq 5 ]
then
export LC_ALL=C.UTF-8
clientid=$1
clientsecret=$2
uripart=$3
method=$4
payload=$5
timestamp=$(date +%s)
nonce=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 60)
base="https://core-hermes.zealid.com"
fulluri="$base$uripart"
reqstr="$method $uripart"
auth_string="$clientid$nonce$timestamp$reqstr$payload"
hmacsig=$(echo -n $auth_string | openssl dgst -binary -sha512 -hmac "$clientsecret" | base64)
hmac="client_id=\"$clientid\",ts=\"$timestamp\",nonce=\"$nonce\",signature=\"$hmacsig\""
echo "HMAC_STRING $hmac "
else
echo "Five input params required:"
echo "1 - client_id"
echo "2 - client_secret"
echo "3 - request_url - everything after https://hermes-dev.zealid.com"
echo "4 - request_method"
echo "5 - request_payload"
fi
import sys
import secrets
import time
import base64
import hmac
import json
def hmac_string(method, url, client, payload=None):
request_method = method
full_path = '/' + '/'.join(url.split('/')[3:])
client_id = client['id']
secret = client['secret']
nonce = secrets.token_urlsafe(32)
ts = int(time.time())
request_string = f"{request_method} {full_path}"
auth_string = f"{client_id}{nonce}{ts}{request_string}{payload if payload else ''}"
signature = base64.b64encode(
hmac.new(
secret.encode("utf-8"),
auth_string.encode("utf-8"),
"sha512"
).digest()
).decode("utf-8")
hmac_string = f'client_id="{client_id}",ts="{ts}",nonce="{nonce}",signature="{signature}"'
return hmac_string
if len(sys.argv) != 6:
print("Five input params required:")
print("1 - client_id")
print("2 - client_secret")
print("3 - request_url - everything after https://hermes-dev.zealid.com")
print("4 - request_method")
print("5 - request_payload")
else:
clientid = sys.argv[1]
clientsecret = sys.argv[2]
uripart = sys.argv[3]
method = sys.argv[4]
payload = sys.argv[5]
base_url = "https://core-hermes.zealid.com"
hmac_string = hmac_string(method,
f"{base_url}{uripart}",
{"id": clientid, "secret": clientsecret},
payload
)
print(f"HMAC_STRING: {hmac_string}")
#!/bin/bash
if [ $# -eq 5 ]
then
export LC_ALL=C.UTF-8
clientid=$1
clientsecret=$2
uripart=$3
method=$4
payload=$5
timestamp=$(date +%s)
nonce=$(LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | head -c 60)
base="https://core-hermes.zealid.com"
fulluri="$base$uripart"
reqstr="$method $uripart"
auth_string="$clientid$nonce$timestamp$reqstr$payload"
hmacsig=$(echo -n $auth_string | openssl dgst -binary -sha512 -hmac "$clientsecret" | base64)
hmac="client_id=\"$clientid\",ts=\"$timestamp\",nonce=\"$nonce\",signature=\"$hmacsig\""
curl $fulluri\
-X $method\
-H "Authorization: HMAC $hmac"\
-H "Content-Type: application/json"\
-d "$payload"
else
echo "Five input params required:"
echo "1 - client_id"
echo "2 - client_secret"
echo "3 - request_url - everything after https://hermes-dev.zealid.com"
echo "4 - request_method"
echo "5 - request_payload"
fi
import sys
import secrets
import time
import base64
import hmac
import json
import requests
def hmac_request(method, url, client, headers={}, payload=None):
request_method = method
full_path = '/' + '/'.join(url.split('/')[3:])
client_id = client['id']
secret = client['secret']
nonce = secrets.token_urlsafe(32)
ts = int(time.time())
request_string = f"{request_method} {full_path}"
session = requests.session()
request = requests.Request(method,
url,
headers=headers,
data=payload)
prepped = request.prepare()
payload = prepped.body
auth_string = f"{client_id}{nonce}{ts}{request_string}{payload if payload else ''}"
signature = base64.b64encode(
hmac.new(
secret.encode("utf-8"), auth_string.encode("utf-8"), "sha512"
).digest()
).decode("utf-8")
hmac_string = f'client_id="{client_id}",ts="{ts}",nonce="{nonce}",signature="{signature}"'
print(f"auth_string: {auth_string}")
print(f"hmac_string: {hmac_string}")
headers.update({"Authorization": f"HMAC {hmac_string}"})
prepped.headers.update(headers) # this is OK
response = session.send(prepped)
try:
result = response.json()
expect:
result = response.content
return result
if len(sys.argv) != 6:
print("Five input params required:")
print("1 - client_id")
print("2 - client_secret")
print("3 - request_url - everything after https://hermes-dev.zealid.com")
print("4 - request_method")
print("5 - request_payload")
else:
clientid = sys.argv[1]
clientsecret = sys.argv[2]
uripart = sys.argv[3]
method = sys.argv[4]
payload = sys.argv[5]
base_url = "https://core-hermes.zealid.com"
response = hmac_request(method,
f"{base_url}{uripart}",
{"id": clientid, "secret": clientsecret},
headers={"Content-type": "application/json"},
payload=payload
)
print(f"{response}")
How to use hmac_string generation script
How to:
- hmac_string generation script returns to you an hmac string that you need to include in the request Authentication header
- hmac_string generation requires the whole request information
- For more information about hmac and it's usage please refer to hmac guide
Be aware!
- For all examples we expect you to pass payload as JSON!
- Your request is expected to have Content-Type: application/json in headers!
- HMAC_STRING value can be different depending if json is sorted or not
- We recommend using hmac_string generators to generate hmac_string for API Reference tests
#For [get_token]
./hmac_string.sh "your_client_id" "your_client_secret" "/mediator/api/get_token" "POST" "{\"grant_type\":\"authorization_code\",\"code\":\"HERMES_CODE\",\"redirect_uri\":\"https://example.com\"}"
#For [get_data]
./hmac_string.sh "your_client_id" "your_client_secret" "/mediator/api/get_data" "POST" "{\"token\":\"HERMES_TOKEN\"}"
#For [get_documents]
./hmac_string.sh "your_client_id" "your_client_secret" "/mediator/api/user/CUSTOMER_ID/documents" "GET" ""
#For [upload]
./hmac_string.sh "your_client_id" "your_client_secret" "/mediator/api/upload/CUSTOMER_ID" "POST" "{\"content\":\"base64filecontent==\",\"digest\":\"sha1offile\",\"filename\":\"your_file_name.pdf\"}"
#For [upload_hash]
./hmac_string.sh "your_client_id" "your_client_secret" "/mediator/api/upload/hash/CUSTOMER_ID" "POST" "{\"content\":\"hashstring\",\"hashname\":\"your_hash_name\"}"
#for [sign QRcode]
./hmac_string.sh "your_client_id" "your_client_secret" "/mediator/api/sign" "POST" "{\"document_id\":\"DOCUMENT_ID\",\"title\":\"my_file.pdf\",\"redirect_url\":\"https://example.com\", \"customer_id\": \"CUSTOMER_ID\"}"
#For [get_token]
python3 hmac_string.py "your_client_id" "your_client_secret" "/mediator/api/get_token" "POST" "{\"grant_type\":\"authorization_code\",\"code\":\"YOUR_HERMES_CODE\",\"redirect_uri\":\"https://example.com\"}"
#For [get_data]
python3 hmac_string.py "your_client_id" "your_client_secret" "/mediator/api/get_data" "POST" "{\"token\":\"YOUR_HERMES_TOKEN\"}"
#For [get_documents]
python3 hmac_string.py "your_client_id" "your_client_secret" "/mediator/api/user/YOUR_CUSTOMER_ID/documents" "GET" ""
#For [upload]
python3 hmac_string.py "your_client_id" "your_client_secret" "/mediator/api/upload/YOUR_CUSTOMER_ID" "POST" "{\"content\":\"base64filecontent==\",\"digest\":\"sha1offile\",\"filename\":\"your_file_name.pdf\"}"
#For [upload_hash]
python3 hmac_string.py "your_client_id" "your_client_secret" "/mediator/api/upload/hash/CUSTOMER_ID" "POST" "{\"content\":\"hashstring\",\"hashname\":\"your_hash_name\"}"
#for [sign QRcode]
python3 hmac_string.py "your_client_id" "your_client_secret" "/mediator/api/sign" "POST" "{\"document_id\":\"YOUR_DOCUMENT_ID\",\"title\":\"my_file.pdf\",\"redirect_url\":\"https://example.com\", \"customer_id\": \"YOUR_CUSTOMER_ID\"}"
How to use HMAC request generation script
How to:
- HMAC request generation scripts accept input in the same format as hmac_string generators
- HMAC request generators actually executes HTTP(S) request with HMAC authentication
Be ware!
- For all examples we expect you to pass payload as JSON!
- HMAC_STRING value can be different depending if json is sorted or not
#for [get_token]
./hmac_curl.sh "your_client_id" "your_client_secret" "/mediator/api/get_token" "POST" "{\"grant_type\":\"authorization_code\",\"code\":\"HERMES_CODE\",\"redirect_uri\":\"https://example.com\"}"
#for [get_data]
./hmac_curl.sh "your_client_id" "your_client_secret" "/mediator/api/get_data" "POST" "{\"token\":\"HERMES_TOKEN\"}"
#for [get_documents]
./hmac_curl.sh "your_client_id" "your_client_secret" "/mediator/api/user/CUSTOMER_ID/documents" "GET" ""
#for [upload]
./hmac_curl.sh "your_client_id" "your_client_secret" "/mediator/api/upload/CUSTOMER_ID" "POST" "{\"content\":\"base64...\",\"digest\":\"sha1...\",\"filename\":\"your_file_name.pdf\"}"
#For [upload_hash]
./hmac_curl.sh "your_client_id" "your_client_secret" "/mediator/api/upload/hash/CUSTOMER_ID" "POST" "{\"content\":\"hashstring\",\"hashname\":\"your_hash_name\"}"
#for [sign QRcode]
./hmac_curl.sh "your_client_id" "your_client_secret" "/mediator/api/sign" "POST" "{\"document_id\":\"DOCUMENT_ID\",\"title\":\"my_file.pdf\",\"redirect_url\":\"https://example.com\", \"customer_id\": \"CUSTOMER_ID\"}"
#For [get_token]
python3 hmac_request.py "your_client_id" "your_client_secret" "/mediator/api/get_token" "POST" "{\"grant_type\":\"authorization_code\",\"code\":\"YOUR_HERMES_CODE\",\"redirect_uri\":\"https://example.com\"}"
#for [get_data]
python3 hmac_request.py "your_client_id" "your_client_secret" "/mediator/api/get_data" "POST" "{\"token\":\"YOUR_HERMES_TOKEN\"}"
#for [get_documents]
python3 hmac_request.py "your_client_id" "your_client_secret" "/mediator/api/user/YOUR_CUSTOMER_ID/documents" "GET" ""
#for [upload]
python3 hmac_request.py "your_client_id" "your_client_secret" "/mediator/api/upload/YOUR_CUSTOMER_ID" "POST" "{\"content\":\"base64...\",\"digest\":\"sha1...\",\"filename\":\"your_file_name.pdf\"}"
#For [upload_hash]
python3 hmac_request.py "your_client_id" "your_client_secret" "/mediator/api/upload/hash/CUSTOMER_ID" "POST" "{\"content\":\"hashstring\",\"hashname\":\"your_hash_name\"}"
#for [sign QRcode]
python3 hmac_request.py "your_client_id" "your_client_secret" "/mediator/api/sign" "POST" "{\"document_id\":\"YOUR_DOCUMENT_ID\",\"title\":\"my_file.pdf\",\"redirect_url\":\"https://example.com\", \"customer_id\": \"YOUR_CUSTOMER_ID\"}"
Retrieve your customer data and get ready for signing
To be able to upload, sign or retrieve documents or data, first of all, you need to authenticate yourself as a user
Prerequisites for actions with documents:
- Scan QR code with ZealiD app
- Retrieve your temporary HERMES_TOKEN
- Retrieve your personal data and customer_id
- Be aware - you will need this customer_id for actions with documents
Generating authentication QR code
How to:
- QR code scanning is initial step of your authentication which helps to map your identity with the help of your device
- To be able to scan QR code you need the ZealiD app and successfully pass onboarding steps
Be aware!
- your_client_id - The same client_id as you provide for HMAC authentication
- After scanning qrcode and successfully confirming your authentication request you will be redirected and you will receive HERMES_CODE as url parameter
- *Make sure you are targeting correct environment!
# NOTE: production environment
# Open in your browser:
curl https://core-hermes.zealid.com/mediator/web_embed/auth_link/start/hermes_orpheus/hermes_orpheus_provider/{your_client_id}
# NOTE: testing environment
# Open in your browser:
curl https://hermes-dev.zealid.com/mediator/web_embed/auth_link/start/hermes_orpheus_dev/hermes_orpheus_dev_provider/{your_client_id}


Steps:
1 - 2. Use the url provided above to GET a template with QR code
3 - 4. While QR code is on your screen - JS in browser is checking request status in server
5 - 7. Scan QR code with Your ZealiD App and confirm request with TouchiD or FaceiD
- After successful confirmation you will be redirected and in new url you can find code=HERMES_CODE -> This is the HERMES_CODE that you will have to provide in get_token request
Expected response:
https://core-hermes.zealid.com/mediator/web_embed/auth_link/success/OKQQJZuQQWsh-DclxhwZDdo_DCd7LOSaqinIIjA35Ms?code=hermes_code_xHVSIv-A...
You are ready!
Congratulations!
- You now have HERMES_CODE which you can use to finish your authentication process and start working with your documents
- For further actions please refer to any of these documentations:
- DATA API in detail documentation where you can find all API calls explained
- API reference if you are more experience user
- Or hmac_request examples in this guide if you want to jump directly on testing from your computer
Updated 5 months ago