Current rollout note
Webhook URL management is available today. Before relying on live partner webhook events, confirm with Rivo that outbound delivery has been enabled for the event types you need.Manage webhook URLs
Webhook management uses the business dashboard JWT flow, not API-key signing.Create webhook
targetUrl must be a valid http or https URL. Duplicate URLs for the same business are rejected.
Example response:
List webhooks
Delete webhook
Delivery format
Every webhook is an HTTPPOST to your targetUrl with a JSON body in this envelope:
Headers:
2xx status once you have stored the event. Process it asynchronously if handling takes longer.
Events can arrive more than once and out of order. Deduplicate using the event name plus the resource reference (or id), and always treat the latest status you read from the API as the source of truth.
Verify the signature
Compute an HMAC-SHA512 of the raw request body using your webhooksecret and compare it with the x-webhook-signature header before trusting the payload.
Events
payment.created
Sent afterPOST /payments/initiate succeeds.
payment.completed
Sent when the checkout is paid in full.amountSettled is what reaches your balance after fee.
payment.failed
Sent when a checkout fails or expires before full payment.reason explains why.
payment_link.created
Sent afterPOST /payment-links succeeds. data is the payment link.
payment_link.paid
Sent when a payment is received on a payment link.data is the payment link, with the received payment under payment.
payment.sender is replaced by payment.cryptoSender with the sending address, and the payment includes network and transactionHash.
payment_link.expired
Sent when a payment link expires, including when you callPOST /payment-links/{id}/expire.
transfer.created
Sent afterPOST /transfers/ngn accepts and queues a transfer. data has the same shape as GET /transfers/ngn/{reference}.
transfer.completed
Sent when the recipient bank account has been paid.transfer.failed
Sent when the transfer cannot be completed.reason explains why. Debited funds are returned to your balance.
virtual-account.created
Sent when a customer virtual account is ready to receive funds.data has the same shape as the matching GET /virtual-accounts/... response, plus currency.
NGN account:
expiresAt.
USD account:
virtual-account.rejected
Sent when a virtual account request is rejected, for example when customer verification fails.reason explains why. You can retry with the same reference after correcting the customer details.
accountNumber, accountName and bankName set to null.
Testing webhooks on staging
On staging (https://sandbox-api.userivo.co), virtual accounts are simulated so you can test your webhook handling end to end:
- NGN accounts (
/virtual-accounts/ngn/temporaryand/virtual-accounts/ngn/permanent) are created instantly with dummy account details, andvirtual-account.createdis sent straight away. - USD accounts (
/virtual-accounts/usd) returnpending and under reviewas in production. About 3 seconds later the account is approved with dummy bank details andvirtual-account.createdis sent. - Use a
referencecontainingreject(for exampleref_reject_001) to simulate a rejection. NGN requests then return400immediately; USD requests still returnpending and under review. In both casesvirtual-account.rejectedis sent.
Security
Keep webhook secrets on your backend only. Verify thex-webhook-signature header before trusting a payload, and return a 2xx response only after your server accepts the event.
To rotate a webhook secret today, delete the webhook URL and create it again. Store the new secret on your backend before enabling event handling for that URL.
Supported IP allowlist
Supported IPs are configured from the business dashboard and apply to signed Rivo Business API-key requests. If no supported IPs are configured, signed API-key requests are accepted from any IP address after normal authentication and signature checks pass. Once at least one supported IP is configured, Rivo only accepts signed API-key requests from the configured IP addresses.Add supported IP
ipAddress must be a valid IPv4 or IPv6 address. Each business can configure up to 5 supported IP addresses.
Example response:
