libeufin

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

commit 6d77803d186047266af4bfe9b49b9b5f0db3d82d
parent be824e2b5977068daaa41d81ae9eb9422bc7036d
Author: Antoine A <>
Date:   Tue,  2 Jun 2026 18:03:41 +0200

nexus: fix fake incoming

Diffstat:
Mlibeufin-common/src/main/kotlin/TalerCommon.kt | 6+++---
Mlibeufin-common/src/main/kotlin/TalerConfig.kt | 3+++
Mlibeufin-nexus/src/main/kotlin/tech/libeufin/nexus/Config.kt | 6+++---
Mlibeufin-nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt | 3++-
Mlibeufin-nexus/src/main/kotlin/tech/libeufin/nexus/api/PreparedTransferApi.kt | 2+-
Mlibeufin-nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsFetch.kt | 2+-
Mlibeufin-nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsSetup.kt | 2+-
Mlibeufin-nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsSubmit.kt | 2+-
Mlibeufin-nexus/src/main/kotlin/tech/libeufin/nexus/cli/Testing.kt | 6+++---
Mlibeufin-nexus/src/main/kotlin/tech/libeufin/nexus/iso20022/pain001.kt | 4++--
Mlibeufin-nexus/src/test/kotlin/Iso20022Test.kt | 4++--
11 files changed, 22 insertions(+), 18 deletions(-)

