CT Market ↔ Nedbank PTI SOAP Service (PTI) — Notes / Archaeology¶
Why this exists¶
We’re reconstructing the SOAP web service integration used for Nedbank Provisional Transaction Information (PTI) messages into CT Market systems (and why it later broke).
Key endpoints¶
- Primary PTI SOAP endpoint (QA + PROD used the same at the time):
https://nedbank.banking.ctmarket.co.za/zoap/ctm/server- Comms test endpoint (simple connectivity check):
https://nedbank.banking.ctmarket.co.za/test/com_check.php
Production URI confirmation¶
- Nedbank asked whether the same URI would be used in PROD.
- Response from CT Market side: Yes, to move fast; a separate QA URI could be created later if needed.
Network & firewall notes¶
CT Market public IP (as stated in early meeting notes)¶
- 102.37.48.32
Nedbank outbound IPs to whitelist (CT Market firewall)¶
- QA:
168.142.128.22/32 - PROD:
168.142.241.22/32
Connectivity issue observed (QA)¶
- Nedbank QA host attempted:
test tcp-connection 102.37.48.32 443 - Result: connection refused
- This suggests something like:
- nothing listening on 443 at that time,
- or an upstream firewall/NAT/port-forward mismatch,
- or web server bound incorrectly.
Certificates / mTLS¶
“Service died” trigger (2025)¶
- 27 Jan 2025: Nedbank support notified CT Market that the PTI certificate would expire on 1 Feb 2025 and requested the latest certificate to update PROD.
- Root cause (as reported internally): certificate renewal was not done and the incoming feed wasn’t actively used, so the breakage went unnoticed until Nedbank flagged expiry.
SOAP contract (what the service must accept/return)¶
Contract files found (local)¶
EnterpriseContext_2008-09.wsdlEnterpriseContext_2008-09.xsdTIWebDistribution_2013-11-01.wsdlTIWebDistribution_2013-11-01.xsd
Nedbank request/response pattern (high level)¶
- Nedbank posts a SOAP envelope containing:
EnterpriseContextheader (needs to be echoed back)DistributeMsgRqbodyContentincludes:Format(XML/CSV/etc)SecurityProxyType(oftenSECURE)DestinationKeyTransformedData(payload; appears base64-ish / encoded when CSV)
Required response (common failure mode)¶
- Nedbank feedback: “You guys are responding with the incorrect response.”
- Correct structure expected (simplified):
- SOAP envelope
- header contains the enterprise context
- body contains
DistributeMsgRswith:ResultCode(expected success code seen in examples:R00)
Observed real example snippets¶
Example request (compressed into one line in email)¶
- SOAP body contained
DistributeMsgRqwith: SecurityProxyType=SECUREDestinationKey=1Format=CSVTransformedData=...(encoded)
Example successful response (seen in DataPower debug)¶
DistributeMsgRsResultCode=R00
PTI behavioural notes from emails¶
- CT Market initially observed PTI messages mainly for Interbank Credits on Batch channel.
- CT Market intention: monitor movements on two subscribed accounts (trust + call), and asked how to receive PTI for “all transactions”.
- Nedbank response (key constraint): PTI messages could only accommodate Current and Savings accounts (at least at that time); a Business account would be opened in QA.
Accounts discussed (historical)¶
- Call Account:
037186068324(Branch code198765) - Trust Account:
1498086543(Branch code198765) - Business Account:
1498086640(Branch code198765)
Evidence of eventual success¶
- After resolving connectivity + format issues, the system shows transaction rows with status “Processed” and credits flowing through.
Files / artifacts gathered so far¶
Manuals / PDFs¶
TI Host to Host Client User Manual ver 52.pdfNedbank CPS Product Manual_August 2020.pdfCape Town Market Pty Ltd PTI - App 23533.pdf
AQ / other¶
Copy of Copy of CT Markert AQ_v1.0.xlsx
Screenshots captured¶
- DataPower “Input Context” showing SOAP envelope +
ResultCode=R00 - CLI test showing connection refused to
102.37.48.32:443 - PTI transaction list showing Processed entries
Open questions / TODOs for the rebuild¶
- What was the original server implementation (language/runtime/framework)?
- Where are the mTLS certs/keys currently stored (or archived)?
- What is the exact TransformedData decoding/format logic expected (CSV templates etc.)?
- What are the expected error ResultCode values besides
R00, and how should we log/alert? - Do we still want single URI for QA/PROD, or do we split now?
Quick “rebuild checklist” (draft)¶
- Stand up HTTPS listener on the correct host/IP and confirm port 443 from Nedbank QA/PROD IPs.
- Re-establish mTLS with renewed certificates and confirm handshake.
- Implement SOAP endpoint per
TIWebDistribution_2013-11-01.wsdl. - Ensure response echoing of
EnterpriseContext+DistributeMsgRs/ResultCode=R00. - Decode/process
TransformedData(according to the chosen template/format). - Add monitoring/alerting for cert expiry + incoming message health.
VM details (for recovery / restore)¶
Source email date: 2020-10-07
Application VM ("Nedbank VM")¶
| Item | Value |
|---|---|
| Purpose | Nedbank PTI SOAP service (app VM) |
| Host (private IP) | 192.168.32.5 |
| Installed stack | PHP, Nginx, Lumen |
| Project path | /var/www/nedbank-service |
| Login user | johan |
| Login password | 021M…ket! (sensitive; rotate/reset if restoring) |
| Notes | Lumen configured; should run migrations out-of-the-box; Eloquent + Facades enabled; local git repo created; Bitbucket remote repo set up (needed Johan’s email to add access). |
Database¶
| Item | Value |
|---|---|
| DB host (private IP) | 192.168.32.4 |
| Database name | Nedbank |
| DB user | Nedbank |
| DB password | pXHi2…0oE! (sensitive; rotate/reset if restoring) |
Access / networking notes¶
| Item | Value |
|---|---|
| VPN access | David offered an account to dial into the cloud VPN for direct access |
| Public access | David could open firewall when ready to hit service from public IP |
VPN / addressing notes (VM networking)¶
Source email (undated in excerpt): VPN setup on Finance VM
Finance VM¶
| Item | Value |
|---|---|
| Ethernet IP (local) | 172.22.0.24/24 |
| VPN IP | 192.168.32.24/24 |
| Notes | VPN connection configured on this VM |
Reference: Nedbank VM¶
| Item | Value |
|---|---|
| Nedbank VM VPN IP | 192.168.32.5 |
Alert / incident email (real-time PTI delivery failures)¶
Source: email snippet (date/sender not included in excerpt)
Message:
- Nedbank reported failures while sending real time PTI notifications and asked CT Market to verify their side.
Key identifiers provided:
| Field | Value |
|---|---|
| Profile No | 4000005683 |
| Instance | 1 |
| Protocol | WEB |
| Destination Address | https://nedbank.banking.ctmarket.co.za/zoap/ctm/server |
Notes:
- This is a good breadcrumb for correlating Nedbank-side logs/transaction keys with CT Market server logs at the time of failure.
PTI ↔ FTI reconciliation issues (historical)¶
Key mismatches / gaps¶
| Issue | What we observed | Why it mattered | Nedbank response / outcome |
|---|---|---|---|
| No shared unique transaction identifier between PTI and FTI | PTI and FTI are separate products; only common fields were typically amount and description | Prevented deterministic matching of each PTI event to its finalised FTI record; some reconciliation would require heuristics/manual review | Confirmed: no direct link between PTI and FTI data beyond amount/description |
| PTI has Channel + Transaction Type strings, but FTI uses Transaction Code (+ Sub Transaction Code) | PTI message includes string fields like channel/type; FTI provides numeric codes | Could not translate FTI codes to PTI’s channel/type labels using the provided manuals alone | Confirmed: transaction codes are not listed on PTI; FTI transaction code indicates the channel/payment type (EFT/ATM/Branch/etc) |
| Need a mapping table from FTI TransactionCode → PTI channel/type | Example: FTI TransactionCode 1324 did not obviously map to PTI labels |
Needed for automated reconciliation and reporting consistency across PTI vs FTI | Nedbank provided a list of transaction codes (and noted they differ conceptually from PTI fields) |
| FTI template lacked record identifiers needed for processing | Desired: FTI CSV Template 3 (includes Record Identifiers) rather than Template 1 | Record identifiers would help de-duplication and internal processing even if PTI/FTI can’t be perfectly matched | Nedbank agreed to adjust the FTI CSV template; change to reflect from the next morning |
| Environment separation needed (QA vs PROD) | Initially the same URI was used for speed; later realised separate URLs were required | Prevented clean QA testing without risking PROD traffic and reduced operational safety | Infrastructure request needed to add/configure QA URL; technical meeting to be scheduled |
Example lines referenced in the thread (for context)¶
PTI example (shows channel/type as strings):
FTI example (uses transaction code/sub-code):
Actions requested / recorded¶
| Item | Value |
|---|---|
| Requested QA endpoint to be used by Nedbank | https://nedbank.banking.ctmarket.co.za/zoap/ctm-qa/server |
| Note | Nedbank indicated an infrastructure request would be logged to add/configure the QA URL and a technical meeting would follow |
| Confirmation requested by Nedbank | Whether CT Market was comfortable with PTI PROD data |
Certificate exchange evidence (historical)¶
Email excerpt (David → Andries)
- “Attached is our certificate.”
- David stated SSL was configured and asked Nedbank to test mutual TLS via:
https://nedbank.banking.ctmarket.co.za/test/com_check.php- He also confirmed firewall access opened for Nedbank QA + PROD IPs.
Attached certificate artifact found
- File:
nedbank_banking_ctmarket_co_za.txt - Appears to be the server certificate for
nedbank.banking.ctmarket.co.za(public TLS) - CN:
nedbank.banking.ctmarket.co.za - Issuer: Sectigo RSA Domain Validation Secure Server CA
- Validity (from cert): 2020-10-23 to 2021-10-23
- SAN includes
nedbank.banking.ctmarket.co.zaandwww.nedbank.banking.ctmarket.co.za
Note
- This cert is a server-auth certificate (not a private client cert). It supports the idea that Nedbank/DataPower needed the endpoint cert/chain imported or pinned on their side.
Re-engagement milestone¶
- Date: Monday, 26 January 2026
- Event: Catch-up meeting with Nedbank to bring the PTI live feed back online.
- Outcome: Nedbank will resend the onboarding/integration information pack, including their required certificate generation specification (how they want the certificate/CSR produced).
Communication log — post-catchup notes (FTI/PTI + cert + endpoints)¶
Email excerpt (date not included in excerpt; follows the Jan 2026 catch-up)
Key points recorded by Nedbank:
| Topic | Notes |
|---|---|
| FTI status | Existing FTI (Bank statement) instance is inactive because an updated certificate was not provided; can be reinstated once updated certificate is provided. |
| Endpoints required | CT Market must provide IP address + endpoint for QA and PROD. |
| PTI vs FTI identifiers | PTI has transaction key; FTI has transaction code; no direct relevance between the two. Common reference point is the actual reference number. If the same transaction key is received, it usually indicates a duplicate transaction. |
| PTI coverage limitations | PTI is provisional; transactions already in the final run are not posted via PTI. Examples that will not appear in PTI but will appear in FTI: charges, fees, debit orders. |
| QA → PROD process | After infrastructure is confirmed, a few QA test files for PTI and FTI will be actioned before enabling the PROD profile. |
| Account type support | TI platform can only host current and savings accounts. |
| Call account | “The call account platform will be advised soonest.” (pending guidance) |
Manual excerpt screenshots (TI Host-to-Host User Manual)¶
These screenshots were attached to the email thread and confirm Nedbank’s WEB-services onboarding expectations.
Web services overview (manual excerpt)¶
- Nedbank’s standard delivery method is to send/push data to the client web service in real time.
- A WSDL (Web Service Definition Language) will be provided by Nedbank.
Information required from the client (manual excerpt):
- Static public IP address(es)
- Fully qualified URL
- Certificates for mutual authentication (if required; Nedbank can provide a certificate, possibly for an additional fee)
- The format/template of the encapsulated content sent in the web service call
TI third-party web service contract (manual excerpt)¶
- Step-by-step guidance:
- Extract the contract files
- Create/initiate a web service wizard
- Use
TIWebDistribution_2013-11-01.wsdlas the primary file - The screenshot shows the contract file set including:
TIWebDistribution_2013-11-01.wsdlTIWebDistribution_2013-11-01.htmEnterpriseContext_2008-09.wsdlEnterpriseContext_2008-09.xsd
Note:
- This aligns with the recovered WSDL/XSD artifacts already in this archive (EnterpriseContext + TIWebDistribution).