From fafebea052d8f70fa0585b4268ddd6636dc72b07 Mon Sep 17 00:00:00 2001 From: TaprootFreak <142087526+TaprootFreak@users.noreply.github.com> Date: Thu, 4 Dec 2025 09:29:49 +0100 Subject: [PATCH 1/2] Disable credit card payment option - Block credit card payments in PaymentInfoService with clear error message - Add PAYMENT_METHOD_NOT_ALLOWED to QuoteError enum - Return error early in TransactionHelper for card payment quotes - Remove obsolete card-specific validation checks --- src/shared/services/payment-info.service.ts | 8 +++++--- .../dto/transaction-helper/quote-error.enum.ts | 1 + .../payment/services/transaction-helper.ts | 17 +++++------------ 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/shared/services/payment-info.service.ts b/src/shared/services/payment-info.service.ts index 0ce7b53d8e..b5d007510f 100644 --- a/src/shared/services/payment-info.service.ts +++ b/src/shared/services/payment-info.service.ts @@ -29,10 +29,12 @@ export class PaymentInfoService { if (!dto.asset) throw new NotFoundException('Asset not found'); if (jwt && !dto.asset.isBuyableOn(jwt.blockchains)) throw new BadRequestException('Asset blockchain mismatch'); + // Credit card payments disabled if ('paymentMethod' in dto && dto.paymentMethod === FiatPaymentMethod.CARD) { - if (!dto.currency.cardSellable) throw new BadRequestException('Currency not sellable via Card'); - if (!dto.asset.cardBuyable) throw new BadRequestException('Asset not buyable via Card'); - } else if ('paymentMethod' in dto && dto.paymentMethod === FiatPaymentMethod.INSTANT) { + throw new BadRequestException('Credit card payments are currently disabled'); + } + + if ('paymentMethod' in dto && dto.paymentMethod === FiatPaymentMethod.INSTANT) { if (!dto.currency.instantSellable) throw new BadRequestException('Currency not sellable via Instant'); if (!dto.asset.instantBuyable) throw new BadRequestException('Asset not buyable via Instant'); } else { diff --git a/src/subdomains/supporting/payment/dto/transaction-helper/quote-error.enum.ts b/src/subdomains/supporting/payment/dto/transaction-helper/quote-error.enum.ts index efd39a051c..ad3fc97c88 100644 --- a/src/subdomains/supporting/payment/dto/transaction-helper/quote-error.enum.ts +++ b/src/subdomains/supporting/payment/dto/transaction-helper/quote-error.enum.ts @@ -9,6 +9,7 @@ export enum QuoteError { LIMIT_EXCEEDED = 'LimitExceeded', NATIONALITY_NOT_ALLOWED = 'NationalityNotAllowed', NAME_REQUIRED = 'NameRequired', + PAYMENT_METHOD_NOT_ALLOWED = 'PaymentMethodNotAllowed', VIDEO_IDENT_REQUIRED = 'VideoIdentRequired', IBAN_CURRENCY_MISMATCH = 'IbanCurrencyMismatch', TRADING_NOT_ALLOWED = 'TradingNotAllowed', diff --git a/src/subdomains/supporting/payment/services/transaction-helper.ts b/src/subdomains/supporting/payment/services/transaction-helper.ts index 7bdf04e4b9..5ea37524cf 100644 --- a/src/subdomains/supporting/payment/services/transaction-helper.ts +++ b/src/subdomains/supporting/payment/services/transaction-helper.ts @@ -826,13 +826,14 @@ export class TransactionHelper implements OnModuleInit { if (!DisabledProcess(Process.TRADE_APPROVAL_DATE) && user?.userData && !user.userData.tradeApprovalDate) return QuoteError.TRADING_NOT_ALLOWED; + // Credit card payments disabled + if (paymentMethodIn === FiatPaymentMethod.CARD) return QuoteError.PAYMENT_METHOD_NOT_ALLOWED; + if (isSell && ibanCountry && !to.isIbanCountryAllowed(ibanCountry)) return QuoteError.IBAN_CURRENCY_MISMATCH; if ( nationality && - ((isBuy && !nationality.bankEnable) || - (paymentMethodIn === FiatPaymentMethod.CARD && !nationality.checkoutEnable) || - ((isSell || isSwap) && !nationality.cryptoEnable)) + ((isBuy && !nationality.bankEnable) || ((isSell || isSwap) && !nationality.cryptoEnable)) ) return QuoteError.NATIONALITY_NOT_ALLOWED; @@ -870,14 +871,6 @@ export class TransactionHelper implements OnModuleInit { if (user && txAmountChf > kycLimitChf) return QuoteError.LIMIT_EXCEEDED; // verification checks - if ( - paymentMethodIn === FiatPaymentMethod.CARD && - user && - !user.userData.completeName && - !user.userData.verifiedName - ) - return QuoteError.NAME_REQUIRED; - if ( txAmountChf > Config.tradingLimits.monthlyDefaultWoKyc && user?.userData?.accountType === AccountType.ORGANIZATION && @@ -886,7 +879,7 @@ export class TransactionHelper implements OnModuleInit { return QuoteError.VIDEO_IDENT_REQUIRED; if ( - ((isSell && to.name !== 'CHF') || paymentMethodIn === FiatPaymentMethod.CARD || isSwap) && + ((isSell && to.name !== 'CHF') || isSwap) && user && !user.userData.hasBankTxVerification && txAmountChf > Config.tradingLimits.monthlyDefaultWoKyc From 75fae889d84befa62995d2b40d1185a18d976922 Mon Sep 17 00:00:00 2001 From: David May Date: Thu, 8 Jan 2026 22:18:45 +0100 Subject: [PATCH 2/2] fix: removed duplicated check --- src/shared/services/payment-info.service.ts | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/shared/services/payment-info.service.ts b/src/shared/services/payment-info.service.ts index b5d007510f..0ce7b53d8e 100644 --- a/src/shared/services/payment-info.service.ts +++ b/src/shared/services/payment-info.service.ts @@ -29,12 +29,10 @@ export class PaymentInfoService { if (!dto.asset) throw new NotFoundException('Asset not found'); if (jwt && !dto.asset.isBuyableOn(jwt.blockchains)) throw new BadRequestException('Asset blockchain mismatch'); - // Credit card payments disabled if ('paymentMethod' in dto && dto.paymentMethod === FiatPaymentMethod.CARD) { - throw new BadRequestException('Credit card payments are currently disabled'); - } - - if ('paymentMethod' in dto && dto.paymentMethod === FiatPaymentMethod.INSTANT) { + if (!dto.currency.cardSellable) throw new BadRequestException('Currency not sellable via Card'); + if (!dto.asset.cardBuyable) throw new BadRequestException('Asset not buyable via Card'); + } else if ('paymentMethod' in dto && dto.paymentMethod === FiatPaymentMethod.INSTANT) { if (!dto.currency.instantSellable) throw new BadRequestException('Currency not sellable via Instant'); if (!dto.asset.instantBuyable) throw new BadRequestException('Asset not buyable via Instant'); } else {