Merge pull request 'feature/resilience4j' (#43) from feature/resilience4j into develop

Reviewed-on: https://git.zeptic.in/himanshu/bbps/pulls/43
This commit is contained in:
2025-12-22 18:13:18 +05:30
19 changed files with 238 additions and 304 deletions
@@ -22,8 +22,8 @@ public class TransactionHistoryMasterDTO {
private String billId;
private String userType;
private String userId;
private Double txnAmount;
private Double totalTxnAmount;
private String txnAmount;
private String totalTxnAmount;
private String billerId;
private String billerCategory;
private String billerName;
@@ -33,15 +33,15 @@ public class TransactionHistoryMasterDTO {
private String quickPay;
private String paymentMode;
private String agentPaymentInformation;
private Double custConvFee;
private String custConvFee;
private String currency;
private String status;
private String requestedIp;
private String customerMobNo;
private String macAddress;
private Double splitPayAmount;
private Double couCustConvFee;
private Boolean settlementVerification;
private String splitPayAmount;
private String couCustConvFee;
private String settlementVerification;
private String fundTxnType;
private String reason;
private String amountTags;
@@ -11,7 +11,7 @@ public class TransactionHistoryParticularDetailsDTO {
private String billerName;
private Double totalTxnAmount;
private String totalTxnAmount;
private String bankTxnId;
@@ -3,7 +3,16 @@ package com.billpaymentservice.bbps.dto.auth;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
public class LoginRequest {
@NotNull(message = "Mobile number cannot be null.")
@@ -11,18 +20,5 @@ public class LoginRequest {
@Pattern(regexp = "^[0-9]{10}$", message = "Mobile number must contain only digits.")
private String mobile;
public LoginRequest() {
}
public LoginRequest(String mobile) {
this.mobile = mobile;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
}
@@ -1,29 +1,17 @@
package com.billpaymentservice.bbps.dto.auth;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class OtpSendResponse {
private boolean success;
private String message;
public OtpSendResponse() {}
public OtpSendResponse(boolean success, String message) {
this.success = success;
this.message = message;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
@@ -6,11 +6,15 @@ import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class RegisterRequest extends BaseClass {
@NotNull(message = "Mobile number cannot be null.")
@@ -3,7 +3,15 @@ package com.billpaymentservice.bbps.dto.auth;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class VerifyOtpRequest {
@NotNull(message = "Mobile number cannot be null.")
@@ -16,27 +24,5 @@ public class VerifyOtpRequest {
@Pattern(regexp = "^[0-9]{6}$", message = "OTP must contain only 6 digits.")
private String otp;
public VerifyOtpRequest() {
}
public VerifyOtpRequest(String mobile, String otp) {
this.mobile = mobile;
this.otp = otp;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getOtp() {
return otp;
}
public void setOtp(String otp) {
this.otp = otp;
}
}
@@ -5,6 +5,8 @@ import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
@@ -26,16 +28,23 @@ import lombok.Setter;
public class BillMaster extends Auditable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "bill_id", unique = true)
private String billId; // primary key
private String reqId; // client se aaya hua
private String txnId; // system-generated
private String refId;
private String billerId;
private String status;
private String mid;
private String actionType;
private String clientUserId;
private String userId;
@Column(name = "initiator_txn_id")
private String initiatorTxnId;
@Column(name = "checker_txn_id")
private String checkerTxnId;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "biller_response_id")
private BillerResponse billerResponse;
@@ -43,6 +52,4 @@ public class BillMaster extends Auditable {
private List<AdditionalInfoBill> additionalInfo;
@OneToMany(mappedBy = "billMaster", cascade = CascadeType.ALL)
private List<CustomerParamBill> customerParams;
// getters and setters
}
@@ -8,15 +8,24 @@ import lombok.Data;
import lombok.NoArgsConstructor;
@Entity
@Table(name = "bbps_bill_validation")
@Table(name = "bbps_bill_validation_master")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BillValidation extends Auditable {
@Id
@Column(name = "bill_id", nullable = false, length = 100)
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "bill_id", unique = true)
private String billId;
private String mid;
private String initiatorTxnId;
private String checkerTxnId;
@Column(name = "ref_id", length = 100)
private String refId;
@@ -55,6 +64,4 @@ public class BillValidation extends Auditable {
@Column(name = "client_user_id")
private String clientUserId;
// Removed local audit fields: creationDate, modifiedDate, createdEpochDate, modifiedEpochDate
// They are now handled by Auditable base class
}
@@ -30,7 +30,7 @@ public class PaymentStartRecord extends Auditable {
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "request_id", unique = true, nullable = false)
@Column(name = "request_id", unique = true, nullable = false)
private String requestId;
@Column(name = "client_mid", nullable = false)
private String clientMid;
@@ -47,24 +47,20 @@ public class PaymentStartRecord extends Auditable {
@Column(name = "amount", nullable = false)
private String amount;
@Column(name = "txn_id")
@Column(name = "txn_id",unique = true)
private String txnId;
@Column(name = "qr_string", columnDefinition = "TEXT")
private String qrString;
// New callback-related fields
@Column(name = "callback_status")
private String callbackStatus;
@Column(name = "bank_response", columnDefinition = "TEXT")
private String bankResponse;
@Column(name = "signature")
private String signature;
@Column(name = "response_type")
private String responseType; // e.g., "QR", "HTML", "JSON"
private String responseType;
@Column(name = "txn_status")
private String txnStatus;
@@ -39,7 +39,7 @@ public class TransactionMaster extends Auditable {
@Column(name = "bank_txn_id",unique = true)
private String bankTxnId;
@Column(name = "txn_id")
@Column(name = "txn_id",unique = true)
private String txnId;
@Column(name = "initiator_txn_id")
@@ -82,10 +82,10 @@ public class TransactionMaster extends Auditable {
private String userId;
@Column(name = "txn_amount")
private Double txnAmount;
private String txnAmount;
@Column(name = "total_txn_amount")
private Double totalTxnAmount;
private String totalTxnAmount;
@Column(name = "biller_id")
private String billerId;
@@ -115,7 +115,7 @@ public class TransactionMaster extends Auditable {
private String agentPaymentInformation;
@Column(name = "cust_conv_fee")
private Double custConvFee;
private String custConvFee;
@Column(name = "currency")
private String currency;
@@ -133,13 +133,13 @@ public class TransactionMaster extends Auditable {
private String macAddress;
@Column(name = "split_pay_amount")
private Double splitPayAmount;
private String splitPayAmount;
@Column(name = "cou_cust_conv_fee")
private Double couCustConvFee;
private String couCustConvFee;
@Column(name = "settlement_verification")
private Boolean settlementVerification;
private String settlementVerification;
@Column(name = "fund_txn_type")
private String fundTxnType;
@@ -4,6 +4,17 @@ import org.springframework.data.jpa.repository.JpaRepository;
import com.billpaymentservice.bbps.entites.BillMaster;
public interface BillMasterRepository extends JpaRepository<BillMaster, String> {
import java.util.Optional;
}
/**
* Repository for BillMaster. Added convenience finder methods so service
* can look up records by client request id (reqId) or txnId.
*/
public interface BillMasterRepository extends JpaRepository<BillMaster, Long> {
Optional<BillMaster> findByReqId(String reqId);
Optional<BillMaster> findByTxnId(String txnId);
BillMaster findByInitiatorTxnId(String initiatorTxnId);
}
@@ -6,6 +6,8 @@ import org.springframework.stereotype.Repository;
import com.billpaymentservice.bbps.entites.BillValidation;
@Repository
public interface BillValidationRepository extends JpaRepository<BillValidation, String> {
public interface BillValidationRepository extends JpaRepository<BillValidation, Long> {
BillValidation findByInitiatorTxnId(String txnId);
}
@@ -22,12 +22,14 @@ import com.billpaymentservice.bbps.dto.sentRequest.FetchBillForwardRequest;
import com.billpaymentservice.bbps.dto.sentRequest.FetchBillValidatestForwardRequest;
import com.billpaymentservice.bbps.entites.BillInitiate;
import com.billpaymentservice.bbps.entites.BillMaster;
import com.billpaymentservice.bbps.entites.BillValidation;
import com.billpaymentservice.bbps.entites.InboundTraceLog;
import com.billpaymentservice.bbps.entites.OutboundTraceLog;
import com.billpaymentservice.bbps.exception.CustomException;
import com.billpaymentservice.bbps.repository.BharatConnectMasterRepository;
import com.billpaymentservice.bbps.repository.BillInitateRepository;
import com.billpaymentservice.bbps.repository.BillMasterRepository;
import com.billpaymentservice.bbps.repository.BillValidationRepository;
import com.billpaymentservice.bbps.repository.InboundTraceLogRepository;
import com.billpaymentservice.bbps.repository.OutboundTraceLogRepository;
import com.billpaymentservice.bbps.service.AgentService;
@@ -52,6 +54,7 @@ public class AgentServiceImpl implements AgentService {
private final BillerMapperHelper mapperHelper;
private final BillMasterRepository billMasterRepository;
private final BillInitateRepository billIntiateRepository;
private final BillValidationRepository billValidationRepository;
private static final Logger LOGGER = LoggerFactory.getLogger(AgentServiceImpl.class);
// Reusable ObjectMapper instance
@@ -62,7 +65,7 @@ public class AgentServiceImpl implements AgentService {
BharatConnectMasterRepository beneficiaryDetailsRepository,
InboundTraceLogRepository inboundTraceLogRepository, OutboundTraceLogRepository outboundTraceLogRepository,
BillMasterRepository billMasterRepository, BillInitateRepository billIntiateRepository,
BillerMapperHelper mapperHelper) {
BillerMapperHelper mapperHelper,BillValidationRepository billValidationRepository) {
this.restClient = restClient;
this.httpService = httpService;
this.helper = helper;
@@ -70,6 +73,7 @@ public class AgentServiceImpl implements AgentService {
this.billMasterRepository = billMasterRepository;
this.billIntiateRepository = billIntiateRepository;
this.mapperHelper = mapperHelper;
this.billValidationRepository=billValidationRepository;
}
@Override
@@ -94,7 +98,13 @@ public class AgentServiceImpl implements AgentService {
OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, fullUrl,
BBPSConstant.HTTP_POST, forwardJson);
LOGGER.debug("Outbound log created successfully for txnId: {} and reqId: {}", txnId, requestId);
BillMaster billMaster =new BillMaster();
billMaster.setReqId(fetchBillRequest.getReqId());
billMaster.setInitiatorTxnId(txnId);
billMaster.setMid(fetchBillRequest.getMid());
billMaster.setClientUserId(fetchBillRequest.getClientUserId());
billMasterRepository.save(billMaster);
try {
LOGGER.info("[{}] Calling external API | URL={}", apiName, fullUrl);
Map<String, String> responseMap = httpService.postRequest(fullUrl, forwardJson,
@@ -114,26 +124,13 @@ public class AgentServiceImpl implements AgentService {
Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
String.valueOf(dataMap.get("remarks")));
}
BillMaster billMaster = new BillMaster();
billMaster.setBillId((String) dataMap.get("billId"));
billMaster.setReqId(fetchBillRequest.getReqId());
billMaster.setTxnId(txnId);
billMaster.setClientUserId(fetchBillRequest.getClientUserId());
billMasterRepository.save(billMaster);
LOGGER.info("BillMaster saved for billId: {}", billMaster.getBillId());
FetchBillResponse fetchBillResponse = objectMapper.convertValue(dataMap, FetchBillResponse.class);
GeneralResp generalResponse = fetchBillResponse.getGenericResponse();
helper.updateInboundLogSuccess(inboundLog, responseData, generalResponse.getStatus());
BillInitiate billInitiate = new BillInitiate();
billInitiate.setBillId((String) dataMap.get("billId"));
billInitiate.setReqId(fetchBillRequest.getReqId());
billInitiate.setTxnId(txnId);
billInitiate.setClientUserId(fetchBillRequest.getClientUserId());
billIntiateRepository.save(billInitiate);
LOGGER.info("BillInitiate entry saved for billId: {}", billInitiate.getBillId());
BillFetchByBillIdRequest billFetchByBillIdRequest = new BillFetchByBillIdRequest();
billFetchByBillIdRequest.setBillId(fetchBillResponse.getBillId());
@@ -146,6 +143,7 @@ public class AgentServiceImpl implements AgentService {
Thread.currentThread().interrupt();
LOGGER.warn("Thread interrupted during delay: {}", e.getMessage());
}
LOGGER.info("Calling internal method Fetching bill by ID: {}", billFetchByBillIdRequest.getBillId());
LOGGER.info("[{}] END | reqId={} | status={}", apiName, requestId, generalResponse.getStatus());
return fetchBillById(billFetchByBillIdRequest, inboundLog);
@@ -171,6 +169,8 @@ public class AgentServiceImpl implements AgentService {
LOGGER.debug("Outbound log created successfully for FetchBillById: {}", fullUrl);
try {
LOGGER.info("Calling external API: {}", fullUrl);
Map<String, String> responseMap = httpService.getRequest(fullUrl,
helper.buildHeaders(beneficiaryDetailsRepository.findByOrgId(BBPSConstant.ORG_ID)));
@@ -192,15 +192,18 @@ public class AgentServiceImpl implements AgentService {
}
BillDataResponse responseWrapper = objectMapper.convertValue(dataMap, BillDataResponse.class);
GeneralResp generalResp = responseWrapper.getGenericResponse();
GeneralResp generalResp = responseWrapper.getGenericResponse();
BillMaster
existingbill=billMasterRepository.findByInitiatorTxnId(
inboundLog.getTxnId());
String status = generalResp.getStatus();
LOGGER.info("Current Bill Status: {}", status);
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
mapperHelper.saveOrUpdateBillData(responseWrapper, billFetchByBillIdRequest, txnId, reqId, userId);
mapperHelper.saveOrUpdateBillData(responseWrapper, billFetchByBillIdRequest, txnId, reqId,billFetchByBillIdRequest.getClientUserId(), existingbill);
LOGGER.info("Bill data saved successfully for billId: {}", billId);
return new ResponseModel(generalResp.getMessage(), generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()), responseWrapper);
} catch (JsonProcessingException e) {
@@ -255,7 +258,7 @@ public class AgentServiceImpl implements AgentService {
// update inbound log success and persist bill data
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
mapperHelper.saveOrUpdateBillData(responseWrapper, billFetchByBillIdRequest, txnId, reqId, userId);
//mapperHelper.saveOrUpdateBillData(responseWrapper, billFetchByBillIdRequest, txnId, reqId, userId);
LOGGER.info("Bill data saved successfully for billId={} | Status={}", billId, generalResp.getStatus());
LOGGER.info("[{}] END | reqId={} | status={}", apiName, reqId, generalResp.getStatus());
return responseModel;
@@ -294,8 +297,14 @@ public class AgentServiceImpl implements AgentService {
forwardJson);
LOGGER.debug("Outbound log created successfully for txnId: {} and reqId: {}", txnId, reqId);
BillValidation billValidation = new BillValidation();
billValidation.setReqId(fetchBillValidateRequest.getReqId());
billValidation.setInitiatorTxnId(txnId);
billValidation.setMid(fetchBillValidateRequest.getMid());
billValidation.setClientUserId(fetchBillValidateRequest.getClientUserId());
billValidationRepository.save(billValidation);
try {
LOGGER.info("[{}] Calling external API | URL={}", apiName, fullUrl);
Map<String, String> responseMap = httpService.postRequest(fullUrl, forwardJson,
helper.buildHeaders(beneficiaryDetailsRepository.findByOrgId(BBPSConstant.ORG_ID)));
@@ -314,24 +323,11 @@ public class AgentServiceImpl implements AgentService {
Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
String.valueOf(dataMap.get("remarks")));
}
BillMaster billMaster = new BillMaster();
billMaster.setBillId((String) dataMap.get("billId"));
billMaster.setReqId(fetchBillValidateRequest.getReqId());
billMaster.setTxnId(txnId);
billMasterRepository.save(billMaster);
LOGGER.info("BillMaster saved for billId: {}", billMaster.getBillId());
FetchBillResponse fetchBillResponse = objectMapper.convertValue(dataMap, FetchBillResponse.class);
GeneralResp generalResponse = fetchBillResponse.getGenericResponse();
helper.updateInboundLogSuccess(inboundLog, responseData, generalResponse.getStatus());
BillInitiate billInitiate = new BillInitiate();
billInitiate.setBillId((String) dataMap.get("billId"));
billInitiate.setReqId(fetchBillValidateRequest.getReqId());
billInitiate.setTxnId(txnId);
billIntiateRepository.save(billInitiate);
LOGGER.info("BillInitiate entry saved for billId: {}", billInitiate.getBillId());
BillFetchByBillIdRequest billFetchByBillIdRequest = new BillFetchByBillIdRequest();
billFetchByBillIdRequest.setBillId(fetchBillResponse.getBillId());
billFetchByBillIdRequest.setMid(fetchBillValidateRequest.getMid());
@@ -362,7 +358,11 @@ public class AgentServiceImpl implements AgentService {
String reqId = billRequest.getReqId();
String billId = billRequest.getBillId();
String fullUrl = agentDtaUrl + BBPSConstant.BILL_VALIDATE_ID_URL + billRequest.getBillId();
BillValidation
billValidation=billValidationRepository.findByInitiatorTxnId(
inboundLog.getTxnId());
billValidation.setCheckerTxnId(txnId);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, reqId, apiName, fullUrl,
BBPSConstant.HTTP_GET, null);
LOGGER.debug("Outbound log created successfully for FetchBillById: {}", fullUrl);
@@ -392,13 +392,14 @@ public class AgentServiceImpl implements AgentService {
FetchBillValidateResponse responseWrapper = objectMapper.convertValue(dataMap,
FetchBillValidateResponse.class);
GeneralResp generalResp = responseWrapper.getGenericResponse();
String status = generalResp.getStatus();
LOGGER.info("Current Bill Status: {}", status);
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
System.out.println("responseWrapper:" + responseWrapper);
mapperHelper.saveBillValidation(responseWrapper, billRequest, txnId);
mapperHelper.saveBillValidation(responseWrapper, billRequest, txnId,billValidation);
return new ResponseModel(generalResp.getMessage(), generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()), responseWrapper);
} catch (JsonProcessingException e) {
@@ -456,7 +457,7 @@ public class AgentServiceImpl implements AgentService {
GeneralResp generalResp = responseWrapper.getGenericResponse();
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
mapperHelper.saveBillValidation(responseWrapper, billRequest, txnId);
//mapperHelper.saveBillValidation(responseWrapper, billRequest, txnId);
LOGGER.info("Bill validation saved successfully for billId: {}", billId);
LOGGER.info("[{}] END | reqId={} | status={}", apiName, reqId, generalResp.getStatus());
return new ResponseModel(generalResp.getMessage(), generalResp.getStatus(),
@@ -112,7 +112,6 @@ public class PaymentServiceImpl implements PaymentService {
LOGGER.debug("Outbound log created for api={} | reqId={} | txnId={}", apiName, requestId, txnId);
TransactionMaster preTransaction=null;
preTransaction = new TransactionMaster();
preTransaction.setTxnId(txnId);
preTransaction.setInitiatorTxnId(txnId);
@@ -164,8 +164,7 @@ public class PaymentStartServiceImpl implements PaymentStartService {
// success: persist and return
helper.updateInboundLogSuccess(inboundLog, respBody, String.valueOf(outcomeCode));
String responseType = (apiResponse.getResponseData() != null && apiResponse.getResponseData().getQrString() != null && !apiResponse.getResponseData().getQrString().isEmpty()) ? BBPSConstant.RESPONSE_TYPE_QR : BBPSConstant.RESPONSE_TYPE_JSON;
String responseType = BBPSConstant.RESPONSE_TYPE_INTENT;
bbpsMapperHelper.savePaymentStartRecord(request, apiResponse, txnId, orderNo, requestJson, respBody, responseType);
LOGGER.info("[startIntentPayment] saved record txnId={} orderNo={} responseType={}", txnId, orderNo, responseType);
@@ -294,7 +293,7 @@ public class PaymentStartServiceImpl implements PaymentStartService {
LOGGER.info("[startWebPayment] received HTML response txnId={} length={}", txnId, respBody.length());
// Save record with HTML (persist original request and HTML response)
String responseTypeWeb = BBPSConstant.RESPONSE_TYPE_HTML;
String responseTypeWeb = BBPSConstant.RESPONSE_TYPE_WEB;
String rawResponseWeb = respBody == null ? "" : respBody;
// Try to extract useful fields from returned HTML (txnId, amount, mid)
@@ -313,7 +312,7 @@ public class PaymentStartServiceImpl implements PaymentStartService {
rd.setAmount(parsedAmount != null && !parsedAmount.isEmpty() ? parsedAmount : "0.00");
rd.setMid(parsedMid);
rd.setOrderNo(orderNo);
rd.setQrString("HTML_RESPONSE");
rd.setQrString(BBPSConstant.RESPONSE_TYPE_WEB);
rd.setCreatedOn(LocalDateTime.now().toString());
apiResp.setResponseData(rd);
@@ -401,10 +400,7 @@ public class PaymentStartServiceImpl implements PaymentStartService {
return new ResponseModel(BBPSConstant.MSG_NO_MATCHING_RECORD, BBPSConstant.MERCHANT_ACK_NO_MATCH, BBPSConstant.HTTP_OK_INT, null);
}
// Update record with bank response and signature
record.setBankResponse(decrypted);
record.setSignature(signature);
// update txn status and callback timestamp
record.setTxnStatus(txnStatus);
record.setCallbackReceivedOn(LocalDateTime.now().toString());
@@ -222,6 +222,9 @@ public class BBPSConstant extends BBPS_RESPONSE_COD_CONSTANT {
public static final String INTERNALSERVER_ERROR_STR = "600";
public static final String USER_UNAUTHORIZED_STR = "401";
public static final String OK_STR = "200";
public static final String RESPONSE_TYPE_INTENT = "INTENT";
public static final String RESPONSE_TYPE_WEB = "WEB";
// Newly added constant for invalid JSON status code
@@ -53,6 +53,7 @@ import com.billpaymentservice.bbps.dto.response.BillDataResponse;
import com.billpaymentservice.bbps.dto.response.ClientReqIdResponse;
import com.billpaymentservice.bbps.dto.response.ComplaintHistoryStatusResponse;
import com.billpaymentservice.bbps.dto.response.ComplaintResponse;
import com.billpaymentservice.bbps.dto.response.FetchBillValidateResponse;
import com.billpaymentservice.bbps.dto.response.PaymentStartApiResponse;
import com.billpaymentservice.bbps.dto.response.PlanResponse;
import com.billpaymentservice.bbps.dto.response.TicketCheckStatusResponse;
@@ -530,7 +531,6 @@ public class BillerMapperHelper {
entity.setNpciTicketStatus(dto.getNpciTicketStatus());
entity.setCreatedTime(dto.getCreatedTime());
entity.setUserId(userId);
entity.setCreateDateTime(new Date());
try {
ComplainStatus saved = complaintStatusRepository.save(entity);
@@ -561,7 +561,7 @@ public class BillerMapperHelper {
entity.setReqId(reqId);
entity.setTxnId(txnId);
entity.setUserId(userId);
entity.setCreateDateTime(new Date());
complaintHistoryRepository.save(entity);
savedCount++;
}
@@ -575,87 +575,6 @@ public class BillerMapperHelper {
}
}
public Map<String, Object> getComplaintStatusJson() {
Map<String, Object> complaints = new HashMap<>();
complaints.put("assignedTo", "XYZ Bank");
complaints.put("complaintDescr", "Testing complaint");
complaints.put("complaintDispos", "Transaction Successful, account not updated");
complaints.put("complaintId", "2dfecc3c-9114-4094-9aa8-ff26f03a9bfd");
complaints.put("complaintNpciId", "FE4123109489834");
complaints.put("complaintRaisedFrom", "agent");
complaints.put("complaintType", "npciComplaint");
complaints.put("createdEpochDate", 1681905485);
complaints.put("creationDate", "2023-04-19T17:28:05.508679Z");
complaints.put("modifiedDate", "2023-04-19T17:28:10.001432Z");
complaints.put("modifiedEpochDate", 1681905490);
complaints.put("refId", "mqcXfZs2XMkRKQfpIwoSYQDnIr231091728");
complaints.put("status", "COMPLAINT_OPEN_SUCCESS");
complaints.put("tenantId", "FE41");
complaints.put("txnId", "24fe190c-42c9-4cb5-9d36-965839b0cb5f");
complaints.put("txnNpciId", "FE4131090DAI26Y0mAxl");
complaints.put("userId", "FE41FE42BNK519012345");
complaints.put("agentId", "FE41FE42BNK519012345");
Map<String, Object> finalJson = new HashMap<>();
finalJson.put("complaints", complaints);
return finalJson;
}
public Map<String, Object> getDummyReopenComplaintJson() {
Map<String, Object> complaints = new HashMap<>();
complaints.put("assignedTo", "Federal Bank");
complaints.put("complaintDescr", "Issue not yet solved - reopening");
complaints.put("complaintDispos", "Transaction Successful, account not updated");
complaints.put("complaintId", "809ec4c7-d81b-4d2b-9c66-3011a6fae714");
complaints.put("complaintNpciId", "FE4123109776644");
complaints.put("complaintRaisedFrom", "agent");
complaints.put("complaintType", "npciComplaint");
complaints.put("createdEpochDate", 1681893776);
complaints.put("creationDate", "2023-04-19T14:12:56.329935Z");
complaints.put("modifiedDate", "2023-04-19T14:19:44.891423Z");
complaints.put("modifiedEpochDate", 1681894184);
complaints.put("refId", "7sQwBamvWFyLxhK84dYgGmV24r831091419");
complaints.put("status", "COMPLAINT_REOPEN_SUCCESS");
complaints.put("tenantId", "FE41");
complaints.put("txnId", "155a4a71-141f-40fd-b772-9d0e020963e8");
complaints.put("txnNpciId", "FE413045Hl3L90ZWg59o");
complaints.put("userId", "FE41FE42BNK519012345");
complaints.put("agentId", "FE41FE42BNK519012345");
Map<String, Object> finalJson = new HashMap<>();
finalJson.put("complaints", complaints);
return finalJson;
}
public Map<String, Object> getDummyClosureComplaintJson() {
Map<String, Object> complaints = new HashMap<>();
complaints.put("complaintDescr", "Closing complaint Issue resolved");
complaints.put("complaintDispos", "Transaction Successful, account not updated");
complaints.put("complaintId", "809ec4c7-d81b-4d2b-9c66-3011a6fae714");
complaints.put("complaintNpciId", "FE4123109776644");
complaints.put("complaintRaisedFrom", "agent");
complaints.put("complaintType", "npciComplaint");
complaints.put("createdEpochDate", 1681893776);
complaints.put("creationDate", "2023-04-19T14:12:56.329935Z");
complaints.put("modifiedDate", "2023-04-19T14:13:32.25255Z");
complaints.put("modifiedEpochDate", 1681893812);
complaints.put("refId", "hHfEKYZExIpxNEV65HMQZ2Lh0DA31091413");
complaints.put("status", "COMPLAINT_CLOSURE_REQUEST_SUCCESS"); // removed spaces
complaints.put("tenantId", "FE41");
complaints.put("txnId", "155a4a71-141f-40fd-b772-9d0e020963e8");
complaints.put("txnNpciId", "FE413045Hl3L90ZWg59o");
complaints.put("userId", "FE41FE42BNK519012345");
complaints.put("agentId", "FE41FE42BNK519012345");
Map<String, Object> finalJson = new HashMap<>();
finalJson.put("complaints", complaints);
return finalJson;
}
public String saveComplainStatusDetail(ViewComplainByIdResponse responseWrapper, String reqId, String txnId,
String userId) {
@@ -676,7 +595,6 @@ public class BillerMapperHelper {
entity.setPage(String.valueOf(responseWrapper.getPage()));
entity.setPageSize(String.valueOf(responseWrapper.getPageSize()));
entity.setUserId(userId);
entity.setCreateDateTime(new Date());
}
@@ -720,7 +638,6 @@ public class BillerMapperHelper {
parent.setUserId(responseWrapper.getUserId());
// Map incoming DTO date strings into Auditable LocalDateTime fields
Date parentCreatedOn = parseToDate(responseWrapper.getCreationDate());
Date parentUpdatedOn = parseToDate(responseWrapper.getModifiedDate());
parent.setCreatedEpochDate(responseWrapper.getCreatedEpochDate());
parent.setModifiedEpochDate(responseWrapper.getModifiedEpochDate());
@@ -856,7 +773,6 @@ public class BillerMapperHelper {
entity.setTotalPages(String.valueOf(responseWrapper.getTotalPages()));
entity.setTotalElements(String.valueOf(responseWrapper.getTotalElements()));
entity.setUserId(userId);
entity.setCreateDateTime(new Date());
}
@@ -902,9 +818,8 @@ public class BillerMapperHelper {
}
public void saveOrUpdateBillData(BillDataResponse responseWrapper,
BillFetchByBillIdRequest billFetchByBillIdRequest, String txnId, String reqId, String userId) {
BillFetchByBillIdRequest billFetchByBillIdRequest, String txnId, String reqId, String userId,BillMaster billMaster) {
BillMaster billMaster = new BillMaster();
billMaster.setBillId(responseWrapper.getBillId());
billMaster.setRefId(responseWrapper.getRefId());
@@ -970,7 +885,6 @@ public class BillerMapperHelper {
if (bmUpdatedOn != null) {
billMaster.setUpdatedDateTime(bmUpdatedOn);
}
billMaster.setCreatedEpochDate(responseWrapper.getCreatedEpochDate());
billMaster.setModifiedEpochDate(responseWrapper.getModifiedEpochDate());
@@ -980,15 +894,16 @@ public class BillerMapperHelper {
// Helper to parse incoming ISO date/time strings (with optional offset) into
// LocalDateTime
private Date parseToDate(String dateStr) {
try {
// example format: 2025-12-17T14:30:45
LocalDateTime ldt = LocalDateTime.parse(dateStr);
return Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
} catch (Exception e) {
return null;
}
try {
// example format: 2025-12-17T14:30:45
LocalDateTime ldt = LocalDateTime.parse(dateStr);
return Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
} catch (Exception e) {
return null;
}
}
// Convert TransactionMaster to master DTO
public TransactionHistoryMasterDTO toDTO(TransactionMaster transactionMaster) {
if (transactionMaster == null)
@@ -1078,55 +993,72 @@ public class BillerMapperHelper {
// Map PaymentStartUserRequest + API response into PaymentStartRecord and
// persist
public PaymentStartRecord savePaymentStartRecord(PaymentStartUserRequest request,
PaymentStartApiResponse apiResponse, String txnId, String orderNo, String requestJson, String rawResponse,
String responseType) {
public PaymentStartRecord savePaymentStartRecord(
PaymentStartUserRequest request,
PaymentStartApiResponse apiResponse,
String txnId,
String orderNo,
String requestJson,
String rawResponse,
String responseType) {
PaymentStartRecord record;
PaymentStartRecord record;
boolean createNewRecord = apiResponse == null && rawResponse == null && responseType == null;
boolean createNewRecord =
apiResponse == null &&
rawResponse == null &&
responseType == null;
if (createNewRecord) {
// 🔒 Duplicate check
if (paymentStartRecordRepository.findByOrderNo(orderNo).isPresent()) {
throw new CustomException("Duplicate OrderNo found", "DUPLICATE_ORDERNO", 400,
"OrderNo already exists");
}
record = new PaymentStartRecord();
} else {
record = paymentStartRecordRepository.findByOrderNo(orderNo)
.orElseThrow(() -> new CustomException("OrderNo not found", "ORDERNO_NOT_FOUND", 404,
"No record exists for given orderNo"));
}
if (createNewRecord) {
// 🔒 Duplicate check
if (paymentStartRecordRepository.findByOrderNo(orderNo).isPresent()) {
throw new CustomException(
"Duplicate OrderNo found",
"DUPLICATE_ORDERNO",
400,
"OrderNo already exists"
);
}
record = new PaymentStartRecord();
} else {
record = paymentStartRecordRepository.findByOrderNo(orderNo)
.orElseThrow(() -> new CustomException(
"OrderNo not found",
"ORDERNO_NOT_FOUND",
404,
"No record exists for given orderNo"
));
}
if (orderNo != null) {
record.setOrderNo(orderNo);
record.setRequestId(request.getReqId());
record.setClientMid(request.getMid());
record.setClientUserId(request.getClientUserId());
record.setInternalTxnId(txnId);
}
if (orderNo != null) {
record.setOrderNo(orderNo);
record.setRequestId(request.getReqId());
record.setClientMid(request.getMid());
record.setClientUserId(request.getClientUserId());
record.setInternalTxnId(txnId);
}
if (apiResponse != null && apiResponse.getResponseData() != null) {
record.setAmount(Optional.ofNullable(apiResponse.getResponseData().getAmount()).orElse("0.00"));
if (apiResponse != null && apiResponse.getResponseData() != null) {
record.setAmount(Optional.ofNullable(
apiResponse.getResponseData().getAmount()).orElse("0.00"));
record.setTxnId(Optional.ofNullable(apiResponse.getResponseData().getTxnId()).orElse("DUMMY_TXN"));
record.setTxnId(Optional.ofNullable(
apiResponse.getResponseData().getTxnId()).orElse("DUMMY_TXN"));
record.setQrString(Optional.ofNullable(apiResponse.getResponseData().getQrString()).orElse("NO_QR"));
Date createdOn = parseToDate(apiResponse.getResponseData().getCreatedOn());
Date createdOn = parseToDate(apiResponse.getResponseData().getCreatedOn());
record.setTxnStatus("PENDING");
} else {
record.setAmount("0.00");
record.setTxnStatus("PENDING");
}
record.setTxnStatus("PENDING");
} else {
record.setAmount("0.00");
record.setTxnStatus("PENDING");
}
record.setResponseType(responseType);
record.setResponseType(responseType);
return paymentStartRecordRepository.save(record);
return paymentStartRecordRepository.save(record);
}
// Map ComplaintRequestDTO to forward request for complaint API
public FetchComplaintForwardRequest fetchComplaintForwardRequestMap(ComplaintRequestDTO complainRequestDTO) {
FetchComplaintForwardRequest forward = new FetchComplaintForwardRequest();
@@ -1162,7 +1094,31 @@ public class BillerMapperHelper {
}
}
// Persist complaint response entity
private String generateComplaintTicketId() {
return "CMP-" + UUID.randomUUID().toString();
}
// Minimal mapping helpers used by AgentServiceImpl
public com.billpaymentservice.bbps.dto.sentRequest.FetchBillForwardRequest fetchBillForwardRequestMap(
com.billpaymentservice.bbps.dto.request.FetchBillRequest req) {
if (req == null)
return null;
com.billpaymentservice.bbps.dto.sentRequest.FetchBillForwardRequest f = new com.billpaymentservice.bbps.dto.sentRequest.FetchBillForwardRequest();
f.setBillerId(req.getBillerId());
f.setBillerName(req.getBillerName());
f.setBillerCategory(req.getBillerCategory());
f.setClientReqId(req.getClientReqId());
f.setMacAdress(req.getMacAdress());
f.setCustomerMobNo(req.getCustomerMobNo());
f.setRemitterName(req.getRemitterName());
f.setPaymentChannel(req.getPaymentChannel());
f.setDeviceBlockTags(req.getDeviceBlockTags());
f.setCustomerParamsRequest(req.getCustomerParamsRequest());
f.setRemitterIdentity(req.getRemitterIdentity());
return f;
}
public String saveComplaintResponseEntity(ComplaintResponse responseWrapper, String requestId, String txnId,
String userId, String requestTxnId, String mid) {
if (responseWrapper == null || responseWrapper.getTicketDetails() == null) {
@@ -1196,31 +1152,6 @@ public class BillerMapperHelper {
}
return "Failed to save";
}
private String generateComplaintTicketId() {
return "CMP-" + UUID.randomUUID().toString();
}
// Minimal mapping helpers used by AgentServiceImpl
public com.billpaymentservice.bbps.dto.sentRequest.FetchBillForwardRequest fetchBillForwardRequestMap(
com.billpaymentservice.bbps.dto.request.FetchBillRequest req) {
if (req == null)
return null;
com.billpaymentservice.bbps.dto.sentRequest.FetchBillForwardRequest f = new com.billpaymentservice.bbps.dto.sentRequest.FetchBillForwardRequest();
f.setBillerId(req.getBillerId());
f.setBillerName(req.getBillerName());
f.setBillerCategory(req.getBillerCategory());
f.setClientReqId(req.getClientReqId());
f.setMacAdress(req.getMacAdress());
f.setCustomerMobNo(req.getCustomerMobNo());
f.setRemitterName(req.getRemitterName());
f.setPaymentChannel(req.getPaymentChannel());
f.setDeviceBlockTags(req.getDeviceBlockTags());
f.setCustomerParamsRequest(req.getCustomerParamsRequest());
f.setRemitterIdentity(req.getRemitterIdentity());
return f;
}
public com.billpaymentservice.bbps.dto.sentRequest.FetchBillValidatestForwardRequest fetchBillValidatestForwardRequest(
com.billpaymentservice.bbps.dto.request.FetchBillValidatestRequest req) {
if (req == null)
@@ -1236,11 +1167,11 @@ public class BillerMapperHelper {
return f;
}
public void saveBillValidation(com.billpaymentservice.bbps.dto.response.FetchBillValidateResponse responseWrapper,
com.billpaymentservice.bbps.dto.request.BillFetchByBillIdRequest billRequest, String txnId) {
public void saveBillValidation(FetchBillValidateResponse responseWrapper,
BillFetchByBillIdRequest billRequest, String txnId,BillValidation entity) {
if (responseWrapper == null || billRequest == null)
return;
BillValidation entity = new BillValidation();
entity.setBillId(responseWrapper.getBillId());
entity.setRefId(responseWrapper.getRefId());
entity.setBillerId(responseWrapper.getBillerId());
@@ -1288,7 +1219,7 @@ public class BillerMapperHelper {
}
}
public ComplaintResponseDto toDto(ComplaintResponseEntity e) {
public ComplaintResponseDto toDto(ComplaintResponseEntity e) {
ComplaintResponseDto dto = new ComplaintResponseDto();
dto.setTicketId(e.getTicketId());
@@ -1350,4 +1281,4 @@ public class BillerMapperHelper {
return dto;
}
}
}
@@ -14,8 +14,10 @@ import org.springframework.stereotype.Component;
import com.billpaymentservice.bbps.dto.UserDetailsDTO;
import com.billpaymentservice.bbps.dto.auth.RegisterRequest;
import com.billpaymentservice.bbps.dto.response.BillDataResponse;
import com.billpaymentservice.bbps.entites.BBPSMastersData;
import com.billpaymentservice.bbps.entites.BharatConnectMaster;
import com.billpaymentservice.bbps.entites.BillMaster;
import com.billpaymentservice.bbps.entites.InboundTraceLog;
import com.billpaymentservice.bbps.entites.OutboundTraceLog;
import com.billpaymentservice.bbps.entites.TransactionMaster;
@@ -284,5 +286,10 @@ public class Helper {
LOGGER.info("TransactionMaster dest after merge: {}", dest);
}
public void mergeNonNullFieldsBillIntiate(BillDataResponse responseWrapper, BillMaster existingbill) {
}
}
@@ -23,9 +23,9 @@ swagger.server.description=Local Development Server
spring.datasource.url=jdbc:postgresql://localhost:5432/bbps_enhanced
spring.datasource.username=postgres
spring.datasource.password=UAT@DB_2025
#spring.datasource.password=UAT@DB_2025
#spring.datasource.password=himanshu@123
spring.datasource.password=himanshu@123
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.type=com.zaxxer.hikari.HikariDataSource