Webhooks are events that enable you to monitor your account, including all objects such as orders, charges, sessions, etc.
You may either poll the API or receive webhooks at a specific URL.
Available Webhook Events
Session Events
Event | Description |
---|---|
session.created | Triggered when a session is created. |
session.consumer_connected | Triggered when a consumer is connected to a session. |
session.fi_account_connected | Triggered when a Financial Institution Account is connected to a session by the consumer. |
session.authorized | Triggered when a session is successfully authorized by the consumer. |
session.authorize_failed | Triggered when a session authorization failed. |
session.finalized | Triggered when an authorized session is converted into an order. |
Order Events
Event | Description |
---|---|
order.created | Triggered when an order is created. |
order.total_finalized | Triggered when there are changes to an order's amount before it can be charged. NOTE: This event is always triggered even if there are no changes to the order total. |
order.canceled | Triggered when an order is canceled. |
order.charged | Triggered when an order is charged/captured. |
Charge Events
Event | Description |
---|---|
charge.created | Triggered when a charge is created. |
charge.succeeded | Triggered when a charge is successful. |
charge.failed | Triggered when a charge attempt has failed. NOTE: For ACH transactions, a charge can trigger a charge.succeeded event before it triggers a charge.failed event due to an ACH return |
charge.retried | Triggered when a charge attempt is retried. |
Refund Events
Event | Description |
---|---|
refund.created | Triggered when a refund is initiated. |
refund.succeeded | Triggered when a refund is successful. |
refund.failed | Triggered when a refund has failed. NOTE: For ACH transactions, a refund can trigger a refund.succeeded event before it triggers a refund.failed event due to an ACH return |
Some API requests may cause multiple events to be created. For example, if you create a new order from a session, you will receive both an order.created
event and a session.finalized
event with respective payloads.
The data
field of the event payload contains a snapshot of the state of corresponding API resource at the time of event creation.
For example a session.xx
event will contain Session object in the data field and a charge.xx
event will contain a Charge object.
Example Event Payload
{
"event_id": "evt_RViwQ325voW3P4RXW4N8fv",
"event_created": "2021-11-30T15:27:54.630965+00:00",
"event_name": "session.created",
"version": "v1",
"data": {
"id": "sess_FmEXSJ3pqsbXQqJFd7bySK",
"create_date": "2021-11-30T15:27:54.627835+00:00",
"status": "started",
"organization_id": "org_mz8VKmRT5WJ78HJZKnvbK5",
"type": "consumer_checkout",
"total_amount": 1000,
"is_valid_consumer": false,
"is_valid_bank_account_selected": false,
"is_sufficient_funds": false,
"consent_text": "I authorize Swifter to debit my bank account and save my authorization for future use with Swifter.",
"fees": 100,
"track_number": "pv96xa"
}
}
Verifying signatures
When a new webhook subscription is created a unique secret key called signing_secret
is also created for it.
All events sent to the target endpoint is signed using the signing_secret with its corresponding signing_secret and provides you with X-Swifter-Signature and X-Swifter-Nonce to verify the authenticity of the payload
Example header
X-Swifter-Nonce 1638286074697
X-Swifter-Signature 1b5674fd304e77c8ce92fcf59d2ad1e587b60c5656f033296e52e88e33c805f3
Swifter generates signatures using HMAC with SHA-256 hash function.
Steps to Verify Signature
- Prepare the
signed_payload
by concatenating the value of headerX-Swifter-Nonce
,.
and the request body - Compute an HMAC with the SHA256 hash function. Use the endpoint’s
signing_secret
as the key, and use thesigned_payload
string as the message. - Compare the created signature to the value of
X-Swifter-Signature
from the request headers
Example Code to compute HMAC signature
key = signing_secret
nonce = headers['X-Swifter-Nonce']
separator = '.'
signed_payload = nonce + separator + raw_body
expected_signature = headers['X-Swifter-Signature']
computed_signature = hmac('sha256', signed_payload, key)
if computed_signature != expected_signature
throw SecurityError
end
import hashlib
import hmac
signing_secret = "super_secret_key".encode("utf-8")
body = "{...}"
nonce = "1638286074697"
separator = "."
signed_payload = f"{nonce}{separator}{body}"
# encode the payload to utf-8 bytes
signed_payload = signed_payload.encode("utf-8")
# now use the hmac.new function and the hexdigest method
computed_signature = hmac.new(signing_secret, signed_payload, hashlib.sha256).hexdigest()
# check if computed_signature equals the `X-Swifter-Signature` from request header
if computed_signature != expected_signature
Idempotency
There could be scenarios where your webhook endpoint might receive the same event multiple times. This is an expected behaviour.
You can identify duplicate events using event_id
field in the event payload. The event_id
field contains an identifier which is unique per event.