libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit 7bdc61500245953689cf0aafae019eda1c539986
parent 8c6e95ee3f5f3c8495ef8c932cd95a99b293c6d7
Author: Antoine A <>
Date:   Tue, 12 Nov 2024 18:08:58 +0100

nexus: add maerki_baumann dialect and parse sample

Diffstat:
Anexus/conf/maerki_baumann.conf | 16++++++++++++++++
Mnexus/sample/platform/gls_pain001.xml | 4++--
Anexus/sample/platform/maerki_baumann_camt053.xml | 196+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Anexus/sample/platform/maerki_baumann_pain001.xml | 2++
Mnexus/sample/platform/postfinance_pain001.xml | 4++--
Mnexus/src/main/kotlin/tech/libeufin/nexus/Config.kt | 3++-
Mnexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt | 2+-
Mnexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsOrder.kt | 5++++-
Mnexus/src/main/kotlin/tech/libeufin/nexus/iso20022/camt.kt | 44+++++++++++++++++++++++++++++++++++++++++++-
Mnexus/src/main/kotlin/tech/libeufin/nexus/iso20022/pain001.kt | 1+
Mnexus/src/test/kotlin/Iso20022Test.kt | 23+++++++++++++++++++++++
Mnexus/src/test/kotlin/RegistrationTest.kt | 29+++++++++++++++++++++++++++++
12 files changed, 321 insertions(+), 8 deletions(-)

