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.
- AML and issuer pre-checks
- Check account hold status for debit account.
-
Validate issuer exists.
-
Rule-engine validation
- Build TransactionRuleModule in validate lifecycle.
- 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.
- Balance sufficiency check
- Call CBS account balance through integration service.
- Compare transaction amount plus computed fees against available balance.
-
Enforce agent category constraints where applicable.
-
Security challenge requirements
- Read matching rule flags for PIN and OTP requirements.
-
If OTP is required, generate transaction OTP reference.
-
Validation proof issuance
- Generate short-lived validation token bound to:
- user
- key payload fingerprint
- expiry
- 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.
- Mandatory validation token verification
- Reject execution if validation token is missing.
- verify_transaction_validation_token enforces:
- signature integrity
- expiry
- user match
- payload fingerprint match
-
single use via Redis consume-once key
-
Rule-driven credential enforcement
- If matching rule requires PIN:
- Validate PIN presence
- Verify policy constraints
- Verify credential hash
- Apply failed-attempt controls
- If rule requires OTP:
-
Verify OTP against otp_reference
-
Multi-leg execution handoff
-
All transactions route to execute_transaction_multi_leg.
-
Rule service usage during execution
- TransactionRuleModule is rebuilt in confirm lifecycle.
- Rule checks are re-applied as execution guardrails.
- 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¶
- Resolve URI keys.
- Build API request templates via APIURIRegistry.
- Build one or more TransactionLeg entries.
- Validate with TransactionRuleModule.
- Create Batch and Transaction records (INITIATED then PENDING).
- Run pre-risk assessment.
- Execute legs sequentially:
- Internal legs use InternalWalletAdapter.
- External legs call issuer adapters via call_issuer_api.
- Record each leg in reconciliation artifacts.
- On all-success:
- Apply charges
- Mark transaction SUCCESSFUL
- Attach issuer reference
- Attempt reconciliation
- Persist legs in transaction udf
- 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.
- Post-execution assessment
- After successful execution, post-transaction AML assessment is queued asynchronously.
- 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:
- Campaign processing
- Successful transactions trigger campaign processing asynchronously.
-
Campaign pipeline can evaluate eligibility and dispatch rewards.
-
Notification pipeline
- Notification channel list is derived from payload.notification.
- Transaction notifications are queued asynchronously (sms, email, push).
-
Additional channel-specific paths exist for balance-check style live events.
-
Dashboard and event stream updates
- Transfer events are emitted at major lifecycle transitions.
-
Dashboard update tasks are queued with transaction context.
-
Reconciliation follow-up
- Leg pair reconciliation is attempted inline after success.
- 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.