diff --git a/src/main/java/com/billpaymentservice/bbps/controller/MasterDataController.java b/src/main/java/com/billpaymentservice/bbps/controller/MasterDataController.java index d485d41..064278d 100644 --- a/src/main/java/com/billpaymentservice/bbps/controller/MasterDataController.java +++ b/src/main/java/com/billpaymentservice/bbps/controller/MasterDataController.java @@ -9,12 +9,14 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; + import com.billpaymentservice.bbps.dto.ResponseModel; import com.billpaymentservice.bbps.dto.request.BillerDetailRequest; import com.billpaymentservice.bbps.dto.request.ContactMasterRequest; import com.billpaymentservice.bbps.dto.request.CustomParamRequest; import com.billpaymentservice.bbps.dto.request.MasterCategoryRequest; import com.billpaymentservice.bbps.dto.request.MasterRequest; +import com.billpaymentservice.bbps.dto.request.PlanRequest; import com.billpaymentservice.bbps.service.MasterDataService; @RequestMapping("/masterData") @@ -104,7 +106,7 @@ public class MasterDataController { * POST Fetch All AMount Options By Biller Id API Fetch Category Wise from BBPS * URL **/ - @PostMapping(value = "/fetchPlanCategories", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + @PostMapping(value = "/fetchAllPlanCategories", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity fetchPlanCategories(@Validated @RequestBody BillerDetailRequest requestModel) { return ResponseEntity.ok(masterDataService.fetchPlanCategorie(requestModel)); } @@ -116,4 +118,15 @@ public class MasterDataController { public ResponseEntity initiatingChannel(@Validated @RequestBody BillerDetailRequest requestModel) { return ResponseEntity.ok(masterDataService.fetchInitiatingChannel(requestModel)); } + + /** + * POST Fetch All AMount Options By Biller Id API Fetch Category Wise from BBPS + * URL + **/ + @PostMapping(value = "/fetchPlanByCategoryName", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity fetchPlanByCategory(@Validated @RequestBody PlanRequest requestModel) { + return ResponseEntity.ok(masterDataService.fetchPlanByCategories(requestModel)); + } + + } diff --git a/src/main/java/com/billpaymentservice/bbps/dto/AdditionalInfo.java b/src/main/java/com/billpaymentservice/bbps/dto/AdditionalInfo.java new file mode 100644 index 0000000..10c6a78 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/AdditionalInfo.java @@ -0,0 +1,20 @@ +package com.billpaymentservice.bbps.dto; + +import java.util.List; +import java.util.UUID; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class AdditionalInfo { + + private UUID planAdditionalInfoId; + private List tags; + +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/BillerIconDTO.java b/src/main/java/com/billpaymentservice/bbps/dto/BillerIconDTO.java new file mode 100644 index 0000000..da29700 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/BillerIconDTO.java @@ -0,0 +1,17 @@ +package com.billpaymentservice.bbps.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class BillerIconDTO { + + private String icon_data; // Base64 or image data + private String icon_type; + +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/MasterCategoryBillerResponse.java b/src/main/java/com/billpaymentservice/bbps/dto/MasterCategoryBillerResponse.java index e85199e..d58c5da 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/MasterCategoryBillerResponse.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/MasterCategoryBillerResponse.java @@ -21,5 +21,6 @@ public class MasterCategoryBillerResponse { private String planMDMRequirement; private String adhocBiller; private String paymentAmountExactness; + private BillerIconDTO biller_icon; } diff --git a/src/main/java/com/billpaymentservice/bbps/dto/PlanDTO.java b/src/main/java/com/billpaymentservice/bbps/dto/PlanDTO.java new file mode 100644 index 0000000..dd952e5 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/PlanDTO.java @@ -0,0 +1,27 @@ +package com.billpaymentservice.bbps.dto; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class PlanDTO { + + private String planId; + private String description; + private String billerId; + private String categoryType; + private List categorySubType; // comes as empty array [] + private String amountInRupees; // numeric but mapped as String for safety + private String effctvFrom; + private String effctvTo; + private String status; + private AdditionalInfo additionalInfo; + +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/PlanTag.java b/src/main/java/com/billpaymentservice/bbps/dto/PlanTag.java new file mode 100644 index 0000000..7d54bdb --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/PlanTag.java @@ -0,0 +1,20 @@ +package com.billpaymentservice.bbps.dto; + +import java.util.UUID; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class PlanTag { + + private UUID tagId; + private String name; + private String value; + +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/PlansListDTO.java b/src/main/java/com/billpaymentservice/bbps/dto/PlansListDTO.java new file mode 100644 index 0000000..04bacbd --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/PlansListDTO.java @@ -0,0 +1,18 @@ +package com.billpaymentservice.bbps.dto; + +import java.util.List; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class PlansListDTO { + + private List plans; + +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/request/FetchBillRequest.java b/src/main/java/com/billpaymentservice/bbps/dto/request/FetchBillRequest.java index 4f5b7c0..3bc58c6 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/request/FetchBillRequest.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/request/FetchBillRequest.java @@ -18,11 +18,11 @@ import lombok.ToString; @ToString public class FetchBillRequest extends BaseClass { - private String tenantId; // M +// private String tenantId; // M private String billerId; // M private String billerName; //M - private String digiledgeKey; // M - private String agentId; // M + // private String digiledgeKey; // M + // private String agentId; // M private String billerCategory; // M private String clientReqId; // C private String macAdress; // C diff --git a/src/main/java/com/billpaymentservice/bbps/dto/request/PlanRequest.java b/src/main/java/com/billpaymentservice/bbps/dto/request/PlanRequest.java new file mode 100644 index 0000000..740c379 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/request/PlanRequest.java @@ -0,0 +1,33 @@ +package com.billpaymentservice.bbps.dto.request; + +import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * DTO for fetching plan list from /masters/plans endpoint. + */ +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class PlanRequest extends BaseClass { + + // ✅ Mandatory: 14-character alphanumeric + @NotBlank(message = "billerId is mandatory") + private String billerId; + + // ✅ Conditional (optional) + private String category; + + private String amountInRupees; + + private String circle; + + // ✅ Optional pagination parameters + private Integer page; + + private Integer pagesize; +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/response/PlanResponse.java b/src/main/java/com/billpaymentservice/bbps/dto/response/PlanResponse.java new file mode 100644 index 0000000..60cf0be --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/response/PlanResponse.java @@ -0,0 +1,27 @@ +package com.billpaymentservice.bbps.dto.response; + +import com.billpaymentservice.bbps.dto.GeneralResp; +import com.billpaymentservice.bbps.dto.PlansListDTO; +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +public class PlanResponse { + + private PlansListDTO plansList; // contains "plans" + + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + private GeneralResp generalResp; // status/message block + private int pageNo; + private int pageSize; + private long totalElements; + private int totalPages; + +} diff --git a/src/main/java/com/billpaymentservice/bbps/entites/BBPSMastersData.java b/src/main/java/com/billpaymentservice/bbps/entites/BBPSMastersData.java new file mode 100644 index 0000000..85f311e --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/entites/BBPSMastersData.java @@ -0,0 +1,46 @@ +package com.billpaymentservice.bbps.entites; + +import com.billpaymentservice.bbps.audit.Auditable; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Getter +@Setter +@Table(name = "bbps_master_data") +public class BBPSMastersData extends Auditable { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "id") + private Long id; + + @Column(name = "mid") + private String mid; + + @Column(name = "api_key") + private String apiKey; + + @Column(name = "secrete_key") + private String secreteKey; + + @Column(name = "is_active") + private Boolean isActive; + + @Column(name = "user_name") + private String userName; + +} diff --git a/src/main/java/com/billpaymentservice/bbps/repository/BBPSMasterDataRepo.java b/src/main/java/com/billpaymentservice/bbps/repository/BBPSMasterDataRepo.java new file mode 100644 index 0000000..68a27b5 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/repository/BBPSMasterDataRepo.java @@ -0,0 +1,14 @@ +package com.billpaymentservice.bbps.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import com.billpaymentservice.bbps.entites.BBPSMastersData; + +@Repository +public interface BBPSMasterDataRepo extends JpaRepository { + + @Query("from BBPSMastersData where mid = ?1 and isDeleted = false") + public BBPSMastersData findByMid(String mid); +} diff --git a/src/main/java/com/billpaymentservice/bbps/repository/MerchantRepository.java b/src/main/java/com/billpaymentservice/bbps/repository/MerchantRepository.java index c773555..a8cf354 100644 --- a/src/main/java/com/billpaymentservice/bbps/repository/MerchantRepository.java +++ b/src/main/java/com/billpaymentservice/bbps/repository/MerchantRepository.java @@ -2,9 +2,11 @@ package com.billpaymentservice.bbps.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; import com.billpaymentservice.bbps.entites.BBPSMerchantValidation; +@Repository public interface MerchantRepository extends JpaRepository { @Query("from BBPSMerchantValidation where mid = ?1 and is_deleted = false") diff --git a/src/main/java/com/billpaymentservice/bbps/service/MasterDataService.java b/src/main/java/com/billpaymentservice/bbps/service/MasterDataService.java index ec815bf..6d1a163 100644 --- a/src/main/java/com/billpaymentservice/bbps/service/MasterDataService.java +++ b/src/main/java/com/billpaymentservice/bbps/service/MasterDataService.java @@ -7,6 +7,8 @@ import com.billpaymentservice.bbps.dto.request.CustomParamRequest; import com.billpaymentservice.bbps.dto.request.MasterCategoryRequest; import com.billpaymentservice.bbps.dto.request.MasterRequest; import com.billpaymentservice.bbps.dto.request.MerchantRequestModel; +import com.billpaymentservice.bbps.dto.request.PlanRequest; + import jakarta.servlet.http.HttpServletRequest; public interface MasterDataService { @@ -31,4 +33,6 @@ public interface MasterDataService { public ResponseModel getDispositionDetails(); + public ResponseModel fetchPlanByCategories(PlanRequest requestModel); + } diff --git a/src/main/java/com/billpaymentservice/bbps/serviceImpl/AgentServiceImpl.java b/src/main/java/com/billpaymentservice/bbps/serviceImpl/AgentServiceImpl.java index a38b25f..ecc9a83 100644 --- a/src/main/java/com/billpaymentservice/bbps/serviceImpl/AgentServiceImpl.java +++ b/src/main/java/com/billpaymentservice/bbps/serviceImpl/AgentServiceImpl.java @@ -51,6 +51,9 @@ public class AgentServiceImpl implements AgentService { @Override public ResponseModel initiateBillFetch(FetchBillRequest fetchBillRequest) { + + helper.validateMerchant(fetchBillRequest.getMid()); + String url = agentDtaUrl + BBPSConstant.BILL_FETCH_INTI; System.out.println(url); @@ -73,6 +76,7 @@ public class AgentServiceImpl implements AgentService { // ✅ Call the API using httpService Map responseMap = httpService.postRequest(url, json, headers); + log.info("Response -: " + responseMap); String responseData = responseMap.get("data"); log.info("📦 Bill Fetch API Response: {}", responseData); @@ -108,6 +112,9 @@ public class AgentServiceImpl implements AgentService { responseModel = new ResponseModel(generalResponse.getMessage(), generalResponse.getStatus(), Integer.parseInt(generalResponse.getStatusCode()), fetchBillResponse); + } catch (CustomException ex) { + log.warn("Merchant validation failed: {}", ex.getMessage()); + return ex.getResponseModel(); // Directly return ResponseModel from exception } catch (Exception e) { log.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e); responseModel.setStatus("500"); @@ -121,25 +128,28 @@ public class AgentServiceImpl implements AgentService { @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 { + + helper.validateMerchant(billFetchByBillIdRequest.getMid()); + + 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(); + Map dataMap = objectMapper.readValue(responseData, new TypeReference>() { }); @@ -162,6 +172,9 @@ public class AgentServiceImpl implements AgentService { } catch (JsonProcessingException e) { log.error("Error parsing responseData JSON: {}", e.getMessage()); throw new CustomException("Invalid JSON received from API"); + } catch (CustomException ex) { + log.warn("Merchant validation failed: {}", ex.getMessage()); + return ex.getResponseModel(); // Directly return ResponseModel from exception } } @@ -171,6 +184,9 @@ public class AgentServiceImpl implements AgentService { ResponseModel responseModel = new ResponseModel(); try { + + helper.validateMerchant(fetchBillValidateRequest.getMid()); + BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); if (headersData == null) { @@ -216,6 +232,9 @@ public class AgentServiceImpl implements AgentService { responseModel = new ResponseModel(generalResponse.getMessage(), generalResponse.getStatus(), Integer.parseInt(generalResponse.getStatusCode()), fetchBillResponse); + } catch (CustomException ex) { + log.warn("Merchant validation failed: {}", ex.getMessage()); + return ex.getResponseModel(); // Directly return ResponseModel from exception } catch (Exception e) { log.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e); responseModel.setStatus("500"); @@ -231,6 +250,7 @@ public class AgentServiceImpl implements AgentService { ResponseModel responseModel = new ResponseModel(); try { + helper.validateMerchant(billRequest.getMid()); BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); @@ -281,6 +301,9 @@ public class AgentServiceImpl implements AgentService { responseModel = new ResponseModel(generalResponse.getRemarks(), generalResponse.getStatus(), Integer.parseInt(generalResponse.getStatusCode()), fetchBillResponse); + } catch (CustomException ex) { + log.warn("Merchant validation failed: {}", ex.getMessage()); + return ex.getResponseModel(); // Directly return ResponseModel from exception } catch (Exception e) { log.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e); responseModel.setStatus("500"); diff --git a/src/main/java/com/billpaymentservice/bbps/serviceImpl/MasterDataServiceImpl.java b/src/main/java/com/billpaymentservice/bbps/serviceImpl/MasterDataServiceImpl.java index be989f0..77d219f 100644 --- a/src/main/java/com/billpaymentservice/bbps/serviceImpl/MasterDataServiceImpl.java +++ b/src/main/java/com/billpaymentservice/bbps/serviceImpl/MasterDataServiceImpl.java @@ -19,6 +19,7 @@ import com.billpaymentservice.bbps.dto.request.ContactMasterRequest; import com.billpaymentservice.bbps.dto.request.CustomParamRequest; import com.billpaymentservice.bbps.dto.request.MasterCategoryRequest; import com.billpaymentservice.bbps.dto.request.MasterRequest; +import com.billpaymentservice.bbps.dto.request.PlanRequest; import com.billpaymentservice.bbps.dto.response.AmountOptionsResponse; import com.billpaymentservice.bbps.dto.response.BillerDataResponse; import com.billpaymentservice.bbps.dto.response.BillerResponse; @@ -26,6 +27,7 @@ import com.billpaymentservice.bbps.dto.response.ChannelsListResponse; import com.billpaymentservice.bbps.dto.response.CustomParamResp; import com.billpaymentservice.bbps.dto.response.CustomerParamGroupsResponse; import com.billpaymentservice.bbps.dto.response.DispositionResponse; +import com.billpaymentservice.bbps.dto.response.PlanResponse; import com.billpaymentservice.bbps.dto.response.PlaneCategoriesResponse; import com.billpaymentservice.bbps.entites.BharatConnectMaster; import com.billpaymentservice.bbps.entites.BillerDetails; @@ -79,13 +81,24 @@ public class MasterDataServiceImpl implements MasterDataService { LOGGER.info("Request DTO: {}", masterRequest); try { + // Merchant Validation + helper.validateMerchant(masterRequest.getMid()); + +// if (!"Valid".equalsIgnoreCase(validateMerchant)) { +// LOGGER.warn("Merchant validation failed: {}", validateMerchant); +// return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); +// } + + // check Tender Id is present DB BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); - log.info("ResPONSE" + headersData); + log.info("Response -: " + headersData); if (headersData == null) { ResponseModel responseModel = new ResponseModel("Tenant Id Is Null", "Not Found", BBPSConstant.BADREQUEST, headersData); return responseModel; } + + // get full url String fullUrl = masterRegisterUrl + BBPSConstant.MASTER_CATEGORY_URL + headersData.getTenantId(); LOGGER.info("Calling external API: {}", fullUrl); @@ -118,22 +131,33 @@ public class MasterDataServiceImpl implements MasterDataService { } catch (JsonProcessingException e) { log.error("Error parsing responseData JSON: {}", e.getMessage()); throw new CustomException("Invalid JSON received from API"); + } catch (CustomException ex) { + LOGGER.warn("Merchant validation failed: {}", ex.getMessage()); + return ex.getResponseModel(); // Directly return ResponseModel from exception } } @Override public ResponseModel getBillerByBillerId(BillerDetailRequest billerDetailRequest) { - String billerId = billerDetailRequest.getBillerId(); - String fullUrl = masterRegisterUrl + BBPSConstant.BILLER_DATA_FETCH_URL + billerId; - - Map responseMap = httpService.getRequest(fullUrl); - String responseData = responseMap.get("data"); - log.info("data is :{}", responseData); - - ObjectMapper objectMapper = new ObjectMapper(); - try { + + helper.validateMerchant(billerDetailRequest.getMid()); + +// if (!"Valid".equalsIgnoreCase(validateMerchant)) { +// LOGGER.warn("Merchant validation failed: {}", validateMerchant); +// return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); +// } + + String billerId = billerDetailRequest.getBillerId(); + String fullUrl = masterRegisterUrl + BBPSConstant.BILLER_DATA_FETCH_URL + billerId; + + Map responseMap = httpService.getRequest(fullUrl); + String responseData = responseMap.get("data"); + log.info("data is :{}", responseData); + + ObjectMapper objectMapper = new ObjectMapper(); + Map dataMap = objectMapper.readValue(responseData, new TypeReference>() { }); @@ -157,6 +181,9 @@ public class MasterDataServiceImpl implements MasterDataService { } catch (JsonProcessingException e) { log.error("Error parsing responseData JSON: {}", e.getMessage()); throw new CustomException("Invalid JSON received from API"); + } catch (CustomException ex) { + LOGGER.warn("Merchant validation failed: {}", ex.getMessage()); + return ex.getResponseModel(); // Directly return ResponseModel from exception } } @@ -164,6 +191,12 @@ public class MasterDataServiceImpl implements MasterDataService { public ResponseModel getCustomerParamByBillerId(CustomParamRequest customerParamRequest) { try { + helper.validateMerchant(customerParamRequest.getMid()); + +// if (!"Valid".equalsIgnoreCase(validateMerchant)) { +// LOGGER.warn("Merchant validation failed: {}", validateMerchant); +// return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); +// } String billerId = customerParamRequest.getBillerId(); String fullUrl = masterRegisterUrl + BBPSConstant.CUSTOMPARAM_URL + billerId; @@ -194,6 +227,9 @@ public class MasterDataServiceImpl implements MasterDataService { } catch (JsonProcessingException e) { log.error("Error parsing responseData JSON: {}", e.getMessage()); throw new CustomException("Invalid JSON received from API"); + } catch (CustomException ex) { + LOGGER.warn("Merchant validation failed: {}", ex.getMessage()); + return ex.getResponseModel(); // Directly return ResponseModel from exception } } @@ -201,21 +237,20 @@ public class MasterDataServiceImpl implements MasterDataService { @Override public ResponseModel getContactMaster(ContactMasterRequest contactMasterRequest) { + // yeh krna hai return new ResponseModel(); } @Override public ResponseModel fetchMasterDataCategoryWise(MasterCategoryRequest masterRequest) { LOGGER.info("Fetching Master Data Category-wise " + masterRequest); - try { + helper.validateMerchant(masterRequest.getMid()); - String validateMerchant = helper.validateMerchant(masterRequest); - - if (!"Valid".equalsIgnoreCase(validateMerchant)) { - LOGGER.warn("Merchant validation failed: {}", validateMerchant); - return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); - } +// if (!"Valid".equalsIgnoreCase(validateMerchant)) { +// LOGGER.warn("Merchant validation failed: {}", validateMerchant); +// return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); +// } String fullUrl = String.format("%s%s?billerName=%s&category=%s&page=%d&pagesize=%d", masterRegisterUrl, BBPSConstant.BILLER_URL, masterRequest.getBillerName(), masterRequest.getCategory(), @@ -250,19 +285,23 @@ public class MasterDataServiceImpl implements MasterDataService { } catch (JsonProcessingException e) { log.error("Error parsing responseData JSON: {}", e.getMessage()); throw new CustomException("Invalid JSON received from API"); + } catch (CustomException ex) { + LOGGER.warn("Merchant validation failed: {}", ex.getMessage()); + return ex.getResponseModel(); // Directly return ResponseModel from exception } } @Override public ResponseModel getDispositionDetails() { - String fullUrl = masterRegisterUrl + BBPSConstant.DISPOSTION_URL; - Map responseMap = httpService.getRequest(fullUrl); - String responseData = responseMap.get("data"); - - ObjectMapper objectMapper = new ObjectMapper(); try { + String fullUrl = masterRegisterUrl + BBPSConstant.DISPOSTION_URL; + Map responseMap = httpService.getRequest(fullUrl); + String responseData = responseMap.get("data"); + + ObjectMapper objectMapper = new ObjectMapper(); + Map dataMap = objectMapper.readValue(responseData, new TypeReference>() { }); @@ -296,6 +335,9 @@ public class MasterDataServiceImpl implements MasterDataService { } catch (JsonProcessingException e) { log.error("Error parsing responseData JSON: {}", e.getMessage()); throw new CustomException("Invalid JSON received from API"); + } catch (CustomException ex) { + LOGGER.warn("Merchant validation failed: {}", ex.getMessage()); + return ex.getResponseModel(); // Directly return ResponseModel from exception } } @@ -305,13 +347,12 @@ public class MasterDataServiceImpl implements MasterDataService { LOGGER.info("Fetching Master Data Category-wise for MID={}", requestModel.getMid()); try { + helper.validateMerchant(requestModel.getMid()); - String validateMerchant = helper.validateMerchant(requestModel); - - if (!"Valid".equalsIgnoreCase(validateMerchant)) { - LOGGER.warn("Merchant validation failed: {}", validateMerchant); - return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); - } +// if (!"Valid".equalsIgnoreCase(validateMerchant)) { +// LOGGER.warn("Merchant validation failed: {}", validateMerchant); +// return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); +// } String fullUrl = masterRegisterUrl + BBPSConstant.CUSTOMER_PARAM_GROUP + requestModel.getBillerId(); // LOGGER.info("Calling Master API: {}", fullUrl); @@ -341,6 +382,9 @@ public class MasterDataServiceImpl implements MasterDataService { } catch (JsonProcessingException e) { log.error("Error parsing responseData JSON: {}", e.getMessage()); throw new CustomException("Invalid JSON received from API"); + } catch (CustomException ex) { + LOGGER.warn("Merchant validation failed: {}", ex.getMessage()); + return ex.getResponseModel(); // Directly return ResponseModel from exception } } @@ -349,12 +393,12 @@ public class MasterDataServiceImpl implements MasterDataService { public ResponseModel fetchAllMasterAmountOption(BillerDetailRequest requestModel) { LOGGER.info("Fetching Master Data Amount List for MID={}", requestModel.getMid()); try { - String validateMerchant = helper.validateMerchant(requestModel); + helper.validateMerchant(requestModel.getMid()); - if (!"Valid".equalsIgnoreCase(validateMerchant)) { - LOGGER.warn("Merchant validation failed: {}", validateMerchant); - return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); - } +// if (!"Valid".equalsIgnoreCase(validateMerchant)) { +// LOGGER.warn("Merchant validation failed: {}", validateMerchant); +// return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); +// } String fullUrl = masterRegisterUrl + BBPSConstant.AMOUNT_OPTIONS + requestModel.getBillerId(); // LOGGER.info("Calling Master API: {}", fullUrl); @@ -389,18 +433,19 @@ public class MasterDataServiceImpl implements MasterDataService { LOGGER.error("Custom Exception: {}", e.getMessage()); throw e; // Rethrow custom exceptions to be handled by the controller } + } @Override public ResponseModel fetchPlanCategorie(BillerDetailRequest requestModel) { LOGGER.info("Fetching Master Data Amount List for MID={}", requestModel.getMid()); try { - String validateMerchant = helper.validateMerchant(requestModel); + helper.validateMerchant(requestModel.getMid()); - if (!"Valid".equalsIgnoreCase(validateMerchant)) { - LOGGER.warn("Merchant validation failed: {}", validateMerchant); - return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); - } +// if (!"Valid".equalsIgnoreCase(validateMerchant)) { +// LOGGER.warn("Merchant validation failed: {}", validateMerchant); +// return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); +// } String fullUrl = masterRegisterUrl + BBPSConstant.PLAN_CATEGORIES + requestModel.getBillerId(); // LOGGER.info("Calling Master API: {}", fullUrl); @@ -441,12 +486,12 @@ public class MasterDataServiceImpl implements MasterDataService { public ResponseModel fetchInitiatingChannel(BillerDetailRequest requestModel) { LOGGER.info("Fetching Initiating Channel List for MID={}", requestModel.getMid()); try { - String validateMerchant = helper.validateMerchant(requestModel); + helper.validateMerchant(requestModel.getMid()); - if (!"Valid".equalsIgnoreCase(validateMerchant)) { - LOGGER.warn("Merchant validation failed: {}", validateMerchant); - return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); - } +// if (!"Valid".equalsIgnoreCase(validateMerchant)) { +// LOGGER.warn("Merchant validation failed: {}", validateMerchant); +// return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); +// } String fullUrl = masterRegisterUrl + BBPSConstant.INITIATING_CHANNEL; LOGGER.info("Calling Master API: {}", fullUrl); @@ -483,4 +528,58 @@ public class MasterDataServiceImpl implements MasterDataService { } } + @Override + public ResponseModel fetchPlanByCategories(PlanRequest requestModel) { + LOGGER.info("Fetching Initiating Fetch Plan Category By Bidder Id for MID={}", requestModel.getMid()); + try { + helper.validateMerchant(requestModel.getMid()); + +// if (!"Valid".equalsIgnoreCase(validateMerchant)) { +// LOGGER.warn("Merchant validation failed: {}", validateMerchant); +// return new ResponseModel("Merchant validation failed", validateMerchant, BBPSConstant.BADREQUEST, null); +// } + + String url = String.format("%s%s?billerId=%s%s%s%s&page=%d&pagesize=%d", masterRegisterUrl, + BBPSConstant.PLANS_URL, requestModel.getBillerId(), + requestModel.getCategory() != null ? "&category=" + requestModel.getCategory() : "", + requestModel.getAmountInRupees() != null ? "&amountInRupees=" + requestModel.getAmountInRupees() + : "", + requestModel.getCircle() != null ? "&circle=" + requestModel.getCircle() : "", + requestModel.getPage(), requestModel.getPagesize()); + + //String fullUrl = masterRegisterUrl + BBPSConstant.PLANS_URL + url; + LOGGER.info("Calling Master API: {}", url); + + Map apiResponse = httpService.getRequest(url); + log.info("Response" + apiResponse); + String responseData = apiResponse.get("data").toString(); + + Map dataMap = objectMapper.readValue(responseData, + new TypeReference>() { + }); + + if (!dataMap.containsKey("generalResp")) { + 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"))); + } + + PlanResponse responseWrapper = objectMapper.convertValue(dataMap, PlanResponse.class); + GeneralResp generalResp = responseWrapper.getGeneralResp(); + + 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"); + } catch (CustomException e) { + LOGGER.error("Custom Exception: {}", e.getMessage()); + throw e; // Rethrow custom exceptions to be handled by the controller + } + } + } diff --git a/src/main/java/com/billpaymentservice/bbps/util/BBPSConstant.java b/src/main/java/com/billpaymentservice/bbps/util/BBPSConstant.java index 24fcdab..11eb29f 100644 --- a/src/main/java/com/billpaymentservice/bbps/util/BBPSConstant.java +++ b/src/main/java/com/billpaymentservice/bbps/util/BBPSConstant.java @@ -42,5 +42,7 @@ public class BBPSConstant { public static final String PAYMENT_URL = "/agent/bills/payment"; public static final String CHECK_TRANSACTION_URL = "/transactions/payment/byTxnId?txnId="; public static final String DISPOSTION_URL = "/disposition"; + + public static final String PLANS_URL = "/plans"; } diff --git a/src/main/java/com/billpaymentservice/bbps/util/Helper.java b/src/main/java/com/billpaymentservice/bbps/util/Helper.java index da8b545..5bd194c 100644 --- a/src/main/java/com/billpaymentservice/bbps/util/Helper.java +++ b/src/main/java/com/billpaymentservice/bbps/util/Helper.java @@ -4,24 +4,24 @@ import java.util.function.Function; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import com.billpaymentservice.bbps.dto.ResponseModel; -import com.billpaymentservice.bbps.dto.request.MerchantRequestModel; -import com.billpaymentservice.bbps.entites.BBPSMerchantValidation; +import com.billpaymentservice.bbps.entites.BBPSMastersData; import com.billpaymentservice.bbps.exception.CustomException; -import com.billpaymentservice.bbps.repository.MerchantRepository; - +import com.billpaymentservice.bbps.repository.BBPSMasterDataRepo; @Component - public class Helper { private static final Logger LOGGER = LoggerFactory.getLogger(Helper.class); - @Autowired - private MerchantRepository merchantRegisterRepo; + private final BBPSMasterDataRepo bbpsMasterDataRepo; + + // Constructor Injection + public Helper(BBPSMasterDataRepo bbpsMasterDataRepo) { + this.bbpsMasterDataRepo = bbpsMasterDataRepo; + } /** * Validates whether the merchant exists and is active. @@ -33,82 +33,119 @@ public class Helper { * * */ - - - - public void startPolling( - T requestObject, // Request object (any type) - Function apiCallFunction, // Function to call API - int intervalSeconds, // gap between two polls - int maxDurationSeconds // total polling time + + public void startPolling(T requestObject, // Request object (any type) + Function apiCallFunction, // Function to call API + int intervalSeconds, // gap between two polls + int maxDurationSeconds // total polling time ) { - new Thread(() -> { - try { - int maxAttempts = maxDurationSeconds / intervalSeconds; + new Thread(() -> { + try { + int maxAttempts = maxDurationSeconds / intervalSeconds; - for (int i = 0; i < maxAttempts; i++) { - LOGGER.info("⏳ Polling attempt {}...", i + 1); + for (int i = 0; i < maxAttempts; i++) { + LOGGER.info("⏳ Polling attempt {}...", i + 1); - ResponseModel response = apiCallFunction.apply(requestObject); - LOGGER.info("📥 Poll response: {}", response); + ResponseModel response = apiCallFunction.apply(requestObject); + LOGGER.info("📥 Poll response: {}", response); - if ("SUCCESS".equalsIgnoreCase(response.getStatus())) { - LOGGER.info("✅ Polling successful, stopping early."); - break; - } + if ("SUCCESS".equalsIgnoreCase(response.getStatus())) { + LOGGER.info("✅ Polling successful, stopping early."); + break; + } - Thread.sleep(intervalSeconds * 1000L); - } - } catch (Exception e) { - LOGGER.error("❌ Error in polling thread: {}", e.getMessage(), e); - } - }).start(); + Thread.sleep(intervalSeconds * 1000L); + } + } catch (Exception e) { + LOGGER.error("❌ Error in polling thread: {}", e.getMessage(), e); + } + }).start(); } - - public boolean isMerchantValidAndActive(MerchantRequestModel requestModel) { - if (requestModel == null || requestModel.getMid() == null) { +// public boolean isMerchantValidAndActive(MerchantRequestModel requestModel) { +// +// if (requestModel == null) { +// LOGGER.warn("MerchantRequestModel or MID is null"); +// throw new CustomException("Invalid request: MID is required"); +// } +// +// // Fetch merchant details +// BBPSMastersData merchantValidation = bbpsMasterDataRepo.findByMid(requestModel.getMid()); +// +// if (merchantValidation == null) { +// LOGGER.warn("Merchant not found for MID: {}", requestModel.getMid()); +// throw new CustomException("Merchant not found"); +// } +// +// if (merchantValidation.getApiKey() == null && merchantValidation.getSecreteKey() == null) { +// +// throw new CustomException("Merchant inactive"); +// } +// +// if (!Boolean.TRUE.equals(merchantValidation.getIsActive())) { +// LOGGER.warn("Merchant inactive for MID: {}", requestModel.getMid()); +// throw new CustomException("Merchant inactive"); +// } +// +// LOGGER.info("Merchant is valid and active for MID: {}", requestModel.getMid()); +// return true; +// } + +// public String validateMerchant(String mid) { +// +// if (mid == null) { +// LOGGER.warn("MerchantRequestModel or MID is null"); +// return "Mid is required"; +// } +// +// // Fetch merchant details +// BBPSMastersData merchantValidation = bbpsMasterDataRepo.findByMid(mid); +// +// if (merchantValidation == null) { +// LOGGER.warn("Merchant not found for MID: {}", mid); +// return "Merchant not found by id"; +// } +// +// if (merchantValidation.getApiKey() == null && merchantValidation.getSecreteKey() == null) { +// LOGGER.warn("Merchant BBPS service is not active MID: {}", mid); +// return "Merchant BBPS Service is not active by mid"; +// } +// +// if (!Boolean.TRUE.equals(merchantValidation.getIsActive())) { +// LOGGER.warn("Merchant inactive for MID: {}", mid); +// return "Merchant is inactive"; +// } +// +// LOGGER.info("Merchant is valid and active for MID: {}", mid); +// return "Valid"; // Success message +// } + + public void validateMerchant(String mid) { + if (mid == null || mid == "") { LOGGER.warn("MerchantRequestModel or MID is null"); - throw new CustomException("Invalid request: MID is required"); + throw new CustomException("Mid is required", "FAILED", BBPSConstant.BADREQUEST, null); } - // Fetch merchant details - BBPSMerchantValidation merchantValidation = merchantRegisterRepo.findByMid(requestModel.getMid()); + BBPSMastersData merchantValidation = bbpsMasterDataRepo.findByMid(mid); if (merchantValidation == null) { - LOGGER.warn("Merchant not found for MID: {}", requestModel.getMid()); - throw new CustomException("Merchant not found"); + LOGGER.warn("Merchant not found for MID: {}", mid); + throw new CustomException("Merchant not found by id", "FAILED", BBPSConstant.BADREQUEST, null); } - if (!Boolean.TRUE.equals(merchantValidation.isActive())) { - LOGGER.warn("Merchant inactive for MID: {}", requestModel.getMid()); - throw new CustomException("Merchant inactive"); + if (merchantValidation.getApiKey() == null && merchantValidation.getSecreteKey() == null) { + 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); } - LOGGER.info("Merchant is valid and active for MID: {}", requestModel.getMid()); - return true; - } - public String validateMerchant(Object requestModel) { + if (!Boolean.TRUE.equals(merchantValidation.getIsActive())) { + LOGGER.warn("Merchant inactive for MID: {}", mid); + throw new CustomException("Merchant is inactive", "FAILED", BBPSConstant.BADREQUEST, null); + } -// if (requestModel == null || requestModel.getMid() == null) { -// LOGGER.warn("MerchantRequestModel or MID is null"); -// return "Invalid request: MID is required"; -// } -// -// // Fetch merchant details -// BBPSMerchantValidation merchant = merchantRegisterRepo.findByMid(requestModel.getMid()); -// -// if (merchant == null) { -// LOGGER.warn("Merchant not found for MID: {}", requestModel.getMid()); -// return "Merchant not found"; -// } -// -// if (!Boolean.TRUE.equals(merchant.isActive())) { -// LOGGER.warn("Merchant inactive for MID: {}", requestModel.getMid()); -// return "Merchant inactive"; -// } -// -// LOGGER.info("Merchant is valid and active for MID: {}", requestModel.getMid()); - return "Valid"; // Success message + LOGGER.info("Merchant is valid and active for MID: {}", mid); + // Agar exception nahi throw hua, merchant valid hai } + } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 1f1c54e..c9da8fd 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -11,7 +11,7 @@ spring.jpa.properties.hibernate.default_schema=public # DataSource -spring.datasource.url=jdbc:postgresql://localhost:5432/TestingDB +spring.datasource.url=jdbc:postgresql://localhost:5432/BBPS spring.datasource.username=postgres spring.datasource.password=UAT@DB_2025 spring.datasource.driver-class-name=org.postgresql.Driver