12.58. DD 58: EBICS Transaction Unique ID

12.58.1. Summary

LibEufin Nexus need to have a single unique ID for each registered incoming transaction. For outgoing transaction we generate a unique ID ourselves but for incoming transaction we are dependent of whatever the bank provide. EBICS and ISO20022 do not provide a perfect transaction identifier and we need to have an ID that is compatible with different ISO20022 dialects and will be compatible with future specification changes.

12.58.2. Problem

ISO20022 provides many transaction identifier:

  • AcctSvcrRef (AccountServicerReference): unique reference, as assigned by the account servicing institution, to unambiguously identify the instruction. The format is ambiguous, and it is only unique within the account servicing institution. This identifier can be present a the entry level and/or at the transaction level (a single entry can be a batch of transaction), this make this identifier sometimes a bit ambiguous.

  • UETR (unique end-to-end transaction reference): universally unique identifier to provide an end-to-end reference of a payment transaction. This is the perfect unique ID, it’s a UUID v4 that is shared with all participant of the transfer.

  • TxId (TransactionIdentification): unique identification, as assigned by the first instructing agent, to unambiguously identify the transaction that is passed on, unchanged, throughout the entire interbank chain. The format is ambiguous and only unique for a “pre-agreed period”, whatever that means, but it is shared all participant of the transfer.

  • EndToEndId (EndToEndIdentification): unique identification, as assigned by the initiating party, to unambiguously identify the transaction. This identification is passed on, unchanged, throughout the entire end-to-end chain. The format is unspecified and nothing guaranteed it will actually be unique as institution are not expected to enforce uniqueness, it is also often NOTPROVIDED.

All those identifiers are optional and of course not a single one of them is consistently present in all dialects and all files.

  • DE dialect: AcctSvcrRef is mandatory in camt.53 and camt.52 but is never present in camt.54 (for instant payments). UETR is optional but never found in practice. TxId is optional but can be found everywhere (also in camt.54). If a transaction is made between two institutions, the TxId is constantly provided, but when a transaction is made within a single institution (between two accounts at the same bank) only the AcctSvcrRef is present.

  • CH dialect: AcctSvcrRef is mandatory everywhere. UETR can be found everywhere. If a transaction is made between two institutions, the UETR is constantly provided, but when a transaction is made within a single institution (between two accounts at the same bank) only the AcctSvcrRef is present. TxId is never provided.

Currently libeufin-nexus stores a single bank id in a bank_id column. This is TxId for DE banks and UETR for CH banks. When a transaction have neither we ignore the transaction and log a warning.

The current state is bad as we ignore transactions that we could actually correctly store and, as ISO20022 is going to move to mandatory UETR in the future, we should be able to support it for all dialects in the future.

12.58.3. Solution

We should embrace this imperfection and store all the identifiers that are provided as there is always at least one present:

We should then be able to store all transaction and support UETR everywhere in the future.

12.58.4. Migration

Before running the SQL migration script we can store the current dialect in a Postgres session variable that will then be used to move the current bank_id into the appropriate column.