Documentation
Webhooks
Introduction
Webhooks allow you to receive real-time notifications of the completion events in the Pinwheel system such as Direct Deposit Switch and Direct Deposit Payment.
You can register a webhook by sending a POST request to the /v1/webhooks/
endpoint.
Event Handling
Webhook events are sent with headers to help you verify an event was sent by Pinwheel. They can also be used to ensure idempotency.
X-PINWHEEL-SIGNATURE: strX-TIMESTAMP: strX-PINWHEEL-WEBHOOK-UUID: str
Verifying Pinwheel is the sender
The X-PINWHEEL-SIGNATURE
header's value can be used to verify Pinwheel was the sender of the event. The signature is generated using HMAC-SHA256 on the payload object within the request body and the X-TIMESTAMP
header value in the form v1:{x-pinwheel-timestamp-value}:{request_body_as_str}
and signed with your API Key Secret.
# Pythonimport hmacimport hashlibsignature = request.headers.get('X-PINWHEEL-SIGNATURE')timestamp = request.headers.get('X-TIMESTAMP')payload = request.json()["payload"]sanitized_request_body_as_str = json.dumps(payload, separators=(",", ":"), ensure_ascii=False,).strip("\t\n\r")msg = f"v1:{timestamp}:{sanitized_request_body_as_str}"generated_hash = hmac.new(key='YOUR_API_SECRET'.encode('utf-8'),msg=msg,digestmode=hashlib.sha256).hexdigest())generated_signature = f"v1={generated_hash}"is_valid = (signature == generated_signature)
// Javascriptimport * as crypto from 'crypto-js';const signature = request.headers.get('X-PINWHEEL-SIGNATURE');const timestamp = request.headers.get('X-TIMESTAMP');const payload = request.json().payload;const message = `v1:${timestamp}:${JSON.stringify(payload)}`;const hash = crypto.HmacSHA256(message, 'YOUR_API_SECRET').toString();const generatedSignature = `v1=${hash}`;const isValid = (signature === generatedSignature)}
Handling duplicate events
The X-PINWHEEL-WEBHOOK-UUID
header can be used to guard against potential duplicate events to make your system idempotent.
Request body
Webhook request bodies are composed of two sections. The top-level section contains three keys. The payload section, contained in the payload
key, contains specific information about the event. See this section for the various payload
bodies for each event.
Top-Level
Key | Type | Description |
---|---|---|
event | string | Event type. See webhook events. |
webhook_id | string | Unique identifier for the object. |
payload | dict | Payload associated with event type. See webhook events for associated payload object. |
Example
{"event": "job_result","webhook_id": uuid,"payload": {...}}
Events and Associated Payloads
Below is a table of the event names and the associated inner payload
body that is returned within the webhook payload.
Event | Payload body |
---|---|
direct_deposit_payment.added | A direct_deposit_payment job object. See the job schema for details. |
direct_deposit_switch.added | A direct_deposit_switch job object. See the job schema for details. |