Octopus POS SDK Integration Guide Addendum
CONFIDENTIAL — System Integration Documentation
11. Webhook Configuration
[cite_start]Configure webhooks to send real-time transaction notifications to aggregators[cite: 225]. [cite_start]The Macrotech webhook system delivers HTTP POST requests to your registered endpoint whenever a transaction event occurs[cite: 225].
💡 System Architecture Note
Webhooks switch the communication model from polling to pushing. Instead of your servers constantly querying Macrotech for transaction states, Macrotech will securely push event data to your environment the millisecond an update occurs on the POS terminal interface.
11.1 Event Types
The following events are emitted asynchronously by the gateway server engine:
| Event Type | Description |
|---|---|
TRANSACTION_APPROVED |
[cite_start]Sent when a transaction is successfully approved[cite: 227]. |
TRANSACTION_DECLINED |
[cite_start]Sent when a transaction is declined by the issuer[cite: 227]. |
TRANSACTION_REVERSED |
[cite_start]Sent when a transaction is reversed[cite: 227]. |
TRANSACTION PENDING |
[cite_start]Sent when a transaction is in a pending state[cite: 227]. |
11.2 Request Headers
Every incoming HTTP POST mutation payload features standard structural transaction metadata wrapped inside the connection request headers:
| Header | Description |
|---|---|
Content-Type |
[cite_start]Always application/json[cite: 229]. |
X-Webhook-Signature |
[cite_start]HMAC-SHA256 signature of the payload (if configured)[cite: 229]. |
X-Event-Type |
[cite_start]The type of event being sent[cite: 229]. |
XTransaction--ID |
[cite_start]Unique identifier of the transaction[cite: 229]. |
11.3 Request Payload
[cite_start]The webhook payload is a JSON object structure containing comprehensive merchant breakdown parameters and ISO network state codes[cite: 231]:
{
"eventType": "TRANSACTION_APPROVED",
"transactionId": 12345,
"stan": "123456",
"rrn": "123456789012",
"merchantId": 100,
"merchantName": "Adebayo Supermarket",
"terminalId": 200,
"terminalTid": "T12345678",
"amount": "25000.00",
"currency": "NGN",
"status": "APPROVED",
"responseCode": "00",
"responseMessage": "Transaction Approved",
"authCode": "ABC123",
"timestamp": "2024-01-15T14:30:00"
}
Data Field Dictionary Blueprint
| Field | Type | Description |
|---|---|---|
eventType |
String | [cite_start]The type of webhook event (see section 11.1)[cite: 251]. |
transactionId |
Integer | [cite_start]Unique numeric identifier of the transaction[cite: 251]. |
stan |
String | [cite_start]System Trace Audit Number unique per terminal per day[cite: 251]. |
rrn |
String | [cite_start]Retrieval Reference Number returned by the issuer[cite: 251]. |
merchantId |
Integer | [cite_start]Internal merchant identifier[cite: 251]. |
merchantName |
String | [cite_start]Display name of the merchant[cite: 251]. |
terminalId |
Integer | [cite_start]Internal terminal identifier[cite: 251]. |
terminalTid |
String | [cite_start]Terminal TID as provisioned by TMS during key exchange[cite: 251]. |
amount |
String | [cite_start]Transaction amount formatted as a decimal string (e.g. "25000.00")[cite: 251]. |
currency |
String | [cite_start]ISO 4217 currency code (e.g. NGN)[cite: 251]. |
status |
String | [cite_start]High-level transaction status string[cite: 251]. |
responseCode |
String | [cite_start]ISO 8583 response code (e.g. "00" = approved)[cite: 251]. |
responseMessage |
String | [cite_start]Human-readable response message (e.g. "Transaction Approved")[cite: 251]. |
authCode |
String | [cite_start]Authorisation code from the issuer (6 characters on approval)[cite: 251]. |
timestamp |
String | [cite_start]ISO 8601 timestamp of the transaction event[cite: 251]. |
11.4 Response Format
[cite_start]Your webhook server must respond with a 2xx HTTP status code within 10 seconds[cite: 253]. [cite_start]A response body is optional but recommended for debugging and audit purposes[cite: 254]:
{
"status": "received",
"message": "Webhook processed successfully",
"timestamp": "2024-01-15T14:30:01"
}
11.5 Signature Verification
[cite_start]When a webhook secret is configured on the Macrotech dashboard, each request includes an X-Webhook-Signature header containing an HMAC-SHA256 signature of the JSON payload encoded in Base64[cite: 263]. [cite_start]Always verify this signature before processing the event to confirm the request originated from Macrotech[cite: 264].
Node.js Implementation Example
const crypto = require('crypto');
function verifySignature (payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(JSON.stringify(payload))
.digest('base64');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler:
app.post('/webhook/endpoint', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const isValid = verifySignature(req.body, signature, 'your-secret-key');
if (!isValid) {
return res.status(401).json({ error: 'Invalid signature' });
}
// Process the webhook
console.log('Received event:', req.body.eventType);
res.status(200).json({ status: 'received' });
});
🛡️ Cybersecurity Alert: Prevent Side-Channel Timing Attacks
[cite_start]WARNING: Always use crypto.timingSafeEqual() for signature comparison[cite: 291]. [cite_start]Standard string equality operators (== or ===) cease evaluations immediately at the first non-matching byte, giving attackers a measurable timing discrepancy that allows them to sequentially guess and forge valid signatures[cite: 291, 292].
11.6 cURL Simulation Node
Execute this diagnostic payload from your command terminal to test your endpoint's network intake pipeline manually:
curl -X POST https://your-server.com/webhook/endpoint \
-H "Content-Type: application/json" \
-H "X-Webhook-Signature: <signature>" \
-H "X-Event-Type: TRANSACTION_APPROVED" \
-H "X-Transaction-ID: 12345" \
-d '{
"eventType": "TRANSACTION_APPROVED",
"transactionId": 12345,
"stan": "123456",
"amount": "25000.00",
"status": "APPROVED",
"responseCode": "00",
"timestamp": "2024-01-15T14:30:00"
}'
11.7 Important Operational Notes
-
[cite_start]
- Webhooks are sent asynchronously and will retry up to the configured number of attempts on failure[cite: 310]. [cite_start]
- Your endpoint must respond within the configured timeout period to be considered successful[cite: 311]. [cite_start]
- Always verify the
X-Webhook-Signatureheader to confirm the request is from Macrotech[cite: 312].
[cite_start] - Design your handler to be idempotent — duplicate webhooks may be delivered during network retry sequences[cite: 313]. [cite_start]
- Event ordering is not guaranteed[cite: 313]. [cite_start]Use the
timestampfield for chronological ordering[cite: 314].
⚙️ TMS Infrastructure Management
[cite_start]NOTE: Re-register your webhook endpoint after any infrastructure or hosting changes[cite: 315]. [cite_start]The Macrotech dashboard (Terminal Management > Webhook Configuration) allows you to update and safely execute runtime test iterations on your endpoint URL parameters at any time[cite: 315].