Skip to content

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.za
  • nedbank.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/server and /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 ResultCode value (historically R00 or XR00).
  • 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 (lxml or defusedxml + lxml).
  • Parse SOAP Envelope and extract:
  • Header/EnterpriseContext (raw XML to echo back)
  • Body/DistributeMsgRq/Content/*
  • Accept text/xml and application/soap+xml content types.
  • Validate and record SOAPAction header when present.
  • Build response envelope with echoed EnterpriseContext and DistributeMsgRs/ResultCode.
  • Configure ResultCode via 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_messages table 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 /health endpoint.

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/server all 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/server
  • https://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.za is 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 (R00 vs XR00).
  • mTLS requirement and certificate chain.
  • Nedbank egress IPs for firewall allowlisting.
  • Call account support status and alternate feed if not supported.