Skip to main content

Banking & Financial Alerts

Financial institutions across Africa rely on SMS for transaction alerts, balance notifications, and fraud warnings — often as the primary channel, since SMS reaches feature phones and works without data. This guide shows how to deliver fast, secure, compliant banking alerts with AfriRoute.

Scenario: Real-Time Transaction Alerts​

A microfinance bank in Tanzania wants to notify customers instantly on every deposit, withdrawal, and suspicious-login event, with guaranteed delivery and a full audit trail for regulatory reporting.

Why SMS for Banking​

  • Universal reach — works on every handset, no app or data required
  • Speed — alerts land in seconds, critical for fraud response
  • Trust — a registered bank sender ID signals authenticity
  • Auditability — every alert is logged with delivery status

Step 1: Send a Transaction Alert​

Tag banking alerts as transactional and route them at high priority:

alert.py
import requests

def send_transaction_alert(account, txn):
msg = (f"{account.bank}: {txn.type} of {txn.amount} {txn.currency} on "
f"a/c ***{account.last4}. Bal: {account.balance} {txn.currency}. "
f"Not you? Call {account.hotline}")
return requests.post('https://api.afriroute.ai/api/v1/sms/send',
headers={'Authorization': 'Bearer $AFRIROUTE_API_KEY'},
json={
'to': account.phone, # +255754123456
'from': 'CRDB-Bank', # registered transactional sender ID
'message': msg,
'category': 'transactional',
'priority': 'high',
'callback_url': 'https://bank.co.tz/webhooks/sms'
}).json()

Step 2: Fraud Alert with Two-Way Confirmation​

For suspicious activity, send an alert the customer can respond to over a two-way long code:

fraud.py
def fraud_alert(account, attempt):
requests.post('https://api.afriroute.ai/api/v1/sms/send',
headers={'Authorization': 'Bearer $AFRIROUTE_API_KEY'},
json={
'to': account.phone,
'from': '22141', # dedicated shortcode for replies
'message': (f"Login attempt from {attempt.location} at {attempt.time}. "
f"Reply YES to approve or NO to block."),
'category': 'transactional',
'priority': 'high'
})

Handle the reply to approve or freeze the account:

reply_handler.py
@app.post('/webhooks/inbound-sms')
def inbound():
data = request.json
if data['text'].strip().upper() == 'NO':
freeze_account(data['from'])
return '', 200

Step 3: Maintain an Audit Trail​

Banking regulators require proof of notification. Record each alert with its message ID and delivery receipt:

record = send_transaction_alert(account, txn)
audit_log.write({
'account': account.id,
'message_id': record['message_id'],
'sent_at': record['timestamp'],
'txn_ref': txn.reference
})

The delivery webhook later stamps delivered_at, completing the record for compliance reporting.

Security & Compliance​

  • Never include full account numbers, PINs, or OTPs together in one alert — mask the account (***1234).
  • Use a registered bank sender ID per country; spoofed financial sender IDs are heavily filtered — see Sender ID Registration.
  • Store consent and PII lawfully under local DPA / NDPR rules — see Data Protection.
  • HMAC-verify webhooks so reply-driven actions can't be forged.

Best Practices​

  1. Prioritize fraud and transaction alerts (priority: high) over marketing traffic.
  2. Keep it short — one segment, clear amount, balance, and hotline.
  3. Include a fraud hotline in every transaction alert.
  4. Monitor delivery rates; a drop can indicate carrier filtering of your sender ID.

Last Updated: May 2026