Webhooks
Webhooks are a notification mechanism that allows platforms to listen for events that can occur asynchronously.
Before starting, you need to setup an endpoint at your server that accepts: post, put or patch.
If you need something for testing, you can use https://webhook.site/.
All webhooks are managed through the webhook endpoint:
/v1/webhooks
The receiver is determined based on the key that is used, either platform or entity.
Registering Webhooks
To register a webhook, please checkout the attached Postman collection.
Payload
Every webhook request includes the same envelope:
{
"id": "<event-uuid>",
"type": "<event-type>",
"created_at": "2026-01-01T00:00:00Z",
"secret_token": "<shared_secret>",
"account_name": "<receiver account name>",
"live": true,
"data": {}
}
The event metadata is also sent as HTTP headers:
X-Event-IDX-Event-TypeX-Event-Attempt-NumberX-Event-Secret
Platform Webhook Events
These events are available when registering webhooks using a Platform API key.
| Event | When It Fires | Purpose | data |
|---|---|---|---|
merchant_created | After a merchant is created via POST /v1/merchants | Sync new merchant onboarding into your platform systems | Merchant |
merchant_updated | After a merchant is updated via PUT /v1/merchants/:id | Keep merchant profile/settings in sync | Merchant |
merchant_semi_activated | When Moyasar changes merchant status to semi_active | Merchant is activated, but settlements are held (entity is put on hold) | Merchant |
merchant_activated | When Moyasar changes merchant status to active | Merchant is fully activated (hold removed), settlements can proceed | Merchant |
merchant_un_hold | When a previously-held merchant becomes active (fired after merchant_activated) | Explicit signal that a hold was removed and settlements can resume | Merchant |
merchant_review_failed | When Moyasar changes merchant status to missing_docs | Review failed due to missing/invalid documents; prompt you to update/resubmit docs | Merchant |
merchant_disabled | When Moyasar changes merchant status to disabled (also when moving to dormant) | Merchant is deactivated; payment processing/settlements are stopped | Merchant |
merchant_hold | When Moyasar changes merchant status to hold | Settlements are paused (e.g. investigation/chargebacks) | Merchant |
merchant_rejected | When Moyasar changes merchant status to rejected | Merchant was rejected; payment processing/settlements are stopped | Merchant |
balance_transferred | When a settlement transfer is completed and the recipient is notified | Notify the recipient (Entity or Platform) that a transfer settled | Transfer |
merchant_balance_transferred | When a settlement transfer is completed for an Entity that belongs to a Platform | Notify the Platform that one of its merchants received a transfer | Transfer |
Timeouts
The webhook client will timeout whenever one of the following durations are exceeded:
- Connect: 10 seconds
- Write: 5 seconds
- Read: 10 seconds
If your server takes more that 10 seconds to finish its job, please put the job on a queue and respond to the webhook client as soon as possible.
Webhook Lifecycle
When a webhook succeeds, an attempt will be logged and the Webhook Attempts log and it is done.
If a webhook fails, then Moyasar will retry the webhook event four more times, making it five attempts including the first one.
Here is the timing for the retries:
| Attempt Number | Delay Time |
|---|---|
| 1 | 60 seconds |
| 2 | 600 seconds = 10 minutes |
| 3 | 1800 seconds = 30 minutes |
| 4 | 3600 seconds = 1 hour |
Webhook Attempts Log
Moyasar servers will keep track of all webhook attempts for an arbitrary amount of time (they will be cleaned without any notice, they are used for development purposes and not for production).
To view webhook attempts (in descending order), make a get request to the following using the receiver key (platform or entity):
/v1/webhooks/attempts
Each attempts will have a result data field that indicates whether it succeeded or failed:
- success: the webhook was delivered successfully
- dns_error: cannot resolve hostname because of a DNS error
- connection_error: cannot establish a connection to the server
- connection_timeout: Connection timed out
- malformed_response: invalid response was returned
- tls_error: cannot establish a TLS connection
- response_timeout: request was sent but read (response) timed out
- response_error: the server did not return a
2xxresponse - invalid_url: invalid webhook URL