Integrations
Python
Server-side steps in Python.
Prerequisites
- A current Python with the
cryptographyandrequestspackages. - The secret key of the scenario and a permanent API token, read from environment variables. Never put them in browser code or in a repository.
- The API address provided with your access.
The call sequence
- Your server encrypts the raw client key with the secret key of the scenario.
- Your page opens the widget with the scenario identifier and the encrypted client key.
- The user completes the steps in the widget.
- Your server learns of the result from the
SESSION_COMPLETEwebhook, or reads session status. - Your server decides on the customer from the server-side status.
Encrypt the client key
The secret key of the scenario never leaves your server. See working with clientKey for the algorithm.
import base64
import hashlib
import os
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
def encrypt_client_key(client_key_raw: str, secret: str) -> str:
# First 32 characters of the SHA-256 hash of the secret, written as hex.
key = hashlib.sha256(secret.encode()).hexdigest()[:32].encode()
iv = os.urandom(16)
padder = padding.PKCS7(128).padder()
data = padder.update(client_key_raw.encode()) + padder.finalize()
encryptor = Cipher(algorithms.AES(key), modes.CBC(iv)).encryptor()
ciphertext = encryptor.update(data) + encryptor.finalize()
return base64.b64encode(iv + ciphertext).decode() # the clientKey for the widget
Store the raw value with your user or order, so that you can match the result later.
Create a session and read it back
import os
import requests
API = os.environ["API_BASE_URL"]
def create_session() -> dict:
reply = requests.post(f"{API}/kyc/session/create", json={
"token": os.environ["API_TOKEN"], # permanent API token
"schemaId": os.environ["SCENARIO_ID"], # scenario identifier
})
body = reply.json()
if "sessionId" not in body:
# A failure arrives as a body with status "error" or "failed".
raise RuntimeError(f"session was not created: {body.get('status')}")
return body # body["status"] is the session status, "idle"
def session_status(session_id: str) -> dict:
reply = requests.post(f"{API}/kyc/session/status", json={
"token": os.environ["API_TOKEN"],
"sessionId": session_id,
})
return reply.json() # branch on body["status"]
Branch on status, never on message text. See response format and errors and session statuses.
Ready-made scripts
The Python examples show authorization with a dashboard token and with a JWT, and downloading the images of a session.
Troubleshooting
| Symptom | What to check |
|---|---|
| The widget does not open | The domain is in the allowed domains, the page is on HTTPS, and the widget is not inside a cross-origin iframe. See installation. |
| The widget reports that decryption failed | The client key was not encrypted, or a different secret key was used, or the string was cut. See working with clientKey. |
| A call returns success but the body has an error | Branch on the status field of the body. See response format and errors. |
| The result never reaches your server | Check the callback URL in the scenario. See webhooks. |