From dc85115c0e410f9ecb67cbe6313043c2bcee9f08 Mon Sep 17 00:00:00 2001 From: Giovanni Berti Date: Fri, 12 Apr 2024 10:45:21 +0200 Subject: [PATCH 1/5] feat(wallet): handle new fields from `GET auth-data` wallet api --- pom.xml | 6 ++-- .../services/v1/TransactionsService.java | 29 +++++++++++++++---- .../utils/PaymentSessionData.java | 4 ++- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 7def3d41c..26512613c 100644 --- a/pom.xml +++ b/pom.xml @@ -393,7 +393,7 @@ generate - https://raw.githubusercontent.com/pagopa/pagopa-infra/main/src/domains/wallet-app/api/payment-wallet-for-ecommerce/v1/_openapi.json.tpl + https://raw.githubusercontent.com/pagopa/pagopa-infra/CHK-2736-wallet-auth-data/src/domains/wallet-app/api/payment-wallet-for-ecommerce/v1/_openapi.json.tpl java webclient false @@ -555,8 +555,8 @@ false scm:git:https://github.com/pagopa/pagopa-ecommerce-commons.git - tag - ${pagopa-ecommerce-commons.version} + branch + CHK-2736-wallet-details install -DskipTests diff --git a/src/main/java/it/pagopa/transactions/services/v1/TransactionsService.java b/src/main/java/it/pagopa/transactions/services/v1/TransactionsService.java index 1cebec9d2..9adaab04d 100644 --- a/src/main/java/it/pagopa/transactions/services/v1/TransactionsService.java +++ b/src/main/java/it/pagopa/transactions/services/v1/TransactionsService.java @@ -14,6 +14,7 @@ import it.pagopa.generated.ecommerce.paymentmethods.v2.dto.*; import it.pagopa.generated.transactions.server.model.*; import it.pagopa.generated.wallet.v1.dto.WalletAuthCardDataDto; +import it.pagopa.generated.wallet.v1.dto.WalletAuthPayPalDataDto; import it.pagopa.transactions.client.EcommercePaymentMethodsClient; import it.pagopa.transactions.client.WalletClient; import it.pagopa.transactions.commands.*; @@ -1314,31 +1315,47 @@ public NewTransactionResponseDto.ClientIdEnum convertClientId( private Mono retrieveInformationFromAuthorizationRequest(RequestAuthorizationRequestDto requestAuthorizationRequestDto, String clientId) { return switch (requestAuthorizationRequestDto.getDetails()) { case CardAuthRequestDetailsDto cardData -> - Mono.just(new PaymentSessionData(cardData.getPan().substring(0, 6), null, Optional.of(cardData.getBrand()).map(Enum::toString).orElse(null), null)); + Mono.just(new PaymentSessionData(cardData.getPan().substring(0, 6), cardData.getPan().substring(cardData.getPan().length() - 4), null, Optional.of(cardData.getBrand()).map(Enum::toString).orElse(null), null, null)); case CardsAuthRequestDetailsDto cards -> - ecommercePaymentMethodsClient.retrieveCardData(requestAuthorizationRequestDto.getPaymentInstrumentId(), cards.getOrderId()).map(response -> new PaymentSessionData(response.getBin(), response.getSessionId(), response.getBrand(), null)); + ecommercePaymentMethodsClient.retrieveCardData(requestAuthorizationRequestDto.getPaymentInstrumentId(), cards.getOrderId()).map(response -> new PaymentSessionData(response.getBin(), null, response.getSessionId(), response.getBrand(), null, null)); case WalletAuthRequestDetailsDto wallet -> walletClient .getWalletInfo(wallet.getWalletId()) .map(walletAuthDataDto -> { String bin = null; - if (walletAuthDataDto.getPaymentMethodData() instanceof WalletAuthCardDataDto cardsData) { - bin = cardsData.getBin(); + String lastFourDigits = null; + String paypalMaskedEmail = null; + + switch (walletAuthDataDto.getPaymentMethodData()) { + case WalletAuthCardDataDto cardsData -> { + bin = cardsData.getBin(); + lastFourDigits = cardsData.getLastFourDigits(); + } + case WalletAuthPayPalDataDto payPalData -> { + paypalMaskedEmail = payPalData.getMaskedEmail(); + } + default -> + throw new InvalidRequestException("Illegal value for wallet payment method data! " + walletAuthDataDto.getClass()); } return new PaymentSessionData( bin, + lastFourDigits, null, walletAuthDataDto.getBrand(), - walletAuthDataDto.getContractId()); + walletAuthDataDto.getContractId(), + paypalMaskedEmail + ); }); case ApmAuthRequestDetailsDto ignore -> ecommercePaymentMethodsClient.getPaymentMethod(requestAuthorizationRequestDto.getPaymentInstrumentId(), clientId).map(response -> new PaymentSessionData(null, null, response.getName(), null)); case RedirectionAuthRequestDetailsDto ignored -> Mono.just(new PaymentSessionData( + null, null, null, "N/A",//TODO handle this value for Nodo close payment + null, null )); - default -> Mono.just(new PaymentSessionData(null, null, null, null)); + default -> Mono.just(new PaymentSessionData(null, null, null, null, null, null)); }; } diff --git a/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java b/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java index 0dd8cfa95..56528876f 100644 --- a/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java +++ b/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java @@ -2,8 +2,10 @@ public record PaymentSessionData( String cardBin, + String lastFourDigits, String sessionId, String brand, - String contractId + String contractId, + String paypalMaskedEmail ) { } From abd73b98efb97c4d2915b1316b5734998e5e037a Mon Sep 17 00:00:00 2001 From: Giovanni Berti Date: Fri, 12 Apr 2024 16:46:07 +0200 Subject: [PATCH 2/5] refactor(auth): refactor payment session data --- pom.xml | 4 +- .../client/PaymentGatewayClient.java | 42 +- .../data/AuthorizationRequestData.java | 5 +- .../data/AuthorizationRequestSessionData.java | 12 +- ...tionRequestAuthorizationHandlerCommon.java | 96 +++-- ...ransactionRequestAuthorizationHandler.java | 2 +- ...ransactionRequestAuthorizationHandler.java | 76 ++-- .../services/v1/TransactionsService.java | 189 ++++----- .../utils/PaymentSessionData.java | 102 ++++- .../client/PaymentGatewayClientTest.java | 303 +++++++++---- ...actionRequestAuthorizationHandlerTest.java | 88 ++-- ...actionRequestAuthorizationHandlerTest.java | 398 +++++++++++++----- .../services/v1/TransactionServiceTests.java | 26 +- .../transactions/utils/LogMaskTests.java | 9 +- 14 files changed, 893 insertions(+), 459 deletions(-) diff --git a/pom.xml b/pom.xml index 26512613c..2973d490b 100644 --- a/pom.xml +++ b/pom.xml @@ -555,8 +555,8 @@ false scm:git:https://github.com/pagopa/pagopa-ecommerce-commons.git - branch - CHK-2736-wallet-details + tag + ${pagopa-ecommerce-commons.version} install -DskipTests diff --git a/src/main/java/it/pagopa/transactions/client/PaymentGatewayClient.java b/src/main/java/it/pagopa/transactions/client/PaymentGatewayClient.java index 9c2f22d3a..486fb6cfc 100644 --- a/src/main/java/it/pagopa/transactions/client/PaymentGatewayClient.java +++ b/src/main/java/it/pagopa/transactions/client/PaymentGatewayClient.java @@ -39,6 +39,7 @@ import it.pagopa.transactions.exceptions.NpgNotRetryableErrorException; import it.pagopa.transactions.utils.ConfidentialMailUtils; import it.pagopa.transactions.utils.NpgBuildData; +import it.pagopa.transactions.utils.PaymentSessionData; import it.pagopa.transactions.utils.UUIDUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -359,6 +360,20 @@ private Mono> requestNpgBuildSession( return buildApiKey.fold( Mono::error, apiKey -> { + String contractId = switch (authorizationData.paymentSessionData()) { + case PaymentSessionData.WalletCardSessionData walletCardSessionData -> walletCardSessionData.contractId(); + case PaymentSessionData.WalletPayPalSessionData walletPayPalSessionData -> walletPayPalSessionData.contractId(); + default -> null; + }; + + // TODO: Remove `isWalletPayment` parameter and let types determine whether it's a payment with wallet + // this check is actually redundant, kept for backward compatibility with `isWalletPayment` + if (isWalletPayment && contractId == null) { + throw new InternalServerErrorException( + "Invalid request missing contractId" + ); + } + if (isApmPayment) { return npgClient.buildFormForPayment( UUID.fromString(correlationId), @@ -371,11 +386,7 @@ private Mono> requestNpgBuildSession( NpgClient.PaymentMethod .fromServiceName(authorizationData.paymentMethodName()), apiKey, - isWalletPayment ? authorizationData.contractId().orElseThrow( - () -> new InternalServerErrorException( - "Invalid request missing contractId" - ) - ) : null, + contractId, authorizationData.paymentNotices().stream() .mapToInt( paymentNotice -> paymentNotice.transactionAmount() @@ -395,11 +406,7 @@ private Mono> requestNpgBuildSession( NpgClient.PaymentMethod .fromServiceName(authorizationData.paymentMethodName()), apiKey, - authorizationData.contractId().orElseThrow( - () -> new InternalServerErrorException( - "Invalid request missing contractId" - ) - ) + contractId ).map(fieldsDto -> Tuples.of(orderId, fieldsDto)); } } @@ -512,22 +519,25 @@ public Mono requestNpgCardsAuthorization( .mapToInt(paymentNotice -> paymentNotice.transactionAmount().value()).sum()) + authorizationData.fee() ); - if (authorizationData.sessionId().isEmpty()) { - return Mono.error( + + Mono sessionId = switch (authorizationData.paymentSessionData()) { + case PaymentSessionData.CardSessionData cardSessionData -> Mono.just(cardSessionData.sessionId()); + default -> Mono.error( new BadGatewayException( "Missing sessionId for transactionId: " + authorizationData.transactionId(), HttpStatus.BAD_GATEWAY ) ); - } + }; + final var pspNpgApiKey = npgApiKeyConfiguration .getApiKeyForPaymentMethod(NpgClient.PaymentMethod.CARDS, authorizationData.pspId()); - return pspNpgApiKey.fold( + return sessionId.flatMap(sxId -> pspNpgApiKey.fold( Mono::error, apiKey -> npgClient.confirmPayment( UUID.fromString(correlationId), - authorizationData.sessionId().get(), + sxId, grandTotal, apiKey ) @@ -583,7 +593,7 @@ public Mono requestNpgCardsAuthorization( ) ) ) - ); + )); }); } diff --git a/src/main/java/it/pagopa/transactions/commands/data/AuthorizationRequestData.java b/src/main/java/it/pagopa/transactions/commands/data/AuthorizationRequestData.java index 4cdd3c3df..b34e8342e 100644 --- a/src/main/java/it/pagopa/transactions/commands/data/AuthorizationRequestData.java +++ b/src/main/java/it/pagopa/transactions/commands/data/AuthorizationRequestData.java @@ -5,6 +5,7 @@ import it.pagopa.ecommerce.commons.domain.PaymentNotice; import it.pagopa.ecommerce.commons.domain.TransactionId; import it.pagopa.generated.transactions.server.model.RequestAuthorizationRequestDetailsDto; +import it.pagopa.transactions.utils.PaymentSessionData; import java.util.List; import java.util.Map; @@ -28,9 +29,7 @@ public record AuthorizationRequestData( String pspBusinessName, Boolean pspOnUs, String paymentGatewayId, - Optional sessionId, - Optional contractId, - String brand, + PaymentSessionData paymentSessionData, RequestAuthorizationRequestDetailsDto authDetails, String asset, diff --git a/src/main/java/it/pagopa/transactions/commands/data/AuthorizationRequestSessionData.java b/src/main/java/it/pagopa/transactions/commands/data/AuthorizationRequestSessionData.java index cc333789b..b35dcc907 100644 --- a/src/main/java/it/pagopa/transactions/commands/data/AuthorizationRequestSessionData.java +++ b/src/main/java/it/pagopa/transactions/commands/data/AuthorizationRequestSessionData.java @@ -1,6 +1,7 @@ package it.pagopa.transactions.commands.data; import it.pagopa.generated.ecommerce.paymentmethods.v2.dto.BundleDto; +import it.pagopa.transactions.utils.PaymentSessionData; import java.util.Map; import java.util.Optional; @@ -13,20 +14,15 @@ * @param paymentMethodDescription the payment method description string * @param bundle the gec bundle matching the authorization * request psp - * @param npgSessionId the NPG session id - * @param brand the brand associated to the payment method - * @param npgContractId the NPG contract id + * @param paymentSessionData data about the specific payment method and + * authorization (e.g. wallet, card, apm) */ public record AuthorizationRequestSessionData( String paymentMethodName, String paymentMethodDescription, Optional bundle, - String brand, - Optional npgSessionId, - Optional npgContractId, - + PaymentSessionData paymentSessionData, String asset, - Map brandAssets ) { } diff --git a/src/main/java/it/pagopa/transactions/commands/handlers/TransactionRequestAuthorizationHandlerCommon.java b/src/main/java/it/pagopa/transactions/commands/handlers/TransactionRequestAuthorizationHandlerCommon.java index 6d73dcff9..1516f19d2 100644 --- a/src/main/java/it/pagopa/transactions/commands/handlers/TransactionRequestAuthorizationHandlerCommon.java +++ b/src/main/java/it/pagopa/transactions/commands/handlers/TransactionRequestAuthorizationHandlerCommon.java @@ -18,6 +18,7 @@ import it.pagopa.transactions.repositories.TransactionCacheInfo; import it.pagopa.transactions.repositories.TransactionTemplateWrapper; import it.pagopa.transactions.repositories.WalletPaymentInfo; +import it.pagopa.transactions.utils.PaymentSessionData; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; import org.springframework.http.HttpStatus; @@ -178,43 +179,55 @@ private Mono walletNpgCardsPaymentFlow( } ) .flatMap( - orderIdAndFieldsDto -> invokeNpgConfirmPayment( - new AuthorizationRequestData( - authorizationData.transactionId(), - authorizationData.paymentNotices(), - authorizationData.email(), - authorizationData.fee(), - authorizationData.paymentInstrumentId(), - authorizationData.pspId(), - authorizationData.paymentTypeCode(), - authorizationData.brokerName(), - authorizationData.pspChannelCode(), - authorizationData.paymentMethodName(), - authorizationData.paymentMethodDescription(), - authorizationData.pspBusinessName(), - authorizationData.pspOnUs(), - authorizationData.paymentGatewayId(), - Optional.of(orderIdAndFieldsDto.getT2().getSessionId()), - authorizationData.contractId(), - authorizationData.brand(), - authorizationData.authDetails(), - authorizationData.asset(), - authorizationData.brandAssets() - ), - orderIdAndFieldsDto.getT1(), - correlationId, - clientId, - Optional.of(userId) - ) - .map( - authorizationOutput -> new AuthorizationOutput( - authorizationOutput.authorizationId(), - authorizationOutput.authorizationUrl(), - Optional.of(orderIdAndFieldsDto.getT2().getSessionId()), - authorizationOutput.npgConfirmSessionId(), - authorizationOutput.authorizationTimeoutMillis() - ) - ) + orderIdAndFieldsDto -> { + PaymentSessionData paymentSessionData = switch (authorizationData.paymentSessionData()) { + case PaymentSessionData.WalletCardSessionData walletCardSessionData -> new PaymentSessionData.WalletCardSessionData( + walletCardSessionData.brand(), + Optional.of(Objects.requireNonNull(orderIdAndFieldsDto.getT2().getSessionId())), + walletCardSessionData.cardBin(), + walletCardSessionData.lastFourDigits(), + walletCardSessionData.contractId() + ); + default -> + throw new IllegalStateException("Unexpected non wallet card payment session data of type: " + authorizationData.paymentSessionData().getClass()); + }; + + return invokeNpgConfirmPayment( + new AuthorizationRequestData( + authorizationData.transactionId(), + authorizationData.paymentNotices(), + authorizationData.email(), + authorizationData.fee(), + authorizationData.paymentInstrumentId(), + authorizationData.pspId(), + authorizationData.paymentTypeCode(), + authorizationData.brokerName(), + authorizationData.pspChannelCode(), + authorizationData.paymentMethodName(), + authorizationData.paymentMethodDescription(), + authorizationData.pspBusinessName(), + authorizationData.pspOnUs(), + authorizationData.paymentGatewayId(), + paymentSessionData, + authorizationData.authDetails(), + authorizationData.asset(), + authorizationData.brandAssets() + ), + orderIdAndFieldsDto.getT1(), + correlationId, + clientId, + Optional.of(userId) + ) + .map( + authorizationOutput -> new AuthorizationOutput( + authorizationOutput.authorizationId(), + authorizationOutput.authorizationUrl(), + Optional.of(orderIdAndFieldsDto.getT2().getSessionId()), + authorizationOutput.npgConfirmSessionId(), + authorizationOutput.authorizationTimeoutMillis() + ) + ); + } ); } @@ -421,11 +434,16 @@ private Mono invokeNpgConfirmPayment( ); }; + Optional sessionId = switch (authorizationData.paymentSessionData()) { + case PaymentSessionData.CardSessionData cardSessionData -> Optional.of(cardSessionData.sessionId()); + default -> Optional.empty(); + }; + return authUrl.map( url -> new AuthorizationOutput( orderId, url, - authorizationData.sessionId(), + sessionId, confirmPaymentSessionId, Optional.empty() ) @@ -463,7 +481,7 @@ private Mono> confirmPayment( protected URI getLogo(AuthorizationRequestData authorizationRequestData) { String paymentTypeCode = authorizationRequestData.paymentTypeCode(); - String brand = authorizationRequestData.brand(); + String brand = authorizationRequestData.paymentSessionData().brand(); String asset = authorizationRequestData.asset(); Optional> brandAssets = authorizationRequestData.brandAssets(); String logo; diff --git a/src/main/java/it/pagopa/transactions/commands/handlers/v1/TransactionRequestAuthorizationHandler.java b/src/main/java/it/pagopa/transactions/commands/handlers/v1/TransactionRequestAuthorizationHandler.java index 55436ca94..1a638109b 100644 --- a/src/main/java/it/pagopa/transactions/commands/handlers/v1/TransactionRequestAuthorizationHandler.java +++ b/src/main/java/it/pagopa/transactions/commands/handlers/v1/TransactionRequestAuthorizationHandler.java @@ -133,7 +133,7 @@ public Mono handle(TransactionRequestAuthorizat AuthorizationOutput authorizationOutput = authorizationOutputAndGateway.getT1(); PaymentGateway paymentGateway = authorizationOutputAndGateway.getT2(); TransactionAuthorizationRequestData.CardBrand cardBrand = TransactionAuthorizationRequestData.CardBrand - .valueOf(authorizationRequestData.brand()); + .valueOf(authorizationRequestData.paymentSessionData().brand()); TransactionAuthorizationRequestedEvent authorizationEvent = new TransactionAuthorizationRequestedEvent( t.getTransactionId().value(), new it.pagopa.ecommerce.commons.documents.v1.TransactionAuthorizationRequestData( diff --git a/src/main/java/it/pagopa/transactions/commands/handlers/v2/TransactionRequestAuthorizationHandler.java b/src/main/java/it/pagopa/transactions/commands/handlers/v2/TransactionRequestAuthorizationHandler.java index d6a574b75..c30f2a086 100644 --- a/src/main/java/it/pagopa/transactions/commands/handlers/v2/TransactionRequestAuthorizationHandler.java +++ b/src/main/java/it/pagopa/transactions/commands/handlers/v2/TransactionRequestAuthorizationHandler.java @@ -8,10 +8,7 @@ import it.pagopa.ecommerce.commons.documents.v2.TransactionAuthorizationRequestData.PaymentGateway; import it.pagopa.ecommerce.commons.documents.v2.TransactionAuthorizationRequestedEvent; import it.pagopa.ecommerce.commons.documents.v2.activation.NpgTransactionGatewayActivationData; -import it.pagopa.ecommerce.commons.documents.v2.authorization.NpgTransactionGatewayAuthorizationRequestedData; -import it.pagopa.ecommerce.commons.documents.v2.authorization.PgsTransactionGatewayAuthorizationRequestedData; -import it.pagopa.ecommerce.commons.documents.v2.authorization.RedirectTransactionGatewayAuthorizationRequestedData; -import it.pagopa.ecommerce.commons.documents.v2.authorization.TransactionGatewayAuthorizationRequestedData; +import it.pagopa.ecommerce.commons.documents.v2.authorization.*; import it.pagopa.ecommerce.commons.domain.v2.TransactionActivated; import it.pagopa.ecommerce.commons.domain.v2.pojos.BaseTransaction; import it.pagopa.ecommerce.commons.generated.server.model.TransactionStatusDto; @@ -35,6 +32,7 @@ import it.pagopa.transactions.repositories.TransactionTemplateWrapper; import it.pagopa.transactions.repositories.TransactionsEventStoreRepository; import it.pagopa.transactions.utils.OpenTelemetryUtils; +import it.pagopa.transactions.utils.PaymentSessionData; import it.pagopa.transactions.utils.TransactionsUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; @@ -219,40 +217,52 @@ public Mono handle(TransactionRequestAuthorizat AuthorizationOutput authorizationOutput = authorizationOutputAndPaymentGateway .getT1(); PaymentGateway paymentGateway = authorizationOutputAndPaymentGateway.getT2(); - String brand = authorizationRequestData.brand(); + String brand = authorizationRequestData.paymentSessionData().brand(); TransactionGatewayAuthorizationRequestedData transactionGatewayAuthorizationRequestedData = switch (paymentGateway) { case VPOS, XPAY -> new PgsTransactionGatewayAuthorizationRequestedData( logo, PgsTransactionGatewayAuthorizationRequestedData.CardBrand.valueOf(brand) ); - case NPG -> new NpgTransactionGatewayAuthorizationRequestedData( - logo, - brand, - authorizationRequestData - .authDetails() instanceof WalletAuthRequestDetailsDto - || authorizationRequestData - .authDetails() instanceof ApmAuthRequestDetailsDto - ? authorizationOutput.npgSessionId() - .orElseThrow( - () -> new InternalServerErrorException( - "Cannot retrieve session id for transaction" - ) - ) // build session id - : authorizationRequestData.sessionId() - .orElseThrow( - () -> new BadGatewayException( - "Cannot retrieve session id for transaction", - HttpStatus.INTERNAL_SERVER_ERROR - ) - ), - authorizationOutput.npgConfirmSessionId().orElse(null), - /* @formatter:off - * FIXME walletInfo set to null: this modification is addressed in - * PR: https://github.com/pagopa/pagopa-ecommerce-transactions-service/pull/475 - * @formatter:on - */ - null - ); + case NPG -> { + WalletInfo walletInfo = switch (command.getData().authDetails()) { + case WalletAuthRequestDetailsDto walletDetails -> { + WalletInfo.WalletDetails walletInfoDetails = switch (command.getData().paymentSessionData()) { + case PaymentSessionData.WalletCardSessionData walletCardSessionData -> new WalletInfo.CardWalletDetails( + walletCardSessionData.cardBin(), + walletCardSessionData.lastFourDigits() + ); + case PaymentSessionData.WalletPayPalSessionData walletPayPalSessionData -> new WalletInfo.PaypalWalletDetails( + walletPayPalSessionData.maskedEmail() + ); + default -> throw new IllegalStateException("Unhandled wallet authorization request details: " + walletDetails.getDetailType()); + }; + + yield new WalletInfo( + walletDetails.getWalletId(), + walletInfoDetails + ); + } + default -> null; + }; + + String sessionId = switch (command.getData().paymentSessionData()) { + case PaymentSessionData.CardSessionData cardSessionData -> + cardSessionData.sessionId(); + default -> authorizationOutput.npgSessionId().orElseThrow( + () -> new BadGatewayException( + "Cannot retrieve session id for transaction", + HttpStatus.INTERNAL_SERVER_ERROR + )); + }; + + yield new NpgTransactionGatewayAuthorizationRequestedData( + logo, + brand, + sessionId, + authorizationOutput.npgConfirmSessionId().orElse(null), + walletInfo + ); + } case REDIRECT -> new RedirectTransactionGatewayAuthorizationRequestedData( logo, authorizationOutput.authorizationTimeoutMillis().orElse(600000) diff --git a/src/main/java/it/pagopa/transactions/services/v1/TransactionsService.java b/src/main/java/it/pagopa/transactions/services/v1/TransactionsService.java index 9adaab04d..c905b3d6a 100644 --- a/src/main/java/it/pagopa/transactions/services/v1/TransactionsService.java +++ b/src/main/java/it/pagopa/transactions/services/v1/TransactionsService.java @@ -499,64 +499,76 @@ public Mono requestTransactionAuthorization( Integer amountTotal = transactionsUtils.getTransactionTotalAmount(transaction); String clientId = transactionsUtils.getClientId(transaction); List paymentNotices = transactionsUtils.getPaymentNotices(transaction); + return retrieveInformationFromAuthorizationRequest(requestAuthorizationRequestDto, clientId) .flatMap( - paymentSessionData -> ecommercePaymentMethodsClient - .calculateFee( - requestAuthorizationRequestDto.getPaymentInstrumentId(), - transactionId, - new CalculateFeeRequestDto() - .touchpoint( - clientId - ) - .bin( - paymentSessionData.cardBin() - ) - .idPspList( - List.of( - requestAuthorizationRequestDto - .getPspId() - ) - ) - .paymentNotices( - paymentNotices - .stream() - .map(p -> - new PaymentNoticeDto() - .paymentAmount(p.getAmount().longValue()) - .primaryCreditorInstitution( - p.getRptId().substring(0, 11) - ) - .transferList( - p.getTransferList() - .stream() - .map( - t -> new TransferListItemDto() - .creditorInstitution( - t.getPaFiscalCode() - ) - .digitalStamp( - t.getDigitalStamp() - ) - .transferCategory( - t.getTransferCategory() - ) - ).toList() - ) - ) - .toList() - ) - .isAllCCP( - transactionsUtils.isAllCcp(transaction, 0) - ), - Integer.MAX_VALUE - ) - .map( - calculateFeeResponseDto -> Tuples.of( - calculateFeeResponseDto, - paymentSessionData - ) - ) + paymentSessionData -> { + String cardBin = switch (paymentSessionData) { + case PaymentSessionData.CardSessionData cardSessionData -> + cardSessionData.cardBin(); + case PaymentSessionData.PgsCardSessionData cardSessionData -> cardSessionData.cardBin(); + case PaymentSessionData.WalletCardSessionData cardSessionData -> + cardSessionData.cardBin(); + default -> null; + }; + + return ecommercePaymentMethodsClient + .calculateFee( + requestAuthorizationRequestDto.getPaymentInstrumentId(), + transactionId, + new CalculateFeeRequestDto() + .touchpoint( + clientId + ) + .bin( + cardBin + ) + .idPspList( + List.of( + requestAuthorizationRequestDto + .getPspId() + ) + ) + .paymentNotices( + paymentNotices + .stream() + .map(p -> + new PaymentNoticeDto() + .paymentAmount(p.getAmount().longValue()) + .primaryCreditorInstitution( + p.getRptId().substring(0, 11) + ) + .transferList( + p.getTransferList() + .stream() + .map( + t -> new TransferListItemDto() + .creditorInstitution( + t.getPaFiscalCode() + ) + .digitalStamp( + t.getDigitalStamp() + ) + .transferCategory( + t.getTransferCategory() + ) + ).toList() + ) + ) + .toList() + ) + .isAllCCP( + transactionsUtils.isAllCcp(transaction, 0) + ), + Integer.MAX_VALUE + ) + .map( + calculateFeeResponseDto -> Tuples.of( + calculateFeeResponseDto, + paymentSessionData + ) + ); + } ) .map( data -> { @@ -580,9 +592,7 @@ public Mono requestTransactionAuthorization( psp.getTaxPayerFee() ) ).findFirst(), - paymentSessionData.brand(), - Optional.ofNullable(paymentSessionData.sessionId()), - Optional.ofNullable(paymentSessionData.contractId()), + paymentSessionData, calculateFeeResponse.getAsset(), calculateFeeResponse.getBrandAssets() ); @@ -603,7 +613,6 @@ public Mono requestTransactionAuthorization( transaction, authSessionData ) - ); } ) @@ -615,9 +624,6 @@ public Mono requestTransactionAuthorization( String paymentMethodName = authorizationRequestSessionData.paymentMethodName(); String paymentMethodDescription = authorizationRequestSessionData.paymentMethodDescription(); BundleDto bundle = authorizationRequestSessionData.bundle().orElseThrow(); - Optional sessionId = authorizationRequestSessionData.npgSessionId(); - String brand = authorizationRequestSessionData.brand(); - Optional contractId = authorizationRequestSessionData.npgContractId(); String asset = authorizationRequestSessionData.asset(); Map brandAssets = authorizationRequestSessionData.brandAssets(); log.info( @@ -663,9 +669,7 @@ public Mono requestTransactionAuthorization( bundle.getPspBusinessName(), bundle.getOnUs(), paymentGatewayId, - sessionId, - contractId, - brand, + authorizationRequestSessionData.paymentSessionData(), requestAuthorizationRequestDto.getDetails(), asset, Optional.ofNullable(brandAssets) @@ -1315,48 +1319,31 @@ public NewTransactionResponseDto.ClientIdEnum convertClientId( private Mono retrieveInformationFromAuthorizationRequest(RequestAuthorizationRequestDto requestAuthorizationRequestDto, String clientId) { return switch (requestAuthorizationRequestDto.getDetails()) { case CardAuthRequestDetailsDto cardData -> - Mono.just(new PaymentSessionData(cardData.getPan().substring(0, 6), cardData.getPan().substring(cardData.getPan().length() - 4), null, Optional.of(cardData.getBrand()).map(Enum::toString).orElse(null), null, null)); + Mono.just(new PaymentSessionData.PgsCardSessionData(Optional.of(cardData.getBrand()).map(Enum::toString).orElse(null), cardData.getPan().substring(0, 6), cardData.getPan().substring(cardData.getPan().length() - 4))); case CardsAuthRequestDetailsDto cards -> - ecommercePaymentMethodsClient.retrieveCardData(requestAuthorizationRequestDto.getPaymentInstrumentId(), cards.getOrderId()).map(response -> new PaymentSessionData(response.getBin(), null, response.getSessionId(), response.getBrand(), null, null)); + ecommercePaymentMethodsClient.retrieveCardData(requestAuthorizationRequestDto.getPaymentInstrumentId(), cards.getOrderId()).map(response -> new PaymentSessionData.CardSessionData(response.getBrand(), response.getSessionId(), response.getBin(), response.getLastFourDigits())); case WalletAuthRequestDetailsDto wallet -> walletClient .getWalletInfo(wallet.getWalletId()) - .map(walletAuthDataDto -> { - String bin = null; - String lastFourDigits = null; - String paypalMaskedEmail = null; - - switch (walletAuthDataDto.getPaymentMethodData()) { - case WalletAuthCardDataDto cardsData -> { - bin = cardsData.getBin(); - lastFourDigits = cardsData.getLastFourDigits(); - } - case WalletAuthPayPalDataDto payPalData -> { - paypalMaskedEmail = payPalData.getMaskedEmail(); - } - default -> - throw new InvalidRequestException("Illegal value for wallet payment method data! " + walletAuthDataDto.getClass()); - } - return new PaymentSessionData( - bin, - lastFourDigits, - null, + .map(walletAuthDataDto -> switch (walletAuthDataDto.getPaymentMethodData()) { + case WalletAuthCardDataDto cardsData -> new PaymentSessionData.WalletCardSessionData( walletAuthDataDto.getBrand(), - walletAuthDataDto.getContractId(), - paypalMaskedEmail + Optional.empty(), + cardsData.getBin(), + cardsData.getLastFourDigits(), + walletAuthDataDto.getContractId() ); + case WalletAuthPayPalDataDto payPalData -> + new PaymentSessionData.WalletPayPalSessionData( + walletAuthDataDto.getContractId(), + payPalData.getMaskedEmail() + ); + default -> + throw new InvalidRequestException("Illegal value for wallet payment method data! " + walletAuthDataDto.getClass()); }); case ApmAuthRequestDetailsDto ignore -> - ecommercePaymentMethodsClient.getPaymentMethod(requestAuthorizationRequestDto.getPaymentInstrumentId(), clientId).map(response -> new PaymentSessionData(null, null, response.getName(), null)); - case RedirectionAuthRequestDetailsDto ignored -> Mono.just(new PaymentSessionData( - null, - null, - null, - "N/A",//TODO handle this value for Nodo close payment - null, - null - )); - default -> Mono.just(new PaymentSessionData(null, null, null, null, null, null)); + ecommercePaymentMethodsClient.getPaymentMethod(requestAuthorizationRequestDto.getPaymentInstrumentId(), clientId).map(response -> new PaymentSessionData.ApmSessionData(response.getName())); + case RedirectionAuthRequestDetailsDto ignored -> Mono.just(new PaymentSessionData.RedirectSessionData()); + default -> throw new IllegalArgumentException("Unhandled authorization request details of type: " + requestAuthorizationRequestDto.getDetails().getDetailType()); }; } - } diff --git a/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java b/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java index 56528876f..9b55efc0f 100644 --- a/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java +++ b/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java @@ -1,11 +1,97 @@ package it.pagopa.transactions.utils; -public record PaymentSessionData( - String cardBin, - String lastFourDigits, - String sessionId, - String brand, - String contractId, - String paypalMaskedEmail -) { +import javax.annotation.Nonnull; +import java.util.Objects; +import java.util.Optional; + +public sealed interface PaymentSessionData permits PaymentSessionData.ApmSessionData,PaymentSessionData.CardSessionData,PaymentSessionData.PgsCardSessionData,PaymentSessionData.RedirectSessionData,PaymentSessionData.WalletCardSessionData,PaymentSessionData.WalletPayPalSessionData { + + @Nonnull + String brand(); + + record PgsCardSessionData( + @Nonnull String brand, + @Nonnull String cardBin, + @Nonnull String lastFourDigits + ) + implements + PaymentSessionData { + public PgsCardSessionData { + Objects.requireNonNull(brand); + Objects.requireNonNull(cardBin); + Objects.requireNonNull(lastFourDigits); + } + } + + record CardSessionData( + @Nonnull String brand, + @Nonnull String sessionId, + @Nonnull String cardBin, + @Nonnull String lastFourDigits + ) + implements + PaymentSessionData { + public CardSessionData { + Objects.requireNonNull(brand); + Objects.requireNonNull(sessionId); + Objects.requireNonNull(cardBin); + Objects.requireNonNull(lastFourDigits); + } + } + + record ApmSessionData( + @Nonnull String brand + ) + implements + PaymentSessionData { + public ApmSessionData { + Objects.requireNonNull(brand); + } + } + + record WalletCardSessionData( + @Nonnull String brand, + @Nonnull Optional sessionId, + @Nonnull String cardBin, + @Nonnull String lastFourDigits, + @Nonnull String contractId + ) + implements + PaymentSessionData { + public WalletCardSessionData { + Objects.requireNonNull(brand); + Objects.requireNonNull(sessionId); + Objects.requireNonNull(cardBin); + Objects.requireNonNull(lastFourDigits); + Objects.requireNonNull(contractId); + } + } + + record WalletPayPalSessionData( + @Nonnull String contractId, + @Nonnull String maskedEmail + ) + implements + PaymentSessionData { + public WalletPayPalSessionData { + Objects.requireNonNull(contractId); + Objects.requireNonNull(maskedEmail); + } + + @Nonnull + @Override + public String brand() { + return "PAYPAL"; + } + } + + record RedirectSessionData() + implements + PaymentSessionData { + @Nonnull + @Override + public String brand() { + return "N/A"; + } + } } diff --git a/src/test/java/it/pagopa/transactions/client/PaymentGatewayClientTest.java b/src/test/java/it/pagopa/transactions/client/PaymentGatewayClientTest.java index 4ba72e529..0b2f7cf81 100644 --- a/src/test/java/it/pagopa/transactions/client/PaymentGatewayClientTest.java +++ b/src/test/java/it/pagopa/transactions/client/PaymentGatewayClientTest.java @@ -36,11 +36,7 @@ import it.pagopa.transactions.exceptions.AlreadyProcessedException; import it.pagopa.transactions.exceptions.BadGatewayException; import it.pagopa.transactions.exceptions.InvalidRequestException; -import it.pagopa.transactions.exceptions.NpgNotRetryableErrorException; -import it.pagopa.transactions.utils.ConfidentialMailUtils; -import it.pagopa.transactions.utils.NpgNotificationUrlMatcher; -import it.pagopa.transactions.utils.NpgOutcomeUrlMatcher; -import it.pagopa.transactions.utils.UUIDUtils; +import it.pagopa.transactions.utils.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -203,6 +199,13 @@ void shouldNotCallAuthorizationGatewayWithInvalidDetailTypeGatewayIdTuple() { TransactionTestUtils.PAYMENT_TOKEN_VALIDITY_TIME_SEC ); + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -218,9 +221,7 @@ void shouldNotCallAuthorizationGatewayWithInvalidDetailTypeGatewayIdTuple() { "pspBusinessName", false, "GID", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, Mockito.mock(RequestAuthorizationRequestDetailsDto.class), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -272,6 +273,12 @@ void shouldReturnAuthorizationResponseForCreditCardWithXPay() throws JsonProcess .brand(CardAuthRequestDetailsDto.BrandEnum.VISA) .threeDsData("threeDsData"); + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "1658", + "4852" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -287,9 +294,7 @@ void shouldReturnAuthorizationResponseForCreditCardWithXPay() throws JsonProcess "pspBusinessName", false, "XPAY", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, cardDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -365,6 +370,13 @@ void shouldReturnAuthorizationResponseForCreditCardWithVPOS() throws JsonProcess .holderName("John Doe") .brand(CardAuthRequestDetailsDto.BrandEnum.VISA) .threeDsData("threeDsData"); + + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "1658", + "4852" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -380,9 +392,7 @@ void shouldReturnAuthorizationResponseForCreditCardWithVPOS() throws JsonProcess "pspBusinessName", false, "VPOS", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, cardDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -461,6 +471,14 @@ void shouldReturnAuthorizationResponseForCardsWithNpg() { ); CardsAuthRequestDetailsDto cardDetails = new CardsAuthRequestDetailsDto() .orderId(UUID.randomUUID().toString()); + + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -476,9 +494,7 @@ void shouldReturnAuthorizationResponseForCardsWithNpg() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, cardDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -493,7 +509,7 @@ void shouldReturnAuthorizationResponseForCardsWithNpg() { .expectNext(ngpStateResponse) .verifyComplete(); String expectedApiKey = npgPspApiKeysConfig.get(authorizationData.pspId()).get(); - String expectedSessionId = authorizationData.sessionId().get(); + String expectedSessionId = paymentSessionData.sessionId(); BigDecimal expectedGranTotalAmount = BigDecimal.valueOf( transaction .getPaymentNotices() @@ -538,6 +554,14 @@ void shouldThrowNpgNotRetryableErrorExceptionOn4xxForCardsWithNpg(Integer npgHtt ); CardsAuthRequestDetailsDto cardDetails = new CardsAuthRequestDetailsDto() .orderId(UUID.randomUUID().toString()); + + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -553,9 +577,7 @@ void shouldThrowNpgNotRetryableErrorExceptionOn4xxForCardsWithNpg(Integer npgHtt "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, cardDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -627,6 +649,14 @@ void shouldThrowGatewayTimeoutExceptionForCardsWithNpg() { ); CardsAuthRequestDetailsDto cardDetails = new CardsAuthRequestDetailsDto() .orderId(UUID.randomUUID().toString()); + + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -642,9 +672,7 @@ void shouldThrowGatewayTimeoutExceptionForCardsWithNpg() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, cardDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -705,6 +733,14 @@ void shouldThrowInternalServerErrorExceptionForCardsWithNpg() { ); CardsAuthRequestDetailsDto cardDetails = new CardsAuthRequestDetailsDto() .orderId(UUID.randomUUID().toString()); + + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -720,9 +756,7 @@ void shouldThrowInternalServerErrorExceptionForCardsWithNpg() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, cardDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -788,6 +822,13 @@ void shouldThrowAlreadyProcessedOn401ForCreditCardWithXpay() throws JsonProcessi .expiryDate("203012") .brand(CardAuthRequestDetailsDto.BrandEnum.VISA) .threeDsData("threeDsData"); + + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "1658", + "4852" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -803,9 +844,7 @@ void shouldThrowAlreadyProcessedOn401ForCreditCardWithXpay() throws JsonProcessi "pspBusinessName", false, "XPAY", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, cardDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -892,6 +931,13 @@ void shouldThrowBadGatewayOn500ForCreditCardWithXPay() throws JsonProcessingExce .expiryDate("203012") .brand(CardAuthRequestDetailsDto.BrandEnum.VISA) .threeDsData("threeDsData"); + + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "1658", + "4852" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -907,9 +953,7 @@ void shouldThrowBadGatewayOn500ForCreditCardWithXPay() throws JsonProcessingExce "pspBusinessName", false, "XPAY", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, cardDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -990,6 +1034,13 @@ void shouldThrowBadGatewayOn500ForCreditCardWithVPOS() throws JsonProcessingExce .expiryDate("203012") .brand(CardAuthRequestDetailsDto.BrandEnum.VISA) .threeDsData("threeDsData"); + + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "1658", + "4852" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1005,9 +1056,7 @@ void shouldThrowBadGatewayOn500ForCreditCardWithVPOS() throws JsonProcessingExce "pspBusinessName", false, "VPOS", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, cardDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1096,6 +1145,13 @@ void fallbackOnEmptyMdcInfoOnMapperErrorForCreditCardWithXPay() throws JsonProce .expiryDate("203012") .brand(CardAuthRequestDetailsDto.BrandEnum.VISA) .threeDsData("threeDsData"); + + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "1658", + "4852" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1111,9 +1167,7 @@ void fallbackOnEmptyMdcInfoOnMapperErrorForCreditCardWithXPay() throws JsonProce "pspBusinessName", false, "XPAY", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, cardDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1188,6 +1242,13 @@ void fallbackOnEmptyMdcInfoOnMapperErrorForCreditCardWithVPOS() throws JsonProce .expiryDate("203012") .brand(CardAuthRequestDetailsDto.BrandEnum.VISA) .threeDsData("threeDsData"); + + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "1658", + "4852" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1203,9 +1264,7 @@ void fallbackOnEmptyMdcInfoOnMapperErrorForCreditCardWithVPOS() throws JsonProce "pspBusinessName", false, "VPOS", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, cardDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1283,6 +1342,12 @@ void shouldThrowInvalidRequestWhenCardDetailsAreMissingForCreditCardWithXPay() { TransactionTestUtils.PAYMENT_TOKEN_VALIDITY_TIME_SEC ); + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "1658", + "4852" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1298,9 +1363,7 @@ void shouldThrowInvalidRequestWhenCardDetailsAreMissingForCreditCardWithXPay() { "pspBusinessName", false, "XPAY", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, null, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1343,6 +1406,12 @@ void shouldThrowInvalidRequestWhenCardDetailsAreMissingForCreditCardWithVPOS() { TransactionTestUtils.PAYMENT_TOKEN_VALIDITY_TIME_SEC ); + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "1658", + "4852" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1358,9 +1427,7 @@ void shouldThrowInvalidRequestWhenCardDetailsAreMissingForCreditCardWithVPOS() { "pspBusinessName", false, "VPOS", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, null, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1413,6 +1480,15 @@ void shouldReturnBuildSessionResponseForWalletWithNpgWithCards() { ); WalletAuthRequestDetailsDto walletDetails = new WalletAuthRequestDetailsDto() .walletId(walletId); + + PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( + "VISA", + Optional.empty(), + "0000", + "1234", + contractId + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1428,9 +1504,7 @@ void shouldReturnBuildSessionResponseForWalletWithNpgWithCards() { "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.of(contractId), - "VISA", + paymentSessionData, walletDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1577,6 +1651,15 @@ void shouldThrowNpgNotRetryableErrorExceptionOn4xxForWalletWithNpg(Integer npgHt ); WalletAuthRequestDetailsDto walletDetails = new WalletAuthRequestDetailsDto() .walletId(walletId); + + PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( + "VISA", + Optional.empty(), + "0000", + "1234", + contractId + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1592,9 +1675,7 @@ void shouldThrowNpgNotRetryableErrorExceptionOn4xxForWalletWithNpg(Integer npgHt "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.of(contractId), - "VISA", + paymentSessionData, walletDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1690,6 +1771,15 @@ void shouldThrowGatewayTimeoutExceptionForWalletWithNpg() { ); WalletAuthRequestDetailsDto walletDetails = new WalletAuthRequestDetailsDto() .walletId(walletId); + + PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( + "VISA", + Optional.empty(), + "0000", + "1234", + contractId + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1705,9 +1795,7 @@ void shouldThrowGatewayTimeoutExceptionForWalletWithNpg() { "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.of(contractId), - "VISA", + paymentSessionData, walletDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1792,6 +1880,15 @@ void shouldThrowInternalServerErrorExceptionForWalletWithNpg() { ); WalletAuthRequestDetailsDto walletDetails = new WalletAuthRequestDetailsDto() .walletId(walletId); + + PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( + "VISA", + Optional.empty(), + "0000", + "1234", + contractId + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1807,9 +1904,7 @@ void shouldThrowInternalServerErrorExceptionForWalletWithNpg() { "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.of(contractId), - "VISA", + paymentSessionData, walletDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1895,6 +1990,15 @@ void shouldReturnBadGatewayExceptionFromBuildSessionForWalletWithNpg(FieldsDto n ); WalletAuthRequestDetailsDto walletDetails = new WalletAuthRequestDetailsDto() .walletId(walletId); + + PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( + "VISA", + Optional.empty(), + "0000", + "1234", + contractId + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1910,9 +2014,7 @@ void shouldReturnBadGatewayExceptionFromBuildSessionForWalletWithNpg(FieldsDto n "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.of(contractId), - "VISA", + paymentSessionData, walletDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2041,7 +2143,7 @@ private static Stream buildSessionInvalidBodyResponse() { } @Test - void shouldReturnBuildSessionResponseForWalletWithNpgForWalletApmMethod() { + void shouldReturnBuildSessionResponseForWalletWithNpgForWalletPayPalMethod() { String walletId = UUID.randomUUID().toString(); String orderId = "orderIdGenerated"; String sessionId = "sessionId"; @@ -2071,6 +2173,12 @@ void shouldReturnBuildSessionResponseForWalletWithNpgForWalletApmMethod() { ); WalletAuthRequestDetailsDto walletDetails = new WalletAuthRequestDetailsDto() .walletId(walletId); + + PaymentSessionData paymentSessionData = new PaymentSessionData.WalletPayPalSessionData( + contractId, + "maskedEmail" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2086,9 +2194,7 @@ void shouldReturnBuildSessionResponseForWalletWithNpgForWalletApmMethod() { "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.of(contractId), - "VISA", + paymentSessionData, walletDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2206,7 +2312,7 @@ void shouldReturnBuildSessionResponseForWalletWithNpgForWalletApmMethod() { } @Test - void shouldThrowErrorForWalletWithNpgForGenericApmMethodAndMissingKey() { + void shouldThrowErrorForWalletWithNpgForPayPalAndMissingKey() { String walletId = UUID.randomUUID().toString(); String orderId = "orderIdGenerated"; String sessionId = "sessionId"; @@ -2236,6 +2342,12 @@ void shouldThrowErrorForWalletWithNpgForGenericApmMethodAndMissingKey() { ); WalletAuthRequestDetailsDto walletDetails = new WalletAuthRequestDetailsDto() .walletId(walletId); + + PaymentSessionData paymentSessionData = new PaymentSessionData.WalletPayPalSessionData( + contractId, + "maskedEmail" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2251,9 +2363,7 @@ void shouldThrowErrorForWalletWithNpgForGenericApmMethodAndMissingKey() { "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.of(contractId), - "VISA", + paymentSessionData, walletDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2379,6 +2489,11 @@ void shouldReturnBuildSessionResponseForWalletWithNpgForApmMethod() { TransactionTestUtils.PAYMENT_TOKEN_VALIDITY_TIME_SEC ); ApmAuthRequestDetailsDto apmDetails = new ApmAuthRequestDetailsDto(); + + PaymentSessionData paymentSessionData = new PaymentSessionData.ApmSessionData( + "BANCOMATPAY" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2394,9 +2509,7 @@ void shouldReturnBuildSessionResponseForWalletWithNpgForApmMethod() { "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, apmDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2528,6 +2641,9 @@ void shouldPerformAuthorizationRequestRetrievingRedirectionUrl( String pspId = "pspId"; it.pagopa.ecommerce.commons.domain.v2.TransactionActivated transaction = it.pagopa.ecommerce.commons.v2.TransactionTestUtils .transactionActivated(ZonedDateTime.now().toString()); + + PaymentSessionData paymentSessionData = new PaymentSessionData.RedirectSessionData(); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2543,9 +2659,7 @@ void shouldPerformAuthorizationRequestRetrievingRedirectionUrl( "pspBusinessName", false, "REDIRECT", - Optional.empty(), - Optional.empty(), - "N/A", + paymentSessionData, new RedirectionAuthRequestDetailsDto(), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2683,6 +2797,9 @@ void shouldPerformAuthorizationRequestRetrievingRedirectionUrlWithoutPaNameWhenM new EmptyTransactionGatewayActivationData(), USER_ID ); + + PaymentSessionData paymentSessionData = new PaymentSessionData.RedirectSessionData(); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2698,9 +2815,7 @@ void shouldPerformAuthorizationRequestRetrievingRedirectionUrlWithoutPaNameWhenM "pspBusinessName", false, "REDIRECT", - Optional.empty(), - Optional.empty(), - "N/A", + paymentSessionData, new RedirectionAuthRequestDetailsDto(), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2800,6 +2915,9 @@ void shouldHandleErrorRetrievingRedirectionUrl( ) { String pspId = "pspId"; TransactionActivated transaction = TransactionTestUtils.transactionActivated(ZonedDateTime.now().toString()); + + PaymentSessionData paymentSessionData = new PaymentSessionData.RedirectSessionData(); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2815,9 +2933,7 @@ void shouldHandleErrorRetrievingRedirectionUrl( "pspBusinessName", false, "REDIRECT", - Optional.empty(), - Optional.empty(), - "N/A", + paymentSessionData, new RedirectionAuthRequestDetailsDto(), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2906,6 +3022,9 @@ void shouldHandleErrorRetrievingRedirectionUrl( void shouldHandleErrorRetrievingRedirectionUrlWithGenericException() { String pspId = "pspId"; TransactionActivated transaction = TransactionTestUtils.transactionActivated(ZonedDateTime.now().toString()); + + PaymentSessionData paymentSessionData = new PaymentSessionData.RedirectSessionData(); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2921,9 +3040,7 @@ void shouldHandleErrorRetrievingRedirectionUrlWithGenericException() { "pspBusinessName", false, "REDIRECT", - Optional.empty(), - Optional.empty(), - "N/A", + paymentSessionData, new RedirectionAuthRequestDetailsDto(), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -3004,6 +3121,9 @@ void shouldHandleErrorRetrievingRedirectionUrlWithGenericException() { @Test void shouldReturnErrorDuringRedirectPaymentTransactionForInvalidPspURL() { TransactionActivated transaction = TransactionTestUtils.transactionActivated(ZonedDateTime.now().toString()); + + PaymentSessionData paymentSessionData = new PaymentSessionData.RedirectSessionData(); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -3019,9 +3139,7 @@ void shouldReturnErrorDuringRedirectPaymentTransactionForInvalidPspURL() { "pspBusinessName", false, "REDIRECT", - Optional.empty(), - Optional.empty(), - "N/A", + paymentSessionData, new RedirectionAuthRequestDetailsDto(), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -3066,6 +3184,9 @@ void shouldReturnErrorDuringRedirectPaymentTransactionForInvalidPspURL() { void shouldReturnErrorDuringRedirectPaymentTransactionForUnmanagedPaymentTypeCode() { String pspId = "pspId"; TransactionActivated transaction = TransactionTestUtils.transactionActivated(ZonedDateTime.now().toString()); + + PaymentSessionData paymentSessionData = new PaymentSessionData.RedirectSessionData(); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -3081,9 +3202,7 @@ void shouldReturnErrorDuringRedirectPaymentTransactionForUnmanagedPaymentTypeCod "pspBusinessName", false, "REDIRECT", - Optional.empty(), - Optional.empty(), - "N/A", + paymentSessionData, new RedirectionAuthRequestDetailsDto(), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) diff --git a/src/test/java/it/pagopa/transactions/commands/handlers/v1/TransactionRequestAuthorizationHandlerTest.java b/src/test/java/it/pagopa/transactions/commands/handlers/v1/TransactionRequestAuthorizationHandlerTest.java index c982ec1cb..b23b24361 100644 --- a/src/test/java/it/pagopa/transactions/commands/handlers/v1/TransactionRequestAuthorizationHandlerTest.java +++ b/src/test/java/it/pagopa/transactions/commands/handlers/v1/TransactionRequestAuthorizationHandlerTest.java @@ -22,6 +22,7 @@ import it.pagopa.transactions.exceptions.BadGatewayException; import it.pagopa.transactions.repositories.TransactionTemplateWrapper; import it.pagopa.transactions.repositories.TransactionsEventStoreRepository; +import it.pagopa.transactions.utils.PaymentSessionData; import it.pagopa.transactions.utils.TransactionsUtils; import org.apache.commons.codec.binary.Base64; import org.junit.jupiter.api.AfterAll; @@ -171,6 +172,12 @@ void shouldSaveAuthorizationEventXPAY() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -186,9 +193,7 @@ void shouldSaveAuthorizationEventXPAY() { "pspBusinessName", false, "XPAY", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, new CardAuthRequestDetailsDto().brand(CardAuthRequestDetailsDto.BrandEnum.VISA), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -258,6 +263,13 @@ void shouldSaveAuthorizationEventNpgCardsRedirectToExternalDomain() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -273,10 +285,7 @@ void shouldSaveAuthorizationEventNpgCardsRedirectToExternalDomain() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId("orderId"), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -364,6 +373,13 @@ void shouldSaveAuthorizationEventNpgCardsPaymentComplete() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -379,9 +395,7 @@ void shouldSaveAuthorizationEventNpgCardsPaymentComplete() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId("orderId"), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -469,6 +483,13 @@ void shouldSaveAuthorizationEventGdiVerification() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -484,9 +505,7 @@ void shouldSaveAuthorizationEventGdiVerification() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId("orderId"), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -579,6 +598,13 @@ void shouldSaveAuthorizationEventBadGatewayException() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -594,9 +620,7 @@ void shouldSaveAuthorizationEventBadGatewayException() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId("orderId"), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -677,6 +701,13 @@ void shouldRejectAlreadyProcessedTransaction() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -692,9 +723,7 @@ void shouldRejectAlreadyProcessedTransaction() { "pspBusinessName", false, null, - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, null, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -763,6 +792,8 @@ void shouldRejectBadGateway() { .pspId("VPOS") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.RedirectSessionData(); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -777,10 +808,8 @@ void shouldRejectBadGateway() { "paymentMethodDescription", "pspBusinessName", false, - "GPAY", - Optional.empty(), - Optional.empty(), - "VISA", + "BAD_PAY", + paymentSessionData, new RedirectionAuthRequestDetailsDto(), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -853,6 +882,13 @@ void shouldMapLogoSuccessfully(String brand) { .paymentInstrumentId("paymentInstrumentId") .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -868,12 +904,10 @@ void shouldMapLogoSuccessfully(String brand) { "pspBusinessName", false, "VPOS", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, new CardAuthRequestDetailsDto() .cvv("000") - .pan("123") + .pan("00001234") .threeDsData("threeDsData") .expiryDate("209912") .brand(CardAuthRequestDetailsDto.BrandEnum.fromValue(brand)) diff --git a/src/test/java/it/pagopa/transactions/commands/handlers/v2/TransactionRequestAuthorizationHandlerTest.java b/src/test/java/it/pagopa/transactions/commands/handlers/v2/TransactionRequestAuthorizationHandlerTest.java index cee488278..11067c96c 100644 --- a/src/test/java/it/pagopa/transactions/commands/handlers/v2/TransactionRequestAuthorizationHandlerTest.java +++ b/src/test/java/it/pagopa/transactions/commands/handlers/v2/TransactionRequestAuthorizationHandlerTest.java @@ -37,6 +37,7 @@ import it.pagopa.transactions.repositories.TransactionTemplateWrapper; import it.pagopa.transactions.repositories.TransactionsEventStoreRepository; import it.pagopa.transactions.utils.OpenTelemetryUtils; +import it.pagopa.transactions.utils.PaymentSessionData; import it.pagopa.transactions.utils.Queues; import it.pagopa.transactions.utils.TransactionsUtils; import org.apache.commons.codec.binary.Base64; @@ -216,6 +217,12 @@ void shouldSaveAuthorizationEventXPAY() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -231,9 +238,7 @@ void shouldSaveAuthorizationEventXPAY() { "pspBusinessName", false, "XPAY", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, new CardAuthRequestDetailsDto().brand(CardAuthRequestDetailsDto.BrandEnum.VISA), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -310,6 +315,12 @@ void shouldSaveAuthorizationEventVPOS() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -325,9 +336,7 @@ void shouldSaveAuthorizationEventVPOS() { "pspBusinessName", false, "VPOS", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, new CardAuthRequestDetailsDto().brand(CardAuthRequestDetailsDto.BrandEnum.VISA), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -407,6 +416,13 @@ void shouldSaveAuthorizationEventNpgCardsRedirectToExternalDomain() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -422,9 +438,7 @@ void shouldSaveAuthorizationEventNpgCardsRedirectToExternalDomain() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -489,7 +503,7 @@ void shouldSaveAuthorizationEventNpgCardsRedirectToExternalDomain() { NpgTransactionGatewayAuthorizationRequestedData npgTransactionGatewayAuthorizationRequestedData = (NpgTransactionGatewayAuthorizationRequestedData) savedEvent .getData().getTransactionGatewayAuthorizationRequestedData(); assertEquals( - authorizationData.sessionId().get(), + paymentSessionData.sessionId(), npgTransactionGatewayAuthorizationRequestedData.getSessionId() ); assertNull(npgTransactionGatewayAuthorizationRequestedData.getConfirmPaymentSessionId()); @@ -540,6 +554,13 @@ void shouldSaveAuthorizationEventNpgCardsPaymentCompleteCheckoutClient() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -555,9 +576,7 @@ void shouldSaveAuthorizationEventNpgCardsPaymentCompleteCheckoutClient() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -774,7 +793,7 @@ void shouldSaveAuthorizationEventNpgCardsPaymentCompleteIOClient() { NpgTransactionGatewayAuthorizationRequestedData npgTransactionGatewayAuthorizationRequestedData = (NpgTransactionGatewayAuthorizationRequestedData) savedEvent .getData().getTransactionGatewayAuthorizationRequestedData(); assertEquals( - authorizationData.sessionId().get(), + paymentSessionData.sessionId(), npgTransactionGatewayAuthorizationRequestedData.getSessionId() ); assertNull(npgTransactionGatewayAuthorizationRequestedData.getConfirmPaymentSessionId()); @@ -825,6 +844,13 @@ void shouldSaveAuthorizationEventGdiVerification() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -840,9 +866,7 @@ void shouldSaveAuthorizationEventGdiVerification() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -918,7 +942,7 @@ void shouldSaveAuthorizationEventGdiVerification() { NpgTransactionGatewayAuthorizationRequestedData npgTransactionGatewayAuthorizationRequestedData = (NpgTransactionGatewayAuthorizationRequestedData) savedEvent .getData().getTransactionGatewayAuthorizationRequestedData(); assertEquals( - authorizationData.sessionId().get(), + paymentSessionData.sessionId(), npgTransactionGatewayAuthorizationRequestedData.getSessionId() ); assertNull(npgTransactionGatewayAuthorizationRequestedData.getConfirmPaymentSessionId()); @@ -969,6 +993,13 @@ void shouldSaveAuthorizationEventBadGatewayException() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -984,9 +1015,7 @@ void shouldSaveAuthorizationEventBadGatewayException() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1075,6 +1104,13 @@ void shouldRejectAlreadyProcessedTransaction() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1090,9 +1126,7 @@ void shouldRejectAlreadyProcessedTransaction() { "pspBusinessName", false, null, - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, null, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1163,6 +1197,13 @@ void shouldRejectBadGateway() { .pspId("VPOS") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1178,9 +1219,7 @@ void shouldRejectBadGateway() { "pspBusinessName", false, "GPAY", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, new CardAuthRequestDetailsDto(), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1255,6 +1294,13 @@ void shouldMapLogoSuccessfully(String brand) { .paymentInstrumentId("paymentInstrumentId") .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1270,10 +1316,7 @@ void shouldMapLogoSuccessfully(String brand) { "pspBusinessName", false, "VPOS", - Optional.empty(), - Optional.empty(), - - "VISA", + paymentSessionData, new CardAuthRequestDetailsDto() .cvv("000") .pan("123") @@ -1359,6 +1402,13 @@ void shouldReturnErrorForMissingStateInNPGConfirmPaymentResponse() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1374,9 +1424,7 @@ void shouldReturnErrorForMissingStateInNPGConfirmPaymentResponse() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1469,6 +1517,13 @@ void shouldReturnErrorForNPGGdiVerificationResponseStateWithNoFieldSetReceived() .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1484,9 +1539,7 @@ void shouldReturnErrorForNPGGdiVerificationResponseStateWithNoFieldSetReceived() "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1582,6 +1635,13 @@ void shouldReturnErrorForNPGGdiVerificationResponseStateWithNoFieldsReceivedInto .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1597,9 +1657,7 @@ void shouldReturnErrorForNPGGdiVerificationResponseStateWithNoFieldsReceivedInto "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId("orderId"), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1696,6 +1754,13 @@ void shouldReturnErrorForNPGGdiVerificationResponseStateWithNullSrcReceivedInFie .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1711,9 +1776,7 @@ void shouldReturnErrorForNPGGdiVerificationResponseStateWithNullSrcReceivedInFie "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1810,6 +1873,13 @@ void shouldReturnErrorForNPGRedirectToExternalDomainStateResponseWithoutPopulate .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1825,9 +1895,7 @@ void shouldReturnErrorForNPGRedirectToExternalDomainStateResponseWithoutPopulate "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -1923,6 +1991,13 @@ void shouldSaveAuthorizationEventNpgCardsRedirectToExternalDomainSavingReceivedS .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -1938,9 +2013,7 @@ void shouldSaveAuthorizationEventNpgCardsRedirectToExternalDomainSavingReceivedS "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId("orderId"), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2002,7 +2075,7 @@ void shouldSaveAuthorizationEventNpgCardsRedirectToExternalDomainSavingReceivedS NpgTransactionGatewayAuthorizationRequestedData npgTransactionGatewayAuthorizationRequestedData = (NpgTransactionGatewayAuthorizationRequestedData) savedEvent .getData().getTransactionGatewayAuthorizationRequestedData(); assertEquals( - authorizationData.sessionId().get(), + paymentSessionData.sessionId(), npgTransactionGatewayAuthorizationRequestedData.getSessionId() ); assertEquals( @@ -2056,6 +2129,13 @@ void shouldSaveAuthorizationEventNpgCardsPaymentCompleteSavingReceivedSessionIdI .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2071,9 +2151,7 @@ void shouldSaveAuthorizationEventNpgCardsPaymentCompleteSavingReceivedSessionIdI "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2140,7 +2218,7 @@ void shouldSaveAuthorizationEventNpgCardsPaymentCompleteSavingReceivedSessionIdI NpgTransactionGatewayAuthorizationRequestedData npgTransactionGatewayAuthorizationRequestedData = (NpgTransactionGatewayAuthorizationRequestedData) savedEvent .getData().getTransactionGatewayAuthorizationRequestedData(); assertEquals( - authorizationData.sessionId().get(), + paymentSessionData.sessionId(), npgTransactionGatewayAuthorizationRequestedData.getSessionId() ); assertEquals( @@ -2194,6 +2272,13 @@ void shouldSaveAuthorizationEventGdiVerificationSavingReceivedSessionIdInEvent() .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2209,9 +2294,7 @@ void shouldSaveAuthorizationEventGdiVerificationSavingReceivedSessionIdInEvent() "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2282,7 +2365,7 @@ void shouldSaveAuthorizationEventGdiVerificationSavingReceivedSessionIdInEvent() NpgTransactionGatewayAuthorizationRequestedData npgTransactionGatewayAuthorizationRequestedData = (NpgTransactionGatewayAuthorizationRequestedData) savedEvent .getData().getTransactionGatewayAuthorizationRequestedData(); assertEquals( - authorizationData.sessionId().get(), + paymentSessionData.sessionId(), npgTransactionGatewayAuthorizationRequestedData.getSessionId() ); assertEquals( @@ -2296,7 +2379,7 @@ void shouldSaveAuthorizationEventGdiVerificationForWallet() { String walletId = UUID.randomUUID().toString(); String contractId = "contractId"; String sessionId = "sessionId"; - String orderId = "oderId"; + String orderId = "orderId"; TransactionId transactionId = new TransactionId(transactionIdUUID); PaymentToken paymentToken = new PaymentToken("paymentToken"); RptId rptId = new RptId("77777777777111111111111111111"); @@ -2340,6 +2423,14 @@ void shouldSaveAuthorizationEventGdiVerificationForWallet() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( + "VISA", + Optional.empty(), + "0000", + "1234", + contractId + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2355,14 +2446,20 @@ void shouldSaveAuthorizationEventGdiVerificationForWallet() { "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.of(contractId), - "VISA", + paymentSessionData, new WalletAuthRequestDetailsDto().detailType("wallet").walletId(walletId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) ); + PaymentSessionData paymentSessionDataAfterBuildSession = new PaymentSessionData.WalletCardSessionData( + "VISA", + Optional.of(sessionId), + "0000", + "1234", + contractId + ); + AuthorizationRequestData authorizationDataAfterBuildSession = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2378,9 +2475,7 @@ void shouldSaveAuthorizationEventGdiVerificationForWallet() { "pspBusinessName", false, "NPG", - Optional.of(sessionId), - Optional.of(contractId), - "VISA", + paymentSessionDataAfterBuildSession, new WalletAuthRequestDetailsDto().detailType("wallet").walletId(walletId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2419,7 +2514,7 @@ void shouldSaveAuthorizationEventGdiVerificationForWallet() { ) .thenReturn(Mono.just(responseRequestNpgBuildSession)); Mockito.when( - paymentGatewayClient.requestNpgCardsAuthorization(authorizationDataAfterBuildSession, correlationId) + paymentGatewayClient.requestNpgCardsAuthorization(any(), any()) ) .thenReturn(Mono.just(stateResponseDto)); TransactionActivatedEvent transactionActivatedEvent = TransactionTestUtils.transactionActivateEvent( @@ -2471,7 +2566,8 @@ void shouldSaveAuthorizationEventGdiVerificationForWallet() { ); assertNull(npgTransactionGatewayAuthorizationRequestedData.getConfirmPaymentSessionId()); Mockito.verify(transactionTemplateWrapper, Mockito.times(1)).save(any()); - + Mockito.verify(paymentGatewayClient, Mockito.times(1)) + .requestNpgCardsAuthorization(authorizationDataAfterBuildSession, correlationId); } @Test @@ -2520,6 +2616,14 @@ void shouldThrowExceptionNoGatewayMatchesDuringAuthorizationForWallet() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( + "VISA", + Optional.empty(), + "0000", + "1234", + contractId + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2535,9 +2639,7 @@ void shouldThrowExceptionNoGatewayMatchesDuringAuthorizationForWallet() { "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.of(contractId), - "VISA", + paymentSessionData, new CardAuthRequestDetailsDto(), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2578,7 +2680,7 @@ void shouldThrowExceptionNoGatewayMatchesDuringAuthorizationForWallet() { } @Test - void shouldPerformTransactionAuthorizationForWalletApmPaymentMethodUsingOrderBuildNpgCall() { + void shouldPerformTransactionAuthorizationForWalletPayPalPaymentMethodUsingOrderBuildNpgCall() { String walletId = UUID.randomUUID().toString(); String contractId = "contractId"; String sessionId = "sessionId"; @@ -2624,6 +2726,11 @@ void shouldPerformTransactionAuthorizationForWalletApmPaymentMethodUsingOrderBui .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.WalletPayPalSessionData( + contractId, + "maskedEmail" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2639,9 +2746,7 @@ void shouldPerformTransactionAuthorizationForWalletApmPaymentMethodUsingOrderBui "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.of(contractId), - "VISA", + paymentSessionData, new WalletAuthRequestDetailsDto().detailType("wallet").walletId(walletId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2760,6 +2865,10 @@ void shouldPerformTransactionAuthorizationForApmPaymentMethodUsingOrderBuildNpgC .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.ApmSessionData( + "BANCOMATPAY" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2775,9 +2884,7 @@ void shouldPerformTransactionAuthorizationForApmPaymentMethodUsingOrderBuildNpgC "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.empty(), - "BANCOMATPAY", + paymentSessionData, new ApmAuthRequestDetailsDto().detailType("apm"), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -2854,7 +2961,9 @@ void shouldPerformTransactionAuthorizationForApmPaymentMethodUsingOrderBuildNpgC @ParameterizedTest @ValueSource(strings = "") @NullSource - void shouldReturnErrorPerformingTransactionAuthorizationForWalletApmForInvalidNpgReturnUrl(String wrongReturnUrl) { + void shouldReturnErrorPerformingTransactionAuthorizationForWalletPayPalForInvalidNpgReturnUrl( + String wrongReturnUrl + ) { String walletId = UUID.randomUUID().toString(); String contractId = "contractId"; String sessionId = "sessionId"; @@ -2900,6 +3009,11 @@ void shouldReturnErrorPerformingTransactionAuthorizationForWalletApmForInvalidNp .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.WalletPayPalSessionData( + contractId, + "maskedEmail" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -2915,9 +3029,7 @@ void shouldReturnErrorPerformingTransactionAuthorizationForWalletApmForInvalidNp "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.of(contractId), - "VISA", + paymentSessionData, new WalletAuthRequestDetailsDto().detailType("wallet").walletId(walletId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -3012,6 +3124,9 @@ void shouldHandleAuthorizationRequestForRedirectionPaymentGateway() { .language(RequestAuthorizationRequestDto.LanguageEnum.IT) .details(new RedirectionAuthRequestDetailsDto()); String expectedLogo = "http://localhost/logo"; + + PaymentSessionData paymentSessionData = new PaymentSessionData.RedirectSessionData(); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -3027,9 +3142,7 @@ void shouldHandleAuthorizationRequestForRedirectionPaymentGateway() { "pspBusinessName", false, "REDIRECT", - Optional.empty(), - Optional.empty(), - null, + paymentSessionData, new RedirectionAuthRequestDetailsDto(), expectedLogo, Optional.empty() @@ -3128,6 +3241,14 @@ void shouldUseDefaultAssetLogoWithNoMappingConfigurationMatchFoundInBrandLogoMap .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); String expectedLogo = "http://expectedLogo"; + + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "UNMATCHED", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -3143,9 +3264,7 @@ void shouldUseDefaultAssetLogoWithNoMappingConfigurationMatchFoundInBrandLogoMap "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "UNMATCHED", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), expectedLogo, Optional.of(Map.of("VISA", "http://visa")) @@ -3210,7 +3329,7 @@ void shouldUseDefaultAssetLogoWithNoMappingConfigurationMatchFoundInBrandLogoMap NpgTransactionGatewayAuthorizationRequestedData npgTransactionGatewayAuthorizationRequestedData = (NpgTransactionGatewayAuthorizationRequestedData) savedEvent .getData().getTransactionGatewayAuthorizationRequestedData(); assertEquals( - authorizationData.sessionId().get(), + paymentSessionData.sessionId(), npgTransactionGatewayAuthorizationRequestedData.getSessionId() ); assertNull(npgTransactionGatewayAuthorizationRequestedData.getConfirmPaymentSessionId()); @@ -3262,6 +3381,14 @@ void shouldUseDefaultAssetLogoWithNoBrandLogoConfiguration() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); String expectedLogo = "http://expectedLogo"; + + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -3277,9 +3404,7 @@ void shouldUseDefaultAssetLogoWithNoBrandLogoConfiguration() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), expectedLogo, Optional.empty() @@ -3344,7 +3469,7 @@ void shouldUseDefaultAssetLogoWithNoBrandLogoConfiguration() { NpgTransactionGatewayAuthorizationRequestedData npgTransactionGatewayAuthorizationRequestedData = (NpgTransactionGatewayAuthorizationRequestedData) savedEvent .getData().getTransactionGatewayAuthorizationRequestedData(); assertEquals( - authorizationData.sessionId().get(), + paymentSessionData.sessionId(), npgTransactionGatewayAuthorizationRequestedData.getSessionId() ); assertNull(npgTransactionGatewayAuthorizationRequestedData.getConfirmPaymentSessionId()); @@ -3396,6 +3521,14 @@ void shouldUseBrandAssetLogoForCardPaymentWithConfiguredBrand() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); String expectedLogo = "http://visa"; + + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -3411,9 +3544,7 @@ void shouldUseBrandAssetLogoForCardPaymentWithConfiguredBrand() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - "VISA", + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), "http//defaultLogo", Optional.of(Map.of("VISA", expectedLogo)) @@ -3478,7 +3609,7 @@ void shouldUseBrandAssetLogoForCardPaymentWithConfiguredBrand() { NpgTransactionGatewayAuthorizationRequestedData npgTransactionGatewayAuthorizationRequestedData = (NpgTransactionGatewayAuthorizationRequestedData) savedEvent .getData().getTransactionGatewayAuthorizationRequestedData(); assertEquals( - authorizationData.sessionId().get(), + paymentSessionData.sessionId(), npgTransactionGatewayAuthorizationRequestedData.getSessionId() ); assertNull(npgTransactionGatewayAuthorizationRequestedData.getConfirmPaymentSessionId()); @@ -3530,6 +3661,14 @@ void shouldUseDefaultLogoForNoBrandInformation() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); String expectedLogo = "http://defaultLogo"; + + PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -3545,12 +3684,10 @@ void shouldUseDefaultLogoForNoBrandInformation() { "pspBusinessName", false, "NPG", - Optional.of(UUID.randomUUID().toString()), - Optional.empty(), - null, + paymentSessionData, new CardsAuthRequestDetailsDto().orderId(orderId), expectedLogo, - Optional.of(Map.of("VISA", "http://visaLogo")) + Optional.empty() ); TransactionRequestAuthorizationCommand requestAuthorizationCommand = new TransactionRequestAuthorizationCommand( @@ -3612,7 +3749,7 @@ void shouldUseDefaultLogoForNoBrandInformation() { NpgTransactionGatewayAuthorizationRequestedData npgTransactionGatewayAuthorizationRequestedData = (NpgTransactionGatewayAuthorizationRequestedData) savedEvent .getData().getTransactionGatewayAuthorizationRequestedData(); assertEquals( - authorizationData.sessionId().get(), + paymentSessionData.sessionId(), npgTransactionGatewayAuthorizationRequestedData.getSessionId() ); assertNull(npgTransactionGatewayAuthorizationRequestedData.getConfirmPaymentSessionId()); @@ -3668,6 +3805,14 @@ void shouldFireWalletUsedEventWhenRequestAuthorizationThroughWallet() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( + "VISA", + Optional.empty(), + "0000", + "1234", + contractId + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -3683,14 +3828,20 @@ void shouldFireWalletUsedEventWhenRequestAuthorizationThroughWallet() { "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.of(contractId), - "VISA", + paymentSessionData, new WalletAuthRequestDetailsDto().detailType("wallet").walletId(walletId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) ); + PaymentSessionData paymentSessionDataAfterBuildSession = new PaymentSessionData.WalletCardSessionData( + "VISA", + Optional.of(sessionId), + "0000", + "1234", + contractId + ); + AuthorizationRequestData authorizationDataAfterBuildSession = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -3706,9 +3857,7 @@ void shouldFireWalletUsedEventWhenRequestAuthorizationThroughWallet() { "pspBusinessName", false, "NPG", - Optional.of(sessionId), - Optional.of(contractId), - "VISA", + paymentSessionDataAfterBuildSession, new WalletAuthRequestDetailsDto().detailType("wallet").walletId(walletId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -3858,6 +4007,13 @@ void shouldNotFireWalletUsedEventWhenRequestAuthorizationWithoutWallet() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.CardSessionData( + "VISA", + UUID.randomUUID().toString(), + "0000", + "1234" + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -3873,9 +4029,7 @@ void shouldNotFireWalletUsedEventWhenRequestAuthorizationWithoutWallet() { "pspBusinessName", false, "VPOS", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, new CardAuthRequestDetailsDto().brand(CardAuthRequestDetailsDto.BrandEnum.VISA), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) @@ -3960,6 +4114,14 @@ void shouldNotAffectRequestAuthorizationWhenFiringWalletUsedFails() { .pspId("PSP_CODE") .language(RequestAuthorizationRequestDto.LanguageEnum.IT); + PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( + "VISA", + Optional.empty(), + "0000", + "1234", + contractId + ); + AuthorizationRequestData authorizationData = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -3975,14 +4137,20 @@ void shouldNotAffectRequestAuthorizationWhenFiringWalletUsedFails() { "pspBusinessName", false, "NPG", - Optional.empty(), - Optional.of(contractId), - "VISA", + paymentSessionData, new WalletAuthRequestDetailsDto().detailType("wallet").walletId(walletId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) ); + PaymentSessionData paymentSessionDataAfterBuildSession = new PaymentSessionData.WalletCardSessionData( + "VISA", + Optional.of(sessionId), + "0000", + "1234", + contractId + ); + AuthorizationRequestData authorizationDataAfterBuildSession = new AuthorizationRequestData( transaction.getTransactionId(), transaction.getPaymentNotices(), @@ -3998,9 +4166,7 @@ void shouldNotAffectRequestAuthorizationWhenFiringWalletUsedFails() { "pspBusinessName", false, "NPG", - Optional.of(sessionId), - Optional.of(contractId), - "VISA", + paymentSessionDataAfterBuildSession, new WalletAuthRequestDetailsDto().detailType("wallet").walletId(walletId), "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) diff --git a/src/test/java/it/pagopa/transactions/services/v1/TransactionServiceTests.java b/src/test/java/it/pagopa/transactions/services/v1/TransactionServiceTests.java index 6ca040144..0128efca9 100644 --- a/src/test/java/it/pagopa/transactions/services/v1/TransactionServiceTests.java +++ b/src/test/java/it/pagopa/transactions/services/v1/TransactionServiceTests.java @@ -2123,9 +2123,13 @@ void shouldRedirectToAuthorizationURIForValidRequestWithNPGWalletDetail() { walletClient.getWalletInfo(walletId) ).thenReturn( Mono.just( - new WalletAuthDataDto().walletId(UUID.fromString(walletId)).brand("VISA") + new WalletAuthDataDto() + .walletId(UUID.fromString(walletId)) + .brand("VISA") .contractId(contractId) - .paymentMethodData(new WalletAuthCardDataDto().bin("bin")) + .paymentMethodData( + new WalletAuthCardDataDto().bin("bin").lastFourDigits("lastFourDigits") + ) ) ); @@ -2159,8 +2163,10 @@ void shouldRedirectToAuthorizationURIForValidRequestWithNPGWalletDetail() { .verifyComplete(); AuthorizationRequestData captureData = commandArgumentCaptor.getValue().getData(); - assertEquals(Optional.empty(), captureData.sessionId()); - assertEquals(contractId, captureData.contractId().get()); + PaymentSessionData.WalletCardSessionData walletCardSessionData = (PaymentSessionData.WalletCardSessionData) captureData + .paymentSessionData(); + assertEquals(Optional.empty(), walletCardSessionData.sessionId()); + assertEquals(contractId, walletCardSessionData.contractId()); assertEquals(calculateFeeResponseDto.getPaymentMethodDescription(), captureData.paymentMethodDescription()); assertEquals(calculateFeeResponseDto.getPaymentMethodName(), captureData.paymentMethodName()); // verify that cache delete is called for each payment notice @@ -2258,9 +2264,9 @@ void shouldRedirectToAuthorizationURIForValidRequestWithNPGApmDetail() { .verifyComplete(); AuthorizationRequestData captureData = commandArgumentCaptor.getValue().getData(); - assertEquals(Optional.empty(), captureData.sessionId()); - assertEquals(Optional.empty(), captureData.contractId()); - assertEquals(paymentMethod.getName(), captureData.brand()); + PaymentSessionData.ApmSessionData apmSessionData = (PaymentSessionData.ApmSessionData) captureData + .paymentSessionData(); + assertEquals(paymentMethod.getName(), apmSessionData.brand()); assertEquals(calculateFeeResponseDto.getPaymentMethodDescription(), captureData.paymentMethodDescription()); assertEquals(calculateFeeResponseDto.getPaymentMethodName(), captureData.paymentMethodName()); // verify that cache delete is called for each payment notice @@ -2367,9 +2373,9 @@ void shouldRedirectToAuthorizationURIForValidRequestWithRedirectDetail() { .verifyComplete(); AuthorizationRequestData captureData = commandArgumentCaptor.getValue().getData(); - assertEquals(Optional.empty(), captureData.sessionId()); - assertEquals(Optional.empty(), captureData.contractId()); - assertEquals("N/A", captureData.brand()); + PaymentSessionData.RedirectSessionData redirectSessionData = (PaymentSessionData.RedirectSessionData) captureData + .paymentSessionData(); + assertEquals("N/A", redirectSessionData.brand()); assertEquals(calculateFeeResponseDto.getPaymentMethodDescription(), captureData.paymentMethodDescription()); assertEquals(calculateFeeResponseDto.getPaymentMethodName(), captureData.paymentMethodName()); // verify that cache delete is called for each payment notice diff --git a/src/test/java/it/pagopa/transactions/utils/LogMaskTests.java b/src/test/java/it/pagopa/transactions/utils/LogMaskTests.java index 3bfe901e1..9f97f654a 100644 --- a/src/test/java/it/pagopa/transactions/utils/LogMaskTests.java +++ b/src/test/java/it/pagopa/transactions/utils/LogMaskTests.java @@ -90,6 +90,11 @@ void shouldMaskCvvPanEmail() throws IOException { ); TransactionActivated transactionActivated = TransactionTestUtils .transactionActivated(ZonedDateTime.now().toString()); + PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( + "VISA", + pan.substring(0, 6), + pan.substring(pan.length() - 4) + ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( transactionActivated.getTransactionId(), transactionActivated.getPaymentNotices(), @@ -105,9 +110,7 @@ void shouldMaskCvvPanEmail() throws IOException { "pspBusinessName", false, "XPAY", - Optional.empty(), - Optional.empty(), - "VISA", + paymentSessionData, cardDetails, "http://asset", Optional.of(Map.of("VISA", "http://visaAsset")) From b58350c9f71da64441bfed613939b1bdb2070c59 Mon Sep 17 00:00:00 2001 From: Giovanni Berti Date: Mon, 15 Apr 2024 10:15:13 +0200 Subject: [PATCH 3/5] refactor(payment-session-data): add checks for card bin and last four digits --- .../utils/PaymentSessionData.java | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java b/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java index 9b55efc0f..6b60410df 100644 --- a/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java +++ b/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java @@ -20,6 +20,9 @@ record PgsCardSessionData( Objects.requireNonNull(brand); Objects.requireNonNull(cardBin); Objects.requireNonNull(lastFourDigits); + + validateCardBin(cardBin); + validateLastFourDigits(lastFourDigits); } } @@ -36,6 +39,9 @@ record CardSessionData( Objects.requireNonNull(sessionId); Objects.requireNonNull(cardBin); Objects.requireNonNull(lastFourDigits); + + validateCardBin(cardBin); + validateLastFourDigits(lastFourDigits); } } @@ -64,6 +70,9 @@ record WalletCardSessionData( Objects.requireNonNull(cardBin); Objects.requireNonNull(lastFourDigits); Objects.requireNonNull(contractId); + + validateCardBin(cardBin); + validateLastFourDigits(lastFourDigits); } } @@ -94,4 +103,16 @@ public String brand() { return "N/A"; } } + + static void validateCardBin(String cardBin) { + if (cardBin.length() > 8 || cardBin.length() < 6) { + throw new IllegalArgumentException("Invalid card bin of length " + cardBin.length()); + } + } + + static void validateLastFourDigits(String lastFourDigits) { + if (lastFourDigits.length() != 4) { + throw new IllegalArgumentException("Invalid last four digits of length " + lastFourDigits.length()); + } + } } From f1c3613171b025e192b6c5c18104c3d2192c9ee1 Mon Sep 17 00:00:00 2001 From: Giovanni Berti Date: Mon, 15 Apr 2024 10:55:53 +0200 Subject: [PATCH 4/5] refactor: use `BIN` and `CardLastFourDigits` domain classes from commons --- ...tionRequestAuthorizationHandlerCommon.java | 5 +- ...ransactionRequestAuthorizationHandler.java | 4 +- .../services/v1/TransactionsService.java | 33 +++-- .../utils/PaymentSessionData.java | 36 ++--- .../client/PaymentGatewayClientTest.java | 99 +++++++------- ...actionRequestAuthorizationHandlerTest.java | 28 ++-- ...actionRequestAuthorizationHandlerTest.java | 129 +++++++++--------- .../services/v1/TransactionServiceTests.java | 7 +- .../services/v2/TransactionServiceTests.java | 2 +- .../transactions/utils/LogMaskTests.java | 6 +- 10 files changed, 179 insertions(+), 170 deletions(-) diff --git a/src/main/java/it/pagopa/transactions/commands/handlers/TransactionRequestAuthorizationHandlerCommon.java b/src/main/java/it/pagopa/transactions/commands/handlers/TransactionRequestAuthorizationHandlerCommon.java index 1516f19d2..0ffd9c2d4 100644 --- a/src/main/java/it/pagopa/transactions/commands/handlers/TransactionRequestAuthorizationHandlerCommon.java +++ b/src/main/java/it/pagopa/transactions/commands/handlers/TransactionRequestAuthorizationHandlerCommon.java @@ -30,10 +30,7 @@ import javax.crypto.SecretKey; import java.net.URI; import java.nio.charset.StandardCharsets; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; @Slf4j diff --git a/src/main/java/it/pagopa/transactions/commands/handlers/v2/TransactionRequestAuthorizationHandler.java b/src/main/java/it/pagopa/transactions/commands/handlers/v2/TransactionRequestAuthorizationHandler.java index c30f2a086..ac9330777 100644 --- a/src/main/java/it/pagopa/transactions/commands/handlers/v2/TransactionRequestAuthorizationHandler.java +++ b/src/main/java/it/pagopa/transactions/commands/handlers/v2/TransactionRequestAuthorizationHandler.java @@ -228,8 +228,8 @@ public Mono handle(TransactionRequestAuthorizat case WalletAuthRequestDetailsDto walletDetails -> { WalletInfo.WalletDetails walletInfoDetails = switch (command.getData().paymentSessionData()) { case PaymentSessionData.WalletCardSessionData walletCardSessionData -> new WalletInfo.CardWalletDetails( - walletCardSessionData.cardBin(), - walletCardSessionData.lastFourDigits() + walletCardSessionData.cardBin().value(), + walletCardSessionData.lastFourDigits().value() ); case PaymentSessionData.WalletPayPalSessionData walletPayPalSessionData -> new WalletInfo.PaypalWalletDetails( walletPayPalSessionData.maskedEmail() diff --git a/src/main/java/it/pagopa/transactions/services/v1/TransactionsService.java b/src/main/java/it/pagopa/transactions/services/v1/TransactionsService.java index c905b3d6a..30cf2151f 100644 --- a/src/main/java/it/pagopa/transactions/services/v1/TransactionsService.java +++ b/src/main/java/it/pagopa/transactions/services/v1/TransactionsService.java @@ -505,10 +505,10 @@ public Mono requestTransactionAuthorization( paymentSessionData -> { String cardBin = switch (paymentSessionData) { case PaymentSessionData.CardSessionData cardSessionData -> - cardSessionData.cardBin(); - case PaymentSessionData.PgsCardSessionData cardSessionData -> cardSessionData.cardBin(); + cardSessionData.cardBin().value(); + case PaymentSessionData.PgsCardSessionData cardSessionData -> cardSessionData.cardBin().value(); case PaymentSessionData.WalletCardSessionData cardSessionData -> - cardSessionData.cardBin(); + cardSessionData.cardBin().value(); default -> null; }; @@ -1318,18 +1318,35 @@ public NewTransactionResponseDto.ClientIdEnum convertClientId( private Mono retrieveInformationFromAuthorizationRequest(RequestAuthorizationRequestDto requestAuthorizationRequestDto, String clientId) { return switch (requestAuthorizationRequestDto.getDetails()) { - case CardAuthRequestDetailsDto cardData -> - Mono.just(new PaymentSessionData.PgsCardSessionData(Optional.of(cardData.getBrand()).map(Enum::toString).orElse(null), cardData.getPan().substring(0, 6), cardData.getPan().substring(cardData.getPan().length() - 4))); + case CardAuthRequestDetailsDto cardData -> { + BIN bin = new BIN(cardData.getPan().substring(0, 6)); + CardLastFourDigits lastFourDigits = new CardLastFourDigits(cardData.getPan().substring(cardData.getPan().length() - 4)); + yield Mono.just( + new PaymentSessionData.PgsCardSessionData( + Optional.of(cardData.getBrand()).map(Enum::toString).orElse(null), + bin, + lastFourDigits + ) + ); + } case CardsAuthRequestDetailsDto cards -> - ecommercePaymentMethodsClient.retrieveCardData(requestAuthorizationRequestDto.getPaymentInstrumentId(), cards.getOrderId()).map(response -> new PaymentSessionData.CardSessionData(response.getBrand(), response.getSessionId(), response.getBin(), response.getLastFourDigits())); + ecommercePaymentMethodsClient.retrieveCardData(requestAuthorizationRequestDto.getPaymentInstrumentId(), cards.getOrderId()) + .map(response -> + new PaymentSessionData.CardSessionData( + response.getBrand(), + response.getSessionId(), + new BIN(response.getBin()), + new CardLastFourDigits(response.getLastFourDigits()) + ) + ); case WalletAuthRequestDetailsDto wallet -> walletClient .getWalletInfo(wallet.getWalletId()) .map(walletAuthDataDto -> switch (walletAuthDataDto.getPaymentMethodData()) { case WalletAuthCardDataDto cardsData -> new PaymentSessionData.WalletCardSessionData( walletAuthDataDto.getBrand(), Optional.empty(), - cardsData.getBin(), - cardsData.getLastFourDigits(), + new BIN(cardsData.getBin()), + new CardLastFourDigits(cardsData.getLastFourDigits()), walletAuthDataDto.getContractId() ); case WalletAuthPayPalDataDto payPalData -> diff --git a/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java b/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java index 6b60410df..018dddeb7 100644 --- a/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java +++ b/src/main/java/it/pagopa/transactions/utils/PaymentSessionData.java @@ -1,5 +1,8 @@ package it.pagopa.transactions.utils; +import it.pagopa.ecommerce.commons.domain.BIN; +import it.pagopa.ecommerce.commons.domain.CardLastFourDigits; + import javax.annotation.Nonnull; import java.util.Objects; import java.util.Optional; @@ -11,8 +14,8 @@ public sealed interface PaymentSessionData permits PaymentSessionData.ApmSession record PgsCardSessionData( @Nonnull String brand, - @Nonnull String cardBin, - @Nonnull String lastFourDigits + @Nonnull BIN cardBin, + @Nonnull CardLastFourDigits lastFourDigits ) implements PaymentSessionData { @@ -20,17 +23,14 @@ record PgsCardSessionData( Objects.requireNonNull(brand); Objects.requireNonNull(cardBin); Objects.requireNonNull(lastFourDigits); - - validateCardBin(cardBin); - validateLastFourDigits(lastFourDigits); } } record CardSessionData( @Nonnull String brand, @Nonnull String sessionId, - @Nonnull String cardBin, - @Nonnull String lastFourDigits + @Nonnull BIN cardBin, + @Nonnull CardLastFourDigits lastFourDigits ) implements PaymentSessionData { @@ -39,9 +39,6 @@ record CardSessionData( Objects.requireNonNull(sessionId); Objects.requireNonNull(cardBin); Objects.requireNonNull(lastFourDigits); - - validateCardBin(cardBin); - validateLastFourDigits(lastFourDigits); } } @@ -58,8 +55,8 @@ record ApmSessionData( record WalletCardSessionData( @Nonnull String brand, @Nonnull Optional sessionId, - @Nonnull String cardBin, - @Nonnull String lastFourDigits, + @Nonnull BIN cardBin, + @Nonnull CardLastFourDigits lastFourDigits, @Nonnull String contractId ) implements @@ -70,9 +67,6 @@ record WalletCardSessionData( Objects.requireNonNull(cardBin); Objects.requireNonNull(lastFourDigits); Objects.requireNonNull(contractId); - - validateCardBin(cardBin); - validateLastFourDigits(lastFourDigits); } } @@ -103,16 +97,4 @@ public String brand() { return "N/A"; } } - - static void validateCardBin(String cardBin) { - if (cardBin.length() > 8 || cardBin.length() < 6) { - throw new IllegalArgumentException("Invalid card bin of length " + cardBin.length()); - } - } - - static void validateLastFourDigits(String lastFourDigits) { - if (lastFourDigits.length() != 4) { - throw new IllegalArgumentException("Invalid last four digits of length " + lastFourDigits.length()); - } - } } diff --git a/src/test/java/it/pagopa/transactions/client/PaymentGatewayClientTest.java b/src/test/java/it/pagopa/transactions/client/PaymentGatewayClientTest.java index 0b2f7cf81..3b6754d9c 100644 --- a/src/test/java/it/pagopa/transactions/client/PaymentGatewayClientTest.java +++ b/src/test/java/it/pagopa/transactions/client/PaymentGatewayClientTest.java @@ -36,6 +36,7 @@ import it.pagopa.transactions.exceptions.AlreadyProcessedException; import it.pagopa.transactions.exceptions.BadGatewayException; import it.pagopa.transactions.exceptions.InvalidRequestException; +import it.pagopa.transactions.exceptions.NpgNotRetryableErrorException; import it.pagopa.transactions.utils.*; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -202,8 +203,8 @@ void shouldNotCallAuthorizationGatewayWithInvalidDetailTypeGatewayIdTuple() { PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( "VISA", UUID.randomUUID().toString(), - "0000", - "1234" + new BIN("0000"), + new CardLastFourDigits("1234") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -275,8 +276,8 @@ void shouldReturnAuthorizationResponseForCreditCardWithXPay() throws JsonProcess PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( "VISA", - "1658", - "4852" + new BIN("1658"), + new CardLastFourDigits("4852") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -373,8 +374,8 @@ void shouldReturnAuthorizationResponseForCreditCardWithVPOS() throws JsonProcess PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( "VISA", - "1658", - "4852" + new BIN("1658"), + new CardLastFourDigits("4852") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -475,8 +476,8 @@ void shouldReturnAuthorizationResponseForCardsWithNpg() { PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( "VISA", UUID.randomUUID().toString(), - "0000", - "1234" + new BIN("0000"), + new CardLastFourDigits("1234") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -558,8 +559,8 @@ void shouldThrowNpgNotRetryableErrorExceptionOn4xxForCardsWithNpg(Integer npgHtt PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( "VISA", UUID.randomUUID().toString(), - "0000", - "1234" + new BIN("0000"), + new CardLastFourDigits("1234") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -653,8 +654,8 @@ void shouldThrowGatewayTimeoutExceptionForCardsWithNpg() { PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( "VISA", UUID.randomUUID().toString(), - "0000", - "1234" + new BIN("0000"), + new CardLastFourDigits("1234") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -737,8 +738,8 @@ void shouldThrowInternalServerErrorExceptionForCardsWithNpg() { PaymentSessionData.CardSessionData paymentSessionData = new PaymentSessionData.CardSessionData( "VISA", UUID.randomUUID().toString(), - "0000", - "1234" + new BIN("0000"), + new CardLastFourDigits("1234") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -825,8 +826,8 @@ void shouldThrowAlreadyProcessedOn401ForCreditCardWithXpay() throws JsonProcessi PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( "VISA", - "1658", - "4852" + new BIN("1658"), + new CardLastFourDigits("4852") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -934,8 +935,8 @@ void shouldThrowBadGatewayOn500ForCreditCardWithXPay() throws JsonProcessingExce PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( "VISA", - "1658", - "4852" + new BIN("1658"), + new CardLastFourDigits("4852") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -1037,8 +1038,8 @@ void shouldThrowBadGatewayOn500ForCreditCardWithVPOS() throws JsonProcessingExce PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( "VISA", - "1658", - "4852" + new BIN("1658"), + new CardLastFourDigits("4852") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -1148,8 +1149,8 @@ void fallbackOnEmptyMdcInfoOnMapperErrorForCreditCardWithXPay() throws JsonProce PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( "VISA", - "1658", - "4852" + new BIN("1658"), + new CardLastFourDigits("4852") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -1245,8 +1246,8 @@ void fallbackOnEmptyMdcInfoOnMapperErrorForCreditCardWithVPOS() throws JsonProce PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( "VISA", - "1658", - "4852" + new BIN("1658"), + new CardLastFourDigits("4852") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -1344,8 +1345,8 @@ void shouldThrowInvalidRequestWhenCardDetailsAreMissingForCreditCardWithXPay() { PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( "VISA", - "1658", - "4852" + new BIN("1658"), + new CardLastFourDigits("4852") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -1408,8 +1409,8 @@ void shouldThrowInvalidRequestWhenCardDetailsAreMissingForCreditCardWithVPOS() { PaymentSessionData paymentSessionData = new PaymentSessionData.PgsCardSessionData( "VISA", - "1658", - "4852" + new BIN("1658"), + new CardLastFourDigits("4852") ); AuthorizationRequestData authorizationData = new AuthorizationRequestData( @@ -1484,8 +1485,8 @@ void shouldReturnBuildSessionResponseForWalletWithNpgWithCards() { PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( "VISA", Optional.empty(), - "0000", - "1234", + new BIN("0000"), + new CardLastFourDigits("1234"), contractId ); @@ -1655,8 +1656,8 @@ void shouldThrowNpgNotRetryableErrorExceptionOn4xxForWalletWithNpg(Integer npgHt PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( "VISA", Optional.empty(), - "0000", - "1234", + new BIN("0000"), + new CardLastFourDigits("1234"), contractId ); @@ -1775,8 +1776,8 @@ void shouldThrowGatewayTimeoutExceptionForWalletWithNpg() { PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( "VISA", Optional.empty(), - "0000", - "1234", + new BIN("0000"), + new CardLastFourDigits("1234"), contractId ); @@ -1884,8 +1885,8 @@ void shouldThrowInternalServerErrorExceptionForWalletWithNpg() { PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( "VISA", Optional.empty(), - "0000", - "1234", + new BIN("0000"), + new CardLastFourDigits("1234"), contractId ); @@ -1994,8 +1995,8 @@ void shouldReturnBadGatewayExceptionFromBuildSessionForWalletWithNpg(FieldsDto n PaymentSessionData paymentSessionData = new PaymentSessionData.WalletCardSessionData( "VISA", Optional.empty(), - "0000", - "1234", + new BIN("0000"), + new CardLastFourDigits("1234"), contractId ); @@ -3258,6 +3259,12 @@ void shouldReturnNpgNotRetryableErrorExceptionForConfiguredErrorCodes(List Date: Mon, 15 Apr 2024 11:03:43 +0200 Subject: [PATCH 5/5] fix(auth-request): add session id missing case for wallet card authorization --- .../handlers/TransactionRequestAuthorizationHandlerCommon.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/it/pagopa/transactions/commands/handlers/TransactionRequestAuthorizationHandlerCommon.java b/src/main/java/it/pagopa/transactions/commands/handlers/TransactionRequestAuthorizationHandlerCommon.java index 0ffd9c2d4..bddd1e8b0 100644 --- a/src/main/java/it/pagopa/transactions/commands/handlers/TransactionRequestAuthorizationHandlerCommon.java +++ b/src/main/java/it/pagopa/transactions/commands/handlers/TransactionRequestAuthorizationHandlerCommon.java @@ -433,6 +433,8 @@ private Mono invokeNpgConfirmPayment( Optional sessionId = switch (authorizationData.paymentSessionData()) { case PaymentSessionData.CardSessionData cardSessionData -> Optional.of(cardSessionData.sessionId()); + case PaymentSessionData.WalletCardSessionData walletCardSessionData -> walletCardSessionData.sessionId(); + default -> Optional.empty(); };