Table of contents

Webhooks

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

TypeDescription
EFT_COLLECTIONEFT debit order collection status changes
DEBICHECK_COLLECTIONDebiCheck collection status changes
DEBICHECK_MANDATEDebiCheck mandate status changes
EFT_PAYMENTEFT payment status changes

‍

Step 1: Create Callback URL

Register a URL to receive webhook notifications.

‍

Endpoint

POST /v2/clientcallbackurl/

‍

Request

BASH

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

FieldTypeRequiredDescription
clientIdintegerYesYour client ID (from merchant profile createdByClient)
urlstringYesHTTPS URL to receive callbacks
callbackTypestringYesEvent type to subscribe to
callbackVersionstringYesCallback version (V2 recommended)

‍

Response

JSON

{
  "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:

‍

BASH

# 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 /v2/callback/collection/eft/{collectionId}/

‍

Request

BASH

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 /v2/callback/test/collection/eft/{collectionId}/

‍

Request

BASH

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

FieldTypeRequiredDescription
collectionStatusstringYesStatus to simulate
callbackVersionstringYesCallback version
overrideUrlstringNoSend to different URL for testing

‍

Override URL Example

Send test callback to a different URL:

‍

JSON

{
  "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

JSON

{
  "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

JSON

{
  "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

JSON

{
  "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)

JSX

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

  1. Respond quickly: Return 200 OK within 5 seconds
  2. Process asynchronously: Queue events for background processing
  3. Handle duplicates: Implement idempotency using the event ID
  4. Do not trust the payload: callbacks are unsigned, so re-read state from the relevant /status endpoint before acting — see Webhook Security below
  5. Log everything: Keep detailed logs for debugging
  6. 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:

  1. Treat the payload as a prompt, not as truth. On receiving a callback, call the relevant /status endpoint — /v2/mandate/{type}/{id}/status, /v2/collection/{type}/{id}/status or /v2/payment/eft/{id}/status — and act on the authoritative response. Never move money or change state on the basis of callback values alone.
  2. 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.
  3. 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

  1. Use a unique path: Include a secret in your webhook URL
  2. Validate payloads: Check expected fields are present
  3. Monitor failures: Alert on repeated delivery failures

‍

Testing Tools

Use these services to test webhooks during development:

‍

Example with Webhook.site

  1. Go to webhook.site and copy your unique URL
  2. Register it as your callback URL:

‍

BASH

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"
  }'

‍

  1. Trigger a test callback to see the payload

‍

Troubleshooting

Common Issues

IssueCauseSolution
No callbacks receivedURL not registeredVerify callback URL configuration
404 errorsWrong endpointCheck your webhook handler path
Timeout errorsSlow processingReturn 200 immediately, process async
Missing eventsWrong callback typeRegister for correct event types

‍

Verify Callback Registration

Get your client ID from merchant profile:

‍

BASH

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.