Product Development Plan - Nedbank PTI SOAP Receiver¶
Goal¶
Deliver a production-ready PTI SOAP receiver that conforms to the Nedbank TIWebDistribution contract, persists inbound messages safely, and runs behind the existing reverse proxy with QA and PROD separation.
Primary spec: pti_web_service_re_implementation_spec_ct_market_↔_nedbank.md
What is done (as of 2026-01-28)¶
- Reverse proxy and DNS routing are configured and validated (WireGuard + Nginx on
rpctm). - Public hostnames are live with TLS and route to this container:
nedbank.reverse-proxy.co.zanedbank.capetownmarket.co.za- Local nginx routes are in place on this container (
0.0.0.0:8000) for: /test/com_check.php-> SOAP server/zoap/ctm/serverand/zoap/ctm-qa/server-> SOAP server- Local SOAP placeholder service is running via FastAPI at
127.0.0.1:8001. - Comms test endpoint returns
OK(/test/com_check.php). - SOAP contract artifacts are available under
nedbank/soap-server/soap_contracts/. - Implementation spec and archaeology notes are documented in
nedbank/documentation/.
Next implementation steps (self-fulfilling order)¶
1) Capture remaining Nedbank inputs (external dependency)¶
Output: a single confirmed integration checklist to lock the final behavior.
- Confirm whether mTLS is required and obtain the client CA chain if yes.
- Confirm expected success
ResultCodevalue (historicallyR00orXR00). - Confirm DataPower egress IPs for QA and PROD allowlisting.
- Confirm certificate/CSR requirements (key type/size, SANs, validity, EKU).
- Confirm whether call account support is available (or alternate feed if not).
- Confirm final QA and PROD URLs to be used.
2) Convert placeholder into real SOAP receiver¶
Output: SOAP endpoint that accepts Nedbank requests and returns a valid SOAP ACK.
- Add XML parsing dependency (
lxmlordefusedxml + lxml). - Parse SOAP
Envelopeand extract: Header/EnterpriseContext(raw XML to echo back)Body/DistributeMsgRq/Content/*- Accept
text/xmlandapplication/soap+xmlcontent types. - Validate and record
SOAPActionheader when present. - Build response envelope with echoed
EnterpriseContextandDistributeMsgRs/ResultCode. - Configure
ResultCodevia env var so it can be changed without code edits.
3) Add persistence + idempotency¶
Output: durable storage and duplicate suppression.
- Choose storage: PostgreSQL for PROD (SQLite acceptable for MVP).
- Create a single
pti_messagestable capturing the minimum fields from the spec. - Compute
fingerprint_hash(SHA-256) from stable fields and enforce a dedupe window. - Store both raw and decoded
TransformedData(never discard raw). - Return success ACK for duplicates without re-processing downstream.
4) Add observability and basic safety rails¶
Output: operational visibility and safe failure behavior.
- Structured logs per request with request id, env, IP, result code, and fingerprint.
- Minimal metrics counters (received, duplicates, decode failures).
- Always return a SOAP ACK even on application errors, with failure
ResultCode. - Add
/healthendpoint.
5) Implement fixtures and automated tests¶
Output: confidence that request parsing and response formatting match contract.
- Add sample SOAP request fixtures based on WSDL/XSD.
- Unit tests:
- SOAP parsing and field extraction
- Base64 decode for CSV payloads
- Response XML namespaces and structure
- Integration test: POST sample SOAP to local nginx and verify HTTP 200 + SOAP ACK.
6) Deploy the real service on this container¶
Output: running service behind local nginx on the existing ports.
- Replace placeholder FastAPI app with real implementation.
- Update systemd service to run the new app (env vars included).
- Confirm
/test/com_check.php,/zoap/ctm/server,/zoap/ctm-qa/serverall work locally.
7) Validate end-to-end via reverse proxy¶
Output: public hostnames correctly proxy and return SOAP ACK.
- From
rpctm, POST a test SOAP request to: https://nedbank.reverse-proxy.co.za/zoap/ctm/serverhttps://nedbank.capetownmarket.co.za/zoap/ctm-qa/server- Confirm logs, persistence, and correct
ResultCode. - Verify header forwarding:
SOAPAction,Content-Type,Host,X-Forwarded-For,X-Request-Id.
8) Production hardening and mTLS (if required)¶
Output: security posture aligned with Nedbank requirements.
- Enable client cert verification in Nginx if Nedbank requires mTLS.
- Log client cert subject/serial when mTLS is enabled.
- Add cert expiry alerts (30/14/7 days).
- Confirm final PROD hostname
nedbank.banking.ctmarket.co.zais served with correct SANs.
9) Nedbank QA tests, then PROD cutover¶
Output: QA sign-off and production activation.
- Provide QA endpoint and IP allowlist to Nedbank.
- Run Nedbank-sent QA test messages and verify persistence + ACKs.
- After QA approval, enable PROD profile and monitor closely.
Current gaps to track¶
- ResultCode confirmation (
R00vsXR00). - mTLS requirement and certificate chain.
- Nedbank egress IPs for firewall allowlisting.
- Call account support status and alternate feed if not supported.