Webhooks
Safepay Nordic uses webhooks to notify your application when an event happens in your account. They are useful for asynchronous events, e.g. when a payer initiates a transaction. When an event occurs, Safepay Nordic collects data about the event, creates an event notification and sends it to your webhook endpoint.
When to use webhooks
Some flows in Safepay Nordic happen asynchronously: at a later time and not directly in response to your code's execution. With those APIs, Safepay Nordic needs to notify your integration about changes to the state of an object so your integration can take subsequent steps.
What your webhook endpoint does depends on the event. For example:
- Marking an item as being sold when a payer completes a payment to escrow.
- Updating a user's profile when they have added a payout bank account.
Best practices for using webhooks
Review these best practices to ensure your webhooks remain secure and function seamlessly with your integration.
Event types
All events are sent to every webhook URL you have configured; you can't choose which events to receive. Respond with a 2xx status to events you don't use and ignore them.
The events and their payloads are described on the flow pages:
user.connected: Connectuser.bankaccount.connected,user.bankaccount.missing: Add bank accounttransaction.payment.paid,transaction.payment.failed,transaction.succeeded,transaction.cancelled: Checkout
Requirements and limitations
- Your notification URL should return a 2xx HTTP status code within 10 seconds. Any other response, or no response, is treated as a failed delivery and the notification is retried with exponential backoff.
- A notification is attempted at most 12 times:
| Attempt number | Time since last attempt | Time since initial notification* |
|---|---|---|
| 1 | - | - |
| 2 | 30 seconds | 30 seconds |
| 3 | 1 minute | 1.5 minutes |
| 4 | 2 minutes | 3.5 minutes |
| 5 | 4 minutes | 7.5 minutes |
| 6 | 8 minutes | 15.5 minutes |
| 7 | 16 minutes | 31.5 minutes |
| 8 | 32 minutes | 63.5 minutes |
| 9 | 64 minutes | 2 hours |
| 10 | 120 minutes | 4 hours |
| 11 | 120 minutes | 6 hours |
| 12 | 120 minutes | 8 hours |
* Approximate values, since each retry is scheduled after the previous delivery attempt has finished.
- Every attempt of the same notification has the same
webhookId. Use it to ignore notifications you have already processed.
- After all retries have been exhausted the notification is never sent again. Use the API to read the current state if you suspect you have missed a notification.
- There is no guarantee of the delivery order. Use
eventDate, or read the current state from the API, rather than relying on the order notifications arrive in.
Check the webhook signatures
All webhook notifications from Safepay Nordic include an x-safepay-signature header. Its value is an HMAC-SHA1 signature of your webhook's notification URL followed by the request body with all space characters removed, using your webhook signature key. You find the signature key, and can generate a new one, on the Webhook tab in the Safepay Nordic portal.
To validate a notification, compute the HMAC-SHA1 in your code and compare it to the signature you received. Use a constant-time comparison, so the check doesn't leak timing information. The hash is sent in standard base64 format RFC 4648 §4 (do not mistake with base64url format RFC 4648 §5).
Example pseudocode that generates the signature:
var signature = new HMACSHA1(signatureKey)
.computeHash(notificationUrl + notificationBody.replaceAll(" ", ""))
.toBase64();
Test webhooks
Call GET /v2/webhooks/examples to get example payloads for all webhook events. Use them to test how your endpoint parses and handles each event. The endpoint doesn't send anything to your webhook URL.
Create and manage webhook
You can view and manage webhooks in the Safepay Nordic portal.
When you create a webhook, the URL must use HTTPS and be unique per webhook.