SWIFT ACK Message Parsing

Rajendra picture Rajendra · Jan 15, 2016 · Viewed 11.4k times · Source

I am Generating a SWIFT Messages MT 110 and MT 103 through my java based application. For reconciliation and sharing with end customer, we need to map the Ack Nak message received from SWIFT terminal back to MT 110 and MT 103 transactions. To do this I need to parse each ACK file and find out

20: Sender's Reference ABC1380Q02418

451:0 (ACK)

451:1 (NAK) then 405 field.

I have tried doing this using Prowide Core (WIFE) Open source SWIFT Java library but I am not able to parse the ACK. Through library I am able to parse MT 110 and MT 103 messages but not ACK or NAK messages. Need you help in understanding how to parse the SWIFT ACK NAK file through Prowide Core (WIFE) Open source SWIFT Java library.

Sample ACK message pasted below:

23/12/15-11:50:14 BulBoardCTFACK-0192-000001 1


--------------------- Instance Type and Transmission --------------

Notification (Transmission) of Original sent to SWIFT (ACK)

Network Delivery Status : Network Ack

Priority/Delivery : Normal

Message Input Reference : 1150 151223ABCINBBADEL2567311531

--------------------------- Message Header -------------------------

Swift Input : FIN 103 Single Customer Credt Transfer

Sender : ABCDINBBDEL TTTT BANK LIMITED (XXXXX BRANCH) YYYYYYYYY YY

Receiver : ANZBAU3MXXX AUSTRALIA AND NEW ZEALAND BANKING GROUP LIMITED MELBOURNE AU

--------------------------- Message Text ---------------------------

20: Sender's Reference ABC1380Q02418

23B: Bank Operation Code CRED

32A: Val Dte/Curr/Interbnk Settld Amt Date : 23 December 2015 Currency : AUD (AUSTRALIAN DOLLAR) Amount : #8000,0#

33B: Currency/Instructed Amount Currency : AUD (AUSTRALIAN DOLLAR) Amount : #8000,0#

50K: Ordering Customer-Name & Address /M4132378 ABC DEF GHI 76 AX , MODEL TOWN EXT , XXXXXXXX

53A: Sender's Correspondent - FI BIC /1111111 00001 ABCDEFBBDEL ABC

57D: Account With Inst -Name & Addr //AU063144 COMMON WEALTH BANK AUSTRALIA SWIFT CODE CTBAAU2S

59: Beneficiary Customer-Name & Addr /555555 ABCDEF YYYYYYYYY

70: Remittance Information MAINTENACE

71A: Details of Charges BEN

71F: Sender's Charges Currency : AUD (AUSTRALIAN DOLLAR) Amount : #0,0#

--------------------------- Message Trailer ------------------------

{CHK:41B1AA23FEDF}

PKI Signature: MAC-Equivalent

---------------------------- Interventions -------------------------

Category : Network Report

Creation Time : 23/12/15 11:50:03

Application : SWIFT Interface

Operator : SYSTEM

Text

{1:F21ABCDEFBBADEL2567311531}{4:{177:1512231150}{451:0}}

Answer

Sebastian Zubrinic picture Sebastian Zubrinic · Dec 27, 2016

The posted sample is an expanded-print-out, not a message in SWIFT FIN format. However, on the last line referred as "Text" you have the FIN system message, which is parseable by Prowide Core.

{1:F21ABCDEFBBADEL2567311531}{4:{177:1512231150}{451:0}}

Field 451 in the system message indicates whether the message was acked (0) or nacked (1). When nacked the field 405 will contain the error code. For example: {405:T33002}

The most common structure is the system message with the ACK/NAK followed by a full copy of the original message:

{1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}}{1:F01LITEBEBBAXXX0066000079}{2:I999LITEBEBBXXXXN}{4:
:20:TESTREF1
:79:This is text line 1
-}{5:{CHK:7602B010CF31}{TNG:}}

First step would be to determine if a received message is and ACK/NAK. Once the message is parsed as SwiftMessage, this methods can be use to verify if it is a regular FIN user to user message or if it is a system message with an ACK/NAK

SwiftMessage.isSystemMessage()
SwiftMessage.isAck()
SwiftMessage.isNack()

Second step would be to split the ACK/NAK information from the identification of the original message. This example uses the most common format which is the ACK/NAK message followed by the full copy of the original message (this is the for example the format used by SAA AFT, or SA Lite autoclient). To parse both the ACK/NAK and the original copy:

Swiftparser parser = new SwiftParser();
SwiftMessage ack = parser.parse(msg);
SwiftMessage original = parser.parse(ack.getUnparsedTexts().getAsFINString());

Finally, to match the acked/nacked message with its original message, a query on candidates must be done (usually searching for messages for the same day and same message type). Finding candidates is not covered by the library because it involves searching the application database or reading the sent messages from a file system directory. Although, within candidates the the matching can be accomplished like this:

AckMessageComparator comparator = new AckMessageComparator();
    for (SwiftMessage candidate : candidates) {
        if (comparator.compare(original, candidate) == 0) {
            //candidate is the message acked/nacked
        }
    }

Depending on the acknowledge notification source the structure of the message may differ. For instance the full copy of the original message could be missing. However, other kind of reference to the original acked/nacked message must be there, for example the MUR (Message User Reference) like this:

{1:F21LITEBEBBAXXX0066000079}{4:{177:1104180901}{451:0}{108:FOO16101900001}}

So to match the original message, instead of using the full message copy and the AckMessageComparator, a message with the same MUR must be found:

for (SwiftMessage candidate : candidates) {
        if (StringUtils.equals(ack.getMUR(), candidate.getMUR())) {
             candidate is the message acked/nacked
        }
    }

If neither the original message copy or MUR are present in the ACK/NAK, maybe the UUID (Unique Identifier) is present and the candidates can be matched stripping from the UUID fields like the receiver address, message type and reference.

Some way or the other the ACK/NAK must provide information to properly match the original message being acknowledged.