package com.billpaymentservice.bbps.serviceImpl; import java.util.Map; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.stereotype.Service; import org.springframework.web.client.RestClient; 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.FetchBillRequest; import com.billpaymentservice.bbps.dto.request.FetchBillValidatestRequest; import com.billpaymentservice.bbps.dto.response.BillDataResponse; import com.billpaymentservice.bbps.dto.response.FetchBillResponse; import com.billpaymentservice.bbps.dto.response.FetchBillValidatestResponse; import com.billpaymentservice.bbps.entites.BharatConnectMaster; import com.billpaymentservice.bbps.exception.CustomException; import com.billpaymentservice.bbps.repository.BharatConnectMasterRepository; import com.billpaymentservice.bbps.service.AgentService; import com.billpaymentservice.bbps.util.BBPSConstant; import com.billpaymentservice.bbps.util.Helper; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; @Service @Slf4j public class AgentServiceImpl implements AgentService { @Value("${agent.data.url}") private String agentDtaUrl; private final RestClient restClient; private final HttpService httpService; private final Helper helper; private final BharatConnectMasterRepository beneficiaryDetailsRepository; public AgentServiceImpl(RestClient restClient, HttpService httpService, Helper helper, BharatConnectMasterRepository beneficiaryDetailsRepository) { this.restClient = restClient; this.httpService = httpService; this.helper = helper; this.beneficiaryDetailsRepository = beneficiaryDetailsRepository; } @Override public ResponseModel initiateBillFetch(FetchBillRequest fetchBillRequest) { String url = agentDtaUrl + BBPSConstant.BILL_FETCH_INTI; System.out.println(url); 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); ResponseModel responseModel = new ResponseModel(); try { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // ✅ Convert request to JSON String json = objectMapper.writeValueAsString(fetchBillRequest); // ✅ Call the API using httpService Map responseMap = httpService.postRequest(url, json, headers); String responseData = responseMap.get("data"); log.info("📦 Bill Fetch API Response: {}", responseData); if (responseData == null || responseData.isEmpty()) { throw new CustomException("Empty response from BBPS server"); } // ✅ Convert JSON string → Map Map dataMap = objectMapper.readValue(responseData, new TypeReference>() { }); // ✅ Validate generalResp if (!dataMap.containsKey("genericResponse")) { throw new CustomException("Invalid response structure from BBPS"); } // ✅ Convert to your custom DTO FetchBillResponse fetchBillResponse = objectMapper.convertValue(dataMap, FetchBillResponse.class); GeneralResp generalResponse = fetchBillResponse.getGenericResponse(); // // start a new thread here helper.startPolling(fetchBillResponse, res -> { BillFetchByBillIdRequest pollReq = new BillFetchByBillIdRequest(); pollReq.setBillId(res.getBillId()); return fetchBillById(pollReq); }, 3, // interval in seconds 15 // total time in seconds ); // ✅ Build final ResponseModel responseModel = new ResponseModel(generalResponse.getMessage(), generalResponse.getStatus(), Integer.parseInt(generalResponse.getStatusCode()), fetchBillResponse); } catch (Exception e) { log.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e); responseModel.setStatus("500"); responseModel.setMessage("Exception occurred"); responseModel.setData(e.getMessage()); } return responseModel; } @Override public ResponseModel fetchBillById(BillFetchByBillIdRequest billFetchByBillIdRequest) { String billId = billFetchByBillIdRequest.getBillId(); String fullUrl = agentDtaUrl + BBPSConstant.BILL_FETCH_BY_ID + billId; System.out.print(fullUrl); 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); Map responseMap = httpService.getRequest(fullUrl, headers); String responseData = responseMap.get("data"); log.info("data is :{}", responseData); ObjectMapper objectMapper = new ObjectMapper(); try { Map dataMap = objectMapper.readValue(responseData, new TypeReference>() { }); if (!dataMap.containsKey("genericResponse")) { throw new CustomException(String.valueOf(dataMap.get("message")), // message String.valueOf(dataMap.get("status")), // status Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), // statusCode (int) String.valueOf(dataMap.get("remarks"))); } BillDataResponse responseWrapper = objectMapper.convertValue(dataMap, BillDataResponse.class); GeneralResp generalResp = responseWrapper.getGenericResponse(); ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(), Integer.parseInt(generalResp.getStatusCode()), responseWrapper); return responseModel; } catch (JsonProcessingException e) { log.error("Error parsing responseData JSON: {}", e.getMessage()); throw new CustomException("Invalid JSON received from API"); } } @Override public ResponseModel initiateBillValidate(FetchBillValidatestRequest fetchBillValidateRequest) { ResponseModel responseModel = new ResponseModel(); try { BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); if (headersData == null) { responseModel = new ResponseModel("Tenant Id Is Null", "Not Found", BBPSConstant.BADREQUEST, headersData); return responseModel; } 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); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); String json = objectMapper.writeValueAsString(fetchBillValidateRequest); String url = agentDtaUrl + BBPSConstant.BILLER_VALIDATE_URL; Map responseMap = httpService.postRequest(url, json, headers); String responseData = responseMap.get("data"); log.info("📦 Bill Fetch API Response: {}", responseData); if (responseData == null || responseData.isEmpty()) { throw new CustomException("Empty response from BBPS server"); } // ✅ Convert JSON string → Map Map dataMap = objectMapper.readValue(responseData, new TypeReference>() { }); // ✅ Validate generalResp if (!dataMap.containsKey("genericResponse")) { throw new CustomException("Invalid response structure from BBPS"); } // ✅ Convert to your custom DTO FetchBillValidatestResponse fetchBillResponse = objectMapper.convertValue(dataMap, FetchBillValidatestResponse.class); GeneralResp generalResponse = fetchBillResponse.getGenericResponse(); // ✅ Build final ResponseModel responseModel = new ResponseModel(generalResponse.getMessage(), generalResponse.getStatus(), Integer.parseInt(generalResponse.getStatusCode()), fetchBillResponse); } catch (Exception e) { log.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e); responseModel.setStatus("500"); responseModel.setMessage("Exception occurred"); responseModel.setData(e.getMessage()); } return responseModel; } @Override public ResponseModel initiateBillValidateByBillId(BillFetchByBillIdRequest billRequest) { ResponseModel responseModel = new ResponseModel(); try { BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); if (headersData == null) { responseModel = new ResponseModel("Tenant Id Is Null", "Not Found", BBPSConstant.BADREQUEST, headersData); return responseModel; } 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); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); String json = objectMapper.writeValueAsString(billRequest); String url = agentDtaUrl + BBPSConstant.BILL_ID_URL + billRequest.getBillId(); log.info("Full URL" + url); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // ✅ Call the API using httpService Map responseMap = httpService.getRequest(url, headers); String responseData = responseMap.get("data"); log.info("📦 Bill Fetch API Response: {}", responseData); if (responseData == null || responseData.isEmpty()) { throw new CustomException("Empty response from BBPS server"); } // ✅ Convert JSON string → Map Map dataMap = objectMapper.readValue(responseData, new TypeReference>() { }); // ✅ Validate generalResp if (!dataMap.containsKey("genericResponse")) { throw new CustomException("Invalid response structure from BBPS"); } // ✅ Convert to your custom DTO BillDataResponse fetchBillResponse = objectMapper.convertValue(dataMap, BillDataResponse.class); GeneralResp generalResponse = fetchBillResponse.getGenericResponse(); // ✅ Build final ResponseModel responseModel = new ResponseModel(generalResponse.getRemarks(), generalResponse.getStatus(), Integer.parseInt(generalResponse.getStatusCode()), fetchBillResponse); } catch (Exception e) { log.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e); responseModel.setStatus("500"); responseModel.setMessage("Exception occurred"); responseModel.setData(e.getMessage()); } return responseModel; } }