Skip to content

Transaction Processing Module

Overview

This module executes financial transactions through a rule-driven lifecycle with mandatory validation proof, secure execution, and multi-leg orchestration.

Base route: - /api/v1/transaction

Primary sources scanned: - app/api/v1/endpoints/transaction.py - app/services/transaction.py - app/services/multi_leg_transaction.py - app/services/transaction_payload_builder.py

Canonical references: - API Route Live Reference - API Route Documentation TODO

Workflow Architecture

The transaction pipeline is split into two required phases: 1. Validation phase (rule/validate) 2. Execution phase (transaction/execute)

Execution is blocked unless validation proof exists and matches the payload.

Validation Workflow (rule/validate)

Endpoint: - POST /api/v1/transaction/rule/validate

Validation sequence: 1. Input guards - Validate channel is one of mobile, ussd, web. - Validate required customer data based on transaction type. - Validate bill-payment identifiers where applicable.

  1. AML and issuer pre-checks
  2. Check account hold status for debit account.
  3. Validate issuer exists.

  4. Rule-engine validation

  5. Build TransactionRuleModule in validate lifecycle.
  6. Execute validate_transaction() to evaluate rule matching, limits, warnings, and fee splits.

Rule service responsibilities in this stage: - Resolve matching rule by channel, transaction type, identity type, and priority. - Enforce rule time conditions (weekday/time windows). - Validate account relationship constraints (for example, debit and credit cannot be the same where disallowed). - Compute split fees from rule ranges and fee tags. - Evaluate limit controls (agent and customer contexts). - Determine whether transaction requires PIN and/or OTP.

  1. Balance sufficiency check
  2. Call CBS account balance through integration service.
  3. Compare transaction amount plus computed fees against available balance.
  4. Enforce agent category constraints where applicable.

  5. Security challenge requirements

  6. Read matching rule flags for PIN and OTP requirements.
  7. If OTP is required, generate transaction OTP reference.

  8. Validation proof issuance

  9. Generate short-lived validation token bound to:
  10. user
  11. key payload fingerprint
  12. expiry
  13. Store token in transaction udf.validation_token.

Validation output: - Fee results - Updated transaction payload (includes validation token) - pin_required flag - otp_required flag

Execution Workflow (transaction/execute)

Endpoint: - POST /api/v1/transaction/transaction/execute

Execution sequence: 1. Input guards and preconditions - Re-run channel/customer/bill identifier checks. - Re-run account hold and issuer checks.

  1. Mandatory validation token verification
  2. Reject execution if validation token is missing.
  3. verify_transaction_validation_token enforces:
  4. signature integrity
  5. expiry
  6. user match
  7. payload fingerprint match
  8. single use via Redis consume-once key

  9. Rule-driven credential enforcement

  10. If matching rule requires PIN:
  11. Validate PIN presence
  12. Verify policy constraints
  13. Verify credential hash
  14. Apply failed-attempt controls
  15. If rule requires OTP:
  16. Verify OTP against otp_reference

  17. Multi-leg execution handoff

  18. All transactions route to execute_transaction_multi_leg.

  19. Rule service usage during execution

  20. TransactionRuleModule is rebuilt in confirm lifecycle.
  21. Rule checks are re-applied as execution guardrails.
  22. Charge creation is finalized only after successful leg execution.

Multi-Leg Transaction Structure

URI key resolution

transaction_type is mapped to one or two URI keys by TransactionPayloadBuilder.resolve_uri_keys(): - issuer_uri_key - ledger_uri_key (optional)

Examples from map: - WALLET_TRANSFER -> wallet_ledger_transfer (single leg) - WALLET_TOPUP -> wallet_ledger_credit + bank_topup_gl (two legs) - WALLET_WITHDRAWAL -> wallet_ledger_debit + bank_withdrawal_gl (two legs) - WALLET_BILL_PAYMENT -> wallet_ledger_debit + bill_payment (two legs) - BILL or BILL_PAYMENTS -> bill_payment (single leg)

Leg model

Each leg tracks: - leg_number - issuer - uri_key - operation (debit or credit) - amount - reference_id - status - response or error

Execution order

  1. Resolve URI keys.
  2. Build API request templates via APIURIRegistry.
  3. Build one or more TransactionLeg entries.
  4. Validate with TransactionRuleModule.
  5. Create Batch and Transaction records (INITIATED then PENDING).
  6. Run pre-risk assessment.
  7. Execute legs sequentially:
  8. Internal legs use InternalWalletAdapter.
  9. External legs call issuer adapters via call_issuer_api.
  10. Record each leg in reconciliation artifacts.
  11. On all-success:
  12. Apply charges
  13. Mark transaction SUCCESSFUL
  14. Attach issuer reference
  15. Attempt reconciliation
  16. Persist legs in transaction udf
  17. Generate receipt token

AML Checks in Flow

