Lithic transaction webhooks are used to receive advice messages. Advice messages require only a response code 200 and do not require a response body. If this isn't received (e.g., if the client backend is offline), Lithic will continually attempt to retransmit the message using exponential backoff (doubling the time between messages each iteration) until the backoff period exceeds 24 hours.
If transaction webhooks are enabled, we'll send an HTTP
POST request to a user-specified url (in the account settings page) whenever a transaction lifecycle event occurs. We recommend responding to transactions webhooks with a 200 at time of receipt. If there is no response or a non-200 response, Lithic will retry sending the webhook. Retries are attempted with exponential backoff, starting with the first retry 5 minutes after the webhook and ending when the next attempt would be over a day.
In sandbox, users can create a transaction webhook by adding a URL on the account settings page of their Lithic account. After logging in, use the dropdown and select Account. On the Account Settings page under Enable API, select Enable Sandbox Webhook and enter a URL.
Transaction Events are generated for the following actions:
|Authorization||The API sends an event for all approvals. Decline events are available with API Issuing accounts|
|Auth Advice||Transaction was declined by an upstream switch or a previous authorization's amount is being adjusted|
|Void||Previous pending authorization is voided|
|Clearing||Clearing for an existing, pending authorization|
|Return||Credit — value is pushed onto card|
To verify that the request is legitimate, you may generate an HMAC of the transaction object and compare it with the one included in the
X-Lithic-HMAC request header.
See below for an example Python 3 implementation of verifying a webhook request.
import base64 import hashlib import hmac import json def to_json_str(json_object): return json.dumps(json_object, sort_keys=True, separators=(',', ':')) def hmac_signature(key, msg): hmac_buffer = hmac.new( key=bytes(key, 'utf-8'), msg=bytes(msg, 'utf-8'), digestmod=hashlib.sha256 ) return base64.b64encode(hmac_buffer.digest()).decode('utf-8') def request_is_from_lithic(api_key, transaction, request_headers): request_hmac = request_headers["X-Lithic-HMAC"] data_hmac = hmac_signature(api_key, to_json_str(transaction)) return hmac.compare_digest(request_hmac, data_hmac)
Please note that the JSON we generate the HMAC from has no extra whitespace, uses all double quotes
"" for strings, and sorts the key-value pairs in all JSON objects by key alphabetically.
The request payload will contain a Transaction object.
Updated 14 days ago