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:
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