diff --git a/nexus/conf/maerki_baumann.conf b/nexus/conf/maerki_baumann.conf @@ -0,0 +1,15 @@ +[nexus-ebics] +CURRENCY = CHF + +BANK_DIALECT = maerki_baumann + +HOST_ID = PFEBICS +USER_ID = PFC00563 +PARTNER_ID = PFC00563 + +IBAN = DE89500105171325381664 +BIC = BIC +NAME = myname + +[libeufin-nexusdb-postgres] +CONFIG = postgres:///libeufincheck +\ No newline at end of file diff --git a/nexus/sample/platform/gls_pain001.xml b/nexus/sample/platform/gls_pain001.xml @@ -1 +1 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09 pain.001.001.09.xsd"><CstmrCdtTrfInitn><GrpHdr><MsgId>MESSAGE_ID</MsgId><CreDtTm>2024-09-09T00:00:00Z</CreDtTm><NbOfTxs>3</NbOfTxs><CtrlSum>47.32</CtrlSum><InitgPty><Nm>myname</Nm></InitgPty><InitnSrc><Nm>LibEuFin</Nm><Prvdr>Taler Systems SA</Prvdr><Vrsn>VERSION</Vrsn></InitnSrc></GrpHdr><PmtInf><PmtInfId>NOTPROVIDED</PmtInfId><PmtMtd>TRF</PmtMtd><BtchBookg>false</BtchBookg><NbOfTxs>3</NbOfTxs><CtrlSum>47.32</CtrlSum><PmtTpInf><SvcLvl><Cd>SEPA</Cd></SvcLvl></PmtTpInf><ReqdExctnDt><Dt>2024-09-09Z</Dt></ReqdExctnDt><Dbtr><Nm>myname</Nm></Dbtr><DbtrAcct><Id><IBAN>CH7789144474425692816</IBAN></Id></DbtrAcct><DbtrAgt><FinInstnId><BICFI>BIC</BICFI></FinInstnId></DbtrAgt><ChrgBr>SLEV</ChrgBr><CdtTrfTxInf><PmtId><InstrId>TX_FIRST</InstrId><EndToEndId>TX_FIRST</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">42</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 42</Ustrd></RmtInf></CdtTrfTxInf><CdtTrfTxInf><PmtId><InstrId>TX_SECOND</InstrId><EndToEndId>TX_SECOND</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">5.11</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 5.11</Ustrd></RmtInf></CdtTrfTxInf><CdtTrfTxInf><PmtId><InstrId>TX_THIRD</InstrId><EndToEndId>TX_THIRD</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">0.21</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 0.21</Ustrd></RmtInf></CdtTrfTxInf></PmtInf></CstmrCdtTrfInitn></Document> -\ No newline at end of file +<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09 pain.001.001.09.xsd"><CstmrCdtTrfInitn><GrpHdr><MsgId>MESSAGE_ID</MsgId><CreDtTm>2024-09-09T00:00:00Z</CreDtTm><NbOfTxs>3</NbOfTxs><CtrlSum>47.32</CtrlSum><InitgPty><Nm>myname</Nm></InitgPty></GrpHdr><PmtInf><PmtInfId>NOTPROVIDED</PmtInfId><PmtMtd>TRF</PmtMtd><BtchBookg>false</BtchBookg><NbOfTxs>3</NbOfTxs><CtrlSum>47.32</CtrlSum><PmtTpInf><SvcLvl><Cd>SEPA</Cd></SvcLvl></PmtTpInf><ReqdExctnDt><Dt>2024-09-09Z</Dt></ReqdExctnDt><Dbtr><Nm>myname</Nm></Dbtr><DbtrAcct><Id><IBAN>CH7789144474425692816</IBAN></Id></DbtrAcct><DbtrAgt><FinInstnId><BICFI>BIC</BICFI></FinInstnId></DbtrAgt><ChrgBr>SLEV</ChrgBr><CdtTrfTxInf><PmtId><InstrId>TX_FIRST</InstrId><EndToEndId>TX_FIRST</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">42</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 42</Ustrd></RmtInf></CdtTrfTxInf><CdtTrfTxInf><PmtId><InstrId>TX_SECOND</InstrId><EndToEndId>TX_SECOND</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">5.11</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 5.11</Ustrd></RmtInf></CdtTrfTxInf><CdtTrfTxInf><PmtId><InstrId>TX_THIRD</InstrId><EndToEndId>TX_THIRD</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">0.21</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 0.21</Ustrd></RmtInf></CdtTrfTxInf></PmtInf></CstmrCdtTrfInitn></Document> +\ No newline at end of file diff --git a/nexus/sample/platform/maerki_baumann_camt053.xml b/nexus/sample/platform/maerki_baumann_camt053.xml @@ -0,0 +1,195 @@ +<?xml version="1.0" encoding="UTF-8"?> +<Document xmlns="urn:iso:std:iso:20022:tech:xsd:camt.053.001.08"> + <BkToCstmrStmt> + <GrpHdr> + <MsgId>2024111201095780</MsgId> + <CreDtTm>2024-11-12T17:10:27+01:00</CreDtTm> + <MsgPgntn> + <PgNb>1</PgNb> + <LastPgInd>true</LastPgInd> + </MsgPgntn> + </GrpHdr> + <Stmt> + <Ntry> + <Amt Ccy="CHF">.8</Amt> + <CdtDbtInd>CRDT</CdtDbtInd> + <RvslInd>false</RvslInd> + <Sts> + <Cd>BOOK</Cd> + </Sts> + <BookgDt> + <Dt>2024-11-04</Dt> + </BookgDt> + <ValDt> + <Dt>2024-11-04</Dt> + </ValDt> + <BkTxCd> + <Domn> + <Cd>PMNT</Cd> + <Fmly> + <Cd>RCDT</Cd> + <SubFmlyCd>OTHR</SubFmlyCd> + </Fmly> + </Domn> + </BkTxCd> + <NtryDtls> + <Btch> + <NbOfTxs>1</NbOfTxs> + <TtlAmt Ccy="CHF">.8</TtlAmt> + <CdtDbtInd>CRDT</CdtDbtInd> + </Btch> + <TxDtls> + <Refs> + <AcctSvcrRef>ZV20241104/765446/1</AcctSvcrRef> + <EndToEndId>NOTPROVIDED</EndToEndId> + <UETR>adbe4a5a-6cea-4263-b259-8ab964561a32</UETR> + <TxId>41103099704.0002</TxId> + </Refs> + <Amt Ccy="CHF">.8</Amt> + <CdtDbtInd>CRDT</CdtDbtInd> + <AmtDtls> + <InstdAmt> + <Amt Ccy="CHF">1</Amt> + </InstdAmt> + <TxAmt> + <Amt Ccy="CHF">1</Amt> + </TxAmt> + </AmtDtls> + <Chrgs> + <Rcrd> + <Amt Ccy="CHF">.2</Amt> + <CdtDbtInd>DBIT</CdtDbtInd> + <ChrgInclInd>true</ChrgInclInd> + <Tp> + <Prtry> + <Id>PT inc.paym.exp</Id> + </Prtry> + </Tp> + <Br>CRED</Br> + </Rcrd> + </Chrgs> + <RltdPties> + <Dbtr> + <Pty> + <Nm>Mr Test</Nm> + </Pty> + </Dbtr> + <DbtrAcct> + <Id> + <IBAN>CH7389144832588726658</IBAN> + </Id> + </DbtrAcct> + </RltdPties> + <RltdAgts> + <DbtrAgt> + <FinInstnId> + <ClrSysMmbId> + <ClrSysId> + <Cd>CHSIC</Cd> + </ClrSysId> + <MmbId>087042</MmbId> + </ClrSysMmbId> + </FinInstnId> + </DbtrAgt> + </RltdAgts> + <RmtInf> + <Ustrd>SFHP6H24C16A5J05Q3FJW2XN1PB3EK70ZPY 5SJ30ADGY68FWN68G</Ustrd> + </RmtInf> + <AddtlTxInf>Bank clearing payment Grothoff Hans</AddtlTxInf> + </TxDtls> + </NtryDtls> + <AddtlNtryInf>Bank clearing payment Grothoff Hans</AddtlNtryInf> + </Ntry> + <Ntry> + <Amt Ccy="CHF">.8</Amt> + <CdtDbtInd>CRDT</CdtDbtInd> + <RvslInd>false</RvslInd> + <Sts> + <Cd>BOOK</Cd> + </Sts> + <BookgDt> + <Dt>2024-11-04</Dt> + </BookgDt> + <ValDt> + <Dt>2024-11-04</Dt> + </ValDt> + <BkTxCd> + <Domn> + <Cd>PMNT</Cd> + <Fmly> + <Cd>RCDT</Cd> + <SubFmlyCd>OTHR</SubFmlyCd> + </Fmly> + </Domn> + </BkTxCd> + <NtryDtls> + <Btch> + <NbOfTxs>1</NbOfTxs> + <TtlAmt Ccy="CHF">.8</TtlAmt> + <CdtDbtInd>CRDT</CdtDbtInd> + </Btch> + <TxDtls> + <Refs> + <AcctSvcrRef>ZV20241104/765447/1</AcctSvcrRef> + <EndToEndId>NOTPROVIDED</EndToEndId> + <UETR>7371795e-62fa-42dd-93b7-da89cc120faa</UETR> + <TxId>41103099704.0003</TxId> + </Refs> + <Amt Ccy="CHF">.8</Amt> + <CdtDbtInd>CRDT</CdtDbtInd> + <AmtDtls> + <InstdAmt> + <Amt Ccy="CHF">1</Amt> + </InstdAmt> + <TxAmt> + <Amt Ccy="CHF">1</Amt> + </TxAmt> + </AmtDtls> + <Chrgs> + <Rcrd> + <Amt Ccy="CHF">.2</Amt> + <CdtDbtInd>DBIT</CdtDbtInd> + <ChrgInclInd>true</ChrgInclInd> + <Tp> + <Prtry> + <Id>PT inc.paym.exp</Id> + </Prtry> + </Tp> + <Br>CRED</Br> + </Rcrd> + </Chrgs> + <RltdPties> + <Dbtr> + <Pty> + <Nm>Mr Test</Nm> + </Pty> + </Dbtr> + <DbtrAcct> + <Id> + <IBAN>CH7389144832588726658</IBAN> + </Id> + </DbtrAcct> + </RltdPties> + <RltdAgts> + <DbtrAgt> + <FinInstnId> + <ClrSysMmbId> + <ClrSysId> + <Cd>CHSIC</Cd> + </ClrSysId> + <MmbId>087042</MmbId> + </ClrSysMmbId> + </FinInstnId> + </DbtrAgt> + </RltdAgts> + <RmtInf> + <Ustrd>Random subject</Ustrd> + </RmtInf> + <AddtlTxInf>Bank clearing payment Grothoff Hans</AddtlTxInf> + </TxDtls> + </NtryDtls> + <AddtlNtryInf>Bank clearing payment Grothoff Hans</AddtlNtryInf> + </Ntry> + </Stmt> + </BkToCstmrStmt> +</Document> +\ No newline at end of file diff --git a/nexus/sample/platform/maerki_baumann_pain001.xml b/nexus/sample/platform/maerki_baumann_pain001.xml @@ -0,0 +1 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09 pain.001.001.09.xsd"><CstmrCdtTrfInitn><GrpHdr><MsgId>MESSAGE_ID</MsgId><CreDtTm>2024-09-09T00:00:00Z</CreDtTm><NbOfTxs>3</NbOfTxs><CtrlSum>47.32</CtrlSum><InitgPty><Nm>myname</Nm></InitgPty></GrpHdr><PmtInf><PmtInfId>NOTPROVIDED</PmtInfId><PmtMtd>TRF</PmtMtd><BtchBookg>false</BtchBookg><NbOfTxs>3</NbOfTxs><CtrlSum>47.32</CtrlSum><PmtTpInf><SvcLvl><Cd>SDVA</Cd></SvcLvl></PmtTpInf><ReqdExctnDt><Dt>2024-09-09Z</Dt></ReqdExctnDt><Dbtr><Nm>myname</Nm></Dbtr><DbtrAcct><Id><IBAN>CH7789144474425692816</IBAN></Id></DbtrAcct><DbtrAgt><FinInstnId><BICFI>BIC</BICFI></FinInstnId></DbtrAgt><ChrgBr>SLEV</ChrgBr><CdtTrfTxInf><PmtId><InstrId>TX_FIRST</InstrId><EndToEndId>TX_FIRST</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">42</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 42</Ustrd></RmtInf></CdtTrfTxInf><CdtTrfTxInf><PmtId><InstrId>TX_SECOND</InstrId><EndToEndId>TX_SECOND</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">5.11</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 5.11</Ustrd></RmtInf></CdtTrfTxInf><CdtTrfTxInf><PmtId><InstrId>TX_THIRD</InstrId><EndToEndId>TX_THIRD</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">0.21</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 0.21</Ustrd></RmtInf></CdtTrfTxInf></PmtInf></CstmrCdtTrfInitn></Document> +\ No newline at end of file diff --git a/nexus/sample/platform/postfinance_pain001.xml b/nexus/sample/platform/postfinance_pain001.xml @@ -1 +1 @@ -<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09 pain.001.001.09.xsd"><CstmrCdtTrfInitn><GrpHdr><MsgId>MESSAGE_ID</MsgId><CreDtTm>2024-09-09T00:00:00Z</CreDtTm><NbOfTxs>3</NbOfTxs><CtrlSum>47.32</CtrlSum><InitgPty><Nm>myname</Nm></InitgPty><InitnSrc><Nm>LibEuFin</Nm><Prvdr>Taler Systems SA</Prvdr><Vrsn>VERSION</Vrsn></InitnSrc></GrpHdr><PmtInf><PmtInfId>NOTPROVIDED</PmtInfId><PmtMtd>TRF</PmtMtd><BtchBookg>false</BtchBookg><NbOfTxs>3</NbOfTxs><CtrlSum>47.32</CtrlSum><PmtTpInf><SvcLvl><Cd>SDVA</Cd></SvcLvl></PmtTpInf><ReqdExctnDt><Dt>2024-09-09Z</Dt></ReqdExctnDt><Dbtr><Nm>myname</Nm></Dbtr><DbtrAcct><Id><IBAN>CH7789144474425692816</IBAN></Id></DbtrAcct><DbtrAgt><FinInstnId><BICFI>BIC</BICFI></FinInstnId></DbtrAgt><ChrgBr>SLEV</ChrgBr><CdtTrfTxInf><PmtId><InstrId>TX_FIRST</InstrId><EndToEndId>TX_FIRST</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">42</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 42</Ustrd></RmtInf></CdtTrfTxInf><CdtTrfTxInf><PmtId><InstrId>TX_SECOND</InstrId><EndToEndId>TX_SECOND</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">5.11</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 5.11</Ustrd></RmtInf></CdtTrfTxInf><CdtTrfTxInf><PmtId><InstrId>TX_THIRD</InstrId><EndToEndId>TX_THIRD</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">0.21</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 0.21</Ustrd></RmtInf></CdtTrfTxInf></PmtInf></CstmrCdtTrfInitn></Document> -\ No newline at end of file +<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:iso:std:iso:20022:tech:xsd:pain.001.001.09 pain.001.001.09.xsd"><CstmrCdtTrfInitn><GrpHdr><MsgId>MESSAGE_ID</MsgId><CreDtTm>2024-09-09T00:00:00Z</CreDtTm><NbOfTxs>3</NbOfTxs><CtrlSum>47.32</CtrlSum><InitgPty><Nm>myname</Nm></InitgPty></GrpHdr><PmtInf><PmtInfId>NOTPROVIDED</PmtInfId><PmtMtd>TRF</PmtMtd><BtchBookg>false</BtchBookg><NbOfTxs>3</NbOfTxs><CtrlSum>47.32</CtrlSum><PmtTpInf><SvcLvl><Cd>SDVA</Cd></SvcLvl></PmtTpInf><ReqdExctnDt><Dt>2024-09-09Z</Dt></ReqdExctnDt><Dbtr><Nm>myname</Nm></Dbtr><DbtrAcct><Id><IBAN>CH7789144474425692816</IBAN></Id></DbtrAcct><DbtrAgt><FinInstnId><BICFI>BIC</BICFI></FinInstnId></DbtrAgt><ChrgBr>SLEV</ChrgBr><CdtTrfTxInf><PmtId><InstrId>TX_FIRST</InstrId><EndToEndId>TX_FIRST</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">42</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 42</Ustrd></RmtInf></CdtTrfTxInf><CdtTrfTxInf><PmtId><InstrId>TX_SECOND</InstrId><EndToEndId>TX_SECOND</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">5.11</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 5.11</Ustrd></RmtInf></CdtTrfTxInf><CdtTrfTxInf><PmtId><InstrId>TX_THIRD</InstrId><EndToEndId>TX_THIRD</EndToEndId></PmtId><Amt><InstdAmt Ccy="EUR">0.21</InstdAmt></Amt><Cdtr><Nm>Test</Nm></Cdtr><CdtrAcct><Id><IBAN>CH4189144589712575493</IBAN></Id></CdtrAcct><RmtInf><Ustrd>Test 0.21</Ustrd></RmtInf></CdtTrfTxInf></PmtInf></CstmrCdtTrfInitn></Document> +\ No newline at end of file diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Config.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Config.kt @@ -80,7 +80,8 @@ class NexusEbicsConfig( val dialect = sect.map("bank_dialect", "dialect", mapOf( "postfinance" to Dialect.postfinance, - "gls" to Dialect.gls + "gls" to Dialect.gls, + "maerki_baumann" to Dialect.maerki_baumann, )).require() /** Path where we store the bank public keys */ diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt @@ -311,7 +311,7 @@ suspend fun keyManagement( val ebics3 = when (cfg.dialect) { // TODO GLS needs EBICS 2.5 for key management Dialect.gls -> false - Dialect.postfinance -> true + else -> true } val req = EbicsKeyMng(cfg, privs, ebics3).request(order) val xml = client.postToBank(cfg.host.baseUrl, req, order.name, txLog.step()) diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsOrder.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsOrder.kt @@ -151,7 +151,8 @@ enum class OrderDoc { enum class Dialect { postfinance, - gls; + gls, + maerki_baumann; fun downloadDoc(doc: OrderDoc, ebics2: Boolean): EbicsOrder { return when (this) { @@ -182,6 +183,7 @@ enum class Dialect { OrderDoc.statement -> EbicsOrder.V3("BTD", "EOP", "DE", "camt.053", null, "ZIP") OrderDoc.notification -> EbicsOrder.V3("BTD", "STM", "DE", "camt.054", null, "ZIP", "SCI") } + maerki_baumann -> throw IllegalArgumentException("Maerki Baumann does not have EBICS access") } } @@ -189,6 +191,7 @@ enum class Dialect { return when (this) { postfinance -> EbicsOrder.V3("BTU", "MCT", "CH", "pain.001", "09") gls -> EbicsOrder.V3("BTU", "SCT", null, "pain.001") + maerki_baumann -> throw IllegalArgumentException("Maerki Baumann does not have EBICS access") } } diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/iso20022/camt.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/iso20022/camt.kt @@ -172,7 +172,14 @@ private fun XmlDestructor.amount(acceptedCurrency: String) = one("Amt") { val currency = attr("Ccy") /** FIXME: test by sending non-CHF to PoFi and see which currency gets here. */ if (currency != acceptedCurrency) throw Exception("Currency $currency not supported") - TalerAmount("$currency:${text()}") + val amount = text() + val concat = if (amount.startsWith('.')) { + "$currency:0$amount" + } else { + "$currency:$amount" + } + println(concat) + TalerAmount(concat) } /** Parse bank transaction code */ @@ -431,6 +438,41 @@ fun parseTx( } } } + Dialect.maerki_baumann -> { + opt("BkToCstmrStmt")?.each("Stmt") { // Camt.053 + opt("Acct") { + // Sanity check on currency and IBAN ? + } + each("Ntry") { + if (!isBooked()) return@each + val code = bankTransactionCode() + if (!code.isPayment()) return@each + + val entryRef = opt("AcctSvcrRef")?.text() + val bookDate = executionDate() + val amount = amount(acceptedCurrency) + one("NtryDtls").one("TxDtls") { + val txRef = opt("Refs")?.opt("AcctSvcrRef")?.text() + val kind = one("CdtDbtInd").enum<Kind>() + val code = optBankTransactionCode() ?: code + val subject = wireTransferSubject() + if (!code.isReversal() && kind == Kind.CRDT) { + val bankId = opt("Refs")?.opt("UETR")?.text() + val debtorPayto = payto("Dbtr") + txsInfo.add(TxInfo.Credit( + ref = bankId ?: txRef ?: entryRef, + bookDate = bookDate, + bankId = bankId, + amount = amount, + subject = subject, + debtorPayto = debtorPayto, + code = code + )) + } + } + } + } + } }} return txsInfo.mapNotNull { diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/iso20022/pain001.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/iso20022/pain001.kt @@ -88,6 +88,7 @@ fun createPain001( el("PmtTpInf/SvcLvl/Cd", when (dialect) { Dialect.postfinance -> "SDVA" + Dialect.maerki_baumann -> "SDVA" // TODO Dialect.gls -> "SEPA" } ) diff --git a/nexus/src/test/kotlin/Iso20022Test.kt b/nexus/src/test/kotlin/Iso20022Test.kt @@ -331,6 +331,29 @@ class Iso20022Test { } @Test + fun maerki_baumann_camt053() { + assertContentEquals( + parseTx(Path("sample/platform/maerki_baumann_camt053.xml").inputStream(), "CHF", Dialect.maerki_baumann), + listOf( + IncomingPayment( + bankId = "adbe4a5a-6cea-4263-b259-8ab964561a32", + amount = TalerAmount("CHF:0.8"), + subject = "SFHP6H24C16A5J05Q3FJW2XN1PB3EK70ZPY 5SJ30ADGY68FWN68G", + executionTime = dateToInstant("2024-11-04"), + debtorPayto = ibanPayto("CH7389144832588726658", "Mr Test") + ), + IncomingPayment( + bankId = "7371795e-62fa-42dd-93b7-da89cc120faa", + amount = TalerAmount("CHF:0.8"), + subject = "Random subject", + executionTime = dateToInstant("2024-11-04"), + debtorPayto = ibanPayto("CH7389144832588726658", "Mr Test") + ) + ) + ) + } + + @Test fun pain002() { assertEquals( parseCustomerPaymentStatusReport(Path("sample/platform/pain002.xml").inputStream()), diff --git a/nexus/src/test/kotlin/RegistrationTest.kt b/nexus/src/test/kotlin/RegistrationTest.kt @@ -398,4 +398,33 @@ class RegistrationTest { ) ) } + + /** Maerki Baumann dialect test */ + @Test + fun maerki_baumann() = setup("maerki_baumann.conf") { db, cfg -> + // Register camt files + db.register(cfg, "sample/platform/maerki_baumann_camt053.xml", OrderDoc.statement) + + // Check state + db.check( + status = emptyMap(), + incoming = listOf( + IncomingPayment( + bankId = "adbe4a5a-6cea-4263-b259-8ab964561a32", + amount = TalerAmount("CHF:0.8"), + subject = "SFHP6H24C16A5J05Q3FJW2XN1PB3EK70ZPY 5SJ30ADGY68FWN68G", + executionTime = dateToInstant("2024-11-04"), + debtorPayto = ibanPayto("CH7389144832588726658", "Mr Test") + ), + IncomingPayment( + bankId = "7371795e-62fa-42dd-93b7-da89cc120faa", + amount = TalerAmount("CHF:0.8"), + subject = "Random subject", + executionTime = dateToInstant("2024-11-04"), + debtorPayto = ibanPayto("CH7389144832588726658", "Mr Test") + ) + ), + outgoing = emptyList() + ) + } } \ No newline at end of file