AML checks happen in two places: 1. Pre-execution block gate - Account hold check is performed before execution entry. - Pre-risk assessment is run before leg execution. - If AML pre-check returns BLOCK, transaction is failed and execution is stopped.

  1. Post-execution assessment
  2. After successful execution, post-transaction AML assessment is queued asynchronously.
  3. Post stage does not block a completed successful transaction response.

Failure and Compensation Workflow

If any leg fails: 1. Mark current leg FAILED. 2. Record failed reconciliation entry. 3. Roll back completed legs through rollback_transaction_legs(). 4. Create reversal transaction audit trail for compensation. 5. Mark main transaction FAILED. 6. Emit failure transfer events with diagnostic context.

This is a saga-style compensation model, not a single ACID external transaction.

Post-Execution Orchestration

After success/failure handling, orchestration continues outside the critical path:

  1. Campaign processing
  2. Successful transactions trigger campaign processing asynchronously.
  3. Campaign pipeline can evaluate eligibility and dispatch rewards.

  4. Notification pipeline

  5. Notification channel list is derived from payload.notification.
  6. Transaction notifications are queued asynchronously (sms, email, push).
  7. Additional channel-specific paths exist for balance-check style live events.

  8. Dashboard and event stream updates

  9. Transfer events are emitted at major lifecycle transitions.
  10. Dashboard update tasks are queued with transaction context.

  11. Reconciliation follow-up

  12. Leg pair reconciliation is attempted inline after success.
  13. If reconciliation cannot complete, transaction remains successful and reconciliation is marked pending.

Sequence Diagram

sequenceDiagram
  autonumber
  participant C as Client
  participant E as transaction.py
  participant R as TransactionRuleModule
  participant CBS as Integration/CBS
  participant M as execute_transaction_multi_leg
  participant L as Legs (Internal or Issuer)
  participant AML as AML Service
  participant BG as Async Tasks

  C->>E: POST /rule/validate
  E->>R: validate_transaction() (validate lifecycle)
  R-->>E: fees, rule flags, warnings
  E->>CBS: account_balance_cbs()
  CBS-->>E: available balance
  E-->>C: validation result + validation_token + pin/otp requirements

  C->>E: POST /transaction/execute (with validation_token)
  E->>E: verify_transaction_validation_token(single use)
  E->>R: get_matching_rule() (confirm lifecycle)
  opt PIN or OTP required
    E->>E: verify pin and or otp
  end
  E->>M: execute_transaction_multi_leg(payload)

  M->>AML: pre-risk assessment
  alt AML BLOCK
    AML-->>M: BLOCK
    M-->>E: fail transaction
    E-->>C: validation failure
  else AML pass
    AML-->>M: PASS
    loop for each leg in order
      M->>L: execute leg (internal adapter or issuer API)
      alt leg failed
        L-->>M: error
        M->>M: rollback_transaction_legs()
        M->>M: create reversal audit trail
        M-->>E: execution failed
        E-->>C: failed response
      else leg success
        L-->>M: success response
      end
    end
    M->>M: apply charges and mark successful
    M->>M: attempt reconciliation
    M-->>E: successful response + receipt token
    E-->>C: transaction success

    par Post execution orchestration
      M->>BG: queue campaign processing
      M->>BG: queue notifications (sms/email/push)
      M->>BG: queue dashboard and transfer events
      M->>BG: queue post-transaction AML assessment
    end
  end

Reconciliation Workflow

Leg-level reconciliation is captured during execution: - record_leg_execution for each executed or failed leg - reconcile_leg_pair attempted after success - transaction reconciliation flags updated: - is_reconciled - reconciliation_note

If auto-reconciliation fails, transaction success is preserved and reconciliation remains pending.

Security and Integrity Controls

  • HMAC receipt tokens for receipt retrieval flows.
  • Validation tokens are single-use and payload-bound.
  • Sensitive fields (pin, otp, tokens, keys) are redacted in extracted API traces.
  • Permission gates are enforced on transaction management endpoints.

Key Workflow Endpoints

Rule lifecycle

  • POST /rule/add
  • POST /rule/get
  • POST /rule/stage
  • POST /rule/edit
  • POST /rule/decline
  • POST /rule/dispose
  • POST /rule/delete
  • POST /rule/lock
  • POST /rule/fetch
  • POST /rule/validate

Execution and monitoring

  • POST /transaction/execute
  • POST /transaction/fetch
  • POST /failed/fetch
  • POST /suspicious/fetch
  • POST /reconciliation/fetch
  • POST /transaction/get
  • POST /transaction/detail

Dispute and reconciliation jobs

  • POST /dispute/add
  • POST /dispute/fetch
  • POST /dispute/get
  • POST /dispute/assign
  • POST /dispute/note/add
  • POST /dispute/status/update
  • POST /dispute/resolve
  • POST /dispute/analytics
  • POST /dispute/report
  • POST /dispute/cancel
  • POST /reconciliation/run
  • POST /reconciliation/download

Known Operational Notes

  • Beneficiary endpoints in transaction router currently include empty permission placeholders and should be tightened.
  • Multi-leg execution assumes reliable issuer adapters; compensation is best-effort and should be monitored through transfer events and reconciliation reports.