improved logs

This commit is contained in:
Lincpay Tech
2025-11-10 10:05:43 +05:30
parent af7cdaf5d7
commit 43baedfecd
53 changed files with 662 additions and 572 deletions
@@ -1,6 +1,5 @@
package com.billpaymentservice.bbps.serviceImpl;
import java.time.LocalDateTime;
import java.util.Map;
import org.modelmapper.ModelMapper;
@@ -11,20 +10,14 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import com.billpaymentservice.bbps.dto.GeneralResp;
import com.billpaymentservice.bbps.dto.ResponseModel;
import com.billpaymentservice.bbps.dto.request.BillFetchByBillIdRequest;
import com.billpaymentservice.bbps.dto.request.BillPaymentRequest;
import com.billpaymentservice.bbps.dto.request.FetchBillRequest;
import com.billpaymentservice.bbps.dto.request.TransactionStatusRequest;
import com.billpaymentservice.bbps.dto.response.BillDataResponse;
import com.billpaymentservice.bbps.dto.response.BillPaymentResponse;
import com.billpaymentservice.bbps.dto.response.FetchBillResponse;
import com.billpaymentservice.bbps.dto.response.TransactionStatusResponse;
import com.billpaymentservice.bbps.entites.AgentFundTransfer;
import com.billpaymentservice.bbps.entites.BharatConnectMaster;
import com.billpaymentservice.bbps.entites.BillInitiate;
import com.billpaymentservice.bbps.entites.BillPayment;
import com.billpaymentservice.bbps.entites.InboundTraceLog;
import com.billpaymentservice.bbps.entites.OutboundTraceLog;
@@ -52,6 +45,7 @@ public class PaymentServiceImpl implements PaymentService {
@Value("${payment.data.url}")
private String paymentUrl;
private final BharatConnectMasterRepository beneficiaryDetailsRepository;
private final HttpService httpService;
private final Helper helper;
@@ -59,12 +53,14 @@ public class PaymentServiceImpl implements PaymentService {
private final InboundTraceLogRepository inboundTraceLogRepository;
private final OutboundTraceLogRepository outboundTraceLogRepository;
private final PaymentIntiateRepository paymentIntiateRepository;
private final TransactionMasterRepository transactionMasterRepository;
private final AgentFundTransferRepository agentFundTransferRepository;
private final TransactionMasterRepository transactionMasterRepository;
private final AgentFundTransferRepository agentFundTransferRepository;
private static final Logger LOGGER = LoggerFactory.getLogger(PaymentServiceImpl.class);
public PaymentServiceImpl(BharatConnectMasterRepository beneficiaryDetailsRepository, HttpService httpService,
Helper helper, PaymentRepository paymentRepository, InboundTraceLogRepository inboundTraceLogRepository,
OutboundTraceLogRepository outboundTraceLogRepository,
PaymentIntiateRepository paymentIntiateRepository,
OutboundTraceLogRepository outboundTraceLogRepository, PaymentIntiateRepository paymentIntiateRepository,
TransactionMasterRepository transactionMasterRepository,
AgentFundTransferRepository agentFundTransferRepository) {
this.beneficiaryDetailsRepository = beneficiaryDetailsRepository;
@@ -78,7 +74,6 @@ public class PaymentServiceImpl implements PaymentService {
this.agentFundTransferRepository = agentFundTransferRepository;
}
private static final Logger LOGGER = LoggerFactory.getLogger(MasterDataServiceImpl.class);
@Override
public ResponseModel initiatePayment(BillPaymentRequest billPaymentRequest) {
String apiName = "InitiatePayment";
@@ -86,6 +81,8 @@ public class PaymentServiceImpl implements PaymentService {
String requestId = billPaymentRequest.getReqId();
String url = paymentUrl + BBPSConstant.PAYMENT_URL;
LOGGER.info("Initiating payment for reqId={} and txnId={}", requestId, txnId);
BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001");
HttpHeaders headers = new HttpHeaders();
headers.set("x-digiledge-key", headersData.getXDigiledgeKey());
@@ -98,25 +95,27 @@ public class PaymentServiceImpl implements PaymentService {
String requestJson = helper.convertObjectToJson(billPaymentRequest);
// ✅ Create inbound & outbound logs
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnId, apiName, billPaymentRequest.getMid(), "POST", requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, url, "POST", requestJson);
try {
LOGGER.info("Calling BBPS payment URL: {}", url);
Map<String, String> responseMap = httpService.postRequest(url, requestJson, headers);
String responseData = responseMap.get("data");
LOGGER.info("Payment API Response: {}", responseData);
LOGGER.info("📦 Payment API Response: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData);
if (responseData == null || responseData.isEmpty()) {
helper.updateInboundLogFailure(inboundLog, "Empty response from BBPS", "FAILED");
LOGGER.warn("Empty response received from BBPS for txnId={}", txnId);
throw new CustomException("Empty response from BBPS server");
}
Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {});
if (!dataMap.containsKey("genericResponse")) {
helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_STRUCTURE");
LOGGER.warn("Invalid response structure received for txnId={}", txnId);
throw new CustomException("Invalid response structure from BBPS");
}
@@ -127,43 +126,44 @@ public class PaymentServiceImpl implements PaymentService {
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
BillPayment entity = mapper.map(billPaymentResponse, BillPayment.class);
paymentRepository.save(entity);
LOGGER.info("BillPayment entity saved successfully for txnId={}", txnId);
helper.updateInboundLogSuccess(inboundLog, responseData, generalResponse.getStatus());
PaymentInitiate paymentInitiate = new PaymentInitiate();
paymentInitiate.setTxnId(txnId);
paymentInitiate.setReqId(requestId);
paymentInitiate.setBankTxnId(billPaymentResponse.getTxnId());
paymentInitiate.setStatus(billPaymentResponse.getStatus());
paymentInitiate.setStatus(billPaymentResponse.getStatus());
paymentIntiateRepository.save(paymentInitiate);
// ✅ Trigger transaction status check
LOGGER.info("PaymentInitiate entry saved successfully for txnId={}", txnId);
TransactionStatusRequest transactionStatusRequest = new TransactionStatusRequest();
transactionStatusRequest.setTxnId(billPaymentResponse.getTxnId());
transactionStatusRequest.setTxnId(billPaymentResponse.getTxnId());
transactionStatusRequest.setReqId(requestId);
try {
Thread.sleep(2000); // Initial wait before first status check
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LOGGER.error("Thread interrupted: {}", e.getMessage());
}
//calling the method to check transaction status
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LOGGER.warn("Thread interrupted during payment delay: {}", e.getMessage());
}
LOGGER.info("Checking transaction status for txnId={}", billPaymentResponse.getTxnId());
return checkTrasactionStatus(transactionStatusRequest, inboundLog);
} catch (JsonProcessingException e) {
LOGGER.error("❌ JSON Parsing Error: {}", e.getMessage());
LOGGER.error("JSON Parsing Error in initiatePayment: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
}
}
public ResponseModel checkTrasactionStatus(TransactionStatusRequest transactionStatusRequest,InboundTraceLog inboundLog) {
public ResponseModel checkTrasactionStatus(TransactionStatusRequest transactionStatusRequest, InboundTraceLog inboundLog) {
String apiName = "CheckTransactionStatus";
String txnId = helper.generateTxnId(15); //our genrated txnId
String txnId = helper.generateTxnId(15);
String requestId = transactionStatusRequest.getReqId();
String url = paymentUrl + BBPSConstant.CHECK_TRANSACTION_URL + transactionStatusRequest.getTxnId(); ;
String url = paymentUrl + BBPSConstant.CHECK_TRANSACTION_URL + transactionStatusRequest.getTxnId();
LOGGER.info("Checking transaction status (internal) for txnId={} and reqId={}", transactionStatusRequest.getTxnId(), requestId);
BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001");
HttpHeaders headers = new HttpHeaders();
@@ -171,68 +171,66 @@ public class PaymentServiceImpl implements PaymentService {
headers.set("agentId", headersData.getAgentId());
headers.set("tenantId", headersData.getTenantId());
headers.setContentType(MediaType.APPLICATION_JSON);
ObjectMapper objectMapper = new ObjectMapper();
ObjectMapper objectMapper = new ObjectMapper();
OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, url, "GET", null);
Map<String, String> responseMap = httpService.getRequest(url, headers);
String responseData = responseMap.get("data");
LOGGER.info("Transaction status response: {}", responseData);
Map<String, String> responseMap = httpService.getRequest(url, headers);
String responseData = responseMap.get("data");
LOGGER.info("Transaction status response: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData);
helper.updateOutboundLogResponse(outboundLog, responseData);
try {
Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {});
if (!dataMap.containsKey("generalResp")) {
helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE");
throw new CustomException(
String.valueOf(dataMap.get("message")),
String.valueOf(dataMap.get("status")),
Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
String.valueOf(dataMap.get("remarks"))
);
}
TransactionStatusResponse responseWrapper = objectMapper.convertValue(dataMap, TransactionStatusResponse.class);
GeneralResp generalResp = responseWrapper.getGeneralResp();
System.out.println("Response Wrapper:"+responseWrapper);
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
TransactionMaster transactionMaster = mapper.map(responseWrapper.getTransactionDAO(), TransactionMaster.class);
transactionMaster.setTxnId(txnId);
transactionMaster.setReqId(transactionStatusRequest.getReqId());
EntityRelationshipUtil.linkTransactionMasterRelationships(transactionMaster);
transactionMasterRepository.save(transactionMaster);
AgentFundTransfer agentFundTransfer = mapper.map(responseWrapper.getAgentFundTransfer(), AgentFundTransfer.class);
agentFundTransfer.setTxnId(txnId);
agentFundTransfer.setReqId(transactionStatusRequest.getReqId());
agentFundTransfer.setTransactionMasterId(transactionMaster.getBankTxnId());
agentFundTransferRepository.save(agentFundTransfer);
String status = generalResp.getStatus();
LOGGER.info("Current transaction status: {}", status);
ResponseModel responseModel = new ResponseModel(
generalResp.getMessage(),
generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()),
responseWrapper
try {
Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {});
if (!dataMap.containsKey("generalResp")) {
helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE");
LOGGER.warn("Invalid transaction status response for txnId={}", transactionStatusRequest.getTxnId());
throw new CustomException(
String.valueOf(dataMap.get("message")),
String.valueOf(dataMap.get("status")),
Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
String.valueOf(dataMap.get("remarks"))
);
}
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return responseModel;
TransactionStatusResponse responseWrapper = objectMapper.convertValue(dataMap, TransactionStatusResponse.class);
GeneralResp generalResp = responseWrapper.getGeneralResp();
LOGGER.info("Transaction status received: {}", generalResp.getStatus());
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing transaction status JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
}
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
TransactionMaster transactionMaster = mapper.map(responseWrapper.getTransactionDAO(), TransactionMaster.class);
transactionMaster.setTxnId(txnId);
transactionMaster.setReqId(transactionStatusRequest.getReqId());
EntityRelationshipUtil.linkTransactionMasterRelationships(transactionMaster);
transactionMasterRepository.save(transactionMaster);
LOGGER.info("TransactionMaster saved successfully for txnId={}", txnId);
AgentFundTransfer agentFundTransfer = mapper.map(responseWrapper.getAgentFundTransfer(), AgentFundTransfer.class);
agentFundTransfer.setTxnId(txnId);
agentFundTransfer.setReqId(transactionStatusRequest.getReqId());
agentFundTransfer.setTransactionMasterId(transactionMaster.getBankTxnId());
agentFundTransferRepository.save(agentFundTransfer);
LOGGER.info("AgentFundTransfer entry saved successfully for txnId={}", txnId);
ResponseModel responseModel = new ResponseModel(
generalResp.getMessage(),
generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()),
responseWrapper
);
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return responseModel;
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing transaction status JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
}
}
@Override
public ResponseModel checkTrasactionStatus(TransactionStatusRequest transactionStatusRequest) {
helper.validateMerchant(transactionStatusRequest.getMid());
@@ -241,60 +239,61 @@ public class PaymentServiceImpl implements PaymentService {
String requestId = transactionStatusRequest.getReqId();
String requestJson = helper.convertObjectToJson(transactionStatusRequest);
String url = paymentUrl + BBPSConstant.CHECK_TRANSACTION_URL + transactionStatusRequest.getTxnId();
LOGGER.info("Checking transaction status (public) for txnId={} and reqId={}", transactionStatusRequest.getTxnId(), requestId);
BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001");
HttpHeaders headers = new HttpHeaders();
headers.set("x-digiledge-key", headersData.getXDigiledgeKey());
headers.set("agentId", headersData.getAgentId());
headers.set("tenantId", headersData.getTenantId());
headers.setContentType(MediaType.APPLICATION_JSON);
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, transactionStatusRequest.getMid(), "POST",
requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, url, "GET", null);
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, transactionStatusRequest.getMid(), "POST", requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, url, "GET", null);
ObjectMapper objectMapper = new ObjectMapper();
Map<String, String> responseMap = httpService.getRequest(url, headers);
String responseData = responseMap.get("data");
LOGGER.info("Transaction status response data: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData);
Map<String, String> responseMap = httpService.getRequest(url, headers);
String responseData = responseMap.get("data");
LOGGER.info("Transaction status response data: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData);
try {
Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {});
// If genericResponse key missing, throw exception
if (!dataMap.containsKey("generalResp")) {
helper.updateInboundLogFailure(inboundLog, responseData, String.valueOf(dataMap.get("status")));
throw new CustomException(
String.valueOf(dataMap.get("message")),
String.valueOf(dataMap.get("status")),
Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
String.valueOf(dataMap.get("remarks"))
);
}
// Convert into proper DTO
TransactionStatusResponse responseWrapper = objectMapper.convertValue(dataMap, TransactionStatusResponse.class);
GeneralResp generalResp = responseWrapper.getGeneralResp();
String status = generalResp.getStatus();
LOGGER.info("Current transaction status: {}", status);
ResponseModel responseModel = new ResponseModel(
generalResp.getMessage(),
generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()),
responseWrapper
try {
Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {});
if (!dataMap.containsKey("generalResp")) {
helper.updateInboundLogFailure(inboundLog, responseData, String.valueOf(dataMap.get("status")));
LOGGER.warn("Invalid transaction status response for txnId={} from BBPS", transactionStatusRequest.getTxnId());
throw new CustomException(
String.valueOf(dataMap.get("message")),
String.valueOf(dataMap.get("status")),
Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
String.valueOf(dataMap.get("remarks"))
);
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return responseModel;
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
}
TransactionStatusResponse responseWrapper = objectMapper.convertValue(dataMap, TransactionStatusResponse.class);
GeneralResp generalResp = responseWrapper.getGeneralResp();
String status = generalResp.getStatus();
LOGGER.info("Current transaction status: {}", status);
ResponseModel responseModel = new ResponseModel(
generalResp.getMessage(),
generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()),
responseWrapper
);
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return responseModel;
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
}
}
}
/* PollBack logic for the fetchTxnByTxnId API
* @Override public ResponseModel fetchTxnByTxnId(BillFetchByBillIdRequest