External Gateways

External Gateway Integrations & Telephony Services

1. Safaricom M-Pesa Daraja C2B/B2C API Integration

The financial engine implements direct automated hooks into Safaricom’s Daraja API to provide zero-touch collection reconciliation via Lipa Na M-Pesa Paybill / STK Push services.

1.1 Secure Authorization Lifecycle

Daraja APIs require an OAuth2 bearer token refreshed every 3,599 seconds. The system executes this handshake via a background task engine and caches the active token inside Redis.

Rendering Chart

1.2 STK Push (M-Pesa Express) Payload Schema

When an agent clicks "Trigger Mobile Payment" at any billing terminal, the HMIS issues a synchronous loopback request to the stkpush/v1/processrequest endpoint:

# apps/financial/gateways/mpesa.py
import base64
import requests
from datetime import datetime
from django.conf import settings

def initiate_stk_push_transaction(phone_number: str, amount: int, account_reference: str) -> dict:
    """
    Triggers an instant Lipa Na M-Pesa Online STK Push to a patient's handset.
    """
    timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
    password_source = f"{settings.MPESA_SHORTCODE}{settings.MPESA_PASSKEY}{timestamp}"
    encoded_password = base64.b64encode(password_source.encode('utf-8')).decode('utf-8')
    
    headers = {"Authorization": f"Bearer {get_active_mpesa_token()}"}
    payload = {
        "BusinessShortCode": settings.MPESA_SHORTCODE,
        "Password": encoded_password,
        "Timestamp": timestamp,
        "TransactionType": "CustomerPayBillOnline",
        "Amount": amount,
        "PartyA": phone_number, # Customer Phone Number
        "PartyB": settings.MPESA_SHORTCODE,
        "PhoneNumber": phone_number,
        "CallBackURL": f"https://{settings.FACILITY_DOMAIN}/api/v1/financial/mpesa/callback",
        "AccountReference": account_reference, # Local Billing Session ID
        "TransactionDesc": f"HMIS Settlement Visit Reference {account_reference}"
    }
    
    response = requests.post(settings.MPESA_STK_PUSH_URL, json=payload, headers=headers)
    response.raise_for_status()
    return response.json()

2. Social Health Authority (SHA) Portal Handshaking

Under the Digital Health Act (2023), integration with SHA (enclosing SHIF, PHF, and emergency structures) requires biometric token assertions paired alongside structured claims packets.

2.1 Complete Claim Pipeline Flow

Rendering Chart

2.2 SHA Biometric Assertions

The local fingerprint readers transmit a hashed ISO/IEC 19794-2 template string client-side. The HMIS maps this assertion directly to the authorization payload block:

{
  "provider_metadata": {
    "facility_kmfl_code": "15432",
    "terminal_id": "ER-TERM-02"
  },
  "claim_identity": {
    "member_sha_id": "SHA-K-29910-A",
    "nupi_id": "NUPI-2026-X8911-M",
    "biometric_session_token": "BIO_SESSION_8812A_VALIDATED"
  },
  "tariff_breakdown": [
    {
      "tariff_code": "SHA-PROC-412",
      "description": "Emergency Appendectomy Procedure",
      "billed_amount_kes": 25000.00
    }
  ]
}

3. Localized SMS Telephony Gateways

Patient engagement loops (e.g., triage prioritization summaries, diagnostic clearance flags, chronic disease clinic recalls) utilize multi-carrier SMS notification engines via localized SMPP/REST aggregators (such as Africa's Talking or Safaricom Bulk SMS channels).

3.1 Non-Blocking Task-Driven Message Dispatch

To ensure that slow external telecommunication lines never bottleneck clinical or financial screens, all outbound messages are offloaded to asynchronous background jobs.

# apps/patient/tasks.py
from huey.contrib.djhuey import task
import requests
from django.conf import settings

@task(retries=3, retry_delay=60)
def dispatch_outbound_patient_sms(recipient_phone: str, message_body: str) -> None:
    """
    Asynchronous queue task handling telecommunication carrier delivery outbox pipelines.
    Triggers retries automatically if external gateway systems encounter network lag.
    """
    payload = {
        "username": settings.SMS_GATEWAY_USERNAME,
        "to": recipient_phone,
        "message": message_body,
        "from": settings.SMS_SENDER_ID # Approved Facility Alphanumeric Alpha Tag
    }
    headers = {
        "Accept": "application/json",
        "Content-Type": "application/x-www-form-urlencoded",
        "ApiKey": settings.SMS_GATEWAY_API_KEY
    }
    
    response = requests.post(settings.SMS_GATEWAY_ENDPOINT, data=payload, headers=headers)
    
    # Trigger exception if status code returns 4xx/5xx to enforce automatic task retry loops
    response.raise_for_status()

4. Error Tolerances, Circuit Breaking, and Offline Queues

Third-party external web connections can drop frequently. The HMIS handles these failures using a Circuit Breaker pattern managed in memory via Redis.

Rendering Chart
  • M-Pesa STK Callback Failure Fallback: If Safaricom's callback notification fails to reach the facility due to an external fiber line drop, the billing terminal initiates an on-demand transaction status pull task checking payment states manually: POST /mpesa/stkpushquery/v1/query.
  • SHA Queue Backup Strategy: When the National Data Highway endpoint enters an offline or maintenance state, signed financial files are safely retained in local database tables labeled pending_offline_sha_claims, waiting to be automatically dispatched during a midnight reconciliation task once connections are restored.

Document Verification Block

Author: Ian Wataka - Backend DeveloperTarget Scope: External API Routing Handshakes & Task Architecture