1. Introduction to webhooks
Numeral uses webhooks to notify your application when an event is created. Webhooks are particularly helpful for asynchronous events, such as a payment being executed by the bank or an account statement being received from a bank.
Events are created when an object is created or updated, either by a user using the API or the dashboard or by Numeral. An update can be the update of any attribute, such as a status, a date, or any other data.
For each event, Numeral will send a POST
request to your API endpoint in JSON format. This API request contains an event
object.
2. Event topics and types
Events have a topic
and a type
. The topic
corresponds to the type of the object that has been created or updated. The type
corresponds to the exact update on the object.
Topic | Lifecycle events |
---|---|
payment_order | Payment order lifecycle events |
incoming_payment | Incoming payment lifecycle events |
return | Return lifecycle events |
return_request | Return request lifecycle events |
inquiry | Inquiry lifecycle events |
balance | Balance lifecycle events |
transaction | Transaction lifecycle events |
counterparty | Counterparty lifecycle events |
counterparty_account | Counterparty account lifecycle events |
virtual_account | Virtual account lifecycle events |
reconciliation | Reconciliation lifecycle events |
expected_payment | Expected payment lifecycle events |
payment_capture | Payment capture lifecycle events |
file | File lifecycle events |
event | Event lifecycle events |
3. Event structure
{
"id": "35bb6411-290d-478e-a478-2f84146c2ddf",
"object": "event",
"topic": "payment_order",
"type": "executed",
"related_object_id": "25102c0f-fc25-44e7-9402-cae6d61ad47f",
"related_object_type": "payment_order",
"status": "delivered",
"status_details": "",
"created_at": "2023-02-01T17:13:15.087995Z",
"data": {
"id": "25102c0f-fc25-44e7-9402-cae6d61ad47f",
"idempotency_key": "",
"object": "payment_order",
"connected_account_id": "a0d22970-3b30-44c9-a5ea-fac6707f6b80",
"connected_account": "a0d22970-3b30-44c9-a5ea-fac6707f6b80",
"type": "sepa",
"direction": "credit",
"amount": 75000,
"currency": "EUR",
"reference": "Invoice ID 89230927",
"value_date": "2023-02-01",
"originating_account": {
"bank_code": "SOGEFRPP",
"holder_name": "SoftwareCo",
"account_number": "FR7601234567890627967100010",
"holder_address": {
"line_1": "1, rue de l'Abondance",
"line_2": "",
"postal_code": "69003",
"city": "Lyon",
"region_state": "",
"country": "FR"
}
},
"receiving_account_id": "",
"receiving_account": {
"bank_code": "BNPAFRPPXXX",
"holder_name": "PartnerCo",
"account_number": "FR7601234567891127967100082",
"holder_address": {
"line_1": "1, rue de la Bourse",
"line_2": "",
"postal_code": "59000",
"city": "Lille",
"region_state": "",
"country": "FR"
}
},
"direct_debit_mandate": null,
"status": "executed",
"status_details": "",
"auto_approval": false,
"reconciliation_status": "unreconciled",
"reconciled_amount": 0,
"metadata": {},
"bank_data": {
"file_id": "b251f19a-55a4-459a-8fb0-8dc2b72443d4",
"message_id": "230201030031Fzmc",
"end_to_end_id": "25102c0ffc2544e79402cae6d61ad47f",
"transaction_id": "25102c0ffc2544e79402cae6d61ad47f",
"original_instruction_id": "25102c0ffc2544e79402cae6d61ad47f"
},
"created_at": "2023-02-01T17:10:00.248706Z",
},
}
4. Registering an API endpoint
In order to use webhooks, you should create an API endpoint on your server and register it using the Numeral's dashboard. To register an API endpoint, go to Developers > Webhooks > Add webhook.
By default, all event topics and types will be sent to your API endpoint. If you would like to only receive specific event topics or types, please get in touch at [email protected].
5. Event delivery modes
Webhook support multiple event delivery modes.
Delivery mode | Order guaranteed | Throughput | Default delivery mode |
---|---|---|---|
Individual events | Yes | Base | ✅ |
Batched events beta | Yes | High | - |
Parallel individual events beta | No | High | - |
Parallel batched events beta | No | Highest | - |
The order is defined as the order of events for a given object, based on its lifecycle.
To guarantee order, Numeral waits for the acknowledgment of receipt of an event before sending the next event. This means, for instance, that a payment_order.processing
event will always be sent before a payment_order.sent
event, as per the payment order lifecycle.
When events are sent in parallel, Numeral does not wait for the acknowledgment of receipt of an event before sending the next event. As a result, order is not guaranteed. As an example, payment_order.sent
might be delivered before payment_order.processing
event.
Contact us at [email protected] if you would like to receive events other than as individual events.
6. Acknowledgment of receipt
To acknowledge the receipt of an event, your API endpoint must respond with a 2xx
HTTP status code to Numeral within 5 seconds.
To guarantee that your API endpoint receives the events in the correct order:
- The next event is sent once the previous event has been received
- Events are delivered steadily over time one by one
- The processing of events stops at the first failed event
The resent failed events feature should be used to resend failed events and resume the sending and delivery of events.
7. Exponential back-off strategy
If your API endpoint takes longer to respond or returns an HTTP status code different from 2xx
, the event will be set to pending_retry
status and re-sent up to 5 times during a ~2.8-hour period using an exponential back-off strategy. The event is set to failed
status after 6 unsuccessful deliveries.
8. Webhook event idempotency
In order to guarantee that each event is unique, every webhook payload includes an idempotency_key
attribute within its JSON body. Additionally, when a webhook is sent individually, the TX-Webhook-ID
HTTP header is set to the value of the idempotency_key
.
The idempotency key is unique for each event / webhook combination. Therefore, if an event is sent multiple times, it will always carry the same idempotency key value, avoiding duplication errors.
9. Verifying webhooks
Webhooks sent by Numeral are signed so that you check that they have not been modified in transit and verify their authenticity. They also originate from a limited list of IPs. Check our dedicated guide to learn how to verify webhooks.