Skip to content

Commit

Permalink
Merge pull request #289 from pagopa/PG-24-Richiesta-su-PGS-in-stato-A…
Browse files Browse the repository at this point in the history
…UTHORIZED-ma-con-patch-su-ecommerce-KO

Pg 24 richiesta su pgs in stato authorized ma con patch su ecommerce ko
  • Loading branch information
albertogelmi-sia authored Oct 11, 2023
2 parents ff7286a + c2e2721 commit 8fb422f
Show file tree
Hide file tree
Showing 16 changed files with 457 additions and 122 deletions.
18 changes: 9 additions & 9 deletions api-specs/api_spec_PGS.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1087,7 +1087,7 @@ components:
example: affd8e24-f99a-406f-9ded-67a4a20c097f
status:
type: string
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED]
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING]
description: status
example: CREATED
authCode:
Expand Down Expand Up @@ -1128,7 +1128,7 @@ components:
type: string
status:
type: string
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED]
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING]
required:
- requestId
- status
Expand Down Expand Up @@ -1171,7 +1171,7 @@ components:
example: "Error while requesting refund for requestId: xxx"
status:
type: string
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED]
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING]
required:
- transactionId
- error
Expand Down Expand Up @@ -1287,7 +1287,7 @@ components:
properties:
status:
type: string
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED]
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING]
requestId:
type: string
vposUrl:
Expand All @@ -1308,7 +1308,7 @@ components:
properties:
status:
type: string
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED]
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING]
responseType:
type: string
enum: [METHOD, CHALLENGE, AUTHORIZATION, ERROR]
Expand All @@ -1332,7 +1332,7 @@ components:
properties:
status:
type: string
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED]
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING]
requestId:
type: string
redirectUrl:
Expand Down Expand Up @@ -1390,7 +1390,7 @@ components:
type: string
status:
type: string
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED]
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING]
error:
type: string
description: "null if no error occurred"
Expand All @@ -1404,7 +1404,7 @@ components:
type: string
status:
type: string
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED]
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING]
error:
type: string
VposDeleteResponse409:
Expand Down Expand Up @@ -1434,6 +1434,6 @@ components:
type: string
status:
type: string
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED]
enum: [CREATED, AUTHORIZED, DENIED, CANCELLED, PROCESSING]
error:
type: string
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,10 @@ public ResponseEntity<VposResumeMethodResponse> resumeCreditCardPayment(@Request
MdcUtils.setMdcFields(mdcFields);
log.info("START - POST {}{} info for requestId: {}", VPOS_AUTHORIZATIONS, REQUEST_PAYMENTS_RESUME_METHOD, requestId);
VposResumeMethodResponse response = new VposResumeMethodResponse(requestId);
resumeStep1Service.startResumeStep1(request, requestId.toString());

if (resumeStep1Service.prepareResumeStep1(requestId.toString())) {
resumeStep1Service.startResumeStep1(request, requestId.toString());
}

log.info("END - POST {}{} info for requestId: {}", VPOS_AUTHORIZATIONS, REQUEST_PAYMENTS_RESUME_METHOD, requestId);
return ResponseEntity.status(HttpStatus.OK).body(response);
Expand All @@ -109,7 +112,10 @@ public ResponseEntity<String> resumeCreditCardPaymentStep2(@RequestHeader(requir
MdcUtils.setMdcFields(mdcFields);
log.info("START - POST {}{} info for requestId: {}", VPOS_AUTHORIZATIONS, REQUEST_PAYMENTS_RESUME_CHALLENGE, requestId);

resumeStep2Service.startResumeStep2(requestId);
if (resumeStep2Service.prepareResumeStep2(requestId)) {
resumeStep2Service.startResumeStep2(requestId);
}

log.info("END - POST {}{} info for requestId: {}", VPOS_AUTHORIZATIONS, REQUEST_PAYMENTS_RESUME_CHALLENGE, requestId);

String vposPollingRedirect = vposPollingUrl + requestId;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,24 +133,21 @@ public ResponseEntity<String> resumeXPayPayment(@PathVariable String requestId,
EsitoXpay outcome = xPay3DSResponse.getOutcome();

String pollingUrlRedirect = StringUtils.join(xpayPollingUrl, requestId);
PaymentRequestEntity entity = paymentRequestRepository.findByGuid(requestId);
if (Objects.isNull(entity)) {
log.error("No XPay entity has been found for requestId: " + requestId);
return ResponseEntity.status(HttpStatus.FOUND).location(URI.create(pollingUrlRedirect)).build();
}

setMdcFields(entity.getMdcInfo());

if (outcome.equals(OK) && checkResumeRequest(entity, requestId, xPay3DSResponse)
&& CREATED.name().equals(entity.getStatus())) {

xPayPaymentAsyncService.executeXPayPaymentCall(requestId, xPay3DSResponse, entity);
} else {
log.info(String.format("Outcome is %s: setting status as DENIED for requestId %s", outcome, requestId));
entity.setStatus(DENIED.name());
paymentRequestRepository.save(entity);

ecommercePatchUtils.executePatchTransactionXPay(entity);
boolean proceed = xPayPaymentAsyncService.prepareResume(requestId, xPay3DSResponse);

if (proceed)
{
PaymentRequestEntity entity = paymentRequestRepository.findByGuid(requestId);
setMdcFields(entity.getMdcInfo());
if (outcome.equals(OK) && checkResumeRequest(entity, requestId, xPay3DSResponse)) {
xPayPaymentAsyncService.executeXPayPaymentCall(requestId, xPay3DSResponse, entity);
} else {
log.info(String.format("Outcome is %s: setting status as DENIED for requestId %s", outcome, requestId));
entity.setStatus(DENIED.name());
paymentRequestRepository.save(entity);
ecommercePatchUtils.executePatchTransactionXPay(entity);
}
}

log.info("END - GET {}{} for requestId {}", REQUEST_PAYMENTS_XPAY, REQUEST_PAYMENTS_RESUME, requestId);
Expand Down Expand Up @@ -233,7 +230,7 @@ private ResponseEntity<XPayPollingResponse> createXPayAuthPollingResponse(Paymen
XPayPollingResponse response = new XPayPollingResponse();
response.setRequestId(requestId);
response.setPaymentRequestStatusEnum(statusEnum);
if (statusEnum.equals(CREATED)) {
if (isStatusOneOf(statusEnum, CREATED, PROCESSING)) {
response.setHtml(paymentRequestEntity.getXpayHtml());
} else if (isStatusOneOf(statusEnum, AUTHORIZED, DENIED, CANCELLED)) {
OutcomeXpayGatewayResponse outcomeXpayGatewayResponse = buildOutcomeXpayGateway(paymentRequestEntity.getErrorCode(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ public enum PaymentRequestStatusEnum {
CREATED(1L, "Creata"),
AUTHORIZED(2L, "Autorizzazione concessa"),
DENIED(3L, "Autorizzazione negata"),
CANCELLED(4L, "Cancellata");
CANCELLED(4L, "Cancellata"),
PROCESSING(5L, "In elaborazione");

private static final Map<String, PaymentRequestStatusEnum> map = new HashMap<>(values().length, 1);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package it.pagopa.pm.gateway.repository;

import it.pagopa.pm.gateway.entity.PaymentRequestEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Lock;
import org.springframework.stereotype.Repository;

import javax.persistence.LockModeType;

@Repository
public interface PaymentRequestLockRepository extends JpaRepository<PaymentRequestEntity, Long> {

@Lock(LockModeType.PESSIMISTIC_WRITE)
PaymentRequestEntity findByGuid(String guid);

}
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ private CcPaymentInfoResponse buildCcPaymentInfoResponse(PaymentRequestEntity pa
}
switch (paymentRequestStatusEnum) {
case CREATED:
case PROCESSING:
ThreeDS2ResponseTypeEnum responseTypeEnum = valueOf(paymentRequestEntity.getResponseType());
response.setThreeDS2ResponseTypeEnum(responseTypeEnum);
response.setVposUrl(vposUrl);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import com.fasterxml.jackson.databind.ObjectMapper;
import it.pagopa.pm.gateway.dto.creditcard.CreditCardResumeRequest;
import it.pagopa.pm.gateway.dto.creditcard.StepZeroRequest;
import it.pagopa.pm.gateway.dto.enums.PaymentRequestStatusEnum;
import it.pagopa.pm.gateway.dto.enums.ThreeDS2ResponseTypeEnum;
import it.pagopa.pm.gateway.dto.vpos.MethodCompletedEnum;
import it.pagopa.pm.gateway.entity.PaymentRequestEntity;
import it.pagopa.pm.gateway.repository.PaymentRequestLockRepository;
import it.pagopa.pm.gateway.repository.PaymentRequestRepository;
import it.pagopa.pm.gateway.service.async.CcResumeStep1AsyncService;
import it.pagopa.pm.gateway.utils.VPosRequestUtils;
Expand All @@ -14,6 +16,8 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;
import java.util.Objects;
Expand All @@ -27,6 +31,9 @@ public class CcResumeStep1Service {
@Value("${vpos.requestUrl}")
private String vposUrl;

@Autowired
private PaymentRequestLockRepository paymentRequestLockRepository;

@Autowired
private PaymentRequestRepository paymentRequestRepository;

Expand All @@ -39,23 +46,42 @@ public class CcResumeStep1Service {
@Autowired
private CcResumeStep1AsyncService ccResumeStep1AsyncService;

public void startResumeStep1(CreditCardResumeRequest request, String requestId) {
PaymentRequestEntity entity = paymentRequestRepository.findByGuid(requestId);
@Transactional(propagation = Propagation.REQUIRES_NEW)
public boolean prepareResumeStep1(String requestId) {
PaymentRequestEntity entity = paymentRequestLockRepository.findByGuid(requestId);

if (Objects.isNull(entity)) {
log.error("No CreditCard request entity has been found for requestId: " + requestId);
return;
log.error("No CreditCard request entity has been found for requestId: {}", requestId);
return false;
}

if (Objects.nonNull(entity.getAuthorizationOutcome())) {
log.warn(String.format("requestId %s already processed", requestId));
log.warn("requestId {} already processed", requestId);
entity.setErrorMessage("requestId already processed");
return;
return false;
}

String responseType = entity.getResponseType();
if (PaymentRequestStatusEnum.CREATED.name().equals(entity.getStatus())
&& responseType != null
&& responseType.equalsIgnoreCase(ThreeDS2ResponseTypeEnum.METHOD.name())) {
log.info("prepareResumeStep1 request in state CREATED METHOD - proceed for requestId: {}", requestId);
entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name());
paymentRequestLockRepository.save(entity);
return true;
} else {
log.info("prepareResumeStep1 request in state {} {} - not proceed for requestId: {}", entity.getStatus(), responseType, requestId);
}
processResume(request, entity, requestId);

return false;
}

public void startResumeStep1(CreditCardResumeRequest request, String requestId) {
PaymentRequestEntity entity = paymentRequestRepository.findByGuid(requestId);
processResume(request, entity);
}

private void processResume(CreditCardResumeRequest request, PaymentRequestEntity entity, String requestId) {
private void processResume(CreditCardResumeRequest request, PaymentRequestEntity entity) {
String methodCompleted = request.getMethodCompleted();
String responseType = entity.getResponseType();
String correlationId = entity.getCorrelationId();
Expand All @@ -68,7 +94,11 @@ private void processResume(CreditCardResumeRequest request, PaymentRequestEntity
ccResumeStep1AsyncService.executeStep1(params, entity, stepZeroRequest);
}
} catch (Exception e) {
log.error("error during execution of resume for requestId {}", requestId, e);
log.error("error during execution of resume for requestId {}", entity.getGuid(), e);
if (PaymentRequestStatusEnum.PROCESSING.name().equals(entity.getStatus())) {
entity.setStatus(PaymentRequestStatusEnum.CREATED.name());
paymentRequestRepository.save(entity);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,83 @@

import com.fasterxml.jackson.databind.ObjectMapper;
import it.pagopa.pm.gateway.dto.creditcard.StepZeroRequest;
import it.pagopa.pm.gateway.dto.enums.PaymentRequestStatusEnum;
import it.pagopa.pm.gateway.dto.enums.ThreeDS2ResponseTypeEnum;
import it.pagopa.pm.gateway.entity.PaymentRequestEntity;
import it.pagopa.pm.gateway.repository.PaymentRequestLockRepository;
import it.pagopa.pm.gateway.repository.PaymentRequestRepository;
import it.pagopa.pm.gateway.service.async.CcResumeStep2AsyncService;
import it.pagopa.pm.gateway.utils.VPosRequestUtils;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Map;
import java.util.Objects;

@Service
@Slf4j
@Transactional
@NoArgsConstructor
public class CcResumeStep2Service {

private PaymentRequestLockRepository paymentRequestLockRepository;
private PaymentRequestRepository paymentRequestRepository;
private VPosRequestUtils vPosRequestUtils;
private ObjectMapper objectMapper;
private CcResumeStep2AsyncService ccResumeStep2AsyncService;

@Autowired
public CcResumeStep2Service(PaymentRequestRepository paymentRequestRepository,
public CcResumeStep2Service(PaymentRequestLockRepository paymentRequestLockRepository,
PaymentRequestRepository paymentRequestRepository,
VPosRequestUtils vPosRequestUtils, ObjectMapper objectMapper,
CcResumeStep2AsyncService ccResumeStep2AsyncService) {
this.paymentRequestLockRepository = paymentRequestLockRepository;
this.paymentRequestRepository = paymentRequestRepository;
this.vPosRequestUtils = vPosRequestUtils;
this.objectMapper = objectMapper;
this.ccResumeStep2AsyncService = ccResumeStep2AsyncService;
}

public void startResumeStep2(String requestId) {
PaymentRequestEntity entity = paymentRequestRepository.findByGuid(requestId);
@Transactional(propagation = Propagation.REQUIRES_NEW)
public boolean prepareResumeStep2(String requestId) {
PaymentRequestEntity entity = paymentRequestLockRepository.findByGuid(requestId);

if (Objects.isNull(entity)) {
log.error("No CreditCard request entity has been found for requestId: " + requestId);
return;
log.error("No CreditCard request entity has been found for requestId: {}", requestId);
return false;
}

if (Objects.nonNull(entity.getAuthorizationOutcome())) {
log.warn(String.format("requestId %s already processed", requestId));
log.warn("requestId {} already processed", requestId);
entity.setErrorMessage("requestId already processed");
return;
return false;
}

String responseType = entity.getResponseType();
if (PaymentRequestStatusEnum.CREATED.name().equals(entity.getStatus())
&& responseType != null
&& responseType.equalsIgnoreCase(ThreeDS2ResponseTypeEnum.CHALLENGE.name())) {
log.info("prepareResumeStep2 request in state CREATED CHALLENGE - proceed for requestId: {}", requestId);
entity.setStatus(PaymentRequestStatusEnum.PROCESSING.name());
paymentRequestLockRepository.save(entity);
return true;
} else {
log.info("prepareResumeStep2 request in state {} {} - not proceed for requestId: {}", entity.getStatus(), responseType, requestId);
}

processResume(entity, requestId);
return false;
}

private void processResume(PaymentRequestEntity entity, String requestId) {
public void startResumeStep2(String requestId) {
PaymentRequestEntity entity = paymentRequestRepository.findByGuid(requestId);
processResume(entity);
}

private void processResume(PaymentRequestEntity entity) {
String responseType = entity.getResponseType();
String correlationId = entity.getCorrelationId();
try {
Expand All @@ -62,7 +89,11 @@ private void processResume(PaymentRequestEntity entity, String requestId) {
ccResumeStep2AsyncService.executeStep2(params, entity, stepZeroRequest);
}
} catch (Exception e) {
log.error("error during execution of resume for requestId {}", requestId, e);
log.error("error during execution of resume for requestId {}", entity.getGuid(), e);
if (PaymentRequestStatusEnum.PROCESSING.name().equals(entity.getStatus())) {
entity.setStatus(PaymentRequestStatusEnum.CREATED.name());
paymentRequestRepository.save(entity);
}
}
}
}
Loading

0 comments on commit 8fb422f

Please sign in to comment.