Webhooks
Receive real-time notifications for payments, disbursements, KYC, and tax compliance events
Vivamo sends webhooks at each stage of a payment or disbursement, when a customer's KYC status changes, and when tax compliance actions (W-9) are required or completed. Webhooks are the most reliable way to track transaction outcomes, especially for asynchronous payment methods like bank transfers.
Registering a webhook
Register your webhook endpoint using the API:
When a webhook is created, Vivamo generates a unique secret key for HMAC signature verification. This key is returned in the creation response — store it securely, as it cannot be retrieved again.
You can also list, update, and delete your registered webhooks.
Updating a webhook
Use PATCH /v1/operators/webhooks/{webhookId} to update a webhook's URL, status, event types, or custom headers without rotating the HMAC secret key. If you need to rotate the secret, delete the webhook and create a new one.
Duplicate webhooks are not allowed. If another webhook already exists with the same URL and overlapping event types, the request will be rejected with a 409 status.
Webhook authentication
Every webhook includes an HMAC-SHA512 signature in the signature HTTP header. This lets you verify that the payload came from Vivamo and was not tampered with.
Verifying the signature
The signature is generated by signing the JSON request body with your webhook's secret key using HMAC-SHA512:
Custom headers
In addition to the HMAC signature, any custom headers you provided during webhook registration are included with every delivery. You can use these as an extra layer of verification (e.g. a pre-shared key).
Retries and responding
Return a 200 status code from your webhook endpoint to acknowledge receipt. If your server returns any other status (or doesn't respond), Vivamo retries delivery up to 5 times with increasing delays:
| Attempt | Delay |
|---|---|
1st retry | 1 minute |
2nd retry | 2 minutes |
3rd retry | 3 minutes |
4th retry | 4 minutes |
5th retry | 5 minutes |
After 5 failed attempts, the webhook is marked as failed. Undelivered webhooks are retained for 24 hours.
Event types
Every webhook payload includes an eventType field that identifies the category of event. Use this field to route incoming webhooks to the appropriate handler.
| eventType | Description |
|---|---|
transaction | A payment or disbursement status change. Use the transactionType field to distinguish between "payment" and "disbursement". |
kyc_verification | A customer's KYC verification status has changed. |
customer_w9_required | A customer needs to complete a W-9 form before disbursements can proceed. Includes a w9CaptureUrl for the form if you wish to present this (not required). |
customer_w9_completed | A customer has successfully submitted their W-9 form. |
Sample Webhook Payloads
Payment results
Payment webhooks use the same structure regardless of payment method. The status field can take the following values:
| Status | Description |
|---|---|
success | The payment completed successfully. |
failed | The payment did not complete. A subStatus will be included with the reason from the gateway or processor (e.g. "Insufficient balance", "Invalid CVV", "AVS failure"). |
declined | The payment was declined by the bank or processor. Specific to pay-by-bank methods that distinguish a decline from a generic failure. |
voided | A previously authorized payment was voided before settlement. |
refunded | A previously settled payment was refunded. |
Success
Failed
Disbursements
Disbursements emit a webhook at every lifecycle transition. The status field tells you which transition occurred:
| Status | Description |
|---|---|
pending-validation | A new disbursement was created and is awaiting your decision via Proceed With Disbursement. |
approved | You approved the disbursement ( allow=true); processor work is in progress. |
rejected | You rejected the disbursement ( allow=false). Terminal — the disbursement is never sent to a processor. |
success | The processor confirmed the disbursement was sent. Terminal. |
failed | The processor returned an error during processing. A subStatus field is included with the reason. Terminal. |
declined | The processor reached the bank or network and got an explicit decline (specific to pay-by-bank). Terminal. |
rejected, failed, and declined are distinct terminal states: rejected reflects your own decision and never reaches a processor, failed indicates a processor-side error during processing, and declined indicates the processor reached the bank/network and was told no. Each fires its own webhook.
The webhook status of approved corresponds to a persisted disbursement status of pending on the disbursement record itself (as returned by Get Disbursement Intent Status and described in the OpenAPI Disbursement schema). The webhook uses approved to mirror rejected and make the operator-decision event unambiguous; the persisted status remains pending because the disbursement is now awaiting processor work.
Creation
Approved
Sent when you approve the disbursement via Proceed With Disbursement with allow=true. The disbursement is now being processed; expect a terminal success, failed, or declined webhook to follow.
Rejected
Sent when you reject the disbursement via Proceed With Disbursement with allow=false. The disbursement is not sent to a processor. Terminal.
Result: Success
Result: Failed
Result: Declined
Customer KYC verification status change
KYC verification results are sent as webhooks when a customer's status changes. See the KYC Verification guide for more detail.
Possible status values are:
| Status | Description |
|---|---|
verified | The verification was successful. |
under_review | Manual review is required. |
rejected | The verification failed. The reason field will provide more details on the failure. |
Verified payload:
Rejected payload:
Customer W-9 tax compliance
W-9 webhooks are sent when a customer needs to complete tax documentation for disbursements, and when they have successfully submitted their form. These events only fire for operators with personal tax reporting enabled.
W-9 required:
Sent when a customer attempts a disbursement but has not yet completed their W-9. The w9CaptureUrl is a one-time link for the customer to fill out the form. Handling this is not required on your end, but you can choose to present the link to the customer to streamline the process.
Warning: The w9CaptureUrl will expire, so it is not advised that this is stored.
W-9 completed:
Sent when a customer has successfully submitted their W-9 form.