package com.billpaymentservice.bbps.util; import java.security.SecureRandom; import java.time.LocalDateTime; import java.util.Date; import java.util.Random; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; import com.billpaymentservice.bbps.dto.UserDetailsDTO; import com.billpaymentservice.bbps.dto.auth.RegisterRequest; import com.billpaymentservice.bbps.entites.BBPSMastersData; import com.billpaymentservice.bbps.entites.BharatConnectMaster; import com.billpaymentservice.bbps.entites.InboundTraceLog; import com.billpaymentservice.bbps.entites.OutboundTraceLog; import com.billpaymentservice.bbps.entites.UserEntity; import com.billpaymentservice.bbps.exception.CustomException; import com.billpaymentservice.bbps.repository.BBPSMasterDataRepo; import com.billpaymentservice.bbps.repository.BillMasterRepository; import com.billpaymentservice.bbps.repository.BillValidationRepository; import com.billpaymentservice.bbps.repository.BillerDataRepository; import com.billpaymentservice.bbps.repository.InboundTraceLogRepository; import com.billpaymentservice.bbps.repository.OutboundTraceLogRepository; import com.billpaymentservice.bbps.repository.UserRepository; import com.fasterxml.jackson.databind.ObjectMapper; @Component public class Helper { private static final Logger LOGGER = LoggerFactory.getLogger(Helper.class); private final InboundTraceLogRepository inboundTraceLogRepository; private final OutboundTraceLogRepository outboundTraceLogRepository; private final UserRepository userRepository; private static final String CHARACTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; private static final SecureRandom secureRandom = new SecureRandom(); private final ObjectMapper objectMapper = new ObjectMapper(); private final BBPSMasterDataRepo bbpsMasterDataRepo; // Constructor Injection public Helper(BBPSMasterDataRepo bbpsMasterDataRepo, InboundTraceLogRepository inboundTraceLogRepository, OutboundTraceLogRepository outboundTraceLogRepository, BillerDataRepository billerDataRepository, BillMasterRepository billMasterRepository, BillValidationRepository billValidationRepository, UserRepository userRepository) { this.inboundTraceLogRepository = inboundTraceLogRepository; this.outboundTraceLogRepository = outboundTraceLogRepository; this.bbpsMasterDataRepo = bbpsMasterDataRepo; this.userRepository = userRepository; } /** * Validates whether the merchant exists and is active. * * @param requestModel MerchantRequestModel containing merchant details * @return true if merchant exists and is active * @throws CustomException if merchant is invalid or inactive * * * */ public void validateMerchant(String mid) { if (mid == null || mid == "") { LOGGER.warn("MerchantRequestModel or MID is null"); throw new CustomException("Mid is required", "FAILED", BBPSConstant.BADREQUEST, null); } BBPSMastersData merchantValidation = bbpsMasterDataRepo.findByMid(mid); if (merchantValidation == null) { LOGGER.warn("Merchant not found for MID: {}", mid); throw new CustomException("Merchant not found by id", "FAILED", BBPSConstant.BADREQUEST, null); } if (StringUtils.isBlank(merchantValidation.getApiKey()) && StringUtils.isBlank(merchantValidation.getSecreteKey())) { LOGGER.warn("Merchant BBPS service is not active MID: {}", mid); throw new CustomException("Merchant BBPS Service is not active by mid", "FAILED", BBPSConstant.BADREQUEST, null); } if (!Boolean.TRUE.equals(merchantValidation.getIsActive())) { LOGGER.warn("Merchant inactive for MID: {}", mid); throw new CustomException("Merchant is inactive", "FAILED", BBPSConstant.BADREQUEST, null); } LOGGER.info("Merchant is valid and active for MID: {}", mid); // Agar exception nahi throw hua, merchant valid hai } public static String generateTxnId(int n) { StringBuilder sb = new StringBuilder(n); for (int i = 0; i < n; i++) { int index = secureRandom.nextInt(CHARACTERS.length()); sb.append(CHARACTERS.charAt(index)); } return sb.toString(); // Prefix } public String convertObjectToJson(Object obj) { if (obj == null) return "null"; try { return new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(obj); } catch (com.fasterxml.jackson.core.JsonProcessingException e) { // log appropriately (use your existing logger) System.err.println("JSON conversion failed: " + e.getMessage()); return "{}"; // or "N/A" depending on your needs } } /* ---------- Trace helper methods ---------- */ public InboundTraceLog createInboundLog(String requestId, String txnId, String apiName, String mid, String httpMethod, String requestPayload) { if (inboundTraceLogRepository.findByRequestId(requestId) != null) { throw new CustomException("Duplicate Request ID: " + requestId); } InboundTraceLog inboundLog = new InboundTraceLog(requestId, txnId, apiName, mid == null ? "N/A" : mid, "BBPS_ORG", httpMethod, requestPayload == null ? "N/A" : requestPayload); inboundTraceLogRepository.save(inboundLog); return inboundLog; } public void updateInboundLogSuccess(InboundTraceLog inboundLog, String responsePayload, String responseCode) { if (inboundLog == null) return; inboundLog.setResponsePayload(responsePayload); inboundLog.setResponseCode(responseCode); inboundLog.setStatus("SUCCESS"); inboundLog.setResponseTime(LocalDateTime.now()); inboundTraceLogRepository.save(inboundLog); } public void updateInboundLogFailure(InboundTraceLog inboundLog, String responsePayload, String responseCode) { if (inboundLog == null) return; inboundLog.setResponsePayload(responsePayload); inboundLog.setResponseCode(responseCode); inboundLog.setStatus("FAILED"); inboundLog.setResponseTime(LocalDateTime.now()); inboundTraceLogRepository.save(inboundLog); } public OutboundTraceLog createOutboundLog(String txnId, String requestId, String apiName, String url, String httpMethod, String requestPayload) { OutboundTraceLog outboundLog = new OutboundTraceLog(txnId, requestId, apiName, url, httpMethod, requestPayload == null ? "N/A" : requestPayload); outboundTraceLogRepository.save(outboundLog); return outboundLog; } public void updateOutboundLogResponse(OutboundTraceLog outboundLog, String responsePayload) { if (outboundLog == null) return; outboundLog.setResponsePayload(responsePayload); outboundLog.setResponseReceiveTime(LocalDateTime.now()); outboundTraceLogRepository.save(outboundLog); } /* ---------- End helpers ---------- */ // New reusable header builder for BBPS calls public HttpHeaders buildHeaders(BharatConnectMaster headersData) { HttpHeaders headers = new HttpHeaders(); if (headersData != null) { headers.set("x-digiledge-key", headersData.getXDigiledgeKey()); headers.set("agentId", headersData.getAgentId()); headers.set("tenantId", headersData.getTenantId()); } headers.setContentType(MediaType.APPLICATION_JSON); return headers; } public UserEntity createNewUser(RegisterRequest request) { UserEntity user = new UserEntity(); // user.setId(generateUserId()); user.setMobile(request.getMobile()); user.setName(request.getName()); user.setEmail(request.getEmail()); user.setMid(request.getMid()); // set audit createdOn timestamp user.setCreatedOn(LocalDateTime.now()); // Generate a unique userId (UUID) String uniqueUserId = generateUniqueUserId(); user.setUserId(uniqueUserId); return user; } public Object mapUserToUserDetailsDTO(UserEntity user) { if (user != null) { return UserDetailsDTO.builder().userId(user.getUserId() != null ? user.getUserId() : null) // Set null if .userEmailId(user.getEmail() != null ? user.getEmail() : null) .userMobNo(user.getMobile() != null ? user.getMobile() : null) .userName(user.getName() != null ? user.getName() : null).build(); } return null; // or handle accordingly if user is null } public T convertJsonToObject(String json, Class clazz) { try { return objectMapper.readValue(json, clazz); } catch (Exception e) { throw new CustomException("Invalid JSON from payment API", "FAILED", 400, json); } } private String generateUniqueUserId() { Random random = new Random(); // Generate a random 6-digit number (between 100000 and 999999) String userId = String.format("USER%06d", random.nextInt(900000) + 100000); // Format as USER-XXXXXX // Check if the userId already exists in the database (theoretically rare but // can happen) while (userRepository.existsByUserId(userId)) { // If it exists, generate a new one userId = String.format("USER-%06d", random.nextInt(900000) + 100000); // Generate new 6-digit number with // prefix } return userId; } }