From 848bfdc091d126fbd97a359e3001cf3d1c7f42f7 Mon Sep 17 00:00:00 2001 From: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com> Date: Tue, 20 Jan 2026 21:20:33 +0100 Subject: [PATCH 1/2] feat(buy): make VIBAN mandatory for EUR transactions (#3005) - Automatically create VIBAN for EUR when user has KYC level 50+ - Throw KycRequired error for EUR users with KYC level below 50 - Non-EUR currencies (CHF, GBP) remain unchanged --- .../core/buy-crypto/routes/buy/buy.service.ts | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/subdomains/core/buy-crypto/routes/buy/buy.service.ts b/src/subdomains/core/buy-crypto/routes/buy/buy.service.ts index 5031a1702e..b52c3c59e2 100644 --- a/src/subdomains/core/buy-crypto/routes/buy/buy.service.ts +++ b/src/subdomains/core/buy-crypto/routes/buy/buy.service.ts @@ -355,6 +355,35 @@ export class BuyService { asset?: Asset, wallet?: Wallet, ): Promise { + // EUR: VIBAN is mandatory + if (selector.currency === 'EUR') { + if (selector.userData.kycLevel < KycLevel.LEVEL_50) { + throw new BadRequestException('KycRequired'); + } + + let virtualIban = await this.virtualIbanService.getActiveForUserAndCurrency(selector.userData, selector.currency); + + if (!virtualIban) { + virtualIban = await this.virtualIbanService.createForUser(selector.userData, selector.currency); + } + + const { address } = selector.userData; + return { + name: selector.userData.completeName, + street: address.street, + ...(address.houseNumber && { number: address.houseNumber }), + zip: address.zip, + city: address.city, + country: address.country?.name, + bank: virtualIban.bank.name, + iban: virtualIban.iban, + bic: virtualIban.bank.bic, + sepaInstant: virtualIban.bank.sctInst, + isPersonalIban: true, + reference: this.getBuyReference(buy?.bankUsage, false), + }; + } + // asset-specific personal IBAN if ( buy && From ccb302c45d30b7bfed3904b9acd2999fc17157d0 Mon Sep 17 00:00:00 2001 From: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com> Date: Tue, 20 Jan 2026 22:13:11 +0100 Subject: [PATCH 2/2] feat(fiat-output): enable auto-completion for EUR transactions (#3010) --- .../supporting/fiat-output/fiat-output-job.service.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/subdomains/supporting/fiat-output/fiat-output-job.service.ts b/src/subdomains/supporting/fiat-output/fiat-output-job.service.ts index a8d19cc2de..f23df436bb 100644 --- a/src/subdomains/supporting/fiat-output/fiat-output-job.service.ts +++ b/src/subdomains/supporting/fiat-output/fiat-output-job.service.ts @@ -393,7 +393,6 @@ export class FiatOutputJobService { amount: Not(IsNull()), isComplete: false, bankTx: { id: IsNull() }, - isReadyDate: Not(IsNull()), }, relations: { bankTx: { transaction: true }, bankTxReturn: true, bankTxRepeat: true }, }); @@ -401,7 +400,7 @@ export class FiatOutputJobService { for (const entity of entities) { try { const bankTx = await this.getMatchingBankTx(entity); - if (!bankTx || entity.isReadyDate > bankTx.created) continue; + if (!bankTx || (entity.isReadyDate && entity.isReadyDate > bankTx.created)) continue; const updateData: Partial = { bankTx,