10-11-25 after conflict

This commit is contained in:
Mohd-Arham
2025-11-10 11:56:29 +05:30
77 changed files with 1600 additions and 572 deletions
@@ -1,16 +1,14 @@
package com.billpaymentservice.bbps.audit; package com.billpaymentservice.bbps.audit;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import org.springframework.data.annotation.CreatedBy; import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy; import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.annotation.LastModifiedDate;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.MappedSuperclass; import jakarta.persistence.MappedSuperclass;
import jakarta.persistence.Temporal; import jakarta.persistence.Temporal;
import jakarta.persistence.TemporalType; import jakarta.persistence.TemporalType;
@@ -1,15 +1,16 @@
package com.billpaymentservice.bbps.config; package com.billpaymentservice.bbps.config;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestClient; import org.springframework.web.client.RestClient;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
@Configuration @Configuration
public class RestClientConfig { public class RestClientConfig {
@@ -3,7 +3,11 @@ package com.billpaymentservice.bbps.controller;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.CrossOrigin;
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.ResponseModel;
import com.billpaymentservice.bbps.dto.request.BillFetchByBillIdRequest; import com.billpaymentservice.bbps.dto.request.BillFetchByBillIdRequest;
@@ -74,7 +74,6 @@ public class MasterDataController {
return ResponseEntity.ok(masterDataService.getCustomerParamByBillerId(customerParamRequest)); return ResponseEntity.ok(masterDataService.getCustomerParamByBillerId(customerParamRequest));
} }
/** /**
* Get All Master Data .The parameter is different from the data we are getting Made By Arham * Get All Master Data .The parameter is different from the data we are getting Made By Arham
* in the MasterRequest * in the MasterRequest
@@ -10,7 +10,6 @@ import org.springframework.web.bind.annotation.RestController;
import com.billpaymentservice.bbps.dto.ResponseModel; import com.billpaymentservice.bbps.dto.ResponseModel;
import com.billpaymentservice.bbps.dto.request.BillPaymentRequest; import com.billpaymentservice.bbps.dto.request.BillPaymentRequest;
import com.billpaymentservice.bbps.dto.request.FetchBillRequest;
import com.billpaymentservice.bbps.dto.request.TransactionStatusRequest; import com.billpaymentservice.bbps.dto.request.TransactionStatusRequest;
import com.billpaymentservice.bbps.service.PaymentService; import com.billpaymentservice.bbps.service.PaymentService;
@@ -9,7 +9,7 @@ import lombok.Setter;
@Setter @Setter
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
public class AdditionalInfoBill { public class AdditionalInfoBillDTO {
private String additionalInfoId; private String additionalInfoId;
private String name; private String name;
private String value; private String value;
@@ -1,8 +1,8 @@
package com.billpaymentservice.bbps.dto; package com.billpaymentservice.bbps.dto;
import jakarta.persistence.*; import java.util.List;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.List;
@Getter @Getter
@Setter @Setter
@@ -1,7 +1,9 @@
package com.billpaymentservice.bbps.dto; package com.billpaymentservice.bbps.dto;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import lombok.Getter; import lombok.Getter;
@@ -1,8 +1,9 @@
package com.billpaymentservice.bbps.dto; package com.billpaymentservice.bbps.dto;
import java.util.List;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.List;
@Getter @Getter
@Setter @Setter
@@ -6,11 +6,13 @@ import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.ToString;
@Getter @Getter
@Setter @Setter
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ToString
public class CustomParamDTO { public class CustomParamDTO {
private String customParamName; private String customParamName;
private String dataType; private String dataType;
@@ -1,11 +1,11 @@
package com.billpaymentservice.bbps.dto; package com.billpaymentservice.bbps.dto;
import java.util.List;
import jakarta.validation.constraints.Min; import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.List;
@Getter @Getter
@Setter @Setter
public class CustomerParamDTO { public class CustomerParamDTO {
@@ -1,10 +1,13 @@
package com.billpaymentservice.bbps.dto; package com.billpaymentservice.bbps.dto;
import java.util.List;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.List; import lombok.ToString;
@Getter @Getter
@Setter @Setter
@ToString
public class CustomerParamGroupsDTO { public class CustomerParamGroupsDTO {
private List<GroupDTO> groups; private List<GroupDTO> groups;
} }
@@ -2,7 +2,6 @@ package com.billpaymentservice.bbps.dto;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString;
@Getter @Getter
@Setter @Setter
@@ -1,8 +1,9 @@
package com.billpaymentservice.bbps.dto; package com.billpaymentservice.bbps.dto;
import java.util.List;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.List;
@Getter @Getter
@Setter @Setter
@@ -1,6 +1,5 @@
package com.billpaymentservice.bbps.dto; package com.billpaymentservice.bbps.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.Min; import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Getter; import lombok.Getter;
@@ -2,7 +2,9 @@ package com.billpaymentservice.bbps.dto;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import jakarta.validation.constraints.*; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -3,6 +3,7 @@ package com.billpaymentservice.bbps.dto;
import java.util.List; import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
@@ -12,10 +13,10 @@ import lombok.Setter;
@Getter @Getter
@Setter @Setter
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public class TransactionDTO { public class TransactionDTO {
@NotBlank private String txnId; @JsonProperty("txnId")
@NotBlank private String bankTxnId;
@NotBlank private String refId; @NotBlank private String refId;
private String txnNpciId; private String txnNpciId;
private String paymentRefId; private String paymentRefId;
@@ -55,12 +56,10 @@ public class TransactionDTO {
private String fundTxnType; private String fundTxnType;
private String reason; private String reason;
private List<String> amountTags; private String amountTags;
private List<String> customerParamsDAOS; private String customerParamsDAOS;
private List<String> paymentInformation; private String paymentInformation;
private List<DeviceBlockTag> deviceBlockTags; private List<DeviceBlockTag> deviceBlockTags;
private List<CustomerParamDAO> customerParamsDAO; private List<CustomerParamDAO> customerParamsDAO;
private String planId; private String planId;
@@ -27,7 +27,6 @@ public abstract class BaseClass {
private String reqId; private String reqId;
private DeviceDetail deviceDetial; private DeviceDetail deviceDetial;
// ✅ 10 User Defined Fields (UDF1–UDF10) // ✅ 10 User Defined Fields (UDF1–UDF10)
private String udf1; private String udf1;
@@ -1,5 +1,6 @@
package com.billpaymentservice.bbps.dto.request; package com.billpaymentservice.bbps.dto.request;
import java.util.List; import java.util.List;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -5,11 +5,13 @@ import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.ToString;
@Getter @Getter
@Setter @Setter
@NoArgsConstructor @NoArgsConstructor
@AllArgsConstructor @AllArgsConstructor
@ToString
public class CustomParamRequest extends BaseClass { public class CustomParamRequest extends BaseClass {
@NotNull @NotNull
@@ -1,5 +1,5 @@
package com.billpaymentservice.bbps.dto.request; package com.billpaymentservice.bbps.dto.request;
public class DispositionRequest extends BaseClass { public class DispositionRequest extends BaseClass {
} }
@@ -1,7 +1,6 @@
package com.billpaymentservice.bbps.dto.request; package com.billpaymentservice.bbps.dto.request;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@Getter @Getter
@@ -2,7 +2,7 @@ package com.billpaymentservice.bbps.dto.response;
import java.util.List; import java.util.List;
import com.billpaymentservice.bbps.dto.AdditionalInfoBill; import com.billpaymentservice.bbps.dto.AdditionalInfoBillDTO;
import com.billpaymentservice.bbps.dto.BillerResponseBill; import com.billpaymentservice.bbps.dto.BillerResponseBill;
import com.billpaymentservice.bbps.dto.CustomerParamDAO; import com.billpaymentservice.bbps.dto.CustomerParamDAO;
import com.billpaymentservice.bbps.dto.GeneralResp; import com.billpaymentservice.bbps.dto.GeneralResp;
@@ -31,7 +31,7 @@ public class BillDataResponse {
private String userId; private String userId;
private BillerResponseBill billerResponse; // nested object private BillerResponseBill billerResponse; // nested object
private List<AdditionalInfoBill> additionalInfo; // array of objects private List<AdditionalInfoBillDTO> additionalInfo; // array of objects
private List<CustomerParamDAO> customerParams; // array of objects private List<CustomerParamDAO> customerParams; // array of objects
private String creationDate; private String creationDate;
@@ -1,6 +1,7 @@
package com.billpaymentservice.bbps.dto.response; package com.billpaymentservice.bbps.dto.response;
import com.billpaymentservice.bbps.dto.GeneralResp; import com.billpaymentservice.bbps.dto.GeneralResp;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
@@ -2,7 +2,6 @@ package com.billpaymentservice.bbps.dto.response;
import com.billpaymentservice.bbps.dto.BillerDTO; import com.billpaymentservice.bbps.dto.BillerDTO;
import com.billpaymentservice.bbps.dto.GeneralResp; import com.billpaymentservice.bbps.dto.GeneralResp;
import com.billpaymentservice.bbps.dto.request.BillerDetailRequest;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
@@ -1,21 +1,22 @@
package com.billpaymentservice.bbps.dto.response; package com.billpaymentservice.bbps.dto.response;
import java.util.List; import java.util.List;
import com.billpaymentservice.bbps.dto.ContactMaster;
import com.billpaymentservice.bbps.dto.CustomParamDTO; import com.billpaymentservice.bbps.dto.CustomParamDTO;
import com.billpaymentservice.bbps.dto.GeneralResp; import com.billpaymentservice.bbps.dto.GeneralResp;
import com.billpaymentservice.bbps.entites.CustomerParam;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import lombok.Setter; import lombok.Setter;
import lombok.ToString;
@Getter @Getter
@Setter @Setter
@AllArgsConstructor @AllArgsConstructor
@NoArgsConstructor @NoArgsConstructor
@ToString
public class CustomParamResp { public class CustomParamResp {
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY) @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private GeneralResp generalResp; private GeneralResp generalResp;
@@ -7,9 +7,11 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString;
@Getter @Getter
@Setter @Setter
@ToString
public class TransactionStatusResponse { public class TransactionStatusResponse {
@JsonProperty("transactionDAO") @JsonProperty("transactionDAO")
@@ -1,8 +1,15 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; import jakarta.persistence.Column;
import jakarta.validation.constraints.*; import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
@@ -0,0 +1,30 @@
package com.billpaymentservice.bbps.entites;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "additional_info_bill")
@Getter
@Setter
public class AdditionalInfoBill {
@Id
@GeneratedValue
private Long id;
private String name;
private String value;
@ManyToOne
@JoinColumn(name = "bill_master_id")
private BillMaster billMaster;
}
@@ -0,0 +1,56 @@
package com.billpaymentservice.bbps.entites;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Table(name = "agent_fund_transfer_Txn_Status")
@NoArgsConstructor
@Getter
@Setter
@AllArgsConstructor
public class AgentFundTransfer {
@Id
@Column(name = "fund_txn_reference_id")
private String fundTxnReferenceId;
@Column(name = "transaction_master_id")
private String TransactionMasterId; //primary key from transaction master
@Column(name = "txn_id")
private String txnId;
@Column(name = "req_id")
private String reqId;
@Column(name = "fund_txn_remarks")
private String fundTxnRemarks;
@Column(name = "fund_txn_date")
private String fundTxnDate;
@Column(name = "fund_txn_amt")
private Double fundTxnAmt;
@Column(name = "fund_utr")
private String fundUTR;
@Column(name = "fund_resp_remarks")
private String fundRespRemarks;
@Column(name = "agent_npci_id")
private String agentNpciId;
@Column(name = "txn_ref_id")
private String txnRefId;
@Column(name = "fund_status")
private String fundStatus;
}
@@ -1,7 +1,12 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; 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.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -1,10 +1,19 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
@Entity @Entity
@Table(name = "amount_option") @Table(name = "amount_option")
@@ -24,7 +24,7 @@ import lombok.Setter;
public class BBPSMastersData extends Auditable<String> { public class BBPSMastersData extends Auditable<String> {
@Id @Id
@GeneratedValue(strategy = GenerationType.AUTO) @GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id") @Column(name = "id")
private Long id; private Long id;
@@ -1,10 +1,5 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import java.time.LocalDateTime;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import com.billpaymentservice.bbps.audit.Auditable; import com.billpaymentservice.bbps.audit.Auditable;
import jakarta.persistence.Column; import jakarta.persistence.Column;
@@ -0,0 +1,26 @@
package com.billpaymentservice.bbps.entites;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "bill_initiate")
public class BillInitiate {
@Id
@Column(name = "req_id")
private String reqId;
@Column(name = "bill_id", nullable = false)
private String billId;
@Column(name = "txn_id")
private String txnId;
}
@@ -0,0 +1,49 @@
package com.billpaymentservice.bbps.entites;
import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
@Entity
@Table(name = "bill_master")
@Builder
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class BillMaster {
@Id
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 actionType;
private String userId;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "biller_response_id")
private BillerResponse billerResponse;
@OneToMany(mappedBy = "billMaster", cascade = CascadeType.ALL)
private List<AdditionalInfoBill> additionalInfo;
@OneToMany(mappedBy = "billMaster", cascade = CascadeType.ALL)
private List<CustomerParamBill> customerParams;
private String creationDate;
private String modifiedDate;
private Long createdEpochDate;
private Long modifiedEpochDate;
// getters and setters
}
@@ -2,7 +2,14 @@ package com.billpaymentservice.bbps.entites;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import jakarta.persistence.*;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -1,14 +1,21 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; import java.util.List;
import jakarta.validation.constraints.*;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.List; import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
@Getter @Getter
@Setter @Setter
@@ -28,8 +35,7 @@ public class BillerDetails {
@NotBlank(message = "Biller name cannot be blank") @NotBlank(message = "Biller name cannot be blank")
private String billerName; private String billerName;
@Column(name = "biller_alias_name", nullable = false) @Column(name = "biller_alias_name")
@NotBlank(message = "Biller alias name cannot be blank")
private String billerAliasName; private String billerAliasName;
@Column(name = "biller_category_name", nullable = false) @Column(name = "biller_category_name", nullable = false)
@@ -43,39 +49,36 @@ public class BillerDetails {
@Column(name = "biller_accepts_adhoc", nullable = false) @Column(name = "biller_accepts_adhoc", nullable = false)
private boolean billerAcceptsAdhoc; private boolean billerAcceptsAdhoc;
@Column(name = "parent_biller", nullable = false) @Column(name = "parent_biller")
private boolean parentBiller; private boolean parentBiller;
@Column(name = "parent_biller_id", nullable = false) @Column(name = "parent_biller_id")
@NotBlank(message = "Parent biller ID cannot be blank")
private String parentBillerId; private String parentBillerId;
@Column(name = "biller_ownership", nullable = false) @Column(name = "biller_ownership")
@NotBlank(message = "Biller ownership is required (PSU or Private)") @NotBlank(message = "Biller ownership is required (PSU or Private)")
private String billerOwnerShp; private String billerOwnerShp;
@Column(name = "biller_coverage", nullable = false) @Column(name = "biller_coverage")
@NotBlank(message = "Biller coverage cannot be blank")
private String billerCoverage; private String billerCoverage;
@Column(name = "fetch_requirement", nullable = false) @Column(name = "fetch_requirement")
@NotBlank(message = "Fetch requirement is mandatory") @NotBlank(message = "Fetch requirement is mandatory")
private String fetchRequirement; private String fetchRequirement;
@Column(name = "payment_amount_exactness", nullable = false) @Column(name = "payment_amount_exactness")
@NotBlank(message = "Payment amount exactness is required") @NotBlank(message = "Payment amount exactness is required")
private String paymentAmountExactness; private String paymentAmountExactness;
@Column(name = "support_bill_validation", nullable = false) @Column(name = "support_bill_validation")
@NotBlank(message = "Support bill validation is required") @NotBlank(message = "Support bill validation is required")
private String supportBillValidation; private String supportBillValidation;
@Column(name = "biller_effctv_from", nullable = false) @Column(name = "biller_effctv_from")
@NotBlank(message = "Effective from date is required") @NotBlank(message = "Effective from date is required")
private String billerEffctvFrom; private String billerEffctvFrom;
@Column(name = "biller_effctv_to", nullable = false) @Column(name = "biller_effctv_to")
@NotBlank(message = "Effective to date is required")
private String billerEffctvTo; private String billerEffctvTo;
@Column(name = "biller_temp_deactivation_start") @Column(name = "biller_temp_deactivation_start")
@@ -84,32 +87,25 @@ public class BillerDetails {
@Column(name = "biller_temp_deactivation_end") @Column(name = "biller_temp_deactivation_end")
private String billerTempDeactivationEnd; private String billerTempDeactivationEnd;
@Column(name = "biller_description", nullable = false, length = 500) @Column(name = "biller_description", length = 500)
@NotBlank(message = "Biller description cannot be blank")
private String billerDescription; private String billerDescription;
@Column(name = "biller_response_type", nullable = false) @Column(name = "biller_response_type")
@NotBlank(message = "Biller response type is required (SINGLE or SELECTIVE)")
private String billerResponseType; private String billerResponseType;
@Column(name = "plan_mdm_requirement", nullable = false) @Column(name = "plan_mdm_requirement")
@NotBlank(message = "Plan MDM requirement cannot be blank")
private String planMDMRequirement; private String planMDMRequirement;
@Column(name = "status", nullable = false) @Column(name = "status")
@NotBlank(message = "Status must be ACTIVE or INACTIVE")
private String status; private String status;
@Column(name = "support_deemed", nullable = false) @Column(name = "support_deemed")
@NotBlank(message = "Support deemed value is required (Yes/No)")
private String supportDeemed; private String supportDeemed;
@Column(name = "support_pending_status", nullable = false) @Column(name = "support_pending_status")
@NotBlank(message = "Support pending status is required (Yes/No)")
private String supportPendingStatus; private String supportPendingStatus;
@Column(name = "biller_time_out", nullable = false) @Column(name = "biller_time_out")
@NotBlank(message = "Biller timeout is required")
private String billerTimeOut; private String billerTimeOut;
@Column(name = "route_url") @Column(name = "route_url")
@@ -151,7 +147,6 @@ public class BillerDetails {
* @OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval = * @OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval =
* true) private List<AdditionalInfo> billerAdditionalInfoPayments; * true) private List<AdditionalInfo> billerAdditionalInfoPayments;
*/ */
@OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval = true) @OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval = true)
private List<InterchangeFeeConf> interchangeFeeConves; private List<InterchangeFeeConf> interchangeFeeConves;
@@ -1,15 +1,17 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import java.util.List; 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.OneToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter @Getter
@Setter @Setter
@@ -17,7 +19,6 @@ import java.util.List;
@ToString @ToString
@Table(name = "biller_plan_response_params") @Table(name = "biller_plan_response_params")
public class BillerPlanResponseParams { public class BillerPlanResponseParams {
@Id @Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // Primary Key private Long id; // Primary Key
@@ -25,7 +26,6 @@ public class BillerPlanResponseParams {
@Column(name = "biller_plan_response_id", nullable = false, unique = true) @Column(name = "biller_plan_response_id", nullable = false, unique = true)
@NotBlank(message = "Biller Plan Response ID cannot be blank") @NotBlank(message = "Biller Plan Response ID cannot be blank")
private String billerPlanResponseId; private String billerPlanResponseId;
// ✅ params list — since it's not a separate table, we can store as JSON or text // ✅ params list — since it's not a separate table, we can store as JSON or text
@Column(name = "params", columnDefinition = "TEXT") @Column(name = "params", columnDefinition = "TEXT")
private String paramsJson; private String paramsJson;
@@ -0,0 +1,58 @@
package com.billpaymentservice.bbps.entites;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Table(name = "biller_response")
@Getter
@Setter
public class BillerResponse {
@Id
@GeneratedValue
private Long id;
@Column(name = "amount")
private String amount;
@Column(name = "bill_date")
private String billDate;
@Column(name = "bill_id")
private String billId;
@Column(name = "bill_number")
private String billNumber;
@Column(name = "bill_period")
private String billPeriod;
@Column(name = "cust_conv_fee")
private String custConvFee;
@Column(name = "cou_cust_conv_fee")
private String couCustConvFee;
@Column(name = "due_date")
private String dueDate;
@Column(name = "customer_name")
private String customerName;
@Column(name = "amount_option")
private Boolean amountOption;
@ManyToOne
@JoinColumn(name = "bill_master_id")
private BillMaster billMaster;
// getters and setters
}
@@ -1,11 +1,21 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.List;
@Getter @Getter
@Setter @Setter
@@ -17,7 +27,7 @@ public class BillerResponseParams {
@Column(name = "biller_response_id", nullable = false, unique = true) @Column(name = "biller_response_id", nullable = false, unique = true)
@NotBlank(message = "Biller Response ID is required") @NotBlank(message = "Biller Response ID is required")
private String billerResponseId; private String billerResponseId;
// 🔗 One-to-One Relationship with BillerDAO // 🔗 One-to-One Relationship with BillerDAO
@OneToOne @OneToOne
@JoinColumn(name = "biller_id", nullable = false) @JoinColumn(name = "biller_id", nullable = false)
@@ -1,12 +1,19 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; 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.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString;
@Getter @Getter
@Setter @Setter
@Entity @Entity
@ToString
@Table(name = "custom_param") @Table(name = "custom_param")
public class CustomParam { public class CustomParam {
@@ -1,16 +1,29 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; import java.util.List;
import jakarta.validation.constraints.*;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString;
import java.util.List;
@Getter @Getter
@Setter @Setter
@Entity @Entity
@Table(name = "customer_param") @Table(name = "customer_param")
@ToString
public class CustomerParam { public class CustomerParam {
@Id @Id
@@ -0,0 +1,31 @@
package com.billpaymentservice.bbps.entites;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "customer_param_bill")
public class CustomerParamBill {
@Id
@GeneratedValue
private Long id;
private String name;
private String value;
private String type;
@ManyToOne
@JoinColumn(name = "bill_master_id")
private BillMaster billMaster;
// getters and setters
}
@@ -1,7 +1,11 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -1,12 +1,22 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToMany;
import jakarta.persistence.OneToOne;
import jakarta.persistence.Table;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import java.util.List;
@Getter @Getter
@Setter @Setter
@Entity @Entity
@@ -0,0 +1,33 @@
package com.billpaymentservice.bbps.entites;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "customer_params_transaction")
public class CustomerParamTransaction {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String paramsId;
private String name;
private String value;
private String type;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "txn_id", referencedColumnName = "bank_txn_id")
private TransactionMaster transactionMaster;
}
@@ -0,0 +1,38 @@
package com.billpaymentservice.bbps.entites;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter;
import lombok.Setter;
@Entity
@Getter
@Setter
@Table(name = "device_block_tag")
public class DeviceBlockTag {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "tag_id")
private String tagId;
@Column(name = "value")
private String value;
// ✅ ManyToOne relation back to TransactionMaster
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "txn_id", referencedColumnName = "bank_txn_id")
private TransactionMaster transactionMaster;
}
@@ -1,7 +1,9 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
@@ -1,12 +1,24 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; import java.util.List;
import jakarta.persistence.CascadeType;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import java.util.List;
@Getter @Getter
@Setter @Setter
@Entity @Entity
@@ -2,14 +2,20 @@ package com.billpaymentservice.bbps.entites;
import java.util.List; 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.ManyToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter @Getter
@Setter @Setter
@@ -2,16 +2,20 @@ package com.billpaymentservice.bbps.entites;
import java.util.List; import java.util.List;
import jakarta.persistence.CollectionTable;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import jakarta.persistence.*;
import jakarta.validation.constraints.*;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Getter @Getter
@Setter @Setter
@Entity @Entity
@@ -1,6 +1,13 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; 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.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -1,13 +1,18 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; import jakarta.persistence.Column;
import jakarta.validation.constraints.*; import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotBlank;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
import com.fasterxml.jackson.annotation.JsonProperty;
@Getter @Getter
@Setter @Setter
@Entity @Entity
@@ -0,0 +1,31 @@
package com.billpaymentservice.bbps.entites;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "payment_initiate")
public class PaymentInitiate {
@Id
@Column(name = "req_id")
private String reqId;
@Column(name = "bank_txn_Id", nullable = false)
private String bankTxnId;
@Column(name = "txn_id")
private String txnId;
@Column(name = "status")
private String status;
}
@@ -5,8 +5,6 @@ package com.billpaymentservice.bbps.entites;
import jakarta.persistence.Column; import jakarta.persistence.Column;
import jakarta.persistence.Entity; import jakarta.persistence.Entity;
import jakarta.persistence.FetchType; import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn; import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne; import jakarta.persistence.ManyToOne;
@@ -24,11 +22,9 @@ import lombok.ToString;
@Table(name = "biller_payment_modes") @Table(name = "biller_payment_modes")
@ToString @ToString
public class PaymentMode { public class PaymentMode {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) @Id //
private Long id;
@Column(name = "payment_model_limit_id", unique = true, length = 50) @Column(name = "payment_model_limit_id", unique = true, length = 50)
@NotBlank(message = "Payment model limit ID cannot be blank") @NotBlank(message = "Payment model limit ID cannot be blank")
private String paymentModelLimitId; private String paymentModelLimitId;
@@ -1,6 +1,14 @@
package com.billpaymentservice.bbps.entites; package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*; import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.ManyToOne;
import jakarta.persistence.Table;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
@@ -0,0 +1,163 @@
package com.billpaymentservice.bbps.entites;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.CascadeType;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.ToString;
@Getter
@Setter
@Entity
@Table(name = "transaction_master")
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class TransactionMaster {
// 👇 JSON me "txn_id" aayega, ye DB me bank_txn_id column me save hoga
@Id
@JsonProperty("txn_id")
@Column(name = "bank_txn_id", nullable = false, unique = true)
private String bankTxnId;
// 👇 Apna internal transaction id, manually generate or system ke through
@Column(name = "txn_id")
private String txnId;
@Column(name = "req_id")
private String reqId;
@Column(name = "ref_id")
private String refId;
@Column(name = "txn_npci_id")
private String txnNpciId;
@Column(name = "payment_ref_id")
private String paymentRefId;
@Column(name = "remitter_name")
private String remitterName;
@Column(name = "order_id")
private String orderId;
@Column(name = "bill_id")
private String billId;
@Column(name = "user_type")
private String userType;
@Column(name = "user_id")
private String userId;
@Column(name = "txn_amount")
private Double txnAmount;
@Column(name = "total_txn_amount")
private Double totalTxnAmount;
@Column(name = "biller_id")
private String billerId;
@Column(name = "biller_category")
private String billerCategory;
@Column(name = "biller_name")
private String billerName;
@Column(name = "client_req_id")
private String clientReqId;
@Column(name = "off_us_pay")
private String offUsPay;
@Column(name = "split_pay")
private String splitPay;
@Column(name = "quick_pay")
private String quickPay;
@Column(name = "payment_mode")
private String paymentMode;
@Column(name = "agent_payment_information", columnDefinition = "TEXT")
private String agentPaymentInformation;
@Column(name = "cust_conv_fee")
private Double custConvFee;
@Column(name = "currency")
private String currency;
@Column(name = "status")
private String status;
@Column(name = "requested_ip")
private String requestedIp;
@Column(name = "customer_mob_no")
private String customerMobNo;
@Column(name = "mac_address")
private String macAddress;
@Column(name = "split_pay_amount")
private Double splitPayAmount;
@Column(name = "cou_cust_conv_fee")
private Double couCustConvFee;
@Column(name = "settlement_verification")
private Boolean settlementVerification;
@Column(name = "fund_txn_type")
private String fundTxnType;
@Column(name = "reason", columnDefinition = "TEXT")
private String reason;
@Column(name = "amount_tags", columnDefinition = "TEXT")
private String amountTags;
@Column(name = "payment_information", columnDefinition = "TEXT")
private String paymentInformation;
// ✅ Relation with DeviceBlockTagEntity
@OneToMany(mappedBy = "transactionMaster", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<DeviceBlockTag> deviceBlockTags;
// ✅ Relation with CustomerParamEntity
@OneToMany(mappedBy = "transactionMaster", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<CustomerParamTransaction> customerParams;
@Column(name = "plan_id")
private String planId;
@Column(name = "plan_type")
private String planType;
@Column(name = "creation_date")
private String creationDate;
@Column(name = "modified_date")
private String modifiedDate;
@Column(name = "created_epoch_date")
private Long createdEpochDate;
@Column(name = "modified_epoch_date")
private Long modifiedEpochDate;
}
@@ -1,66 +0,0 @@
package com.billpaymentservice.bbps.entites;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
import java.util.List;
@Entity
@Getter
@Setter
@Table(name = "transaction_status")
public class TransactionStatus {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String txnId;
@Column(nullable = false)
private String refId;
private String txnNpciId;
private String orderId;
private String billId;
private String userType;
private String userId;
private Double txnAmount;
private Double totalTxnAmount;
private String billerId;
private String billerCategory;
private String billerName;
private String clientReqId;
private String offUsPay;
private String splitPay;
private String quickPay;
private String paymentMode;
private Double 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 fundTxnType;
private String reason;
private String planId;
private String planType;
private LocalDateTime creationDate;
private LocalDateTime modifiedDate;
private Long createdEpochDate;
private Long modifiedEpochDate;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "fund_transfer_id")
private AgentFundTransferEntity agentFundTransfer;
@OneToMany(cascade = CascadeType.ALL)
@JoinColumn(name = "transaction_id")
private List<CustomerParamDAO> customerParamsDAO;
}
@@ -1,61 +1,57 @@
package com.billpaymentservice.bbps.exception; package com.billpaymentservice.bbps.exception;
import org.springframework.http.HttpStatus; import java.util.*;
import org.springframework.http.ResponseEntity; import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.*;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.ExceptionHandler;
import com.billpaymentservice.bbps.dto.ResponseModel; import com.billpaymentservice.bbps.dto.ResponseModel;
import java.util.HashMap;
import java.util.Map;
@ControllerAdvice @ControllerAdvice
public class GlobalExceptionHandler { public class GlobalExceptionHandler {
// ✅ Handle CustomException private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(CustomException.class)
public ResponseEntity<ResponseModel<?>> handleCustomException(CustomException ex) {
return new ResponseEntity<>(ex.getResponseModel(), HttpStatus.BAD_REQUEST);
}
// ✅ Handle validation errors
@ExceptionHandler(MethodArgumentNotValidException.class) @ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ResponseModel<?>> handleValidationExceptions(MethodArgumentNotValidException ex) { public ResponseEntity<ResponseModel<?>> handleValidation(MethodArgumentNotValidException ex) {
List<Map<String, String>> fieldErrors = ex.getBindingResult().getFieldErrors()
.stream()
.map(fe -> Map.of("field", fe.getField(), "message", fe.getDefaultMessage()))
.collect(Collectors.toList());
Map<String, String> errors = new HashMap<>(); logger.warn("Validation failed: {}", fieldErrors);
ResponseModel<List<Map<String, String>>> resp = new ResponseModel<>(
ex.getBindingResult().getFieldErrors().forEach(error -> { "Validation failed for request",
errors.put(error.getField(), error.getDefaultMessage()); "FAILED",
}); HttpStatus.BAD_REQUEST.value(),
null
ResponseModel<?> response = new ResponseModel<>(
"Validation Failed",
"FAILED",
HttpStatus.BAD_REQUEST.value(),
errors
); );
// put validation errors into data or duplicate field in ResponseModel as required
resp.setData(fieldErrors);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resp);
}
return new ResponseEntity<>(response, HttpStatus.BAD_REQUEST); @ExceptionHandler(AppException.class)
public ResponseEntity<ResponseModel<?>> handleAppException(AppException ex) {
logger.warn("AppException: status={}, message={}", ex.getStatus(), ex.getMessage());
ResponseModel<?> resp = new ResponseModel<>(ex.getMessage(), ex.getStatus(), ex.getStatusCode(), ex.getData());
return ResponseEntity.status(HttpStatus.valueOf(ex.getStatusCode())).body(resp);
} }
// ✅ NEW: Handle ALL other exceptions (Generic Handler)
@ExceptionHandler(Exception.class) @ExceptionHandler(Exception.class)
public ResponseEntity<ResponseModel<?>> handleAllExceptions(Exception ex) { public ResponseEntity<ResponseModel<?>> handleAll(Exception ex) {
logger.error("Unhandled exception", ex);
// ✅ Internal logging (tumhare system ko pata chale)
System.err.println("INTERNAL SERVER ERROR: " + ex.getMessage());
ex.printStackTrace(); // Stack trace for debugging
// ✅ Client ko generic message
ResponseModel<?> response = new ResponseModel<>( ResponseModel<?> response = new ResponseModel<>(
"Service temporarily unavailable. Please try again later.", "Service temporarily unavailable. Please try again later.",
"FAILED", "FAILED",
HttpStatus.INTERNAL_SERVER_ERROR.value(), HttpStatus.INTERNAL_SERVER_ERROR.value(),
null null
); );
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
return new ResponseEntity<>(response, HttpStatus.INTERNAL_SERVER_ERROR);
} }
} }
@@ -0,0 +1,9 @@
package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.billpaymentservice.bbps.entites.AgentFundTransfer;
public interface AgentFundTransferRepository extends JpaRepository<AgentFundTransfer, String> {
}
@@ -1,7 +1,6 @@
package com.billpaymentservice.bbps.repository; package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import org.springframework.web.servlet.function.ServerRequest.Headers;
import com.billpaymentservice.bbps.entites.BharatConnectMaster; import com.billpaymentservice.bbps.entites.BharatConnectMaster;
@@ -0,0 +1,11 @@
package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.billpaymentservice.bbps.entites.BillInitiate;
@Repository
public interface BillInitateRepository extends JpaRepository<BillInitiate, String> {
}
@@ -0,0 +1,9 @@
package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.billpaymentservice.bbps.entites.BillMaster;
public interface BillMasterRepository extends JpaRepository<BillMaster, String> {
}
@@ -1,15 +1,16 @@
package com.billpaymentservice.bbps.repository; package com.billpaymentservice.bbps.repository;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import com.billpaymentservice.bbps.entites.BillerDetails; import com.billpaymentservice.bbps.entites.BillerDetails;
import java.util.List;
@Repository @Repository
public interface BillerDataRepository extends JpaRepository<BillerDetails, String> { public interface BillerDataRepository extends JpaRepository<BillerDetails, String> {
Optional<BillerDetails> findByBillerId(String billerId);
} }
@@ -0,0 +1,9 @@
package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.billpaymentservice.bbps.entites.CustomParam;
public interface CustomParamRepository extends JpaRepository<CustomParam, Long> {
}
@@ -0,0 +1,9 @@
package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.billpaymentservice.bbps.entites.PaymentInitiate;
public interface PaymentIntiateRepository extends JpaRepository<PaymentInitiate, String> {
}
@@ -0,0 +1,9 @@
package com.billpaymentservice.bbps.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.billpaymentservice.bbps.entites.TransactionMaster;
public interface TransactionMasterRepository extends JpaRepository<TransactionMaster, String> {
}
@@ -7,11 +7,8 @@ import com.billpaymentservice.bbps.dto.request.CustomParamRequest;
import com.billpaymentservice.bbps.dto.request.DispositionRequest; import com.billpaymentservice.bbps.dto.request.DispositionRequest;
import com.billpaymentservice.bbps.dto.request.MasterCategoryRequest; import com.billpaymentservice.bbps.dto.request.MasterCategoryRequest;
import com.billpaymentservice.bbps.dto.request.MasterRequest; import com.billpaymentservice.bbps.dto.request.MasterRequest;
import com.billpaymentservice.bbps.dto.request.MerchantRequestModel;
import com.billpaymentservice.bbps.dto.request.PlanRequest; import com.billpaymentservice.bbps.dto.request.PlanRequest;
import jakarta.servlet.http.HttpServletRequest;
public interface MasterDataService { public interface MasterDataService {
public ResponseModel getBillerByBillerId(BillerDetailRequest billerDetailRequest); public ResponseModel getBillerByBillerId(BillerDetailRequest billerDetailRequest);
@@ -2,7 +2,6 @@ package com.billpaymentservice.bbps.service;
import com.billpaymentservice.bbps.dto.ResponseModel; import com.billpaymentservice.bbps.dto.ResponseModel;
import com.billpaymentservice.bbps.dto.request.BillPaymentRequest; import com.billpaymentservice.bbps.dto.request.BillPaymentRequest;
import com.billpaymentservice.bbps.dto.request.FetchBillRequest;
import com.billpaymentservice.bbps.dto.request.TransactionStatusRequest; import com.billpaymentservice.bbps.dto.request.TransactionStatusRequest;
public interface PaymentService { public interface PaymentService {
@@ -1,8 +1,9 @@
package com.billpaymentservice.bbps.serviceImpl; package com.billpaymentservice.bbps.serviceImpl;
import java.time.LocalDateTime;
import java.util.Map; import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@@ -18,10 +19,14 @@ import com.billpaymentservice.bbps.dto.response.BillDataResponse;
import com.billpaymentservice.bbps.dto.response.FetchBillResponse; import com.billpaymentservice.bbps.dto.response.FetchBillResponse;
import com.billpaymentservice.bbps.dto.response.FetchBillValidatestResponse; import com.billpaymentservice.bbps.dto.response.FetchBillValidatestResponse;
import com.billpaymentservice.bbps.entites.BharatConnectMaster; import com.billpaymentservice.bbps.entites.BharatConnectMaster;
import com.billpaymentservice.bbps.entites.BillInitiate;
import com.billpaymentservice.bbps.entites.BillMaster;
import com.billpaymentservice.bbps.entites.InboundTraceLog; import com.billpaymentservice.bbps.entites.InboundTraceLog;
import com.billpaymentservice.bbps.entites.OutboundTraceLog; import com.billpaymentservice.bbps.entites.OutboundTraceLog;
import com.billpaymentservice.bbps.exception.CustomException; import com.billpaymentservice.bbps.exception.CustomException;
import com.billpaymentservice.bbps.repository.BharatConnectMasterRepository; import com.billpaymentservice.bbps.repository.BharatConnectMasterRepository;
import com.billpaymentservice.bbps.repository.BillInitateRepository;
import com.billpaymentservice.bbps.repository.BillMasterRepository;
import com.billpaymentservice.bbps.repository.InboundTraceLogRepository; import com.billpaymentservice.bbps.repository.InboundTraceLogRepository;
import com.billpaymentservice.bbps.repository.OutboundTraceLogRepository; import com.billpaymentservice.bbps.repository.OutboundTraceLogRepository;
import com.billpaymentservice.bbps.service.AgentService; import com.billpaymentservice.bbps.service.AgentService;
@@ -36,7 +41,6 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Service @Service
@Slf4j
public class AgentServiceImpl implements AgentService { public class AgentServiceImpl implements AgentService {
@Value("${agent.data.url}") @Value("${agent.data.url}")
@@ -47,24 +51,32 @@ public class AgentServiceImpl implements AgentService {
private final Helper helper; private final Helper helper;
private final BharatConnectMasterRepository beneficiaryDetailsRepository; private final BharatConnectMasterRepository beneficiaryDetailsRepository;
private final BillerMapperHelper mapperHelper; private final BillerMapperHelper mapperHelper;
private final BillMasterRepository billMasterRepository;
private final BillInitateRepository billIntiateRepository;
private static final Logger LOGGER = LoggerFactory.getLogger(AgentServiceImpl.class);
public AgentServiceImpl(RestClient restClient, HttpService httpService, Helper helper, public AgentServiceImpl(RestClient restClient, HttpService httpService, Helper helper,
BharatConnectMasterRepository beneficiaryDetailsRepository, BharatConnectMasterRepository beneficiaryDetailsRepository,
InboundTraceLogRepository inboundTraceLogRepository, OutboundTraceLogRepository outboundTraceLogRepository, InboundTraceLogRepository inboundTraceLogRepository, OutboundTraceLogRepository outboundTraceLogRepository,
BillMasterRepository billMasterRepository, BillInitateRepository billIntiateRepository,
BillerMapperHelper mapperHelper) { BillerMapperHelper mapperHelper) {
this.restClient = restClient; this.restClient = restClient;
this.httpService = httpService; this.httpService = httpService;
this.helper = helper; this.helper = helper;
this.beneficiaryDetailsRepository = beneficiaryDetailsRepository; this.beneficiaryDetailsRepository = beneficiaryDetailsRepository;
this.billMasterRepository = billMasterRepository;
this.billIntiateRepository = billIntiateRepository;
this.mapperHelper = mapperHelper; this.mapperHelper = mapperHelper;
} }
@Override @Override
public ResponseModel initiateBillFetch(FetchBillRequest fetchBillRequest) { public ResponseModel initiateBillFetch(FetchBillRequest fetchBillRequest) {
LOGGER.info("Initiating bill fetch for request ID: {} and MID", fetchBillRequest.getReqId(),
fetchBillRequest.getMid());
String apiName = "InitiateBillFetch"; String apiName = "InitiateBillFetch";
String txnId = helper.generateTxnId(15); String txnId = helper.generateTxnId(15);
String requestId = fetchBillRequest.getReqId(); String requestId = fetchBillRequest.getReqId();
String url = agentDtaUrl + BBPSConstant.BILL_FETCH_INTI; String fullUrl = agentDtaUrl + BBPSConstant.BILL_FETCH_INTI;
helper.validateMerchant(fetchBillRequest.getMid()); helper.validateMerchant(fetchBillRequest.getMid());
@@ -82,60 +94,75 @@ public class AgentServiceImpl implements AgentService {
// ✅ Create inbound & outbound logs // ✅ Create inbound & outbound logs
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnId, apiName, fetchBillRequest.getMid(), InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnId, apiName, fetchBillRequest.getMid(),
"POST", requestJson); "POST", requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, url, "POST", requestJson); OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, fullUrl, "POST",
requestJson);
LOGGER.debug("Outbound log created successfully for txnId: {} and reqId: {}", txnId, requestId);
try { try {
Map<String, String> responseMap = httpService.postRequest(url, requestJson, headers); LOGGER.info("Calling external API: {}", fullUrl);
Map<String, String> responseMap = httpService.postRequest(fullUrl, requestJson, headers);
String responseData = responseMap.get("data"); String responseData = responseMap.get("data");
log.info("📦 Bill Fetch API Response: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData); helper.updateOutboundLogResponse(outboundLog, responseData);
LOGGER.debug("Response received from BBPS: {}", responseData);
if (responseData == null || responseData.isEmpty()) {
helper.updateInboundLogFailure(inboundLog, "Empty response from BBPS", "FAILED");
throw new CustomException("Empty response from BBPS server");
}
Map<String, Object> dataMap = objectMapper.readValue(responseData, Map<String, Object> dataMap = objectMapper.readValue(responseData,
new TypeReference<Map<String, Object>>() { new TypeReference<Map<String, Object>>() {
}); });
if (!dataMap.containsKey("genericResponse")) { if (!dataMap.containsKey("genericResponse")) {
helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_STRUCTURE"); helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE");
throw new CustomException("Invalid response structure from BBPS"); LOGGER.warn("Invalid response received for txnId: {}", txnId);
throw new CustomException(String.valueOf(dataMap.get("message")), String.valueOf(dataMap.get("status")),
Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
String.valueOf(dataMap.get("remarks")));
} }
BillMaster billMaster = new BillMaster();
billMaster.setBillId((String) dataMap.get("billId"));
billMaster.setReqId(fetchBillRequest.getReqId());
billMaster.setTxnId(txnId);
billMasterRepository.save(billMaster);
LOGGER.info("BillMaster saved for billId: {}", billMaster.getBillId());
FetchBillResponse fetchBillResponse = objectMapper.convertValue(dataMap, FetchBillResponse.class); FetchBillResponse fetchBillResponse = objectMapper.convertValue(dataMap, FetchBillResponse.class);
GeneralResp generalResponse = fetchBillResponse.getGenericResponse(); GeneralResp generalResponse = fetchBillResponse.getGenericResponse();
helper.updateInboundLogSuccess(inboundLog, responseData, generalResponse.getStatus()); helper.updateInboundLogSuccess(inboundLog, responseData, generalResponse.getStatus());
// ✅ Directly call fetchBillById (no polling) BillInitiate billInitiate = new BillInitiate();
billInitiate.setBillId((String) dataMap.get("billId"));
billInitiate.setReqId(fetchBillRequest.getReqId());
billInitiate.setTxnId(txnId);
billIntiateRepository.save(billInitiate);
LOGGER.info("BillInitiate entry saved for billId: {}", billInitiate.getBillId());
BillFetchByBillIdRequest billFetchByBillIdRequest = new BillFetchByBillIdRequest(); BillFetchByBillIdRequest billFetchByBillIdRequest = new BillFetchByBillIdRequest();
billFetchByBillIdRequest.setBillId(fetchBillResponse.getBillId()); billFetchByBillIdRequest.setBillId(fetchBillResponse.getBillId());
billFetchByBillIdRequest.setMid(fetchBillRequest.getMid()); billFetchByBillIdRequest.setMid(fetchBillRequest.getMid());
billFetchByBillIdRequest.setReqId(requestId); billFetchByBillIdRequest.setReqId(requestId);
LOGGER.info("Waiting for 2 seconds before fetching bill by ID...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LOGGER.warn("Thread interrupted during delay: {}", e.getMessage());
}
LOGGER.info("Calling internal method Fetching bill by ID: {}", billFetchByBillIdRequest.getBillId());
return fetchBillById(billFetchByBillIdRequest, inboundLog); return fetchBillById(billFetchByBillIdRequest, inboundLog);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("❌ JSON Parsing Error: {}", e.getMessage()); LOGGER.error("JSON Parsing Error: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API"); throw new CustomException("Invalid JSON received from API");
} catch (CustomException ce) {
throw ce;
} catch (Exception e) {
log.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "EXCEPTION");
throw new CustomException("Bill Fetch initiation failed: " + e.getMessage());
} }
} }
public ResponseModel fetchBillById(BillFetchByBillIdRequest billFetchByBillIdRequest, InboundTraceLog inboundLog) { public ResponseModel fetchBillById(BillFetchByBillIdRequest billFetchByBillIdRequest, InboundTraceLog inboundLog) {
LOGGER.info("Fetching bill by BILLID for request ID={} and MID={}", billFetchByBillIdRequest.getReqId(),
billFetchByBillIdRequest.getMid());
String apiName = "FetchBillById"; String apiName = "FetchBillById";
String txnId = helper.generateTxnId(15); String txnId = helper.generateTxnId(15);
String requestId = billFetchByBillIdRequest.getReqId(); String reqId = billFetchByBillIdRequest.getReqId();
String billId = billFetchByBillIdRequest.getBillId(); String billId = billFetchByBillIdRequest.getBillId();
String url = agentDtaUrl + BBPSConstant.BILL_FETCH_BY_ID + "1ced7566-1add-4e01-9ed6-04cd67ac9684"; String fullUrl = agentDtaUrl + BBPSConstant.BILL_FETCH_BY_ID + "1ced7566-1add-4e01-9ed6-04cd67ac9684";
helper.validateMerchant(billFetchByBillIdRequest.getMid()); helper.validateMerchant(billFetchByBillIdRequest.getMid());
@@ -147,127 +174,101 @@ public class AgentServiceImpl implements AgentService {
headers.setContentType(MediaType.APPLICATION_JSON); headers.setContentType(MediaType.APPLICATION_JSON);
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, url, "GET", null); OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, reqId, apiName, fullUrl, "GET", null);
LOGGER.debug("Outbound log created successfully for FetchBillById: {}", fullUrl);
// ✅ Loop setup try {
long startTime = System.currentTimeMillis(); LOGGER.info("Calling external API: {}", fullUrl);
long maxWaitTimeMs = 40000; // 40 seconds Map<String, String> responseMap = httpService.getRequest(fullUrl, headers);
long intervalMs = 5000; // 5 seconds String responseData = responseMap.get("data");
LOGGER.info("Bill FetchById Response: {}", responseData);
while (true) { helper.updateOutboundLogResponse(outboundLog, responseData);
try {
Map<String, String> responseMap = httpService.getRequest(url, headers);
String responseData = responseMap.get("data");
log.info("📦 Bill FetchById Response: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData); Map<String, Object> dataMap = objectMapper.readValue(responseData,
new TypeReference<Map<String, Object>>() {
});
Map<String, Object> dataMap = objectMapper.readValue(responseData, if (!dataMap.containsKey("genericResponse")) {
new TypeReference<Map<String, Object>>() { helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE");
}); LOGGER.warn("Invalid response structure for txnId: {}", txnId);
throw new CustomException(String.valueOf(dataMap.get("message")), String.valueOf(dataMap.get("status")),
if (!dataMap.containsKey("genericResponse")) { Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE"); String.valueOf(dataMap.get("remarks")));
throw new CustomException(String.valueOf(dataMap.get("message")),
String.valueOf(dataMap.get("status")),
Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
String.valueOf(dataMap.get("remarks")));
}
BillDataResponse responseWrapper = objectMapper.convertValue(dataMap, BillDataResponse.class);
GeneralResp generalResp = responseWrapper.getGenericResponse();
String status = generalResp.getStatus();
log.info("📡 Current Bill Status: {}", status);
// ✅ Check for "INPROGRESS" or pending state
if ("INPROGRESS".equalsIgnoreCase(status)) {
if (System.currentTimeMillis() - startTime > maxWaitTimeMs) {
helper.updateInboundLogFailure(inboundLog, "Timeout after 40 seconds", "FAILED");
throw new CustomException("Timeout waiting for bill fetch completion", "FAILED", 408,
"Bill fetch still in progress");
}
Thread.sleep(intervalMs);
continue; // retry again
}
// ✅ Final successful response
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return new ResponseModel(generalResp.getMessage(), generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()), responseWrapper);
} catch (JsonProcessingException e) {
log.error("Error parsing BillById JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "INTERRUPTED");
throw new CustomException("Thread interrupted during bill status check");
} catch (CustomException ce) {
throw ce;
} catch (Exception e) {
log.error("❌ Exception in fetchBillById(): {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "EXCEPTION");
throw new CustomException("Bill Fetch by ID failed: " + e.getMessage());
} }
BillDataResponse responseWrapper = objectMapper.convertValue(dataMap, BillDataResponse.class);
GeneralResp generalResp = responseWrapper.getGenericResponse();
String status = generalResp.getStatus();
LOGGER.info("Current Bill Status: {}", status);
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
helper.saveOrUpdateBillerData(responseWrapper, billFetchByBillIdRequest);
LOGGER.info("Bill data saved successfully for billId: {}", billId);
return new ResponseModel(generalResp.getMessage(), generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()), responseWrapper);
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing BillById JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} }
} }
@Override @Override
public ResponseModel fetchBillById(BillFetchByBillIdRequest billFetchByBillIdRequest) { public ResponseModel fetchBillById(BillFetchByBillIdRequest billFetchByBillIdRequest) {
String apiName = "FetchBillById";
String txnId = helper.generateTxnId(15);
String reqId = billFetchByBillIdRequest.getReqId();
String billId = billFetchByBillIdRequest.getBillId();
String fullUrl = agentDtaUrl + BBPSConstant.BILL_FETCH_BY_ID + "1ced7566-1add-4e01-9ed6-04cd67ac9684";
LOGGER.info("Initiating {} API for billId={} and reqId={}", apiName, billId, reqId);
try { try {
helper.validateMerchant(billFetchByBillIdRequest.getMid()); helper.validateMerchant(billFetchByBillIdRequest.getMid());
LOGGER.debug("Merchant validated successfully for MID={}", billFetchByBillIdRequest.getMid());
String billId = billFetchByBillIdRequest.getBillId();
String fullUrl = agentDtaUrl + BBPSConstant.BILL_FETCH_BY_ID + billId;
System.out.print(fullUrl);
BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001");
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.set("x-digiledge-key", headersData.getXDigiledgeKey()); headers.set("x-digiledge-key", headersData.getXDigiledgeKey());
headers.set("agentId", headersData.getAgentId()); headers.set("agentId", headersData.getAgentId());
headers.set("tenantId", headersData.getTenantId()); headers.set("tenantId", headersData.getTenantId());
headers.setContentType(MediaType.APPLICATION_JSON); headers.setContentType(MediaType.APPLICATION_JSON);
LOGGER.info("Calling external BBPS API for FetchBillById, URL={}", fullUrl);
Map<String, String> responseMap = httpService.getRequest(fullUrl, headers); Map<String, String> responseMap = httpService.getRequest(fullUrl, headers);
String responseData = responseMap.get("data"); String responseData = responseMap.get("data");
log.info("data is :{}", responseData); LOGGER.info("Response received from BBPS for billId={} : {}", billId, responseData);
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
Map<String, Object> dataMap = objectMapper.readValue(responseData, Map<String, Object> dataMap = objectMapper.readValue(responseData,
new TypeReference<Map<String, Object>>() { new TypeReference<Map<String, Object>>() {
}); });
if (!dataMap.containsKey("genericResponse")) { if (!dataMap.containsKey("genericResponse")) {
LOGGER.warn("Invalid response structure received for billId={} | Response={}", billId, responseData);
throw new CustomException(String.valueOf(dataMap.get("message")), // message throw new CustomException(String.valueOf(dataMap.get("message")), // message
String.valueOf(dataMap.get("status")), // status String.valueOf(dataMap.get("status")), // status
Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), // statusCode (int) Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), // statusCode
String.valueOf(dataMap.get("remarks"))); String.valueOf(dataMap.get("remarks")));
} }
BillDataResponse responseWrapper = objectMapper.convertValue(dataMap, BillDataResponse.class); BillDataResponse responseWrapper = objectMapper.convertValue(dataMap, BillDataResponse.class);
GeneralResp generalResp = responseWrapper.getGenericResponse(); GeneralResp generalResp = responseWrapper.getGenericResponse();
ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(), ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()), responseWrapper); Integer.parseInt(generalResp.getStatusCode()), responseWrapper);
helper.saveOrUpdateBillerData(responseWrapper, billFetchByBillIdRequest);
LOGGER.info("Bill data saved successfully for billId={} | Status={}", billId, generalResp.getStatus());
return responseModel; return responseModel;
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Error parsing responseData JSON: {}", e.getMessage()); LOGGER.error("Error parsing responseData JSON for billId={} : {}", billId, e.getMessage(), e);
throw new CustomException("Invalid JSON received from API"); 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
} }
} }
@Override @Override
@@ -306,7 +307,7 @@ public class AgentServiceImpl implements AgentService {
Map<String, String> responseMap = httpService.postRequest(url, json, headers); Map<String, String> responseMap = httpService.postRequest(url, json, headers);
String responseData = responseMap.get("data"); String responseData = responseMap.get("data");
log.info("📦 Bill Fetch API Response: {}", responseData); LOGGER.info("📦 Bill Fetch API Response: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData); helper.updateOutboundLogResponse(outboundLog, responseData);
if (responseData == null || responseData.isEmpty()) { if (responseData == null || responseData.isEmpty()) {
@@ -334,10 +335,10 @@ public class AgentServiceImpl implements AgentService {
Integer.parseInt(generalResponse.getStatusCode()), fetchBillResponse); Integer.parseInt(generalResponse.getStatusCode()), fetchBillResponse);
} catch (CustomException ex) { } catch (CustomException ex) {
log.warn("Merchant validation failed: {}", ex.getMessage()); LOGGER.warn("Merchant validation failed: {}", ex.getMessage());
return ex.getResponseModel(); return ex.getResponseModel();
} catch (Exception e) { } catch (Exception e) {
log.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e); LOGGER.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e);
responseModel.setStatus("500"); responseModel.setStatus("500");
responseModel.setMessage("Exception occurred"); responseModel.setMessage("Exception occurred");
responseModel.setData(e.getMessage()); responseModel.setData(e.getMessage());
@@ -371,13 +372,13 @@ public class AgentServiceImpl implements AgentService {
String json = objectMapper.writeValueAsString(billRequest); String json = objectMapper.writeValueAsString(billRequest);
String url = agentDtaUrl + BBPSConstant.BILL_ID_URL + billRequest.getBillId(); String url = agentDtaUrl + BBPSConstant.BILL_ID_URL + billRequest.getBillId();
log.info("Full URL" + url); LOGGER.info("Full URL" + url);
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
Map<String, String> responseMap = httpService.getRequest(url, headers); Map<String, String> responseMap = httpService.getRequest(url, headers);
String responseData = responseMap.get("data"); String responseData = responseMap.get("data");
log.info("📦 Bill Fetch API Response: {}", responseData); LOGGER.info("📦 Bill Fetch API Response: {}", responseData);
if (responseData == null || responseData.isEmpty()) { if (responseData == null || responseData.isEmpty()) {
throw new CustomException("Empty response from BBPS server"); throw new CustomException("Empty response from BBPS server");
@@ -398,10 +399,10 @@ public class AgentServiceImpl implements AgentService {
Integer.parseInt(generalResponse.getStatusCode()), fetchBillResponse); Integer.parseInt(generalResponse.getStatusCode()), fetchBillResponse);
} catch (CustomException ex) { } catch (CustomException ex) {
log.warn("Merchant validation failed: {}", ex.getMessage()); LOGGER.warn("Merchant validation failed: {}", ex.getMessage());
return ex.getResponseModel(); return ex.getResponseModel();
} catch (Exception e) { } catch (Exception e) {
log.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e); LOGGER.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e);
responseModel.setStatus("500"); responseModel.setStatus("500");
responseModel.setMessage("Exception occurred"); responseModel.setMessage("Exception occurred");
responseModel.setData(e.getMessage()); responseModel.setData(e.getMessage());
@@ -410,4 +411,191 @@ public class AgentServiceImpl implements AgentService {
return responseModel; return responseModel;
} }
/*
* @Override public ResponseModel
* initiateBillValidate(FetchBillValidatestRequest fetchBillValidateRequest) {
*
* ResponseModel responseModel = new ResponseModel(); try {
*
* helper.validateMerchant(fetchBillValidateRequest.getMid());
*
* 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<String, String> 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<String, Object> dataMap =
* objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>()
* {});
*
* // ✅ 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 (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");
* responseModel.setMessage("Exception occurred");
* responseModel.setData(e.getMessage()); }
*
* return responseModel; }
*
* @Override public ResponseModel
* initiateBillValidateByBillId(BillFetchByBillIdRequest billRequest) {
*
* ResponseModel responseModel = new ResponseModel(); try {
* helper.validateMerchant(billRequest.getMid());
*
* 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<String, String> 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<String, Object> dataMap =
* objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>()
* {});
*
* // ✅ 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 (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");
* responseModel.setMessage("Exception occurred");
* responseModel.setData(e.getMessage()); }
*
* return responseModel; }
*/
/*
* POLLING METHOD public ResponseModel fetchBillById(BillFetchByBillIdRequest
* billFetchByBillIdRequest, InboundTraceLog inboundLog) { String apiName =
* "FetchBillById"; String txnId = helper.generateTxnId(15); String reqId =
* billFetchByBillIdRequest.getReqId(); String billId =
* billFetchByBillIdRequest.getBillId(); String url = agentDtaUrl +
* BBPSConstant.BILL_FETCH_BY_ID + "1ced7566-1add-4e01-9ed6-04cd67ac9684";
*
* helper.validateMerchant(billFetchByBillIdRequest.getMid());
*
* 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);
*
* ObjectMapper objectMapper = new ObjectMapper(); OutboundTraceLog outboundLog
* = helper.createOutboundLog(txnId, reqId, apiName, url, "GET", null);
*
* // ✅ Loop setup long startTime = System.currentTimeMillis(); long
* maxWaitTimeMs = 40000; // 40 seconds long intervalMs = 5000; // 5 seconds
*
* while (true) { try { Map<String, String> responseMap =
* httpService.getRequest(url, headers); String responseData =
* responseMap.get("data"); log.info("📦 Bill FetchById Response: {}",
* responseData);
*
* helper.updateOutboundLogResponse(outboundLog, responseData);
*
* Map<String, Object> dataMap = objectMapper.readValue(responseData, new
* TypeReference<Map<String, Object>>() {});
*
* if (!dataMap.containsKey("genericResponse")) {
* helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE");
* throw new CustomException( String.valueOf(dataMap.get("message")),
* String.valueOf(dataMap.get("status")),
* Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
* String.valueOf(dataMap.get("remarks")) ); }
*
* BillDataResponse responseWrapper = objectMapper.convertValue(dataMap,
* BillDataResponse.class); GeneralResp generalResp =
* responseWrapper.getGenericResponse();
*
* String status = generalResp.getStatus();
* log.info("📡 Current Bill Status: {}", status); // ✅ Check for "INPROGRESS"
* or pending state if ("INPROGRESS".equalsIgnoreCase(status)) { if
* (System.currentTimeMillis() - startTime > maxWaitTimeMs) {
* helper.updateInboundLogFailure(inboundLog, "Timeout after 40 seconds",
* "FAILED"); throw new CustomException("Timeout", "FAILED", 408,
* "Bill fetch still in progress"); } Thread.sleep(intervalMs); continue; //
* retry again } // ✅ Final successful response
* helper.updateInboundLogSuccess(inboundLog, responseData,
* generalResp.getStatus()); return new ResponseModel( generalResp.getMessage(),
* generalResp.getStatus(), Integer.parseInt(generalResp.getStatusCode()),
* responseWrapper ); } catch (JsonProcessingException e) {
* log.error("Error parsing BillById JSON: {}", e.getMessage());
* helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
* throw new CustomException("Invalid JSON received from API"); } catch
* (InterruptedException e) { Thread.currentThread().interrupt();
* helper.updateInboundLogFailure(inboundLog, e.getMessage(), "INTERRUPTED");
* throw new CustomException("Thread interrupted during bill status check"); } }
* }
*/
} }
@@ -8,13 +8,11 @@ import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.http.client.JdkClientHttpRequestFactory;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.HttpClientErrorException; import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.RestClient; import org.springframework.web.client.RestClient;
import com.billpaymentservice.bbps.dto.request.FetchBillRequest;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@@ -13,6 +13,9 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.billpaymentservice.bbps.dto.CustomerParamGroupsDTO; import com.billpaymentservice.bbps.dto.CustomerParamGroupsDTO;
import com.billpaymentservice.bbps.dto.CustomParamDTO;
import com.billpaymentservice.bbps.dto.GeneralResp; import com.billpaymentservice.bbps.dto.GeneralResp;
import com.billpaymentservice.bbps.dto.MasterApiResponse; import com.billpaymentservice.bbps.dto.MasterApiResponse;
import com.billpaymentservice.bbps.dto.ResponseModel; import com.billpaymentservice.bbps.dto.ResponseModel;
@@ -35,12 +38,14 @@ import com.billpaymentservice.bbps.dto.response.PlaneCategoriesResponse;
import com.billpaymentservice.bbps.entites.BharatConnectMaster; import com.billpaymentservice.bbps.entites.BharatConnectMaster;
import com.billpaymentservice.bbps.entites.BillerCategoryWise; import com.billpaymentservice.bbps.entites.BillerCategoryWise;
import com.billpaymentservice.bbps.entites.BillerDetails; import com.billpaymentservice.bbps.entites.BillerDetails;
import com.billpaymentservice.bbps.entites.CustomParam;
import com.billpaymentservice.bbps.entites.DispositionDetails; import com.billpaymentservice.bbps.entites.DispositionDetails;
import com.billpaymentservice.bbps.entites.InboundTraceLog; import com.billpaymentservice.bbps.entites.InboundTraceLog;
import com.billpaymentservice.bbps.entites.OutboundTraceLog; import com.billpaymentservice.bbps.entites.OutboundTraceLog;
import com.billpaymentservice.bbps.exception.CustomException; import com.billpaymentservice.bbps.exception.CustomException;
import com.billpaymentservice.bbps.repository.BharatConnectMasterRepository; import com.billpaymentservice.bbps.repository.BharatConnectMasterRepository;
import com.billpaymentservice.bbps.repository.BillerDataRepository; import com.billpaymentservice.bbps.repository.BillerDataRepository;
import com.billpaymentservice.bbps.repository.CustomParamRepository;
import com.billpaymentservice.bbps.repository.DispositionRepository; import com.billpaymentservice.bbps.repository.DispositionRepository;
import com.billpaymentservice.bbps.repository.InboundTraceLogRepository; import com.billpaymentservice.bbps.repository.InboundTraceLogRepository;
import com.billpaymentservice.bbps.repository.MerchantRepository; import com.billpaymentservice.bbps.repository.MerchantRepository;
@@ -68,17 +73,17 @@ public class MasterDataServiceImpl implements MasterDataService {
private final DispositionRepository dispositionRepository; private final DispositionRepository dispositionRepository;
private final Helper helper; private final Helper helper;
private final BillerDataRepository billerDataRespository; private final BillerDataRepository billerDataRespository;
private static final Logger log = LoggerFactory.getLogger(MasterDataServiceImpl.class);
private final HttpService httpService; private final HttpService httpService;
private final ObjectMapper objectMapper = new ObjectMapper(); private final ObjectMapper objectMapper = new ObjectMapper();
private final InboundTraceLogRepository inboundTraceLogRepository; private final InboundTraceLogRepository inboundTraceLogRepository;
private final OutboundTraceLogRepository outboundTraceLogRepository; private final OutboundTraceLogRepository outboundTraceLogRepository;
private final CustomParamRepository customParamReposiotory;
public MasterDataServiceImpl(MerchantRepository merchantRegisterRepo, HttpService httpService, public MasterDataServiceImpl(MerchantRepository merchantRegisterRepo, HttpService httpService,
HttpClientApi httpClientApi, Helper helper, BillerDataRepository billerDataRespository, HttpClientApi httpClientApi, Helper helper, BillerDataRepository billerDataRespository,
DispositionRepository dispositionRepository, BharatConnectMasterRepository beneficiaryDetailsRepository, DispositionRepository dispositionRepository, BharatConnectMasterRepository beneficiaryDetailsRepository,
InboundTraceLogRepository inboundTraceLogRepository, OutboundTraceLogRepository outboundTraceLogRepository, InboundTraceLogRepository inboundTraceLogRepository, OutboundTraceLogRepository outboundTraceLogRepository,
BillerMapperHelper mapperHelper) { BillerMapperHelper mapperHelper, CustomParamRepository customParamReposiotory) {
this.merchantRegisterRepo = merchantRegisterRepo; this.merchantRegisterRepo = merchantRegisterRepo;
this.httpService = httpService; this.httpService = httpService;
this.httpClientApi = httpClientApi; this.httpClientApi = httpClientApi;
@@ -89,54 +94,39 @@ public class MasterDataServiceImpl implements MasterDataService {
this.inboundTraceLogRepository = inboundTraceLogRepository; this.inboundTraceLogRepository = inboundTraceLogRepository;
this.outboundTraceLogRepository = outboundTraceLogRepository; this.outboundTraceLogRepository = outboundTraceLogRepository;
this.mapperHelper = mapperHelper; this.mapperHelper = mapperHelper;
this.customParamReposiotory = customParamReposiotory;
} }
@Override @Override
public ResponseModel getMasterData(MasterRequest masterRequest) { public ResponseModel getMasterData(MasterRequest masterRequest) {
LOGGER.info("Request DTO: {}", masterRequest); LOGGER.info("Fetching Master Data for ReqId={} and MID={}", masterRequest.getReqId(), masterRequest.getMid());
String txnID = helper.generateTxnId(15); String txnID = helper.generateTxnId(15);
String apiName = "GetMasterData"; String apiName = "GetMasterData";
String requestId = masterRequest.getReqId(); String requestId = masterRequest.getReqId();
String requestJson = helper.convertObjectToJson(masterRequest); String requestJson = helper.convertObjectToJson(masterRequest);
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, masterRequest.getMid(), "POST", InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, masterRequest.getMid(), "POST",
requestJson); requestJson);
try { try {
// Merchant Validation // Merchant Validation
helper.validateMerchant(masterRequest.getMid()); 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 // check Tender Id is present DB
BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001");
log.info("Response -: " + headersData);
if (headersData == null) { if (headersData == null) {
helper.updateInboundLogFailure(inboundLog, "Tenant Id Is Null", "NOT_FOUND"); LOGGER.warn("header data not found for the orgID");
return new ResponseModel("Tenant Id Is Null", "Not Found", BBPSConstant.BADREQUEST, headersData); throw new CustomException("Something went wrong", "FAILED", 500, "");
} }
// get full url // get full url
String fullUrl = masterRegisterUrl + BBPSConstant.MASTER_CATEGORY_URL + headersData.getTenantId(); String fullUrl = masterRegisterUrl + BBPSConstant.MASTER_CATEGORY_URL + headersData.getTenantId();
LOGGER.info("Calling external API: {}", fullUrl); LOGGER.info("Calling external API: {}", fullUrl);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null); OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null);
Map<String, String> responseMap = httpService.getRequest(fullUrl); Map<String, String> responseMap = httpService.getRequest(fullUrl);
String responseData = responseMap.get("data"); String responseData = responseMap.get("data");
LOGGER.info("Response Data: {}", responseData); LOGGER.info("Response Data: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData); helper.updateOutboundLogResponse(outboundLog, responseData);
Map<String, Object> dataMap = objectMapper.readValue(responseData, Map<String, Object> dataMap = objectMapper.readValue(responseData,
new TypeReference<Map<String, Object>>() { new TypeReference<Map<String, Object>>() {
}); });
if (!dataMap.containsKey("generalResp")) { if (!dataMap.containsKey("generalResp")) {
helper.updateInboundLogFailure(inboundLog, responseData, String.valueOf(dataMap.get("status"))); helper.updateInboundLogFailure(inboundLog, responseData, String.valueOf(dataMap.get("status")));
throw new CustomException(String.valueOf(dataMap.get("message")), // message throw new CustomException(String.valueOf(dataMap.get("message")), // message
@@ -157,14 +147,17 @@ public class MasterDataServiceImpl implements MasterDataService {
return responseModel; return responseModel;
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Error parsing responseData JSON: {}", e.getMessage()); LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API"); throw new CustomException("Invalid JSON received from API");
} }
} }
@Override @Override
public ResponseModel getBillerByBillerId(BillerDetailRequest billerDetailRequest) { public ResponseModel getBillerByBillerId(BillerDetailRequest billerDetailRequest) {
LOGGER.info("Fetching Biller Detail By Biller Id for ReqId={} and MID={}", billerDetailRequest.getReqId(),
billerDetailRequest.getMid());
helper.validateMerchant(billerDetailRequest.getMid()); helper.validateMerchant(billerDetailRequest.getMid());
String txnID = helper.generateTxnId(15); String txnID = helper.generateTxnId(15);
@@ -172,56 +165,50 @@ public class MasterDataServiceImpl implements MasterDataService {
String requestId = billerDetailRequest.getReqId(); String requestId = billerDetailRequest.getReqId();
String billerId = billerDetailRequest.getBillerId(); String billerId = billerDetailRequest.getBillerId();
String fullUrl = masterRegisterUrl + BBPSConstant.BILLER_DATA_FETCH_URL + billerId; String fullUrl = masterRegisterUrl + BBPSConstant.BILLER_DATA_FETCH_URL + billerId;
String requestJson = helper.convertObjectToJson(billerDetailRequest); String requestJson = helper.convertObjectToJson(billerDetailRequest);
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, billerDetailRequest.getMid(), InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, billerDetailRequest.getMid(),
"POST", requestJson); "POST", requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null); OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null);
LOGGER.info("Calling external API: {}", fullUrl);
Map<String, String> responseMap = httpService.getRequest(fullUrl); Map<String, String> responseMap = httpService.getRequest(fullUrl);
String responseData = responseMap.get("data"); String responseData = responseMap.get("data");
log.info("data is :{}", responseData); LOGGER.info("fetched data from api is :{}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData); helper.updateOutboundLogResponse(outboundLog, responseData);
try { try {
Map<String, Object> dataMap = objectMapper.readValue(responseData, Map<String, Object> dataMap = objectMapper.readValue(responseData,
new TypeReference<Map<String, Object>>() { new TypeReference<Map<String, Object>>() {
}); });
if (!dataMap.containsKey("generalResp")) { if (!dataMap.containsKey("generalResp")) {
helper.updateInboundLogFailure(inboundLog, responseData, String.valueOf(dataMap.get("status"))); helper.updateInboundLogFailure(inboundLog, responseData, String.valueOf(dataMap.get("status")));
throw new CustomException(String.valueOf(dataMap.get("message")), String.valueOf(dataMap.get("status")), throw new CustomException(String.valueOf(dataMap.get("message")), String.valueOf(dataMap.get("status")),
Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
String.valueOf(dataMap.get("remarks"))); String.valueOf(dataMap.get("remarks")));
} }
BillerDataResponse responseWrapper = objectMapper.convertValue(dataMap, BillerDataResponse.class); BillerDataResponse responseWrapper = objectMapper.convertValue(dataMap, BillerDataResponse.class);
GeneralResp generalResp = responseWrapper.getGeneralResp(); GeneralResp generalResp = responseWrapper.getGeneralResp();
ModelMapper mapper = new ModelMapper(); ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
BillerDetails entity = mapper.map(responseWrapper.getBillerDAO(), BillerDetails.class); BillerDetails entity = mapper.map(responseWrapper.getBillerDAO(), BillerDetails.class);
EntityRelationshipUtil.linkBillerRelationships(entity); EntityRelationshipUtil.linkBillerRelationships(entity);// linking nesting entity foreign key
helper.saveOrUpdateBillerData(entity);
ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(), ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()), responseWrapper); Integer.parseInt(generalResp.getStatusCode()), responseWrapper);
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus()); helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return responseModel; return responseModel;
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Error parsing responseData JSON: {}", e.getMessage()); LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API"); throw new CustomException("Invalid JSON received from API");
} }
} }
@Override @Override
public ResponseModel getCustomerParamByBillerId(CustomParamRequest customerParamRequest) { public ResponseModel getCustomerParamByBillerId(CustomParamRequest customerParamRequest) {
LOGGER.info("Fetching Customer Param By Biller Id for ReqId={} and MID={}", customerParamRequest.getReqId(),
customerParamRequest.getMid());
String txnID = helper.generateTxnId(15); String txnID = helper.generateTxnId(15);
String apiName = "GetCustomerParamByBillerId"; String apiName = "GetCustomerParamByBillerId";
String requestId = customerParamRequest.getReqId(); String requestId = customerParamRequest.getReqId();
@@ -231,20 +218,14 @@ public class MasterDataServiceImpl implements MasterDataService {
try { try {
helper.validateMerchant(customerParamRequest.getMid()); 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 billerId = customerParamRequest.getBillerId();
String fullUrl = masterRegisterUrl + BBPSConstant.CUSTOMPARAM_URL + billerId; String fullUrl = masterRegisterUrl + BBPSConstant.CUSTOMPARAM_URL + billerId;
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null); OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null);
LOGGER.info("Calling external API: {}", fullUrl);
Map<String, String> responseMap = httpService.getRequest(fullUrl); Map<String, String> responseMap = httpService.getRequest(fullUrl);
String responseData = responseMap.get("data"); String responseData = responseMap.get("data");
log.info("data is :{}", responseData); LOGGER.info("data is :{}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData); helper.updateOutboundLogResponse(outboundLog, responseData);
@@ -260,26 +241,34 @@ public class MasterDataServiceImpl implements MasterDataService {
} }
CustomParamResp responseWrapper = objectMapper.convertValue(dataMap, CustomParamResp.class); CustomParamResp responseWrapper = objectMapper.convertValue(dataMap, CustomParamResp.class);
List<CustomParamDTO> customParams = responseWrapper.getCustomParamResp();
GeneralResp generalResp = responseWrapper.getGeneralResp(); GeneralResp generalResp = responseWrapper.getGeneralResp();
List<CustomParamDTO> customParam = responseWrapper.getCustomParamResp();
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
// Map DTOs to entities
List<CustomParam> entities = customParams.stream().map(dto -> mapper.map(dto, CustomParam.class))
.collect(Collectors.toList());
// Save all to DB
customParamReposiotory.saveAll(entities);
ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(), ResponseModel responseModel = new ResponseModel(generalResp.getMessage(), generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()), responseWrapper); Integer.parseInt(generalResp.getStatusCode()), responseWrapper);
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus()); helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return responseModel; return responseModel;
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Error parsing responseData JSON: {}", e.getMessage()); LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API"); throw new CustomException("Invalid JSON received from API");
} }
} }
@Override @Override
public ResponseModel getContactMaster(ContactMasterRequest contactMasterRequest) { public ResponseModel getContactMaster(ContactMasterRequest contactMasterRequest) {
return new ResponseModel(); return new ResponseModel(); // things not comming from api
} }
@Override @Override
@@ -292,10 +281,8 @@ public class MasterDataServiceImpl implements MasterDataService {
String requestJson = helper.convertObjectToJson(masterRequest); String requestJson = helper.convertObjectToJson(masterRequest);
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, masterRequest.getMid(), "POST", InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, masterRequest.getMid(), "POST",
requestJson); requestJson);
try { try {
helper.validateMerchant(masterRequest.getMid()); helper.validateMerchant(masterRequest.getMid());
String fullUrl = String.format("%s%s?billerName=%s&category=%s&page=%d&pagesize=%d", masterRegisterUrl, String fullUrl = String.format("%s%s?billerName=%s&category=%s&page=%d&pagesize=%d", masterRegisterUrl,
BBPSConstant.BILLER_URL, masterRequest.getBillerName(), masterRequest.getCategory(), BBPSConstant.BILLER_URL, masterRequest.getBillerName(), masterRequest.getCategory(),
masterRequest.getPageStart(), masterRequest.getPageEnd()); masterRequest.getPageStart(), masterRequest.getPageEnd());
@@ -334,7 +321,7 @@ public class MasterDataServiceImpl implements MasterDataService {
return responseModel; return responseModel;
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Error parsing responseData JSON: {}", e.getMessage()); LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API"); throw new CustomException("Invalid JSON received from API");
} }
@@ -342,15 +329,19 @@ public class MasterDataServiceImpl implements MasterDataService {
@Override @Override
public ResponseModel getDispositionDetails(DispositionRequest dispositionDetailRequest) { public ResponseModel getDispositionDetails(DispositionRequest dispositionDetailRequest) {
LOGGER.info("Fetching Disposition Details for ReqId={} and MID={}", dispositionDetailRequest.getReqId(),
dispositionDetailRequest.getMid());
String txnID = helper.generateTxnId(15); String txnID = helper.generateTxnId(15);
String apiName = "GetDispositionDetails"; String apiName = "GetDispositionDetails";
String requestId = dispositionDetailRequest.getReqId(); String requestId = dispositionDetailRequest.getReqId();
; helper.validateMerchant(dispositionDetailRequest.getMid());
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName,
dispositionDetailRequest.getMid(), "GET", "N/A"); dispositionDetailRequest.getMid(), "GET", "N/A");
String fullUrl = masterRegisterUrl + BBPSConstant.DISPOSTION_URL; String fullUrl = masterRegisterUrl + BBPSConstant.DISPOSTION_URL;
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null); OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null);
LOGGER.info("Calling external API: {}", fullUrl);
Map<String, String> responseMap = httpService.getRequest(fullUrl); Map<String, String> responseMap = httpService.getRequest(fullUrl);
String responseData = responseMap.get("data"); String responseData = responseMap.get("data");
@@ -393,16 +384,17 @@ public class MasterDataServiceImpl implements MasterDataService {
return responseModel; return responseModel;
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Error parsing responseData JSON: {}", e.getMessage()); LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API"); throw new CustomException("Invalid JSON received from API");
} }
} }
@Override @Override
public ResponseModel fetchCustomerParamGroup(BillerDetailRequest requestModel) { public ResponseModel fetchCustomerParamGroup(BillerDetailRequest requestModel) {
LOGGER.info("Fetching Master Data CategoryResponseList-wise for MID={}", requestModel.getMid()); LOGGER.info("Fetching Customer Param Group for ReqId={} and MID={}", requestModel.getReqId(),
requestModel.getMid());
String txnID = helper.generateTxnId(15); String txnID = helper.generateTxnId(15);
String apiName = "FetchCustomerParamGroup"; String apiName = "FetchCustomerParamGroup";
String requestId = requestModel.getReqId(); String requestId = requestModel.getReqId();
@@ -414,7 +406,7 @@ public class MasterDataServiceImpl implements MasterDataService {
String fullUrl = masterRegisterUrl + BBPSConstant.CUSTOMER_PARAM_GROUP + requestModel.getBillerId(); String fullUrl = masterRegisterUrl + BBPSConstant.CUSTOMER_PARAM_GROUP + requestModel.getBillerId();
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null); OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null);
LOGGER.info("Calling external API: {}", fullUrl);
Map<String, String> apiResponse = httpService.getRequest(fullUrl); Map<String, String> apiResponse = httpService.getRequest(fullUrl);
String responseData = apiResponse.get("data").toString(); String responseData = apiResponse.get("data").toString();
helper.updateOutboundLogResponse(outboundLog, responseData); helper.updateOutboundLogResponse(outboundLog, responseData);
@@ -446,7 +438,7 @@ public class MasterDataServiceImpl implements MasterDataService {
return responseModel; return responseModel;
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Error parsing responseData JSON: {}", e.getMessage()); LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API"); throw new CustomException("Invalid JSON received from API");
} }
@@ -455,8 +447,9 @@ public class MasterDataServiceImpl implements MasterDataService {
@Override @Override
public ResponseModel fetchAllMasterAmountOption(BillerDetailRequest requestModel) { public ResponseModel fetchAllMasterAmountOption(BillerDetailRequest requestModel) {
LOGGER.info("Fetching Master Data Amount List for MID={}", requestModel.getMid());
LOGGER.info("Fetching Master Data Amount List for ReqId={} and MID={}", requestModel.getReqId(),
requestModel.getMid());
String txnID = helper.generateTxnId(15); String txnID = helper.generateTxnId(15);
String apiName = "FetchAllMasterAmountOption"; String apiName = "FetchAllMasterAmountOption";
String requestId = requestModel.getReqId(); String requestId = requestModel.getReqId();
@@ -468,9 +461,9 @@ public class MasterDataServiceImpl implements MasterDataService {
String fullUrl = masterRegisterUrl + BBPSConstant.AMOUNT_OPTIONS + requestModel.getBillerId(); String fullUrl = masterRegisterUrl + BBPSConstant.AMOUNT_OPTIONS + requestModel.getBillerId();
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null); OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null);
LOGGER.info("Calling external API: {}", fullUrl);
Map<String, String> apiResponse = httpService.getRequest(fullUrl); Map<String, String> apiResponse = httpService.getRequest(fullUrl);
log.info("Response" + apiResponse); LOGGER.info("Response" + apiResponse);
String responseData = apiResponse.get("data").toString(); String responseData = apiResponse.get("data").toString();
helper.updateOutboundLogResponse(outboundLog, responseData); helper.updateOutboundLogResponse(outboundLog, responseData);
@@ -502,7 +495,7 @@ public class MasterDataServiceImpl implements MasterDataService {
return responseModel; return responseModel;
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Error parsing responseData JSON: {}", e.getMessage()); LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API"); throw new CustomException("Invalid JSON received from API");
} }
@@ -511,8 +504,7 @@ public class MasterDataServiceImpl implements MasterDataService {
@Override @Override
public ResponseModel fetchPlanCategorie(BillerDetailRequest requestModel) { public ResponseModel fetchPlanCategorie(BillerDetailRequest requestModel) {
LOGGER.info("Fetching Master Data Amount List for MID={}", requestModel.getMid()); LOGGER.info("Fetching Plan Categories for ReqId={} and MID={}", requestModel.getReqId(), requestModel.getMid());
String txnID = helper.generateTxnId(15); String txnID = helper.generateTxnId(15);
String apiName = "FetchPlanCategorie"; String apiName = "FetchPlanCategorie";
String requestId = requestModel.getReqId(); String requestId = requestModel.getReqId();
@@ -524,9 +516,9 @@ public class MasterDataServiceImpl implements MasterDataService {
String fullUrl = masterRegisterUrl + BBPSConstant.PLAN_CATEGORIES + requestModel.getBillerId(); String fullUrl = masterRegisterUrl + BBPSConstant.PLAN_CATEGORIES + requestModel.getBillerId();
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null); OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null);
LOGGER.info("Calling external API: {}", fullUrl);
Map<String, String> apiResponse = httpService.getRequest(fullUrl); Map<String, String> apiResponse = httpService.getRequest(fullUrl);
log.info("Response" + apiResponse); LOGGER.info("Response" + apiResponse);
String responseData = apiResponse.get("data").toString(); String responseData = apiResponse.get("data").toString();
helper.updateOutboundLogResponse(outboundLog, responseData); helper.updateOutboundLogResponse(outboundLog, responseData);
@@ -556,16 +548,17 @@ public class MasterDataServiceImpl implements MasterDataService {
return responseModel; return responseModel;
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Error parsing responseData JSON: {}", e.getMessage()); LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API"); throw new CustomException("Invalid JSON received from API");
} }
} }
@Override @Override
public ResponseModel fetchInitiatingChannel(BillerDetailRequest requestModel) { public ResponseModel fetchInitiatingChannel(BillerDetailRequest requestModel) {
LOGGER.info("Fetching Initiating Channel List for MID={}", requestModel.getMid()); LOGGER.info("Fetching Initiating Channel for ReqId={} and MID={}", requestModel.getReqId(),
requestModel.getMid());
String txnID = helper.generateTxnId(15); String txnID = helper.generateTxnId(15);
String apiName = "FetchInitiatingChannel"; String apiName = "FetchInitiatingChannel";
String requestId = requestModel.getReqId(); String requestId = requestModel.getReqId();
@@ -576,12 +569,11 @@ public class MasterDataServiceImpl implements MasterDataService {
helper.validateMerchant(requestModel.getMid()); helper.validateMerchant(requestModel.getMid());
String fullUrl = masterRegisterUrl + BBPSConstant.INITIATING_CHANNEL; String fullUrl = masterRegisterUrl + BBPSConstant.INITIATING_CHANNEL;
LOGGER.info("Calling Master API: {}", fullUrl);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null); OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, fullUrl, "GET", null);
LOGGER.info("Calling Master API: {}", fullUrl);
Map<String, String> apiResponse = httpService.getRequest(fullUrl); Map<String, String> apiResponse = httpService.getRequest(fullUrl);
log.info("Response" + apiResponse); LOGGER.info("Response" + apiResponse);
String responseData = apiResponse.get("data").toString(); String responseData = apiResponse.get("data").toString();
helper.updateOutboundLogResponse(outboundLog, responseData); helper.updateOutboundLogResponse(outboundLog, responseData);
@@ -609,16 +601,17 @@ public class MasterDataServiceImpl implements MasterDataService {
return responseModel; return responseModel;
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Error parsing responseData JSON: {}", e.getMessage()); LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API"); throw new CustomException("Invalid JSON received from API");
} }
} }
public ResponseModel fetchPlanByCategories(PlanRequest requestModel) { public ResponseModel fetchPlanByCategories(PlanRequest requestModel) {
LOGGER.info("Fetching Initiating Fetch Plan CategoryResponseList By Biller Id for MID={}",
requestModel.getMid());
LOGGER.info("Fetching Plan By Categories for ReqId={} and MID={}", requestModel.getReqId(),
requestModel.getMid());
String txnID = helper.generateTxnId(15); String txnID = helper.generateTxnId(15);
String apiName = "FetchPlanByCategories"; String apiName = "FetchPlanByCategories";
String requestId = requestModel.getReqId(); String requestId = requestModel.getReqId();
@@ -639,11 +632,10 @@ public class MasterDataServiceImpl implements MasterDataService {
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, requestModel.getMid(), "POST", InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, requestModel.getMid(), "POST",
requestJson); requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, url, "GET", null); OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, url, "GET", null);
try { try {
Map<String, String> apiResponse = httpService.getRequest(url); Map<String, String> apiResponse = httpService.getRequest(url);
String responseData = apiResponse.get("data"); String responseData = apiResponse.get("data");
log.info("Response Data: {}", responseData); LOGGER.info("Response Data: {}", responseData);
// Update outbound log with response // Update outbound log with response
helper.updateOutboundLogResponse(outboundLog, responseData); helper.updateOutboundLogResponse(outboundLog, responseData);
@@ -672,7 +664,7 @@ public class MasterDataServiceImpl implements MasterDataService {
return responseModel; return responseModel;
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
log.error("Error parsing responseData JSON: {}", e.getMessage()); LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API"); throw new CustomException("Invalid JSON received from API");
} }
@@ -1,6 +1,5 @@
package com.billpaymentservice.bbps.serviceImpl; package com.billpaymentservice.bbps.serviceImpl;
import java.time.LocalDateTime;
import java.util.Map; import java.util.Map;
import org.modelmapper.ModelMapper; import org.modelmapper.ModelMapper;
@@ -11,28 +10,30 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.billpaymentservice.bbps.dto.GeneralResp; import com.billpaymentservice.bbps.dto.GeneralResp;
import com.billpaymentservice.bbps.dto.ResponseModel; import com.billpaymentservice.bbps.dto.ResponseModel;
import com.billpaymentservice.bbps.dto.request.BillFetchByBillIdRequest;
import com.billpaymentservice.bbps.dto.request.BillPaymentRequest; import com.billpaymentservice.bbps.dto.request.BillPaymentRequest;
import com.billpaymentservice.bbps.dto.request.FetchBillRequest;
import com.billpaymentservice.bbps.dto.request.TransactionStatusRequest; import com.billpaymentservice.bbps.dto.request.TransactionStatusRequest;
import com.billpaymentservice.bbps.dto.response.BillDataResponse;
import com.billpaymentservice.bbps.dto.response.BillPaymentResponse; import com.billpaymentservice.bbps.dto.response.BillPaymentResponse;
import com.billpaymentservice.bbps.dto.response.FetchBillResponse;
import com.billpaymentservice.bbps.dto.response.TransactionStatusResponse; import com.billpaymentservice.bbps.dto.response.TransactionStatusResponse;
import com.billpaymentservice.bbps.entites.AgentFundTransfer;
import com.billpaymentservice.bbps.entites.BharatConnectMaster; import com.billpaymentservice.bbps.entites.BharatConnectMaster;
import com.billpaymentservice.bbps.entites.BillPayment; import com.billpaymentservice.bbps.entites.BillPayment;
import com.billpaymentservice.bbps.entites.InboundTraceLog; import com.billpaymentservice.bbps.entites.InboundTraceLog;
import com.billpaymentservice.bbps.entites.OutboundTraceLog; import com.billpaymentservice.bbps.entites.OutboundTraceLog;
import com.billpaymentservice.bbps.entites.PaymentInitiate;
import com.billpaymentservice.bbps.entites.TransactionMaster;
import com.billpaymentservice.bbps.exception.CustomException; import com.billpaymentservice.bbps.exception.CustomException;
import com.billpaymentservice.bbps.repository.AgentFundTransferRepository;
import com.billpaymentservice.bbps.repository.BharatConnectMasterRepository; import com.billpaymentservice.bbps.repository.BharatConnectMasterRepository;
import com.billpaymentservice.bbps.repository.InboundTraceLogRepository; import com.billpaymentservice.bbps.repository.InboundTraceLogRepository;
import com.billpaymentservice.bbps.repository.OutboundTraceLogRepository; import com.billpaymentservice.bbps.repository.OutboundTraceLogRepository;
import com.billpaymentservice.bbps.repository.PaymentIntiateRepository;
import com.billpaymentservice.bbps.repository.PaymentRepository; import com.billpaymentservice.bbps.repository.PaymentRepository;
import com.billpaymentservice.bbps.repository.TransactionMasterRepository;
import com.billpaymentservice.bbps.service.PaymentService; import com.billpaymentservice.bbps.service.PaymentService;
import com.billpaymentservice.bbps.util.BBPSConstant; import com.billpaymentservice.bbps.util.BBPSConstant;
import com.billpaymentservice.bbps.util.EntityRelationshipUtil;
import com.billpaymentservice.bbps.util.Helper; import com.billpaymentservice.bbps.util.Helper;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
@@ -44,26 +45,35 @@ public class PaymentServiceImpl implements PaymentService {
@Value("${payment.data.url}") @Value("${payment.data.url}")
private String paymentUrl; private String paymentUrl;
private final BharatConnectMasterRepository beneficiaryDetailsRepository; private final BharatConnectMasterRepository beneficiaryDetailsRepository;
private final HttpService httpService; private final HttpService httpService;
private final Helper helper; private final Helper helper;
private final PaymentRepository paymentRepository; private final PaymentRepository paymentRepository;
private final InboundTraceLogRepository inboundTraceLogRepository; private final InboundTraceLogRepository inboundTraceLogRepository;
private final OutboundTraceLogRepository outboundTraceLogRepository; private final OutboundTraceLogRepository outboundTraceLogRepository;
private final PaymentIntiateRepository paymentIntiateRepository;
private final TransactionMasterRepository transactionMasterRepository;
private final AgentFundTransferRepository agentFundTransferRepository;
private static final Logger LOGGER = LoggerFactory.getLogger(PaymentServiceImpl.class);
public PaymentServiceImpl(BharatConnectMasterRepository beneficiaryDetailsRepository, HttpService httpService, public PaymentServiceImpl(BharatConnectMasterRepository beneficiaryDetailsRepository, HttpService httpService,
Helper helper, PaymentRepository paymentRepository, InboundTraceLogRepository inboundTraceLogRepository, Helper helper, PaymentRepository paymentRepository, InboundTraceLogRepository inboundTraceLogRepository,
OutboundTraceLogRepository outboundTraceLogRepository) { OutboundTraceLogRepository outboundTraceLogRepository, PaymentIntiateRepository paymentIntiateRepository,
TransactionMasterRepository transactionMasterRepository,
AgentFundTransferRepository agentFundTransferRepository) {
this.beneficiaryDetailsRepository = beneficiaryDetailsRepository; this.beneficiaryDetailsRepository = beneficiaryDetailsRepository;
this.httpService = httpService; this.httpService = httpService;
this.helper = helper; this.helper = helper;
this.paymentRepository = paymentRepository; this.paymentRepository = paymentRepository;
this.inboundTraceLogRepository = inboundTraceLogRepository; this.inboundTraceLogRepository = inboundTraceLogRepository;
this.outboundTraceLogRepository = outboundTraceLogRepository; this.outboundTraceLogRepository = outboundTraceLogRepository;
this.paymentIntiateRepository = paymentIntiateRepository;
this.transactionMasterRepository = transactionMasterRepository;
this.agentFundTransferRepository = agentFundTransferRepository;
} }
private static final Logger LOGGER = LoggerFactory.getLogger(MasterDataServiceImpl.class);
@Override @Override
public ResponseModel initiatePayment(BillPaymentRequest billPaymentRequest) { public ResponseModel initiatePayment(BillPaymentRequest billPaymentRequest) {
String apiName = "InitiatePayment"; String apiName = "InitiatePayment";
@@ -71,6 +81,8 @@ public class PaymentServiceImpl implements PaymentService {
String requestId = billPaymentRequest.getReqId(); String requestId = billPaymentRequest.getReqId();
String url = paymentUrl + BBPSConstant.PAYMENT_URL; String url = paymentUrl + BBPSConstant.PAYMENT_URL;
LOGGER.info("Initiating payment for reqId={} and txnId={}", requestId, txnId);
BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001");
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.set("x-digiledge-key", headersData.getXDigiledgeKey()); headers.set("x-digiledge-key", headersData.getXDigiledgeKey());
@@ -83,25 +95,27 @@ public class PaymentServiceImpl implements PaymentService {
String requestJson = helper.convertObjectToJson(billPaymentRequest); String requestJson = helper.convertObjectToJson(billPaymentRequest);
// ✅ Create inbound & outbound logs
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnId, apiName, billPaymentRequest.getMid(), "POST", requestJson); InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnId, apiName, billPaymentRequest.getMid(), "POST", requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, url, "POST", requestJson); OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, url, "POST", requestJson);
try { try {
LOGGER.info("Calling BBPS payment URL: {}", url);
Map<String, String> responseMap = httpService.postRequest(url, requestJson, headers); Map<String, String> responseMap = httpService.postRequest(url, requestJson, headers);
String responseData = responseMap.get("data"); String responseData = responseMap.get("data");
LOGGER.info("Payment API Response: {}", responseData);
LOGGER.info("📦 Payment API Response: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData); helper.updateOutboundLogResponse(outboundLog, responseData);
if (responseData == null || responseData.isEmpty()) { if (responseData == null || responseData.isEmpty()) {
helper.updateInboundLogFailure(inboundLog, "Empty response from BBPS", "FAILED"); helper.updateInboundLogFailure(inboundLog, "Empty response from BBPS", "FAILED");
LOGGER.warn("Empty response received from BBPS for txnId={}", txnId);
throw new CustomException("Empty response from BBPS server"); throw new CustomException("Empty response from BBPS server");
} }
Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {}); Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {});
if (!dataMap.containsKey("genericResponse")) { if (!dataMap.containsKey("genericResponse")) {
helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_STRUCTURE"); helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_STRUCTURE");
LOGGER.warn("Invalid response structure received for txnId={}", txnId);
throw new CustomException("Invalid response structure from BBPS"); throw new CustomException("Invalid response structure from BBPS");
} }
@@ -112,35 +126,44 @@ public class PaymentServiceImpl implements PaymentService {
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
BillPayment entity = mapper.map(billPaymentResponse, BillPayment.class); BillPayment entity = mapper.map(billPaymentResponse, BillPayment.class);
paymentRepository.save(entity); paymentRepository.save(entity);
LOGGER.info("BillPayment entity saved successfully for txnId={}", txnId);
helper.updateInboundLogSuccess(inboundLog, responseData, generalResponse.getStatus()); helper.updateInboundLogSuccess(inboundLog, responseData, generalResponse.getStatus());
PaymentInitiate paymentInitiate = new PaymentInitiate();
paymentInitiate.setTxnId(txnId);
paymentInitiate.setReqId(requestId);
paymentInitiate.setBankTxnId(billPaymentResponse.getTxnId());
paymentInitiate.setStatus(billPaymentResponse.getStatus());
paymentIntiateRepository.save(paymentInitiate);
LOGGER.info("PaymentInitiate entry saved successfully for txnId={}", txnId);
// ✅ Trigger transaction status check
TransactionStatusRequest transactionStatusRequest = new TransactionStatusRequest(); TransactionStatusRequest transactionStatusRequest = new TransactionStatusRequest();
transactionStatusRequest.setTxnId(entity.getTxnId()); transactionStatusRequest.setTxnId(billPaymentResponse.getTxnId());
transactionStatusRequest.setReqId(requestId); transactionStatusRequest.setReqId(requestId);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LOGGER.warn("Thread interrupted during payment delay: {}", e.getMessage());
}
LOGGER.info("Checking transaction status for txnId={}", billPaymentResponse.getTxnId());
return checkTrasactionStatus(transactionStatusRequest, inboundLog); return checkTrasactionStatus(transactionStatusRequest, inboundLog);
} catch (JsonProcessingException e) { } catch (JsonProcessingException e) {
LOGGER.error("❌ JSON Parsing Error: {}", e.getMessage()); LOGGER.error("JSON Parsing Error in initiatePayment: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR"); helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API"); throw new CustomException("Invalid JSON received from API");
} catch (CustomException ce) {
throw ce; // will be handled by global exception handler
} catch (Exception e) {
LOGGER.error("❌ Exception in initiatePayment(): {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "EXCEPTION");
throw new CustomException("Payment initiation failed: " + e.getMessage());
} }
} }
public ResponseModel checkTrasactionStatus(TransactionStatusRequest transactionStatusRequest, InboundTraceLog inboundLog) {
public ResponseModel checkTrasactionStatus(TransactionStatusRequest transactionStatusRequest,InboundTraceLog inboundLog) {
String apiName = "CheckTransactionStatus"; String apiName = "CheckTransactionStatus";
String txnId = helper.generateTxnId(15); //our genrated txnId String txnId = helper.generateTxnId(15);
String requestId = transactionStatusRequest.getReqId(); String requestId = transactionStatusRequest.getReqId();
String url = paymentUrl + BBPSConstant.CHECK_TRANSACTION_URL + transactionStatusRequest.getTxnId(); ; String url = paymentUrl + BBPSConstant.CHECK_TRANSACTION_URL + transactionStatusRequest.getTxnId();
LOGGER.info("Checking transaction status (internal) for txnId={} and reqId={}", transactionStatusRequest.getTxnId(), requestId);
BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001");
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
@@ -148,69 +171,63 @@ public class PaymentServiceImpl implements PaymentService {
headers.set("agentId", headersData.getAgentId()); headers.set("agentId", headersData.getAgentId());
headers.set("tenantId", headersData.getTenantId()); headers.set("tenantId", headersData.getTenantId());
headers.setContentType(MediaType.APPLICATION_JSON); headers.setContentType(MediaType.APPLICATION_JSON);
ObjectMapper objectMapper = new ObjectMapper();
ObjectMapper objectMapper = new ObjectMapper();
OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, url, "GET", null); OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId, apiName, url, "GET", null);
long startTime = System.currentTimeMillis(); Map<String, String> responseMap = httpService.getRequest(url, headers);
long maxWaitTimeMs = 40000; String responseData = responseMap.get("data");
long intervalMs = 5000; LOGGER.info("Transaction status response: {}", responseData);
while (true) { helper.updateOutboundLogResponse(outboundLog, responseData);
Map<String, String> responseMap = httpService.getRequest(url, headers);
String responseData = responseMap.get("data");
LOGGER.info("Transaction status response: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData); try {
Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {});
try { if (!dataMap.containsKey("generalResp")) {
Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {}); helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE");
LOGGER.warn("Invalid transaction status response for txnId={}", transactionStatusRequest.getTxnId());
if (!dataMap.containsKey("generalResp")) { throw new CustomException(
helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE"); String.valueOf(dataMap.get("message")),
throw new CustomException( String.valueOf(dataMap.get("status")),
String.valueOf(dataMap.get("message")), Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
String.valueOf(dataMap.get("status")), String.valueOf(dataMap.get("remarks"))
Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
String.valueOf(dataMap.get("remarks"))
);
}
TransactionStatusResponse responseWrapper = objectMapper.convertValue(dataMap, TransactionStatusResponse.class);
GeneralResp generalResp = responseWrapper.getGeneralResp();
String status = generalResp.getStatus();
LOGGER.info("Current transaction status: {}", status);
if ("INPROGRESS".equalsIgnoreCase(status)) {
if (System.currentTimeMillis() - startTime > maxWaitTimeMs) {
helper.updateInboundLogFailure(inboundLog, "Timeout after 40 seconds", "FAILED");
throw new CustomException("Timeout waiting for transaction completion", "FAILED", 408, "Transaction still in progress");
}
Thread.sleep(intervalMs);
continue;
}
ResponseModel responseModel = new ResponseModel(
generalResp.getMessage(),
generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()),
responseWrapper
); );
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return responseModel;
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing transaction status JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "INTERRUPTED");
throw new CustomException("Thread interrupted during transaction check");
} }
TransactionStatusResponse responseWrapper = objectMapper.convertValue(dataMap, TransactionStatusResponse.class);
GeneralResp generalResp = responseWrapper.getGeneralResp();
LOGGER.info("Transaction status received: {}", generalResp.getStatus());
ModelMapper mapper = new ModelMapper();
mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
TransactionMaster transactionMaster = mapper.map(responseWrapper.getTransactionDAO(), TransactionMaster.class);
transactionMaster.setTxnId(txnId);
transactionMaster.setReqId(transactionStatusRequest.getReqId());
EntityRelationshipUtil.linkTransactionMasterRelationships(transactionMaster);
transactionMasterRepository.save(transactionMaster);
LOGGER.info("TransactionMaster saved successfully for txnId={}", txnId);
AgentFundTransfer agentFundTransfer = mapper.map(responseWrapper.getAgentFundTransfer(), AgentFundTransfer.class);
agentFundTransfer.setTxnId(txnId);
agentFundTransfer.setReqId(transactionStatusRequest.getReqId());
agentFundTransfer.setTransactionMasterId(transactionMaster.getBankTxnId());
agentFundTransferRepository.save(agentFundTransfer);
LOGGER.info("AgentFundTransfer entry saved successfully for txnId={}", txnId);
ResponseModel responseModel = new ResponseModel(
generalResp.getMessage(),
generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()),
responseWrapper
);
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return responseModel;
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing transaction status JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} }
} }
@@ -222,62 +239,63 @@ public class PaymentServiceImpl implements PaymentService {
String requestId = transactionStatusRequest.getReqId(); String requestId = transactionStatusRequest.getReqId();
String requestJson = helper.convertObjectToJson(transactionStatusRequest); String requestJson = helper.convertObjectToJson(transactionStatusRequest);
String url = paymentUrl + BBPSConstant.CHECK_TRANSACTION_URL + transactionStatusRequest.getTxnId(); String url = paymentUrl + BBPSConstant.CHECK_TRANSACTION_URL + transactionStatusRequest.getTxnId();
LOGGER.info("Checking transaction status (public) for txnId={} and reqId={}", transactionStatusRequest.getTxnId(), requestId);
BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001");
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.set("x-digiledge-key", headersData.getXDigiledgeKey()); headers.set("x-digiledge-key", headersData.getXDigiledgeKey());
headers.set("agentId", headersData.getAgentId()); headers.set("agentId", headersData.getAgentId());
headers.set("tenantId", headersData.getTenantId()); headers.set("tenantId", headersData.getTenantId());
headers.setContentType(MediaType.APPLICATION_JSON); headers.setContentType(MediaType.APPLICATION_JSON);
InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, transactionStatusRequest.getMid(), "POST",
requestJson); InboundTraceLog inboundLog = helper.createInboundLog(requestId, txnID, apiName, transactionStatusRequest.getMid(), "POST", requestJson);
OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, url, "GET", null); OutboundTraceLog outboundLog = helper.createOutboundLog(txnID, requestId, apiName, url, "GET", null);
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
Map<String, String> responseMap = httpService.getRequest(url, headers); Map<String, String> responseMap = httpService.getRequest(url, headers);
String responseData = responseMap.get("data"); String responseData = responseMap.get("data");
LOGGER.info("Transaction status response data: {}", responseData); LOGGER.info("Transaction status response data: {}", responseData);
helper.updateOutboundLogResponse(outboundLog, responseData); helper.updateOutboundLogResponse(outboundLog, responseData);
try { try {
Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {}); Map<String, Object> dataMap = objectMapper.readValue(responseData, new TypeReference<Map<String, Object>>() {});
if (!dataMap.containsKey("generalResp")) {
// If genericResponse key missing, throw exception helper.updateInboundLogFailure(inboundLog, responseData, String.valueOf(dataMap.get("status")));
if (!dataMap.containsKey("generalResp")) { LOGGER.warn("Invalid transaction status response for txnId={} from BBPS", transactionStatusRequest.getTxnId());
helper.updateInboundLogFailure(inboundLog, responseData, String.valueOf(dataMap.get("status"))); throw new CustomException(
throw new CustomException( String.valueOf(dataMap.get("message")),
String.valueOf(dataMap.get("message")), String.valueOf(dataMap.get("status")),
String.valueOf(dataMap.get("status")), Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), String.valueOf(dataMap.get("remarks"))
String.valueOf(dataMap.get("remarks"))
);
}
// Convert into proper DTO
TransactionStatusResponse responseWrapper = objectMapper.convertValue(dataMap, TransactionStatusResponse.class);
GeneralResp generalResp = responseWrapper.getGeneralResp();
String status = generalResp.getStatus();
LOGGER.info("Current transaction status: {}", status);
ResponseModel responseModel = new ResponseModel(
generalResp.getMessage(),
generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()),
responseWrapper
); );
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return responseModel;
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} }
TransactionStatusResponse responseWrapper = objectMapper.convertValue(dataMap, TransactionStatusResponse.class);
GeneralResp generalResp = responseWrapper.getGeneralResp();
String status = generalResp.getStatus();
LOGGER.info("Current transaction status: {}", status);
ResponseModel responseModel = new ResponseModel(
generalResp.getMessage(),
generalResp.getStatus(),
Integer.parseInt(generalResp.getStatusCode()),
responseWrapper
);
helper.updateInboundLogSuccess(inboundLog, responseData, generalResp.getStatus());
return responseModel;
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
throw new CustomException("Invalid JSON received from API");
} }
} }
}
/* /* PollBack logic for the fetchTxnByTxnId API
* @Override public ResponseModel fetchTxnByTxnId(BillFetchByBillIdRequest * @Override public ResponseModel fetchTxnByTxnId(BillFetchByBillIdRequest
* billFetchByBillIdRequest) { * billFetchByBillIdRequest) {
* *
@@ -327,4 +345,75 @@ public class PaymentServiceImpl implements PaymentService {
* } * }
*/ */
/*
* public ResponseModel checkTrasactionStatus(TransactionStatusRequest
* transactionStatusRequest,InboundTraceLog inboundLog) { String apiName =
* "CheckTransactionStatus"; String txnId = helper.generateTxnId(15); //our
* genrated txnId String requestId = transactionStatusRequest.getReqId(); String
* url = paymentUrl + BBPSConstant.CHECK_TRANSACTION_URL +
* transactionStatusRequest.getTxnId(); ;
*
* 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); ObjectMapper objectMapper
* = new ObjectMapper();
*
* OutboundTraceLog outboundLog = helper.createOutboundLog(txnId, requestId,
* apiName, url, "GET", null);
*
* long startTime = System.currentTimeMillis(); long maxWaitTimeMs = 40000; long
* intervalMs = 5000;
*
* while (true) { Map<String, String> responseMap = httpService.getRequest(url,
* headers); String responseData = responseMap.get("data");
* LOGGER.info("Transaction status response: {}", responseData);
*
* helper.updateOutboundLogResponse(outboundLog, responseData);
*
* try { Map<String, Object> dataMap = objectMapper.readValue(responseData, new
* TypeReference<Map<String, Object>>() {});
*
* if (!dataMap.containsKey("generalResp")) {
* helper.updateInboundLogFailure(inboundLog, responseData, "INVALID_RESPONSE");
* throw new CustomException( String.valueOf(dataMap.get("message")),
* String.valueOf(dataMap.get("status")),
* Integer.parseInt(String.valueOf(dataMap.get("statusCode"))),
* String.valueOf(dataMap.get("remarks")) ); }
*
* TransactionStatusResponse responseWrapper =
* objectMapper.convertValue(dataMap, TransactionStatusResponse.class);
* GeneralResp generalResp = responseWrapper.getGeneralResp();
*
* String status = generalResp.getStatus();
* LOGGER.info("Current transaction status: {}", status);
*
* if ("INPROGRESS".equalsIgnoreCase(status)) { if (System.currentTimeMillis() -
* startTime > maxWaitTimeMs) { helper.updateInboundLogFailure(inboundLog,
* "Timeout after 40 seconds", "FAILED"); throw new
* CustomException("Timeout waiting for transaction completion", "FAILED", 408,
* "Transaction still in progress"); }
*
* Thread.sleep(intervalMs); continue; }
*
* ResponseModel responseModel = new ResponseModel( generalResp.getMessage(),
* generalResp.getStatus(), Integer.parseInt(generalResp.getStatusCode()),
* responseWrapper );
*
* helper.updateInboundLogSuccess(inboundLog, responseData,
* generalResp.getStatus()); return responseModel;
*
* } catch (JsonProcessingException e) {
* LOGGER.error("Error parsing transaction status JSON: {}", e.getMessage());
* helper.updateInboundLogFailure(inboundLog, e.getMessage(), "JSON_ERROR");
* throw new CustomException("Invalid JSON received from API"); } catch
* (InterruptedException e) { Thread.currentThread().interrupt();
* helper.updateInboundLogFailure(inboundLog, e.getMessage(), "INTERRUPTED");
* throw new CustomException("Thread interrupted during transaction check"); } }
* }
*
*
*/
@@ -1,6 +1,9 @@
package com.billpaymentservice.bbps.util; package com.billpaymentservice.bbps.util;
import com.billpaymentservice.bbps.entites.*; import com.billpaymentservice.bbps.entites.BillerDetails;
import com.billpaymentservice.bbps.entites.BillerResponseParams;
import com.billpaymentservice.bbps.entites.InterchangeFee;
import com.billpaymentservice.bbps.entites.TransactionMaster;
public class EntityRelationshipUtil { public class EntityRelationshipUtil {
@@ -62,5 +65,29 @@ public class EntityRelationshipUtil {
} }
} }
} }
public static void linkTransactionMasterRelationships(TransactionMaster entity) {
if (entity == null) return;
// ✅ DeviceBlockTag relationship link karna
if (entity.getDeviceBlockTags() != null) {
entity.getDeviceBlockTags().forEach(tag -> {
if (tag != null) {
tag.setTransactionMaster(entity);
}
});
}
// ✅ CustomerParamTransaction relationship link karna
if (entity.getCustomerParams() != null) {
entity.getCustomerParams().forEach(param -> {
if (param != null) {
param.setTransactionMaster(entity);
}
});
}
}
} }
@@ -2,26 +2,36 @@ package com.billpaymentservice.bbps.util;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Function; import java.util.function.Function;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.billpaymentservice.bbps.dto.AdditionalInfoBillDTO;
import com.billpaymentservice.bbps.dto.CustomerParamDAO;
import com.billpaymentservice.bbps.dto.ResponseModel; import com.billpaymentservice.bbps.dto.ResponseModel;
import com.billpaymentservice.bbps.dto.request.BillFetchByBillIdRequest;
import com.billpaymentservice.bbps.dto.response.BillDataResponse;
import com.billpaymentservice.bbps.entites.AdditionalInfoBill;
import com.billpaymentservice.bbps.entites.BBPSMastersData; import com.billpaymentservice.bbps.entites.BBPSMastersData;
import com.billpaymentservice.bbps.exception.CustomException; import com.billpaymentservice.bbps.entites.BillMaster;
import com.billpaymentservice.bbps.repository.BBPSMasterDataRepo; import com.billpaymentservice.bbps.entites.BillerDetails;
import com.billpaymentservice.bbps.repository.InboundTraceLogRepository; import com.billpaymentservice.bbps.entites.BillerResponse;
import com.billpaymentservice.bbps.dto.request.BillerDetailRequest; import com.billpaymentservice.bbps.entites.CustomerParamBill;
import com.billpaymentservice.bbps.dto.request.MerchantRequestModel;
import com.billpaymentservice.bbps.entites.BBPSMerchantValidation;
import com.billpaymentservice.bbps.entites.InboundTraceLog; import com.billpaymentservice.bbps.entites.InboundTraceLog;
import com.billpaymentservice.bbps.entites.OutboundTraceLog; import com.billpaymentservice.bbps.entites.OutboundTraceLog;
import com.billpaymentservice.bbps.entites.PaymentChannel;
import com.billpaymentservice.bbps.entites.PaymentMode;
import com.billpaymentservice.bbps.exception.CustomException; import com.billpaymentservice.bbps.exception.CustomException;
import com.billpaymentservice.bbps.repository.MerchantRepository; import com.billpaymentservice.bbps.repository.BBPSMasterDataRepo;
import com.billpaymentservice.bbps.repository.BillMasterRepository;
import com.billpaymentservice.bbps.repository.BillerDataRepository;
import com.billpaymentservice.bbps.repository.InboundTraceLogRepository;
import com.billpaymentservice.bbps.repository.OutboundTraceLogRepository; import com.billpaymentservice.bbps.repository.OutboundTraceLogRepository;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@Component @Component
@@ -36,13 +46,18 @@ public class Helper {
private final ObjectMapper objectMapper = new ObjectMapper(); private final ObjectMapper objectMapper = new ObjectMapper();
private final BBPSMasterDataRepo bbpsMasterDataRepo; private final BBPSMasterDataRepo bbpsMasterDataRepo;
private final BillerDataRepository billerDataRespository;
private final BillMasterRepository billMasterRepository;
// Constructor Injection // Constructor Injection
public Helper(BBPSMasterDataRepo bbpsMasterDataRepo, InboundTraceLogRepository inboundTraceLogRepository, public Helper(BBPSMasterDataRepo bbpsMasterDataRepo, InboundTraceLogRepository inboundTraceLogRepository,
OutboundTraceLogRepository outboundTraceLogRepository) { OutboundTraceLogRepository outboundTraceLogRepository,BillerDataRepository billerDataRepository,
BillMasterRepository billMasterRepository) {
this.bbpsMasterDataRepo = bbpsMasterDataRepo; this.bbpsMasterDataRepo = bbpsMasterDataRepo;
this.inboundTraceLogRepository = inboundTraceLogRepository; this.inboundTraceLogRepository = inboundTraceLogRepository;
this.outboundTraceLogRepository = outboundTraceLogRepository; this.outboundTraceLogRepository = outboundTraceLogRepository;
this.billerDataRespository=billerDataRepository;
this.billMasterRepository=billMasterRepository;
} }
/** /**
@@ -182,7 +197,110 @@ public class Helper {
outboundLog.setResponseReceiveTime(LocalDateTime.now()); outboundLog.setResponseReceiveTime(LocalDateTime.now());
outboundTraceLogRepository.save(outboundLog); outboundTraceLogRepository.save(outboundLog);
} }
/* ---------- End helpers ---------- */ /* ---------- End helpers ---------- */
public void saveOrUpdateBillerData(BillerDetails newEntity) {
Optional<BillerDetails> existingOpt = billerDataRespository.findByBillerId(newEntity.getBillerId());
if (existingOpt.isPresent()) {
BillerDetails existing = existingOpt.get();
// Update base biller fields
existing.setBillerName(newEntity.getBillerName());
existing.setBillerAliasName(newEntity.getBillerAliasName());
existing.setBillerDescription(newEntity.getBillerDescription());
existing.setStatus(newEntity.getStatus());
existing.setBillerCoverage(newEntity.getBillerCoverage());
// ... (update other simple fields as needed)
// ✅ Clear and replace nested lists to avoid duplicate inserts
existing.getBillerPaymentModes().clear();
if (newEntity.getBillerPaymentModes() != null) {
for (PaymentMode mode : newEntity.getBillerPaymentModes()) {
mode.setBiller(existing);
existing.getBillerPaymentModes().add(mode);
}
}
existing.getBillerPaymentChannels().clear();
if (newEntity.getBillerPaymentChannels() != null) {
for (PaymentChannel channel : newEntity.getBillerPaymentChannels()) {
channel.setBiller(existing);
existing.getBillerPaymentChannels().add(channel);
}
}
billerDataRespository.save(existing);
}
else {
// brand new biller
billerDataRespository.save(newEntity);
}
}
public void saveOrUpdateBillerData(BillDataResponse responseWrapper,
BillFetchByBillIdRequest billFetchByBillIdRequest) {
BillMaster billMaster =new BillMaster();
billMaster.setBillId("12333333hjsdfjsfdj");
billMaster.setRefId(responseWrapper.getRefId());
billMaster.setBillerId(responseWrapper.getBillerId());
billMaster.setStatus(responseWrapper.getStatus());
billMaster.setActionType(responseWrapper.getActionType());
billMaster.setUserId(responseWrapper.getUserId());
billMaster.setReqId(billFetchByBillIdRequest.getReqId()); // if available from your API request
billMaster.setTxnId("jhnjhbhj"); // give it from method
// ---- BILLER RESPONSE ----
BillerResponse billerResponse = new BillerResponse();
if (responseWrapper.getBillerResponse() != null) {
billerResponse.setBillId(responseWrapper.getBillerResponse().getBillId());
billerResponse.setAmount(responseWrapper.getBillerResponse().getAmount());
billerResponse.setBillDate(responseWrapper.getBillerResponse().getBillDate());
billerResponse.setBillNumber(responseWrapper.getBillerResponse().getBillNumber());
billerResponse.setBillPeriod(responseWrapper.getBillerResponse().getBillPeriod());
billerResponse.setCustConvFee(responseWrapper.getBillerResponse().getCustConvFee());
billerResponse.setCouCustConvFee(responseWrapper.getBillerResponse().getCouCustConvFee());
billerResponse.setDueDate(responseWrapper.getBillerResponse().getDueDate());
billerResponse.setCustomerName(responseWrapper.getBillerResponse().getCustomerName());
billerResponse.setAmountOption(responseWrapper.getBillerResponse().isAmountOption());
billerResponse.setBillMaster(billMaster); // maintain mapping
}
billMaster.setBillerResponse(billerResponse);
// ---- ADDITIONAL INFO ----
List<AdditionalInfoBill> additionalInfos = new ArrayList<>();
if (responseWrapper.getAdditionalInfo() != null) {
for (AdditionalInfoBillDTO info : responseWrapper.getAdditionalInfo()) {
AdditionalInfoBill entity = new AdditionalInfoBill();
entity.setName(info.getName());
entity.setValue(info.getValue());
entity.setBillMaster(billMaster); // maintain mapping
additionalInfos.add(entity);
}
}
billMaster.setAdditionalInfo(additionalInfos);
// ---- CUSTOMER PARAMS ----
List<CustomerParamBill> customerParams = new ArrayList<>();
if (responseWrapper.getCustomerParams() != null) {
for (CustomerParamDAO param : responseWrapper.getCustomerParams()) {
CustomerParamBill entity = new CustomerParamBill();
entity.setName(param.getName());
entity.setValue(param.getValue());
entity.setType(param.getType());
entity.setBillMaster(billMaster);
customerParams.add(entity);
}
}
billMaster.setCustomerParams(customerParams);
// ---- DATES ----
billMaster.setCreationDate(responseWrapper.getCreationDate());
billMaster.setModifiedDate(responseWrapper.getModifiedDate());
billMaster.setCreatedEpochDate(responseWrapper.getCreatedEpochDate());
billMaster.setModifiedEpochDate(responseWrapper.getModifiedEpochDate());
billMasterRepository.save(billMaster);
}
} }
@@ -20,7 +20,11 @@ swagger.server.description=Local Development Server
# DataSource # DataSource
spring.datasource.url=jdbc:postgresql://localhost:5432/BBPS spring.datasource.url=jdbc:postgresql://localhost:5432/BBPS
spring.datasource.username=postgres spring.datasource.username=postgres
<<<<<<< HEAD
spring.datasource.password=UAT@DB_2025 spring.datasource.password=UAT@DB_2025
=======
spring.datasource.password=himanshu@123
>>>>>>> 43baedfecdf5e3718ba3e8b932536b3798957d22
spring.datasource.driver-class-name=org.postgresql.Driver spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.type=com.zaxxer.hikari.HikariDataSource spring.datasource.type=com.zaxxer.hikari.HikariDataSource