diff --git a/pom.xml b/pom.xml index efc8bc9..c73831f 100644 --- a/pom.xml +++ b/pom.xml @@ -96,6 +96,12 @@ spring-boot-starter + org.modelmapper + modelmapper + 3.2.0 + + + org.springframework.boot spring-boot-starter-test test diff --git a/src/main/java/com/billpaymentservice/bbps/controller/PaymentController.java b/src/main/java/com/billpaymentservice/bbps/controller/PaymentController.java new file mode 100644 index 0000000..69170b4 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/controller/PaymentController.java @@ -0,0 +1,55 @@ +package com.billpaymentservice.bbps.controller; + +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.billpaymentservice.bbps.dto.ResponseModel; +import com.billpaymentservice.bbps.dto.request.BillPaymentRequest; +import com.billpaymentservice.bbps.dto.request.FetchBillRequest; +import com.billpaymentservice.bbps.dto.request.TransactionStatusRequest; +import com.billpaymentservice.bbps.service.PaymentService; + +@RestController +@RequestMapping("/agent/payment") +public class PaymentController { + + /** + * Fetches bill details from external BBPS service + */ + + private final PaymentService paymentService; + public PaymentController(PaymentService paymentService) { + this.paymentService=paymentService; + } + + @PostMapping( + value = "/intiatePayment", + consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE + ) + public ResponseEntity requestBillFetch( + @Validated @RequestBody BillPaymentRequest billPaymentRequest) { + + ResponseModel response = paymentService.initiatePayment(billPaymentRequest); + return ResponseEntity.ok(response); + } + + @PostMapping( + value = "/checkTransactionStatus", + consumes = MediaType.APPLICATION_JSON_VALUE, + produces = MediaType.APPLICATION_JSON_VALUE + ) + public ResponseEntity checkTransactionStatus( + @Validated @RequestBody TransactionStatusRequest transactionStatusRequest) { + + ResponseModel response = paymentService.checkTrasactionStatus(transactionStatusRequest); + return ResponseEntity.ok(response); + } + + +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/AdditionalInfo.java b/src/main/java/com/billpaymentservice/bbps/dto/AdditionalInfo.java index fa1aa80..cee0dcb 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/AdditionalInfo.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/AdditionalInfo.java @@ -1,15 +1,43 @@ package com.billpaymentservice.bbps.dto; + +import jakarta.persistence.*; +import jakarta.validation.constraints.*; import lombok.Getter; import lombok.Setter; - @Getter - @Setter - public class AdditionalInfo { - private String paramConfigId; - private String paramName; - private String dataTypeDAO; - private String dataTypeModel; - private boolean optional; - private boolean visibility; - } +@Getter +@Setter +@Entity +@Table(name = "additional_info") +public class AdditionalInfo { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; // primary key for the table + + @Column(name = "param_config_id", nullable = false) + @NotBlank(message = "Param Config ID cannot be blank") + private String paramConfigId; + + @Column(name = "param_name", nullable = false) + @NotBlank(message = "Param name cannot be blank") + private String paramName; + + @Column(name = "data_type_dao") + private String dataTypeDAO; + + @Column(name = "data_type_model") + private String dataTypeModel; + + @Column(name = "optional", nullable = false) + private boolean optional; + + @Column(name = "visibility", nullable = false) + private boolean visibility; + + // 🔗 Many AdditionalInfos belong to one Biller + @ManyToOne + @JoinColumn(name = "biller_id", nullable = false) + private BillerDAO biller; +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/AgentFundTransfer.java b/src/main/java/com/billpaymentservice/bbps/dto/AgentFundTransfer.java new file mode 100644 index 0000000..9c4b85a --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/AgentFundTransfer.java @@ -0,0 +1,22 @@ +package com.billpaymentservice.bbps.dto; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class AgentFundTransfer { + @NotBlank private String fundTxnReferenceId; + @NotBlank private String fundTxnRemarks; + @NotBlank private String fundTxnDate; + + @NotNull private Double fundTxnAmt; + + @NotBlank private String fundUTR; + private String fundRespRemarks; + private String agentNpciId; + private String txnRefId; + + @NotBlank private String fundStatus; // FUND_TRANSFER_SUCCESS or FUND_TRANSFER_FAILED +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/AmountOption.java b/src/main/java/com/billpaymentservice/bbps/dto/AmountOption.java index 574e92d..b020587 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/AmountOption.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/AmountOption.java @@ -1,15 +1,32 @@ package com.billpaymentservice.bbps.dto; -import java.util.List; +import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; +import java.util.List; +@Entity +@Table(name = "amount_option") @Getter @Setter public class AmountOption { - private String amountOptionId; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "amount_option_id") + private Long id; + + @ElementCollection + @CollectionTable( + name = "amount_option_breakup_sets", + joinColumns = @JoinColumn(name = "amount_option_id") + ) + @Column(name = "amount_breakup_value") private List amountBreakupSets; - + // 🔗 Relationship with BillerResponseParams + @ManyToOne + @JoinColumn(name = "biller_response_id", nullable = false) + private BillerResponseParams billerResponseParams; } diff --git a/src/main/java/com/billpaymentservice/bbps/dto/BillerDAO.java b/src/main/java/com/billpaymentservice/bbps/dto/BillerDAO.java index 3892abc..6a1f64e 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/BillerDAO.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/BillerDAO.java @@ -1,58 +1,158 @@ package com.billpaymentservice.bbps.dto; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import lombok.Getter; +import lombok.Setter; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + import java.util.List; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -import lombok.Getter; -import lombok.Setter; - @Getter @Setter +@Entity +@Table(name = "biller_details") @JsonIgnoreProperties(ignoreUnknown = true) public class BillerDAO { - private String billerId; - private String billerName; - private String billerAliasName; - private String billerCategoryName; - private String billerMode; - private boolean billerAcceptsAdhoc; - private boolean parentBiller; - private String parentBillerId; - private String billerOwnerShp; - private String billerCoverage; - private String fetchRequirement; - private String paymentAmountExactness; - private String supportBillValidation; - private String billerEffctvFrom; - private String billerEffctvTo; - private String billerTempDeactivationStart; - private String billerTempDeactivationEnd; - - private List billerPaymentModes; - private List billerPaymentChannels; - private List billerCustomerParams; - private CustomerParamGroups customerParamGroups; - private BillerResponseParams billerResponseParams; - private List billerAdditionalInfos; - private List billerAdditionalInfoPayments; - private List interchangeFeeConves; - private List interchangeFees; - private String status; - private String billerDescription; - private String supportDeemed; - private String supportPendingStatus; - private String billerTimeOut; - private String routeUrl; + @Id + @Column(name = "biller_id", length = 14, nullable = false, unique = true) + @NotBlank(message = "Biller ID is mandatory") + @Size(min = 14, max = 14, message = "Biller ID must be 14 characters long") + private String billerId; + + @Column(name = "biller_name", nullable = false) + @NotBlank(message = "Biller name cannot be blank") + private String billerName; + + @Column(name = "biller_alias_name", nullable = false) + @NotBlank(message = "Biller alias name cannot be blank") + private String billerAliasName; + + @Column(name = "biller_category_name", nullable = false) + @NotBlank(message = "Biller category name cannot be blank") + private String billerCategoryName; + + @Column(name = "biller_mode", nullable = false) + @NotBlank(message = "Biller mode cannot be blank") + private String billerMode; + + @Column(name = "biller_accepts_adhoc", nullable = false) + private boolean billerAcceptsAdhoc; + + @Column(name = "parent_biller", nullable = false) + private boolean parentBiller; + + @Column(name = "parent_biller_id", nullable = false) + @NotBlank(message = "Parent biller ID cannot be blank") + private String parentBillerId; + + @Column(name = "biller_ownership", nullable = false) + @NotBlank(message = "Biller ownership is required (PSU or Private)") + private String billerOwnerShp; + + @Column(name = "biller_coverage", nullable = false) + @NotBlank(message = "Biller coverage cannot be blank") + private String billerCoverage; + + @Column(name = "fetch_requirement", nullable = false) + @NotBlank(message = "Fetch requirement is mandatory") + private String fetchRequirement; + + @Column(name = "payment_amount_exactness", nullable = false) + @NotBlank(message = "Payment amount exactness is required") + private String paymentAmountExactness; + + @Column(name = "support_bill_validation", nullable = false) + @NotBlank(message = "Support bill validation is required") + private String supportBillValidation; + + @Column(name = "biller_effctv_from", nullable = false) + @NotBlank(message = "Effective from date is required") + private String billerEffctvFrom; + + @Column(name = "biller_effctv_to", nullable = false) + @NotBlank(message = "Effective to date is required") + private String billerEffctvTo; + + @Column(name = "biller_temp_deactivation_start") + private String billerTempDeactivationStart; + + @Column(name = "biller_temp_deactivation_end") + private String billerTempDeactivationEnd; + + @Column(name = "biller_description", nullable = false, length = 500) + @NotBlank(message = "Biller description cannot be blank") + private String billerDescription; + + @Column(name = "biller_response_type", nullable = false) + @NotBlank(message = "Biller response type is required (SINGLE or SELECTIVE)") private String billerResponseType; - private BillerPlanResponseParams billerPlanResponseParams; + + @Column(name = "plan_mdm_requirement", nullable = false) + @NotBlank(message = "Plan MDM requirement cannot be blank") private String planMDMRequirement; - private List planAdditionalInfos; - private String upmsEnabled; - private String clickpayEnabled; - private String deemedSuccessEnabled; + + @Column(name = "status", nullable = false) + @NotBlank(message = "Status must be ACTIVE or INACTIVE") + private String status; + + @Column(name = "support_deemed", nullable = false) + @NotBlank(message = "Support deemed value is required (Yes/No)") + private String supportDeemed; + + @Column(name = "support_pending_status", nullable = false) + @NotBlank(message = "Support pending status is required (Yes/No)") + private String supportPendingStatus; + + @Column(name = "biller_time_out", nullable = false) + @NotBlank(message = "Biller timeout is required") + private String billerTimeOut; + + @Column(name = "route_url") + private String routeUrl; + + @Column(name = "upms_enabled") + private String upmsEnabled; + + @Column(name = "clickpay_enabled") + private String clickpayEnabled; + + @Column(name = "deemed_success_enabled") + private String deemedSuccessEnabled; + + @Column(name = "selection_type") private String selectionType; - // getters and setters + // ✅ Relationships — Each maps to its sub-arrays or objects in API + + @OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval = true) + private List billerPaymentModes; + + @OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval = true) + private List billerPaymentChannels; + + @OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval = true) + private List billerCustomerParams; + + @OneToOne(mappedBy = "biller", cascade = CascadeType.ALL) + private CustomerParamGroups customerParamGroups; + + @OneToOne(mappedBy = "biller", cascade = CascadeType.ALL) + private BillerResponseParams billerResponseParams; + + @OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval = true) + private List billerAdditionalInfos; + + @OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval = true) + private List billerAdditionalInfoPayments; + + @OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval = true) + private List interchangeFeeConves; + + @OneToMany(mappedBy = "biller", cascade = CascadeType.ALL, orphanRemoval = true) + private List interchangeFees; + + @OneToOne(mappedBy = "biller", cascade = CascadeType.ALL) + private BillerPlanResponseParams billerPlanResponseParams; } diff --git a/src/main/java/com/billpaymentservice/bbps/dto/BillerPlanResponseParams.java b/src/main/java/com/billpaymentservice/bbps/dto/BillerPlanResponseParams.java index 00baff0..32a1fc0 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/BillerPlanResponseParams.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/BillerPlanResponseParams.java @@ -5,12 +5,36 @@ import java.util.List; import lombok.Getter; import lombok.Setter; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import lombok.Getter; +import lombok.Setter; +import java.util.List; + @Getter @Setter +@Entity +@Table(name = "biller_plan_response_params") public class BillerPlanResponseParams { - private String billerPlanResponseId; - private List params; - private List amountOptions; - // getters and setters + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; // Primary Key + + @Column(name = "biller_plan_response_id", nullable = false, unique = true) + @NotBlank(message = "Biller Plan Response ID cannot be blank") + private String billerPlanResponseId; + + // ✅ params list — since it's not a separate table, we can store as JSON or text + @Column(name = "params", columnDefinition = "TEXT") + private String paramsJson; + + @Column(name = "amount_options", columnDefinition = "TEXT") + private String amountOptionsJson; + + // 🔗 Relationship with BillerDAO + @OneToOne + @JoinColumn(name = "biller_id", nullable = false) + private BillerDAO biller; } + diff --git a/src/main/java/com/billpaymentservice/bbps/dto/BillerResponseParams.java b/src/main/java/com/billpaymentservice/bbps/dto/BillerResponseParams.java index 28b7f6e..aba6893 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/BillerResponseParams.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/BillerResponseParams.java @@ -1,16 +1,39 @@ package com.billpaymentservice.bbps.dto; -import java.util.List; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; +import java.util.List; @Getter @Setter +@Entity +@Table(name = "biller_response_params") public class BillerResponseParams { - private String billerResponseId; - private List params; - private List amountOptions; - // getters and setters + @Id + @Column(name = "biller_response_id", nullable = false, unique = true) + @NotBlank(message = "Biller Response ID is required") + private String billerResponseId; + + // 🔗 One-to-One Relationship with BillerDAO + @OneToOne + @JoinColumn(name = "biller_id", nullable = false) + private BillerDAO biller; + + // ✅ Since params and amountOptions are lists of objects, + // we can store them as JSON or in a separate table (simplified here using @ElementCollection) + + @ElementCollection + @CollectionTable( + name = "biller_response_params_data", + joinColumns = @JoinColumn(name = "biller_response_id") + ) + @Column(name = "param_value") + private List params; + + @OneToMany(mappedBy = "billerResponseParams", cascade = CascadeType.ALL, orphanRemoval = true) + private List amountOptions; } diff --git a/src/main/java/com/billpaymentservice/bbps/dto/CustomerParam.java b/src/main/java/com/billpaymentservice/bbps/dto/CustomerParam.java index 7323370..ba3850f 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/CustomerParam.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/CustomerParam.java @@ -1,26 +1,58 @@ package com.billpaymentservice.bbps.dto; -import java.util.List; - -import com.fasterxml.jackson.annotation.JsonAlias; - +import jakarta.persistence.*; +import jakarta.validation.constraints.*; import lombok.Getter; import lombok.Setter; +import java.util.List; + @Getter @Setter +@Entity +@Table(name = "customer_param") public class CustomerParam { - private String paramConfigId; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "param_config_id") + private Long id; // Primary key + + @NotBlank(message = "Parameter name is required") + @Column(name = "param_name", nullable = false) private String paramName; + @Column(name = "data_type_dao") private String dataTypeDAO; + + @Column(name = "data_type_model") private String dataTypeModel; + + @Column(name = "is_optional") private boolean optional; + + @Min(0) + @Column(name = "min_length") private int minLength; + + @Min(0) + @Column(name = "max_length") private int maxLength; + + @Column(name = "regex") private String regex; + + @Column(name = "is_visible") private boolean visibility; - // 👇 Add this new line + + // Store list of values as JSON or comma-separated string + @ElementCollection + @CollectionTable(name = "customer_param_values", joinColumns = @JoinColumn(name = "param_id")) + @Column(name = "value") private List values; - // getters and setters -} \ No newline at end of file + + // 🔗 Many customer parameters belong to one biller + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "biller_id") + private BillerDAO biller; +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/CustomerParamBill.java b/src/main/java/com/billpaymentservice/bbps/dto/CustomerParamBill.java deleted file mode 100644 index 6e985e9..0000000 --- a/src/main/java/com/billpaymentservice/bbps/dto/CustomerParamBill.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.billpaymentservice.bbps.dto; - -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; - -@Getter -@Setter -@AllArgsConstructor -@NoArgsConstructor -public class CustomerParamBill { - private String name; - private String value; - private String type; -} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/CustomerParamDAO.java b/src/main/java/com/billpaymentservice/bbps/dto/CustomerParamDAO.java new file mode 100644 index 0000000..838b960 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/CustomerParamDAO.java @@ -0,0 +1,14 @@ +package com.billpaymentservice.bbps.dto; + +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class CustomerParamDAO { + @NotBlank private String paramsId; + @NotBlank private String name; + @NotBlank private String value; + private String type; +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/CustomerParamGroups.java b/src/main/java/com/billpaymentservice/bbps/dto/CustomerParamGroups.java index a90d01c..0c77583 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/CustomerParamGroups.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/CustomerParamGroups.java @@ -1,14 +1,29 @@ package com.billpaymentservice.bbps.dto; -import java.util.List; - +import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; +import java.util.List; + @Getter @Setter +@Entity +@Table(name = "customer_param_groups") public class CustomerParamGroups { - private List groups; - // getters and setters + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "group_container_id") + private Long id; + + // 🔗 One set of groups belongs to one biller + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "biller_id") + private BillerDAO biller; + + // 🔗 One CustomerParamGroups contains multiple Group objects + @OneToMany(mappedBy = "customerParamGroups", cascade = CascadeType.ALL, orphanRemoval = true) + private List groups; } + diff --git a/src/main/java/com/billpaymentservice/bbps/dto/Group.java b/src/main/java/com/billpaymentservice/bbps/dto/Group.java index 0f85a49..d9ea685 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/Group.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/Group.java @@ -1,17 +1,46 @@ package com.billpaymentservice.bbps.dto; -import java.util.List; +import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; +import java.util.List; + @Getter @Setter +@Entity +@Table(name = "biller_groups") public class Group { - private String groupId; - private List params; // e.g., ["Admission No/Application No/GR No"] - private List groups; // nested groups - private String name; // group name - private String input; // input count as string - // getters and setters + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "group_id") + private Long id; + + @Column(name = "group_name") + private String name; + + @Column(name = "input") + private String input; + + // Example: "Admission No/Application No/GR No" → stored as multiple params + @ElementCollection + @CollectionTable(name = "group_params", joinColumns = @JoinColumn(name = "group_id")) + @Column(name = "param_name") + private List params; + + // 🔗 Parent group relationship (for nested groups) + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "parent_group_id") + private Group parentGroup; + + // 🔁 Child groups (self-reference) + @OneToMany(mappedBy = "parentGroup", cascade = CascadeType.ALL, orphanRemoval = true) + private List groups; + + // 🔗 Back reference to CustomerParamGroups + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "group_container_id") + private CustomerParamGroups customerParamGroups; } diff --git a/src/main/java/com/billpaymentservice/bbps/dto/InterchangeFee.java b/src/main/java/com/billpaymentservice/bbps/dto/InterchangeFee.java index d5950fb..f56570f 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/InterchangeFee.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/InterchangeFee.java @@ -5,14 +5,43 @@ import java.util.List; import lombok.Getter; import lombok.Setter; + +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import lombok.Getter; +import lombok.Setter; +import java.util.List; + @Getter @Setter +@Entity +@Table(name = "interchange_fee") public class InterchangeFee { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; // Primary key + + @Column(name = "interchange_fee_id", nullable = false, unique = true) + @NotBlank(message = "Interchange Fee ID cannot be blank") private String interchangeFeeId; + + @Column(name = "fee_code", nullable = false) + @NotBlank(message = "Fee code is mandatory") private String feeCode; + + @Column(name = "fee_description") private String feeDesc; + + @Column(name = "fee_direction") private String feeDirection; + + // ✅ Relationship with InterchangeFeeDetail (One-to-Many) + @OneToMany(mappedBy = "interchangeFee", cascade = CascadeType.ALL, orphanRemoval = true) private List interchangeFeeDetails; - // getters and setters + // 🔗 Many InterchangeFee entries belong to one Biller + @ManyToOne + @JoinColumn(name = "biller_id", nullable = false) + private BillerDAO biller; } diff --git a/src/main/java/com/billpaymentservice/bbps/dto/InterchangeFeeConf.java b/src/main/java/com/billpaymentservice/bbps/dto/InterchangeFeeConf.java index 9d1c0a5..a69f152 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/InterchangeFeeConf.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/InterchangeFeeConf.java @@ -5,18 +5,59 @@ import java.util.List; import lombok.Getter; import lombok.Setter; + +import jakarta.persistence.*; +import jakarta.validation.constraints.*; +import lombok.Getter; +import lombok.Setter; +import java.util.List; + @Getter @Setter +@Entity +@Table(name = "interchange_fee_conf") public class InterchangeFeeConf { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; // Primary Key for DB table + + @Column(name = "interchange_fee_conf_id", nullable = false, unique = true) + @NotBlank(message = "Interchange Fee Config ID cannot be blank") private String interChangeFeeConfId; + + @Column(name = "mti") private String mti; + + @Column(name = "payment_mode") private String paymentMode; + + @Column(name = "payment_channel") private String paymentChannel; + + @Column(name = "response_code") private String responseCode; + + // ⚙️ Since 'fees' is a list of simple strings, we use ElementCollection + @ElementCollection + @CollectionTable( + name = "interchange_fee_conf_fees", + joinColumns = @JoinColumn(name = "interchange_fee_conf_id_fk") + ) + @Column(name = "fee_value") private List fees; + + @Column(name = "default_fee") private boolean defaultFee; + + @Column(name = "effective_from") private String effctvFrom; + + @Column(name = "effective_to") private String effctvTo; - // getters and setters -} \ No newline at end of file + // 🔗 Many InterchangeFeeConf records belong to one Biller + @ManyToOne + @JoinColumn(name = "biller_id", nullable = false) + private BillerDAO biller; +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/InterchangeFeeDetail.java b/src/main/java/com/billpaymentservice/bbps/dto/InterchangeFeeDetail.java index 3fa584d..b25fcfa 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/InterchangeFeeDetail.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/InterchangeFeeDetail.java @@ -1,17 +1,39 @@ package com.billpaymentservice.bbps.dto; +import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; +@Entity +@Table(name = "interchange_fee_detail") @Getter @Setter public class InterchangeFeeDetail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "interchange_fee_det_id", unique = true, nullable = false) private String interchangeFeeDetId; + + @Column(name = "tran_amt_range_max") private long tranAmtRangeMax; + + @Column(name = "tran_amt_range_min") private long tranAmtRangeMin; + + @Column(name = "percent_fee") private double percentFee; + + @Column(name = "flat_fee") private double flatFee; + + @Column(name = "effctv_from") private String effctvFrom; - // getters and setters + // 🔗 Many InterchangeFeeDetail belong to one InterchangeFee + @ManyToOne + @JoinColumn(name = "interchange_fee_id", nullable = false) + private InterchangeFee interchangeFee; } diff --git a/src/main/java/com/billpaymentservice/bbps/dto/PaymentChannel.java b/src/main/java/com/billpaymentservice/bbps/dto/PaymentChannel.java index 85f970b..0f9a93a 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/PaymentChannel.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/PaymentChannel.java @@ -1,17 +1,39 @@ package com.billpaymentservice.bbps.dto; +import jakarta.persistence.*; +import jakarta.validation.constraints.*; import lombok.Getter; import lombok.Setter; +import com.fasterxml.jackson.annotation.JsonProperty; @Getter @Setter +@Entity +@Table(name = "payment_channel") public class PaymentChannel { - private String paymentChannelLimitId; + + @Id + @Column(name = "payment_channel_limit_id") + @JsonProperty("paymentChannelLimitId") // 👈 Map JSON field to this property + private String id; // Primary key (manual, not auto-generated) + + @NotBlank(message = "Payment channel is required") + @Column(name = "payment_channel", nullable = false) private String paymentChannel; + + @Min(value = 0, message = "Max limit cannot be negative") + @Column(name = "max_limit") private long maxLimit; + + @Min(value = 0, message = "Min limit cannot be negative") + @Column(name = "min_limit") private long minLimit; + + @Column(name = "support_pending_status") private String supportPendingStatus; - // getters and setters + // 🔗 Many PaymentChannels belong to one Biller + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "biller_id") + private BillerDAO biller; } - diff --git a/src/main/java/com/billpaymentservice/bbps/dto/PaymentMode.java b/src/main/java/com/billpaymentservice/bbps/dto/PaymentMode.java index 34b5299..5c17269 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/PaymentMode.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/PaymentMode.java @@ -1,18 +1,45 @@ package com.billpaymentservice.bbps.dto; + +import jakarta.persistence.*; +import jakarta.validation.constraints.*; import lombok.Getter; import lombok.Setter; @Getter @Setter +@Entity +@Table(name = "biller_payment_modes") public class PaymentMode { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "payment_model_limit_id", unique = true, length = 50) + @NotBlank(message = "Payment model limit ID cannot be blank") private String paymentModelLimitId; + + @Column(name = "payment_mode", nullable = false, length = 50) + @NotBlank(message = "Payment mode is mandatory") private String paymentMode; + + @Column(name = "max_limit") + @PositiveOrZero(message = "Max limit must be zero or positive") private long maxLimit; + + @Column(name = "min_limit") + @PositiveOrZero(message = "Min limit must be zero or positive") private long minLimit; + + @Column(name = "support_pending_status", length = 10) + @Pattern(regexp = "^(Yes|No)?$", message = "Support pending status must be either 'Yes' or 'No'") private String supportPendingStatus; - + // 🔗 Many-to-One relationship with BillerDAO + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "biller_id", nullable = false) + private BillerDAO biller; } diff --git a/src/main/java/com/billpaymentservice/bbps/dto/TransactionDAO.java b/src/main/java/com/billpaymentservice/bbps/dto/TransactionDAO.java new file mode 100644 index 0000000..04c29e3 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/TransactionDAO.java @@ -0,0 +1,63 @@ +package com.billpaymentservice.bbps.dto; + +import java.time.LocalDateTime; +import java.util.List; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; + public class TransactionDAO { + + @NotBlank private String txnId; + @NotBlank private String refId; + + private String txnNpciId; + + @NotBlank private String orderId; + @NotBlank private String billId; + @NotBlank private String userType; + @NotBlank private String userId; + + @NotNull private Double txnAmount; + @NotNull private Double totalTxnAmount; + + @NotBlank private String billerId; + @NotBlank private String billerCategory; + @NotBlank 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 List amountTags; + private List customerParamsDAOS; + private List paymentInformation; + + private List customerParamsDAO; + + private String planId; + private String planType; + + private LocalDateTime creationDate; + private LocalDateTime modifiedDate; + + private Long createdEpochDate; + private Long modifiedEpochDate; + } + + diff --git a/src/main/java/com/billpaymentservice/bbps/dto/request/AmountBreakRequest.java b/src/main/java/com/billpaymentservice/bbps/dto/request/AmountBreakRequest.java new file mode 100644 index 0000000..7276ce3 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/request/AmountBreakRequest.java @@ -0,0 +1,11 @@ +package com.billpaymentservice.bbps.dto.request; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class AmountBreakRequest { + private String name; + private double value; +} \ No newline at end of file diff --git a/src/main/java/com/billpaymentservice/bbps/dto/request/BillPaymentRequest.java b/src/main/java/com/billpaymentservice/bbps/dto/request/BillPaymentRequest.java new file mode 100644 index 0000000..ae83835 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/request/BillPaymentRequest.java @@ -0,0 +1,30 @@ +package com.billpaymentservice.bbps.dto.request; +import java.util.List; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class BillPaymentRequest { + + private String tenantId; + private String refId; + private String billId; + private boolean amountOptions; + private String paymentMode; + private String paymentInformation; + private String billerId; + private String billerName; + private String billerCategory; + private String macAdress; + private String customerMobNo; + private Integer txnAmount; + private String paymentRefId; + private String paymentChannel; + + private List deviceBlockTags; + private List customerParamsRequest; + private List remitterIdentity; + private List amountBreakSet; +} + diff --git a/src/main/java/com/billpaymentservice/bbps/dto/request/CustomerParamTagRequest.java b/src/main/java/com/billpaymentservice/bbps/dto/request/CustomerParamTagRequest.java new file mode 100644 index 0000000..2b0d73f --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/request/CustomerParamTagRequest.java @@ -0,0 +1,12 @@ +package com.billpaymentservice.bbps.dto.request; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class CustomerParamTagRequest { + private String name; + private String value; +} + diff --git a/src/main/java/com/billpaymentservice/bbps/dto/request/DeviceBlockTagRequest.java b/src/main/java/com/billpaymentservice/bbps/dto/request/DeviceBlockTagRequest.java new file mode 100644 index 0000000..9b11800 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/request/DeviceBlockTagRequest.java @@ -0,0 +1,11 @@ +package com.billpaymentservice.bbps.dto.request; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class DeviceBlockTagRequest { + private String name; + private String value; +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/request/RemitterIdentityRequest.java b/src/main/java/com/billpaymentservice/bbps/dto/request/RemitterIdentityRequest.java new file mode 100644 index 0000000..22cc067 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/request/RemitterIdentityRequest.java @@ -0,0 +1,11 @@ +package com.billpaymentservice.bbps.dto.request; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class RemitterIdentityRequest { + private String name; + private String value; +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/request/TransactionStatusRequest.java b/src/main/java/com/billpaymentservice/bbps/dto/request/TransactionStatusRequest.java new file mode 100644 index 0000000..32f90bc --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/request/TransactionStatusRequest.java @@ -0,0 +1,9 @@ +package com.billpaymentservice.bbps.dto.request; + +import jakarta.validation.constraints.NotNull; + +public class TransactionStatusRequest extends BaseClass{ + @NotNull + private String txnId; // UUID of transaction + +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/response/BillDataResponse.java b/src/main/java/com/billpaymentservice/bbps/dto/response/BillDataResponse.java index d53db3a..17e792d 100644 --- a/src/main/java/com/billpaymentservice/bbps/dto/response/BillDataResponse.java +++ b/src/main/java/com/billpaymentservice/bbps/dto/response/BillDataResponse.java @@ -4,7 +4,7 @@ import java.util.List; import com.billpaymentservice.bbps.dto.AdditionalInfoBill; import com.billpaymentservice.bbps.dto.BillerResponseBill; -import com.billpaymentservice.bbps.dto.CustomerParamBill; +import com.billpaymentservice.bbps.dto.CustomerParamDAO; import com.billpaymentservice.bbps.dto.GeneralResp; import com.billpaymentservice.bbps.dto.GeneralResponse; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @@ -31,7 +31,7 @@ public class BillDataResponse { private BillerResponseBill billerResponse; // nested object private List additionalInfo; // array of objects - private List customerParams; // array of objects + private List customerParams; // array of objects private String creationDate; private String modifiedDate; diff --git a/src/main/java/com/billpaymentservice/bbps/dto/response/BillPaymentResponse.java b/src/main/java/com/billpaymentservice/bbps/dto/response/BillPaymentResponse.java new file mode 100644 index 0000000..93d0fcd --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/response/BillPaymentResponse.java @@ -0,0 +1,21 @@ +package com.billpaymentservice.bbps.dto.response; + +import com.billpaymentservice.bbps.dto.GeneralResp; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class BillPaymentResponse { + + private String txnId; + private String refId; + private String billerId; + private String billerCategory; + private String actionType; + private String status; + private double txnAmount; + private String paymentMode; + private String currency; + private GeneralResp genericResponse; // ✅ Common response block +} diff --git a/src/main/java/com/billpaymentservice/bbps/dto/response/TransactionStatusResponse.java b/src/main/java/com/billpaymentservice/bbps/dto/response/TransactionStatusResponse.java new file mode 100644 index 0000000..258f6bc --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/dto/response/TransactionStatusResponse.java @@ -0,0 +1,24 @@ +package com.billpaymentservice.bbps.dto.response; + +import com.billpaymentservice.bbps.dto.AgentFundTransfer; +import com.billpaymentservice.bbps.dto.GeneralResp; +import com.billpaymentservice.bbps.dto.TransactionDAO; +import com.fasterxml.jackson.annotation.JsonProperty; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class TransactionStatusResponse { + + @JsonProperty("transactionDAO") + private TransactionDAO transactionDAO; + + @JsonProperty("agentFundTransfer") + private AgentFundTransfer agentFundTransfer; + + @JsonProperty("generalResp") + private GeneralResp generalResp; +} + diff --git a/src/main/java/com/billpaymentservice/bbps/entites/AgentFundTransferEntity.java b/src/main/java/com/billpaymentservice/bbps/entites/AgentFundTransferEntity.java new file mode 100644 index 0000000..f687f91 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/entites/AgentFundTransferEntity.java @@ -0,0 +1,32 @@ +package com.billpaymentservice.bbps.entites; + + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; + +@Entity +@Getter +@Setter +@Table(name = "agent_fund_transfer") +public class AgentFundTransferEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String fundTxnReferenceId; + + @Column(nullable = false) + private String fundTxnRemarks; + + private String fundTxnDate; + private Double fundTxnAmt; + private String fundUTR; + private String fundRespRemarks; + private String agentNpciId; + private String txnRefId; + private String fundStatus; +} + diff --git a/src/main/java/com/billpaymentservice/bbps/entites/BeneficiaryDetails.java b/src/main/java/com/billpaymentservice/bbps/entites/BharatConnectMaster.java similarity index 89% rename from src/main/java/com/billpaymentservice/bbps/entites/BeneficiaryDetails.java rename to src/main/java/com/billpaymentservice/bbps/entites/BharatConnectMaster.java index 42b5909..758396c 100644 --- a/src/main/java/com/billpaymentservice/bbps/entites/BeneficiaryDetails.java +++ b/src/main/java/com/billpaymentservice/bbps/entites/BharatConnectMaster.java @@ -22,8 +22,8 @@ import lombok.Setter; @AllArgsConstructor @NoArgsConstructor @Entity -@Table(name = "beneficiary_details") -public class BeneficiaryDetails extends Auditable { +@Table(name = "Bharat_connect_master") +public class BharatConnectMaster extends Auditable { @Id @Column(name = "org_id", nullable = false, unique = true, length = 50) @@ -48,4 +48,7 @@ public class BeneficiaryDetails extends Auditable { @Column(name = "api_base_url", length = 500) private String apiBaseUrl; + + @Column(name = "is_active") + private boolean isActive=false; } diff --git a/src/main/java/com/billpaymentservice/bbps/entites/BillPayment.java b/src/main/java/com/billpaymentservice/bbps/entites/BillPayment.java new file mode 100644 index 0000000..c4ed1cc --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/entites/BillPayment.java @@ -0,0 +1,55 @@ +package com.billpaymentservice.bbps.entites; + +import java.time.LocalDateTime; +import java.util.List; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Entity +@Table(name = "bill_payment") +public class BillPayment { + + @Id + @Column(name = "txn_id") + private String txnId; + + @Column(name = "ref_id") + private String refId; + + @Column(name = "biller_id") + private String billerId; + + @Column(name = "biller_category") + private String billerCategory; + + @Column(name = "biller_name") + private String billerName; + + @Column(name = "payment_mode") + private String paymentMode; + + @Column(name = "txn_amount") + private double txnAmount; + + @Column(name = "status") + private String status; + + @Column(name = "currency") + private String currency; + + @Column(name = "payment_channel") + private String paymentChannel; + + @Column(name = "customer_mobile") + private String customerMobNo; + + @Column(name = "created_at") + private LocalDateTime createdAt = LocalDateTime.now(); + + // 🔗 One bill payment has many remitter identities + @OneToMany(mappedBy = "billPayment", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true) + private List remitterIdentities; +} diff --git a/src/main/java/com/billpaymentservice/bbps/entites/CustomerParamDAO.java b/src/main/java/com/billpaymentservice/bbps/entites/CustomerParamDAO.java new file mode 100644 index 0000000..d9ce0d7 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/entites/CustomerParamDAO.java @@ -0,0 +1,22 @@ +package com.billpaymentservice.bbps.entites; + + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; + +@Entity +@Getter +@Setter +@Table(name = "customer_params") +public class CustomerParamDAO { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String paramsId; + private String name; + private String value; + private String type; +} diff --git a/src/main/java/com/billpaymentservice/bbps/entites/RemitterIdentity.java b/src/main/java/com/billpaymentservice/bbps/entites/RemitterIdentity.java new file mode 100644 index 0000000..66d2e1b --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/entites/RemitterIdentity.java @@ -0,0 +1,28 @@ +package com.billpaymentservice.bbps.entites; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Entity +@Table(name = "remitter_identity") +public class RemitterIdentity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "name") + private String name; + + @Column(name = "value") + private String value; + + // Many remitter identities belong to one bill payment + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "txn_id") + private BillPayment billPayment; +} diff --git a/src/main/java/com/billpaymentservice/bbps/entites/TransactionStatus.java b/src/main/java/com/billpaymentservice/bbps/entites/TransactionStatus.java new file mode 100644 index 0000000..cf9a9f5 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/entites/TransactionStatus.java @@ -0,0 +1,66 @@ +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 customerParamsDAO; +} diff --git a/src/main/java/com/billpaymentservice/bbps/repository/BeneficiaryDetailsRepository.java b/src/main/java/com/billpaymentservice/bbps/repository/BharatConnectMasterRepository.java similarity index 53% rename from src/main/java/com/billpaymentservice/bbps/repository/BeneficiaryDetailsRepository.java rename to src/main/java/com/billpaymentservice/bbps/repository/BharatConnectMasterRepository.java index aa7a763..8eb7927 100644 --- a/src/main/java/com/billpaymentservice/bbps/repository/BeneficiaryDetailsRepository.java +++ b/src/main/java/com/billpaymentservice/bbps/repository/BharatConnectMasterRepository.java @@ -3,11 +3,11 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import org.springframework.web.servlet.function.ServerRequest.Headers; -import com.billpaymentservice.bbps.entites.BeneficiaryDetails; +import com.billpaymentservice.bbps.entites.BharatConnectMaster; @Repository -public interface BeneficiaryDetailsRepository extends JpaRepository +public interface BharatConnectMasterRepository extends JpaRepository { - public BeneficiaryDetails findByOrgId(String orgId); + public BharatConnectMaster findByOrgId(String orgId); } diff --git a/src/main/java/com/billpaymentservice/bbps/repository/BillerDataRepository.java b/src/main/java/com/billpaymentservice/bbps/repository/BillerDataRepository.java new file mode 100644 index 0000000..c798e17 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/repository/BillerDataRepository.java @@ -0,0 +1,34 @@ +package com.billpaymentservice.bbps.repository; + + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import com.billpaymentservice.bbps.dto.BillerDAO; +import java.util.List; + +@Repository +public interface BillerDataRepository extends JpaRepository { + + // ✅ Custom finder methods + + // Find billers by category name + List findByBillerCategoryName(String billerCategoryName); + + // Find all active billers + List findByStatus(String status); + + // Find billers by alias name + BillerDAO findByBillerAliasName(String billerAliasName); + + // Find billers by parent biller ID + List findByParentBillerId(String parentBillerId); + + // Check if a biller exists by name + boolean existsByBillerName(String billerName); + + // Fetch biller by mode (e.g., ONLINE, OFFLINE) + List findByBillerMode(String billerMode); + + // Fetch biller by ownership (PSU / PRIVATE) + List findByBillerOwnerShp(String billerOwnerShp); +} diff --git a/src/main/java/com/billpaymentservice/bbps/repository/PaymentRepository.java b/src/main/java/com/billpaymentservice/bbps/repository/PaymentRepository.java new file mode 100644 index 0000000..c710a69 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/repository/PaymentRepository.java @@ -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.BillPayment; + +@Repository +public interface PaymentRepository extends JpaRepository { + +} diff --git a/src/main/java/com/billpaymentservice/bbps/service/PaymentService.java b/src/main/java/com/billpaymentservice/bbps/service/PaymentService.java new file mode 100644 index 0000000..84596f4 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/service/PaymentService.java @@ -0,0 +1,14 @@ +package com.billpaymentservice.bbps.service; + +import com.billpaymentservice.bbps.dto.ResponseModel; +import com.billpaymentservice.bbps.dto.request.BillPaymentRequest; +import com.billpaymentservice.bbps.dto.request.FetchBillRequest; +import com.billpaymentservice.bbps.dto.request.TransactionStatusRequest; + +public interface PaymentService { + + public ResponseModel initiatePayment(BillPaymentRequest billPaymentRequest); + + public ResponseModel checkTrasactionStatus(TransactionStatusRequest transactionStatusRequest); + +} diff --git a/src/main/java/com/billpaymentservice/bbps/serviceImpl/AgentServiceImpl.java b/src/main/java/com/billpaymentservice/bbps/serviceImpl/AgentServiceImpl.java index d5027dc..9c031db 100644 --- a/src/main/java/com/billpaymentservice/bbps/serviceImpl/AgentServiceImpl.java +++ b/src/main/java/com/billpaymentservice/bbps/serviceImpl/AgentServiceImpl.java @@ -8,9 +8,9 @@ import com.billpaymentservice.bbps.dto.request.FetchBillRequest; import com.billpaymentservice.bbps.dto.response.BillDataResponse; import com.billpaymentservice.bbps.dto.response.BillerDataResponse; import com.billpaymentservice.bbps.dto.response.FetchBillResponse; -import com.billpaymentservice.bbps.entites.BeneficiaryDetails; +import com.billpaymentservice.bbps.entites.BharatConnectMaster; import com.billpaymentservice.bbps.exception.CustomException; -import com.billpaymentservice.bbps.repository.BeneficiaryDetailsRepository; +import com.billpaymentservice.bbps.repository.BharatConnectMasterRepository; import com.billpaymentservice.bbps.service.AgentService; import com.billpaymentservice.bbps.util.BBPSConstant; import com.billpaymentservice.bbps.util.Helper; @@ -40,9 +40,9 @@ public class AgentServiceImpl implements AgentService { private final RestClient restClient; private final HttpService httpService; private final Helper helper; - private final BeneficiaryDetailsRepository beneficiaryDetailsRepository; + private final BharatConnectMasterRepository beneficiaryDetailsRepository; - public AgentServiceImpl(RestClient restClient,HttpService httpService,Helper helper, BeneficiaryDetailsRepository beneficiaryDetailsRepository) { + public AgentServiceImpl(RestClient restClient,HttpService httpService,Helper helper, BharatConnectMasterRepository beneficiaryDetailsRepository) { this.restClient=restClient; this.httpService=httpService; this.helper=helper; @@ -54,7 +54,7 @@ public class AgentServiceImpl implements AgentService { String url = agentDtaUrl+BBPSConstant.BILL_FETCH_INTI; System.out.println(url); - BeneficiaryDetails headersData=beneficiaryDetailsRepository.findByOrgId("ORG001"); + BharatConnectMaster headersData=beneficiaryDetailsRepository.findByOrgId("ORG001"); HttpHeaders headers = new HttpHeaders(); headers.set("x-digiledge-key",headersData.getXDigiledgeKey()); @@ -133,7 +133,7 @@ public class AgentServiceImpl implements AgentService { String fullUrl = agentDtaUrl + BBPSConstant.BILL_FETCH_BY_ID+billId; System.out.print(fullUrl); - BeneficiaryDetails headersData=beneficiaryDetailsRepository.findByOrgId("ORG001"); + BharatConnectMaster headersData=beneficiaryDetailsRepository.findByOrgId("ORG001"); HttpHeaders headers = new HttpHeaders(); headers.set("x-digiledge-key",headersData.getXDigiledgeKey()); diff --git a/src/main/java/com/billpaymentservice/bbps/serviceImpl/MasterDataServiceImpl.java b/src/main/java/com/billpaymentservice/bbps/serviceImpl/MasterDataServiceImpl.java index 5b1a410..6705379 100644 --- a/src/main/java/com/billpaymentservice/bbps/serviceImpl/MasterDataServiceImpl.java +++ b/src/main/java/com/billpaymentservice/bbps/serviceImpl/MasterDataServiceImpl.java @@ -13,6 +13,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; +import com.billpaymentservice.bbps.dto.BillerDAO; import com.billpaymentservice.bbps.dto.GeneralResp; import com.billpaymentservice.bbps.dto.MasterApiResponse; import com.billpaymentservice.bbps.dto.ResponseModel; @@ -29,6 +30,7 @@ import com.billpaymentservice.bbps.dto.response.CustomParamResp; import com.billpaymentservice.bbps.entites.BBPSMerchantValidation; import com.billpaymentservice.bbps.exception.AppException; import com.billpaymentservice.bbps.exception.CustomException; +import com.billpaymentservice.bbps.repository.BillerDataRepository; import com.billpaymentservice.bbps.repository.MerchantRepository; import com.billpaymentservice.bbps.service.MasterDataService; import com.billpaymentservice.bbps.util.BBPSConstant; @@ -50,6 +52,7 @@ public class MasterDataServiceImpl implements MasterDataService { private MerchantRepository merchantRegisterRepo; private HttpClientApi httpClientApi; private Helper helper; + private final BillerDataRepository billerDataRespository; private static final Logger log = LoggerFactory.getLogger(MasterDataServiceImpl.class); @@ -60,13 +63,15 @@ public class MasterDataServiceImpl implements MasterDataService { public MasterDataServiceImpl(MerchantRepository merchantRegisterRepo, HttpService httpService, HttpClientApi httpClientApi, - Helper helper + Helper helper, + BillerDataRepository billerDataRespository ) { this.merchantRegisterRepo = merchantRegisterRepo; this.httpService = httpService; this.httpClientApi = httpClientApi; this.helper = helper; - + this.billerDataRespository=billerDataRespository; + } @Override @@ -94,7 +99,17 @@ public class MasterDataServiceImpl implements MasterDataService { } BillerDataResponse responseWrapper = objectMapper.convertValue(dataMap, BillerDataResponse.class); + GeneralResp generalResp = responseWrapper.getGeneralResp(); + BillerDAO biller = responseWrapper.getBillerDAO(); + + if (biller != null) { + LOGGER.info("Saving biller {} to database...", biller.getBillerId()); + billerDataRespository.save(biller); + } else { + LOGGER.warn("No biller found in response to save."); + } + ResponseModel responseModel=new ResponseModel( generalResp.getMessage(), generalResp.getStatus(), @@ -138,6 +153,7 @@ public class MasterDataServiceImpl implements MasterDataService { MasterApiResponse responseWrapper = objectMapper.convertValue(dataMap, MasterApiResponse.class); GeneralResp generalResp = responseWrapper.getGeneralResp(); + ResponseModel responseModel = new ResponseModel( generalResp.getMessage(), diff --git a/src/main/java/com/billpaymentservice/bbps/serviceImpl/PaymentServiceImpl.java b/src/main/java/com/billpaymentservice/bbps/serviceImpl/PaymentServiceImpl.java new file mode 100644 index 0000000..ca93664 --- /dev/null +++ b/src/main/java/com/billpaymentservice/bbps/serviceImpl/PaymentServiceImpl.java @@ -0,0 +1,229 @@ +package com.billpaymentservice.bbps.serviceImpl; + +import java.util.Map; + +import org.modelmapper.ModelMapper; +import org.modelmapper.convention.MatchingStrategies; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Service; + +import com.billpaymentservice.bbps.dto.GeneralResp; +import com.billpaymentservice.bbps.dto.GeneralResponse; +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.FetchBillRequest; +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.FetchBillResponse; +import com.billpaymentservice.bbps.dto.response.TransactionStatusResponse; +import com.billpaymentservice.bbps.entites.BharatConnectMaster; +import com.billpaymentservice.bbps.entites.BillPayment; +import com.billpaymentservice.bbps.exception.CustomException; +import com.billpaymentservice.bbps.repository.BharatConnectMasterRepository; +import com.billpaymentservice.bbps.repository.PaymentRepository; +import com.billpaymentservice.bbps.service.PaymentService; +import com.billpaymentservice.bbps.util.BBPSConstant; +import com.billpaymentservice.bbps.util.Helper; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; + +@Service +public class PaymentServiceImpl implements PaymentService { + + @Value("${payment.data.url}") + private String paymentUrl; + private final BharatConnectMasterRepository beneficiaryDetailsRepository; + private final HttpService httpService; + private final Helper helper; + private final PaymentRepository paymentRepository; + + public PaymentServiceImpl(BharatConnectMasterRepository beneficiaryDetailsRepository, HttpService httpService, + Helper helper, PaymentRepository paymentRepository) { + this.beneficiaryDetailsRepository = beneficiaryDetailsRepository; + this.httpService = httpService; + this.helper = helper; + this.paymentRepository = paymentRepository; + } + + private static final Logger LOGGER = LoggerFactory.getLogger(MasterDataServiceImpl.class); + + @Override + public ResponseModel initiatePayment(BillPaymentRequest billPaymentRequest) { + + String url = paymentUrl + BBPSConstant.PAYMENT_URL; + System.out.println(url); + + BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId("ORG001"); + + HttpHeaders headers = new HttpHeaders(); + headers.set("x-digiledge-key", headersData.getXDigiledgeKey()); + headers.set("agentId", headersData.getAgentId()); + headers.set("tenantId", headersData.getTenantId()); + headers.setContentType(MediaType.APPLICATION_JSON); + + ResponseModel responseModel = new ResponseModel(); + + try { + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + + // ✅ Convert request to JSON + String json = objectMapper.writeValueAsString(billPaymentRequest); + + // ✅ Call the API using httpService + Map responseMap = httpService.postRequest(url, json, headers); + String responseData = responseMap.get("data"); + + LOGGER.info("📦 Bill Fetch API Response: {}", responseData); + + if (responseData == null || responseData.isEmpty()) { + throw new CustomException("Empty response from BBPS server"); + } + + // ✅ Convert JSON string → Map + Map dataMap = objectMapper.readValue(responseData, + new TypeReference>() { + }); + + // ✅ Validate generalResp + if (!dataMap.containsKey("genericResponse")) { + throw new CustomException("Invalid response structure from BBPS"); + } + + // ✅ Convert to your custom DTO + BillPaymentResponse billPaymentResponse = objectMapper.convertValue(dataMap, BillPaymentResponse.class); + GeneralResp generalResponse = billPaymentResponse.getGenericResponse(); + // + // start a new thread here + /* + * helper.startPolling(fetchBillResponse, res -> { BillFetchByBillIdRequest + * pollReq = new BillFetchByBillIdRequest(); pollReq.setBillId(res.getBillId()); + * return fetchBillById(pollReq); }, 3, // interval in seconds 15 // total time + * in seconds ); + */ + ModelMapper mapper = new ModelMapper(); + mapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT); + BillPayment entity = mapper.map(billPaymentResponse, BillPayment.class); + paymentRepository.save(entity); + + // ✅ Build final ResponseModel + responseModel = new ResponseModel(generalResponse.getMessage(), generalResponse.getStatus(), + Integer.parseInt(generalResponse.getStatusCode()), billPaymentResponse); + + } catch (Exception e) { + LOGGER.error("❌ Exception in initiateBillFetch(): {}", e.getMessage(), e); + responseModel.setStatus("500"); + responseModel.setMessage("Exception occurred"); + responseModel.setData(e.getMessage()); + } + + return responseModel; + } + + @Override + public ResponseModel checkTrasactionStatus(TransactionStatusRequest transactionStatusRequest) { + + 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); + + Map responseMap = httpService.getRequest(url,headers); + String responseData = responseMap.get("data"); + LOGGER.info("data is :{}", responseData); + + + ObjectMapper objectMapper = new ObjectMapper(); + + try { + Map dataMap = objectMapper.readValue(responseData, + new TypeReference>() { + }); + if (!dataMap.containsKey("genericResponse")) { + throw new CustomException(String.valueOf(dataMap.get("message")), // message + String.valueOf(dataMap.get("status")), // status + Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), // statusCode (int) + String.valueOf(dataMap.get("remarks")) ); + } + + TransactionStatusResponse responseWrapper = objectMapper.convertValue(dataMap, TransactionStatusResponse.class); + + GeneralResp generalResp = responseWrapper.getGeneralResp(); + + ResponseModel responseModel=new ResponseModel( generalResp.getMessage(), + generalResp.getStatus(), + Integer.parseInt(generalResp.getStatusCode()), + responseWrapper); + + return responseModel; + + } catch (JsonProcessingException e) { + LOGGER.error("Error parsing responseData JSON: {}", e.getMessage()); + throw new CustomException("Invalid JSON received from API"); + } + } + + /* + * @Override public ResponseModel fetchTxnByTxnId(BillFetchByBillIdRequest + * billFetchByBillIdRequest) { + * + * String billId = billFetchByBillIdRequest.getBillId(); String fullUrl = + * agentDtaUrl + BBPSConstant.BILL_FETCH_BY_ID+billId; + * System.out.print(fullUrl); + * + * BeneficiaryDetails + * headersData=beneficiaryDetailsRepository.findByOrgId("ORG001"); + * + * HttpHeaders headers = new HttpHeaders(); + * headers.set("x-digiledge-key",headersData.getXDigiledgeKey()); + * headers.set("agentId", headersData.getAgentId()); headers.set("tenantId", + * headersData.getTenantId()); + * headers.setContentType(MediaType.APPLICATION_JSON); + * + * Map responseMap = httpService.getRequest(fullUrl,headers); + * String responseData = responseMap.get("data"); log.info("data is :{}", + * responseData); + * + * + * ObjectMapper objectMapper = new ObjectMapper(); + * + * try { Map dataMap = objectMapper.readValue(responseData, new + * TypeReference>() { }); if + * (!dataMap.containsKey("genericResponse")) { throw new + * CustomException(String.valueOf(dataMap.get("message")), // message + * String.valueOf(dataMap.get("status")), // status + * Integer.parseInt(String.valueOf(dataMap.get("statusCode"))), // statusCode + * (int) String.valueOf(dataMap.get("remarks")) ); } + * + * BillDataResponse responseWrapper = objectMapper.convertValue(dataMap, + * BillDataResponse.class); + * + * GeneralResp generalResp = responseWrapper.getGenericResponse(); + * + * ResponseModel responseModel=new ResponseModel( generalResp.getMessage(), + * generalResp.getStatus(), Integer.parseInt(generalResp.getStatusCode()), + * responseWrapper); + * + * return responseModel; + * + * } catch (JsonProcessingException e) { + * LOGGER.error("Error parsing responseData JSON: {}", e.getMessage()); throw + * new CustomException("Invalid JSON received from API"); } + * + * } + */ + +} diff --git a/src/main/java/com/billpaymentservice/bbps/util/BBPSConstant.java b/src/main/java/com/billpaymentservice/bbps/util/BBPSConstant.java index 0b5d7f7..d1f0b6b 100644 --- a/src/main/java/com/billpaymentservice/bbps/util/BBPSConstant.java +++ b/src/main/java/com/billpaymentservice/bbps/util/BBPSConstant.java @@ -30,5 +30,7 @@ public class BBPSConstant { public static final String CUSTOMPARAM_URL="/customerParam?billerId="; public static final String BILL_FETCH_INTI="/couapp/bills/fetch"; public static final String BILL_FETCH_BY_ID="/couapp/bills/fetch/byId?billId="; + public static final String PAYMENT_URL="/agent/bills/payment"; + public static final String CHECK_TRANSACTION_URL="/transactions/payment/byTxnId?txnId="; } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 28f1267..ddcf1e0 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -31,6 +31,7 @@ logging.level.io.github.resilience4j.retry=DEBUG # BBPS URLs master.data.url = https://bbps-staging.digiledge.in/agent/cou-master/masters agent.data.url=https://bbps-staging.digiledge.in/agent/bill-payment-new +payment.data.url=https://bbps-staging.digiledge.in/couapp # Resilience4j Retry