diff --git a/libeufin-common/src/main/kotlin/TalerCommon.kt b/libeufin-common/src/main/kotlin/TalerCommon.kt @@ -139,7 +139,7 @@ value class TalerTimestamp constructor(val instant: Instant) { } } } - + companion object { fun never(): TalerTimestamp = TalerTimestamp(Instant.MAX) } @@ -535,8 +535,8 @@ class IbanPayto internal constructor( return "payto://iban/$bic$iban$name" } - fun rand(name: String? = null): IbanPayto = parse( - "payto://iban/SANDBOXX/${IBAN.rand(Country.DE)}${ + fun rand(name: String? = null, country: Country = Country.DE): IbanPayto = parse( + "payto://iban/SANDBOXX/${IBAN.rand(country)}${ if (name != null) { "?receiver-name=${name.encodeURLParameter()}" } else { diff --git a/libeufin-common/src/main/kotlin/TalerConfig.kt b/libeufin-common/src/main/kotlin/TalerConfig.kt @@ -471,6 +471,9 @@ class TalerConfigSection internal constructor( /** Access [option] as BaseURL */ fun baseURL(option: String) = option(option, "baseURL") { BaseURL.parse(it) } + /** Access [option] as IBAN */ + fun iban(option: String) = option(option, "IBAN") { IBAN.parse(it) } + /** Access [option] as Int */ fun number(option: String) = option(option, "number") { it.toIntOrNull() ?: throw ValueError("'$it' not a valid number") diff --git a/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/Config.kt b/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/Config.kt @@ -90,13 +90,13 @@ class NexusEbicsConfig( val host by lazy { NexusHostConfig(sect) } /** Bank account metadata */ val account = IbanAccountMetadata( - iban = sect.string("iban").require(), + iban = sect.iban("iban").require(), bic = sect.string("bic").require(), name = sect.string("name").require() ) - val qrIban = sect.string("qr_iban").orNull() + val qrIban = sect.iban("qr_iban").orNull() /** Bank account payto */ - val payto = IbanPayto.build(account.iban, account.bic, account.name) + val payto = IbanPayto.build(account.iban.toString(), account.bic, account.name) val dialect = sect.map("bank_dialect", "bank dialect", mapOf( "postfinance" to Dialect.postfinance, diff --git a/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt b/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt @@ -40,11 +40,12 @@ import tech.libeufin.nexus.api.observabilityApi import tech.libeufin.nexus.cli.LibeufinNexus import tech.libeufin.nexus.db.Database import com.github.ajalt.clikt.core.main +import tech.libeufin.common.IBAN import java.time.Instant /** Triple identifying one IBAN bank account */ data class IbanAccountMetadata( - val iban: String, + val iban: IBAN, val bic: String?, val name: String ) diff --git a/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/api/PreparedTransferApi.kt b/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/api/PreparedTransferApi.kt @@ -69,7 +69,7 @@ fun Routing.preparedTransferAPI(db: Database, cfg: NexusConfig) = conditional(cf TalerErrorCode.BANK_BAD_SIGNATURE ) - val iban = req.credit_account.expectIban().iban.toString() + val iban = req.credit_account.expectIban().iban val reference = if (iban == cfg.ebics.account.iban) { null } else if (iban == cfg.ebics.qrIban) { diff --git a/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsFetch.kt b/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsFetch.kt @@ -233,7 +233,7 @@ suspend fun registerTxs( ): Int { var nbTx: Int = 0 parseTx(xml).forEach { accountTx -> - if (accountTx.iban == cfg.ebics.account.iban) { + if (accountTx.iban == cfg.ebics.account.iban.toString()) { require(accountTx.currency == null || accountTx.currency == cfg.currency) { "Expected transactions of currency ${cfg.currency} got ${accountTx.currency}" } accountTx.txs.forEach { tx -> when (tx) { diff --git a/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsSetup.kt b/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsSetup.kt @@ -143,7 +143,7 @@ class EbicsSetup: TalerCmd() { // Check partner info match config if (partner.name != null && partner.name != cfg.ebics.account.name) logger.warn("Expected NAME '${cfg.ebics.account.name}' from config got '${partner.name}' from bank") - val account = partner.accounts.find { it.iban == cfg.ebics.account.iban } + val account = partner.accounts.find { it.iban == cfg.ebics.account.iban.toString() } if (account != null) { if (account.currency != null && account.currency != cfg.currency) logger.error("Expected CURRENCY '${cfg.currency}' from config got '${account.currency}' from bank") diff --git a/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsSubmit.kt b/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/cli/EbicsSubmit.kt @@ -44,7 +44,7 @@ fun batchToPain001Msg(account: IbanAccountMetadata, batch: PaymentBatch): Pain00 } Pain001Tx( creditor = IbanAccountMetadata( - iban = payto.iban.value, + iban = payto.iban, bic = payto.bic, name = payto.receiverName ?: "Unknown" ), diff --git a/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/cli/Testing.kt b/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/cli/Testing.kt @@ -107,11 +107,11 @@ class FakeIncoming : TalerCmd() { creditPayto?.let { if (reference != null) { - require(it.iban.toString() == cfg.ebics.qrIban) { + require(it.iban == cfg.ebics.qrIban) { "Creditor must be the exchange QRR account expected ${cfg.ebics.account.iban} got ${it.iban}" } } else { - require(it.iban.toString() == cfg.ebics.account.iban) { + require(it.iban == cfg.ebics.account.iban) { "Creditor must be the exchange expected ${cfg.ebics.account.iban} got ${it.iban}" } } @@ -125,7 +125,7 @@ class FakeIncoming : TalerCmd() { db, cfg.ingest, IncomingPayment( amount = amount, - debtor = debitPayto ?: payto ?: IbanPayto.rand("Testing Account"), + debtor = debitPayto ?: payto ?: IbanPayto.rand("Testing Account", Country.valueOf(cfg.ebics.account.iban.value.substring(0 until 2))), subject = reference ?: subject ?: "", creditFee = creditFee, executionTime = Instant.now(), diff --git a/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/iso20022/pain001.kt b/libeufin-nexus/src/main/kotlin/tech/libeufin/nexus/iso20022/pain001.kt @@ -102,7 +102,7 @@ fun createPain001( } el("ReqdExctnDt/Dt", DateTimeFormatter.ISO_DATE.format(zonedTimestamp)) el("Dbtr/Nm", msg.debtor.name) - el("DbtrAcct/Id/IBAN", msg.debtor.iban) + el("DbtrAcct/Id/IBAN", msg.debtor.iban.toString()) el("DbtrAgt/FinInstnId") { if (msg.debtor.bic != null) { el("BICFI", msg.debtor.bic) @@ -131,7 +131,7 @@ fun createPain001( el("Ctry", "DE") }*/ } - el("CdtrAcct/Id/IBAN", tx.creditor.iban) + el("CdtrAcct/Id/IBAN", tx.creditor.iban.toString()) el("RmtInf/Ustrd", tx.subject) } } diff --git a/libeufin-nexus/src/test/kotlin/Iso20022Test.kt b/libeufin-nexus/src/test/kotlin/Iso20022Test.kt @@ -30,7 +30,7 @@ class Iso20022Test { @Test fun pain001() { val creditor = IbanAccountMetadata( - iban = "CH4189144589712575493", + iban = IBAN.parse("CH4189144589712575493"), bic = null, name = "Test" ) @@ -38,7 +38,7 @@ class Iso20022Test { messageId = "MESSAGE_ID", timestamp = dateToInstant("2024-09-09"), debtor = IbanAccountMetadata( - iban = "CH7789144474425692816", + iban = IBAN.parse("CH7789144474425692816"), bic = "BIC", name = "myname" ),