Webhook Callback
TemboPlus sends real-time webhook notifications when transactions occur in your collection accounts. When a transaction happens, the system sends a POST request to your designated webhook URL.
π― Overview
When transactions occur on your allocated accounts, our system sends real-time webhook notifications to your configured endpoint. This enables immediate transaction processing and reconciliation in your application.
π¨ Webhook Request Format
Your webhook endpoint will receive HTTP POST requests with these characteristics:
Method: POST
Content-Type: application/json
Headers: Standard HTTP headers plus
x-request-id
for tracing
Request Body Structure
{
"timestamp": "2025-09-15T12:34:56+03:00",
"signature": "base64-encoded-hmac-sha256",
"payload": "stringified-json-of-transaction-data"
}
Transaction Data (inside payload string)
{
"event": "transaction.created",
"account": {
"accountNo": "1234567890",
"accountName": "Business Account Ltd",
"bankId": "uuid-of-bank"
},
"transaction": {
"id": "unique-transaction-id",
"transactionId": "bank-transaction-id-or-null",
"reference": "TXN-REF-123456",
"paymentReference": "PAY-REF-789",
"transactionDate": "2025-09-15T10:30:00+03:00",
"creditOrDebit": "CREDIT",
"currency": "TZS",
"amountCredit": 50000.00,
"amountDebit": 0,
"availableBalance": 150000.00,
"currentBalance": 150000.00,
"description": "Customer payment received"
},
"counterparty": null
}
π Security Verification
HMAC Signature Validation Process
Each webhook includes a cryptographic signature that you must verify:
Extract Components: Get
timestamp
,signature
, andpayload
from request bodyCreate Signing Content: Concatenate
timestamp + payload
as a stringCalculate HMAC: Use HMAC-SHA256 with your provided hash key (base64 decode the key first)
Encode Result: Base64 encode the HMAC result
Compare: The calculated signature must exactly match the received signature
Signature Validation Algorithm
signing_content = timestamp + payload
calculated_hmac = HMAC-SHA256(base64_decode(your_hash_key), signing_content)
expected_signature = base64_encode(calculated_hmac)
is_valid = (expected_signature === received_signature)
Example Implementation (Node.js)
const crypto = require('crypto');
function validateWebhook(envelope, yourHashKey) {
const { timestamp, signature, payload } = envelope;
// Create signing content by concatenating timestamp and payload
const signingContent = timestamp + payload;
// Calculate HMAC-SHA256 signature
const expectedSignature = crypto
.createHmac('sha256', Buffer.from(yourHashKey, 'base64'))
.update(signingContent, 'utf-8')
.digest('base64');
// Compare signatures
return signature === expectedSignature;
}
ποΈ Implementation Requirements
1. Endpoint Configuration
Protocol: HTTPS only (HTTP not supported)
Method: Accept POST requests
Content-Type: Parse
application/json
Response Time: Respond within 30 seconds
Response Code: Return HTTP 200 for successful processing
2. Request Processing Flow
Receive Request: Accept POST with JSON body
Validate Signature: Verify HMAC signature (reject if invalid)
Parse Payload: Extract transaction data from
payload
stringCheck Duplicates: Handle potential duplicate deliveries
Process Transaction: Execute your business logic
Respond: Return HTTP 200 success response
3. Idempotency Handling
Webhooks may be delivered multiple times. Implement duplicate detection using:
Transaction ID: Use the unique
transaction.id
fieldStorage: Track processed transaction IDs in database/cache
Response: Return HTTP 200 for already-processed transactions
π Delivery Behavior
Retry Policy
Our system automatically retries failed webhook deliveries:
Success Criteria: HTTP status codes 200-299
Permanent Failures: HTTP 400-499 (except 408 Request Timeout, 429 Too Many Requests)
Temporary Failures: HTTP 500-599, network errors, timeouts
Retry Schedule: Exponential backoff starting at 2 seconds
Maximum Attempts: Up to 20 retries over 24 hours
Expected Response Format
Your endpoint should return a simple HTTP 200 success response:
{
"message": "Transaction processed successfully",
"transactionId": "unique-transaction-id"
}
π» Implementation Example
Conceptual Flow (Language Agnostic)
1. Receive HTTP POST request
2. Parse JSON request body
3. Validate HMAC signature
- If invalid: Return HTTP 401
4. Extract transaction data from payload
5. Check if transaction already processed
- If duplicate: Return HTTP 200
6. Execute business logic:
- Update account balances
- Trigger notifications
- Log transaction
- Update records
7. Mark transaction as processed
8. Return HTTP 200 success
Node.js Implementation Example
const express = require('express');
const app = express();
app.use(express.json());
// In-memory storage (use database in production)
const processedTransactions = new Set();
app.post('/webhook/transactions', async (req, res) => {
try {
// 1. Validate webhook signature
if (!validateWebhook(req.body, YOUR_HASH_KEY)) {
return res.status(401).json({ error: 'Invalid signature' });
}
// 2. Parse transaction data
const data = JSON.parse(req.body.payload);
const transactionId = data.transaction.id;
// 3. Handle duplicates
if (processedTransactions.has(transactionId)) {
return res.status(200).json({ message: 'Already processed' });
}
// 4. Process transaction
await processTransaction(data);
// 5. Mark as processed
processedTransactions.add(transactionId);
// 6. Return success
res.status(200).json({
message: 'Transaction processed',
transactionId
});
} catch (error) {
console.error('Webhook processing error:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
async function processTransaction(webhookData) {
const { account, transaction } = webhookData;
// Your business logic here
console.log(`Processing ${transaction.creditOrDebit} of ${transaction.currency} ${transaction.amountCredit || transaction.amountDebit} on account ${account.accountNo}`);
// Example actions:
// - Update local account balance
// - Send customer notification
// - Trigger reconciliation process
// - Log to audit trail
}
βοΈ Setup Requirements
Partner Configuration
Webhook URL: Provide your HTTPS endpoint URL
Hash Key: You'll receive a base64-encoded signing key
Account Allocation: Ensure accounts are allocated to your partner account
Testing Your Implementation
Test Request Format
POST https://your-domain.com/webhook/transactions
Content-Type: application/json
{
"timestamp": "2025-09-15T12:00:00+03:00",
"signature": "calculated-signature-here",
"payload": "{\"event\":\"transaction.created\",\"account\":{\"accountNo\":\"TEST123\",\"accountName\":\"Test Account\",\"bankId\":\"test-bank\"},\"transaction\":{\"id\":\"TEST-001\",\"reference\":\"TEST-REF\",\"transactionDate\":\"2025-09-15T11:30:00+03:00\",\"creditOrDebit\":\"CREDIT\",\"currency\":\"TZS\",\"amountCredit\":1000,\"amountDebit\":0,\"currentBalance\":5000,\"description\":\"Test payment\"}}"
}
β
Implementation Checklist
Essential Requirements
Recommended Enhancements
π Troubleshooting
Common Issues
No webhooks received
Verify endpoint URL is publicly accessible via HTTPS
Confirm accounts are properly allocated to your partner
Check that endpoint responds with HTTP 200
Signature validation failures
Ensure hash key is stored and used correctly
Verify signing content is exactly
timestamp + payload
(string concatenation)Confirm payload is the raw JSON string, not a parsed object
Check that hash key is base64-decoded before HMAC calculation
Duplicate processing
Implement idempotency using the unique
transaction.id
Store processed IDs in persistent storage (database, not memory)
Always return HTTP 200 for already-processed transactions
Processing timeouts
Ensure webhook processing completes within 30 seconds
Consider async processing for complex business logic
Return HTTP 200 immediately, then process in background
π Support
For webhook integration assistance, contact our technical support team with:
Your partner identifier
Webhook endpoint URL
Sample request/response logs
Error messages or unexpected behavior details
π Security Note: Always validate webhook signatures before processing transaction data to ensure authenticity and prevent unauthorized access to your system.
Last updated