EFT debit orders (standard debit orders) enable merchants to collect funds from customer bank accounts with written, electronic, or voice-recorded authorisation.
Overview
EFT debit orders are cost-efficient payment instruments for collecting recurring revenue. The process involves:
- Create a Mandate: Obtain and store customer authorisation
- Create Collections: Submit collection instructions against the mandate
- Monitor Status: Track collection results and handle failures
Service Types
|Service Type|Description|Settlement|
|---|---|---|
|`SAMEDAY`|Processed and settled same day|Same day|
|`ONEDAY`|Processed within one business day|Next business day|
|`TWODAY`|Processed within two business days|Two business days|
Mandates
A mandate represents the customer's authorisation to debit their account.
Create EFT Mandate
Endpoint
POST /v2/mandate/eft/
Request
BASH
curl -X POST https://dev.api.revio.co.za/v2/mandate/eft/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"defaultServiceType": "ONEDAY",
"profileCode": "TEST1",
"abbreviatedName": "TESTMERCH1",
"contractReference": "CONTRACT001",
"debtor": {
"accountNumber": "010553922",
"accountType": "CURRENT",
"bank": "ABSA",
"branchCode": "632005",
"firstName": "John",
"lastName": "Smith",
"identification": {
"emailAddress": "john@example.com",
"idNumber": "2001014800086",
"phoneNumber": "+27-123456789",
"passportNumber": ""
}
},
"creditor": {
"accountNumber": "12345678",
"accountType": "CURRENT",
"branchCode": "051001",
"name": "TEST MERCHANT 1",
"bank": "STANDARDBANK",
"phoneNumber": "+27-615333440",
"emailAddress": "merchant@test.com"
},
"releaseDate": "2024-12-31T00:00:00.000Z",
"frequency": "MONTHLY",
"collectionDay": 15,
"amountCents": 10000,
"currency": "ZAR",
"entryClass": "21",
"verifyAccount": false
}'
Request Fields
|Field|Type|Required|Description|
|---|---|---|---|
|`defaultServiceType`|string|Yes|Default service type: `SAMEDAY`, `ONEDAY`, `TWODAY`|
|`profileCode`|string|Yes|Your merchant profile code|
|`abbreviatedName`|string|Yes|Your PASA-registered abbreviated name|
|`contractReference`|string|Yes|Unique contract reference (max 14 characters)|
|`externalReference`|string|No|Your external reference ID (must be unique)|
|`debtor`|object|Yes|Customer (payer) details|
|`creditor`|object|Yes|Merchant (payee) details|
|`ultimateCreditor`|object|No|Split payment recipient (if required)|
|`releaseDate`|string|No|Date when mandate becomes active|
|`frequency`|string|Yes|Collection frequency|
|`collectionDay`|integer|Yes|Day of month for collections (1-31)|
|`amountCents`|integer|Yes|Collection amount in cents|
|`currency`|string|Yes|Currency code (`ZAR`)|
|`entryClass`|string|Yes|Always `21`|
|`verifyAccount`|boolean|No|Perform bank account verification|
Debtor Object
|Field|Type|Required|Description|
|---|---|---|---|
|`accountNumber`|string|Yes|Customer bank account number|
|`accountType`|string|Yes|Account type: `CURRENT`, `SAVINGS`, `TRANSMISSION`|
|`bank`|string|Yes|Bank name (uppercase, one word)|
|`branchCode`|string|Yes|Bank branch code|
|`firstName`|string|Yes|Customer first name|
|`lastName`|string|Yes|Customer last name|
|`identification.emailAddress`|string|Yes|Customer email|
|`identification.idNumber`|string|Yes|SA ID number|
|`identification.phoneNumber`|string|Yes|Phone number (format: `+27-XXXXXXXXX`)|
|`identification.passportNumber`|string|No|Passport number (if no ID)|
Creditor Object
|Field|Type|Required|Description|
|---|---|---|---|
|`accountNumber`|string|Yes|Your settlement account number|
|`accountType`|string|Yes|Account type|
|`branchCode`|string|Yes|Your bank branch code|
|`name`|string|Yes|Your registered merchant name|
|`bank`|string|Yes|Your bank name|
|`phoneNumber`|string|Yes|Your contact number|
|`emailAddress`|string|Yes|Your email address|
Frequency Values
|Value|Description|
|---|---|
|`WEEKLY`|Every week|
|`MONTHLY`|Every month|
|`QUARTERLY`|Every 3 months|
|`BIANNUALLY`|Every 6 months|
|`ANNUALLY`|Every year|
Bank Names
Use uppercase, single-word format:
ABSASTANDARDBANKFNBNEDBANKCAPITECINVESTECBIDVEST
Response
JSON
{
"id": "8f4a6b0f-fa9b-4f45-8e19-b75c1a70432a",
"status": "ACTIVE",
"defaultServiceType": "ONEDAY",
"profileCode": "TEST1",
"abbreviatedName": "TESTMERCH1",
"contractReference": "CONTRACT001",
"debtor": { ... },
"creditor": { ... },
"frequency": "MONTHLY",
"collectionDay": 15,
"amountCents": 10000,
"createdAt": "2024-01-15T10:30:00.000Z"
}
Bank Account Verification
Set verifyAccount: true to verify the debtor's bank account before creating the mandate:
JSON
{
"verifyAccount": true
}
The verification checks:
- Account exists
- Account is open
- Account type matches
- Account accepts debits
- ID number matches the account holder
If verification fails, the mandate will not be created. See Bank Account Verification for details.
Ultimate Creditor (Split Payments)
For split payment scenarios, include the ultimateCreditor object:
JSON
{
"ultimateCreditor": {
"accountNumber": "010553983",
"accountType": "CURRENT",
"branchCode": "051001",
"name": "PARTNER COMPANY",
"bank": "STANDARDBANK",
"phoneNumber": "+27-615333440",
"emailAddress": "partner@test.com",
"idNumber": "4101014800082"
}
}
Collections
Collections are individual debit instructions processed against a mandate.
Create EFT Collection
Endpoint
POST /v2/collection/eft/from_mandate/
Request
BASH
curl -X POST https://dev.api.revio.co.za/v2/collection/eft/from_mandate/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"mandateId": "8f4a6b0f-fa9b-4f45-8e19-b75c1a70432a",
"collectionDate": "2024-02-15T00:00:00.000Z",
"amountCents": 10000,
"serviceType": "ONEDAY"
}'
Request Fields
|Field|Type|Required|Description|
|---|---|---|---|
|`mandateId`|string|Yes|ID of the mandate to collect against|
|`collectionDate`|string|Yes|Date to process collection (ISO 8601)|
|`amountCents`|integer|Yes|Collection amount in cents|
|`externalReference`|string|No|Your external reference ID|
|`serviceType`|string|No|Override default service type|
Response
JSON
{
"id": "63d94be3-1faf-428b-89f3-bc5271be8015",
"mandateId": "8f4a6b0f-fa9b-4f45-8e19-b75c1a70432a",
"status": "PENDING",
"collectionDate": "2024-02-15T00:00:00.000Z",
"amountCents": 10000,
"serviceType": "ONEDAY"
}
Get Collection Status
Endpoint
GET /v2/collection/eft/{collectionId}/status/
Request
BASH
curl -X GET https://dev.api.revio.co.za/v2/collection/eft/63d94be3-1faf-428b-89f3-bc5271be8015/status/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response
JSON
{
"id": "63d94be3-1faf-428b-89f3-bc5271be8015",
"status": "COMPLETED",
"statementId": "stmt_12345"
}
Collection Statuses
|Status|Description|
|---|---|
|`PENDING`|Collection submitted, awaiting processing|
|`PROCESSING`|Collection being processed by bank|
|`COMPLETED`|Collection successful|
|`UNPAID`|Collection failed (insufficient funds, etc.)|
|`DISPUTED`|Customer disputed the collection|
|`CANCELLED`|Collection cancelled before processing|
Bank Account Verification
Verify customer bank details before creating mandates.
Verification Checks
|Check|Field|Description|
|---|---|---|
|`AccountExists`|Account number|Account exists at bank|
|`AccountIsOpen`|Account status|Account is active/open|
|`AccountTypeMatches`|Account type|Provided type matches actual|
|`AccountAcceptsDebits`|Account capabilities|Account can receive debits|
|`IdNumberMatches`|ID number|ID matches account holder|
Failure Response
JSON
{
"value": {
"Message": "Debtor account verification failure: details={\"AccountExists\":true,\"AccountIsOpen\":false,\"AccountTypeMatches\":null,\"IdNumberMatches\":null,\"AccountAcceptsDebits\":null}"
},
"statusCode": 400
}
Cut-off Times
Submit collections before these cut-off times:
|Service Type|Weekday Cut-off|Weekend Cut-off|
|---|---|---|
|Same-day|08:00 - 16:20|08:00 - 09:45|
|One-day (dated)|08:00 - 16:00|08:00 - 10:15|
|Two-day (dated)|08:00 - 14:30 (2 days before)|08:00 - 09:00|
Reconciliation
Revio automatically reconciles collection results to bank statements. Successfully reconciled collections include a statementId field:
JSON
{
"id": "63d94be3-1faf-428b-89f3-bc5271be8015",
"status": "COMPLETED",
"statementId": "stmt_12345"
}
Contact your Revio account manager to enable automatic reconciliation.
Error Handling
Common Errors
|Error|Cause|Resolution|
|---|---|---|
|`400 Bad Request`|Invalid request data|Check required fields and formats|
|`404 Not Found`|Mandate/collection not found|Verify the ID|
|`409 Conflict`|Duplicate external reference|Use a unique reference|
Unpaid Collections
When a collection returns unpaid:
- Do not resubmit until the next mandated date
- After 2 consecutive "Not provided for" failures, obtain a new mandate
- "Account Closed" or "Payment Stopped" requires customer contact
Best Practices
- Store mandate IDs: Keep track of mandate IDs for future collections
- Use external references: Add your own references for easier reconciliation
- Handle failures gracefully: Implement retry logic respecting PASA rules
- Verify accounts: Use
verifyAccount: true to reduce failed collections - Submit early: Submit collections well before cut-off times