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

"session.created"
"session.consumer_connected"
"session.fi_account_connected"
"session.authorized"
"session.authorize_failed"
"session.finalized"

Order Events

"order.created"
"order.total_finalized"
"order.canceled"
"order.charged"

Charge Events

"charge.created"
"charge.succeeded"
"charge.failed"

When an event occurs, we create a new Event object. For example, when an Order is created, we create an order.created event; and when a Session is authorized by a customer we send a session.authorized event if it fails we create a session.authorize_failed event.

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.

The state of the API resource at the time of the change is embedded in the event's data field. For example a session.** event will contain Session in the data field and a charge.* event will contain a Charge*

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 Sparc Pay to debit my bank account and save my authorization for future use with Sparc Pay.",
    "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 X-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 the signed_payload string as the message.

Compare the created signature to the X-Swifter-Signature from the request headers

Example Code to compute HMAC signature

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
assert computed_signature == expected_signature