Guides
/
Webhooks

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:

AttemptDelay
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.

eventTypeDescription
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:

StatusDescription
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:

StatusDescription
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:

StatusDescription
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.

Built with