Webhooks enable real-time notifications when transaction statuses change.
Overview
The Revio API allows you to:
- Configure webhook URLs for different event types
- Receive real-time callbacks when collections or payments change status
- Test webhook integrations in the sandbox environment
There is no limit to the number of webhooks you can configure.
Callback Types
| Type | Description |
|---|---|
EFT_COLLECTION | EFT debit order collection status changes |
DEBICHECK_COLLECTION | DebiCheck collection status changes |
DEBICHECK_MANDATE | DebiCheck mandate status changes |
EFT_PAYMENT | EFT payment status changes |
Step 1: Create Callback URL
Register a URL to receive webhook notifications.
Endpoint
POST https://api.revio.co.za/v2/clientcallbackurl/Request
curl -X POST https://dev.api.revio.co.za/v2/clientcallbackurl/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"clientId": 109,
"url": "https://your-server.com/webhooks/revio",
"callbackType": "EFT_COLLECTION",
"callbackVersion": "V2"
}'Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
clientId | integer | Yes | Your client ID (from merchant profile createdByClient) |
url | string | Yes | HTTPS URL to receive callbacks |
callbackType | string | Yes | Event type to subscribe to |
callbackVersion | string | Yes | Callback version (V2 recommended) |
Response
{
"id": "callback-url-123",
"clientId": 109,
"url": "https://your-server.com/webhooks/revio",
"callbackType": "EFT_COLLECTION",
"callbackVersion": "V2"
}Register Multiple Callback Types
Create separate callback URLs for each event type:
# EFT Collections
curl -X POST https://dev.api.revio.co.za/v2/clientcallbackurl/ \
-d '{"clientId": 109, "url": "https://...", "callbackType": "EFT_COLLECTION", "callbackVersion": "V2"}'
# DebiCheck Collections
curl -X POST https://dev.api.revio.co.za/v2/clientcallbackurl/ \
-d '{"clientId": 109, "url": "https://...", "callbackType": "DEBICHECK_COLLECTION", "callbackVersion": "V2"}'
# DebiCheck Mandates
curl -X POST https://dev.api.revio.co.za/v2/clientcallbackurl/ \
-d '{"clientId": 109, "url": "https://...", "callbackType": "DEBICHECK_MANDATE", "callbackVersion": "V2"}'
# EFT Payments
curl -X POST https://dev.api.revio.co.za/v2/clientcallbackurl/ \
-d '{"clientId": 109, "url": "https://...", "callbackType": "EFT_PAYMENT", "callbackVersion": "V2"}'Step 2: Trigger Callback Event
Trigger a callback for a specific collection (useful for re-sending notifications).
Endpoint
POST https://api.revio.co.za/v2/callback/collection/eft/{collectionId}/Request
curl -X POST https://dev.api.revio.co.za/v2/callback/collection/eft/63d94be3-1faf-428b-89f3-bc5271be8015/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"collectionStatus": "UNPAID",
"callbackVersion": "V2"
}'This sends the current collection status to your configured callback URL.
Step 3: Test Callback (Sandbox)
Simulate callback events to test your webhook handler without affecting actual transactions.
Endpoint
POST https://api.revio.co.za/v2/callback/test/collection/eft/{collectionId}/Request
curl -X POST https://dev.api.revio.co.za/v2/callback/test/collection/eft/63d94be3-1faf-428b-89f3-bc5271be8015/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"collectionStatus": "UNPAID",
"callbackVersion": "V2"
}'Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
collectionStatus | string | Yes | Status to simulate |
callbackVersion | string | Yes | Callback version |
overrideUrl | string | No | Send to different URL for testing |
Override URL Example
Send test callback to a different URL:
{
"overrideUrl": "https://webhook.site/your-test-id",
"collectionStatus": "COMPLETED",
"callbackVersion": "V2"
}Callback Payload
When a status change occurs, Revio sends a POST request to your webhook URL.
EFT Collection Callback
{
"id": "63d94be3-1faf-428b-89f3-bc5271be8015",
"type": "EFT_COLLECTION",
"status": "COMPLETED",
"mandateId": "8f4a6b0f-fa9b-4f45-8e19-b75c1a70432a",
"contractReference": "CONTRACT001",
"amountCents": 10000,
"collectionDate": "2024-02-15T00:00:00.000Z",
"statementId": "stmt_12345",
"timestamp": "2024-02-15T14:30:00.000Z"
}DebiCheck Mandate Callback
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"type": "DEBICHECK_MANDATE",
"status": "COMPLETED",
"contractReference": "DC001",
"authenticationType": "REALTIME",
"timestamp": "2024-02-15T14:30:00.000Z"
}DebiCheck Collection Callback
{
"id": "coll-123-456-789",
"type": "DEBICHECK_COLLECTION",
"status": "COMPLETED",
"mandateId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"amountCents": 10000,
"timestamp": "2024-02-15T14:30:00.000Z"
}Handling Webhooks
Webhook Handler Example (Node.js)
const express = require('express');
const app = express();
app.use(express.json());
app.post('/webhooks/revio', (req, res) => {
const event = req.body;
console.log('Received webhook:', event.type, event.status);
switch (event.type) {
case 'EFT_COLLECTION':
handleEftCollection(event);
break;
case 'DEBICHECK_COLLECTION':
handleDebicheckCollection(event);
break;
case 'DEBICHECK_MANDATE':
handleDebicheckMandate(event);
break;
case 'EFT_PAYMENT':
handleEftPayment(event);
break;
}
// Always respond with 200 OK
res.status(200).send('OK');
});
function handleEftCollection(event) {
if (event.status === 'COMPLETED') {
// Mark payment as successful in your system
} else if (event.status === 'UNPAID') {
// Handle failed collection
}
}Best Practices
- Respond quickly: Return 200 OK within 5 seconds
- Process asynchronously: Queue events for background processing
- Handle duplicates: Implement idempotency using the event ID
- Do not trust the payload: callbacks are unsigned, so re-read state from the relevant
/statusendpoint before acting — see Webhook Security below - Log everything: Keep detailed logs for debugging
- Retry handling: Handle the same event being sent multiple times
Webhook Security
Callbacks on this API are not signed. There is no signature header and no public key, so a callback cannot be authenticated from its content. Anyone who learns your callback URL can post to it. Design on that basis:
- Treat the payload as a prompt, not as truth. On receiving a callback, call the relevant
/statusendpoint —/v2/mandate/{type}/{id}/status,/v2/collection/{type}/{id}/statusor/v2/payment/eft/{id}/status— and act on the authoritative response. Never move money or change state on the basis of callback values alone. - Keep the URL unguessable and treat it as a secret: a long random path segment, rotated if it is ever exposed in a log or a support ticket.
- Reconcile independently. The
/v2/event/*endpoints are polled by you over an authenticated connection, so they are the trustworthy basis for reconciliation.
The card APIs do sign their callbacks, with an X-Signature header over an RSA signature. That mechanism does not exist here — do not carry the assumption across between the two.
URL Requirements
- Must use HTTPS
- Must be publicly accessible
- Should respond within 5 seconds
Recommendations
- Use a unique path: Include a secret in your webhook URL
- Validate payloads: Check expected fields are present
- Monitor failures: Alert on repeated delivery failures
Testing Tools
Use these services to test webhooks during development:
- Webhook.site - Free webhook testing
- RequestBin - Inspect webhook payloads
- ngrok - Expose local servers
Example with Webhook.site
- Go to webhook.site and copy your unique URL
- Register it as your callback URL:
curl -X POST https://dev.api.revio.co.za/v2/clientcallbackurl/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"clientId": 109,
"url": "https://webhook.site/your-unique-id",
"callbackType": "EFT_COLLECTION",
"callbackVersion": "V2"
}'- Trigger a test callback to see the payload
Troubleshooting
Common Issues
| Issue | Cause | Solution |
|---|---|---|
| No callbacks received | URL not registered | Verify callback URL configuration |
| 404 errors | Wrong endpoint | Check your webhook handler path |
| Timeout errors | Slow processing | Return 200 immediately, process async |
| Missing events | Wrong callback type | Register for correct event types |
Verify Callback Registration
Get your client ID from merchant profile:
curl -X GET https://dev.api.revio.co.za/v2/merchantprofile/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"The createdByClient field is your client ID for webhook registration.