make some changes
This commit is contained in:
@@ -36,7 +36,7 @@ public class PaymentController {
|
||||
|
||||
@PostMapping(value = "/intiatePayment", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
|
||||
public ResponseEntity<ResponseModel> requestBillFetch(
|
||||
@Validated @RequestBody BillPaymentRequest billPaymentRequest) {
|
||||
@RequestBody BillPaymentRequest billPaymentRequest) {
|
||||
|
||||
ResponseModel response = paymentService.initiatePayment(billPaymentRequest);
|
||||
return ResponseEntity.ok(response);
|
||||
|
||||
@@ -11,43 +11,33 @@ import lombok.Setter;
|
||||
@Setter
|
||||
public class BillPaymentRequest extends BaseClass {
|
||||
|
||||
@NotBlank(message = "ref id cannot be null or empty")
|
||||
private String refId;
|
||||
|
||||
@NotBlank(message = "bill id cannot be null or empty")
|
||||
private String billId;
|
||||
|
||||
// Change the field to Boolean (wrapper) type to allow @NotNull validation
|
||||
@NotNull(message = "Amount options cannot be null.")
|
||||
private boolean amountOptions; // Changed to Boolean (wrapper type)
|
||||
|
||||
@NotBlank(message = "payment mode cannot be null or empty")
|
||||
private String paymentMode;
|
||||
|
||||
@NotBlank(message = "payment information cannot be null or empty")
|
||||
private String paymentInformation;
|
||||
|
||||
@NotBlank(message = "biller id cannot be null or empty")
|
||||
private String billerId;
|
||||
|
||||
@NotBlank(message = "biller name cannot be null or empty")
|
||||
private String billerName;
|
||||
|
||||
@NotBlank(message = "biller category cannot be null or empty")
|
||||
private String billerCategory;
|
||||
|
||||
private String macAdress;
|
||||
|
||||
private String customerMobNo;
|
||||
|
||||
@NotNull(message = "Transaction amount cannot be null.")
|
||||
private Integer txnAmount; // Changed to @NotNull as it's an Integer (non-nullable)
|
||||
private String txnAmount; // Changed to @NotNull as it's an Integer (non-nullable)
|
||||
|
||||
private String paymentRefId;
|
||||
|
||||
private String clientReqId;
|
||||
|
||||
@NotBlank(message = "payment channel cannot be null or empty")
|
||||
private String paymentChannel;
|
||||
|
||||
private List<DeviceBlockTagRequest> deviceBlockTags;
|
||||
|
||||
+1
-1
@@ -29,7 +29,7 @@ public class BillPaymentForwardRequest {
|
||||
private String billerCategory;
|
||||
private String macAdress;
|
||||
private String customerMobNo;
|
||||
private Integer txnAmount;
|
||||
private String txnAmount;
|
||||
private String paymentRefId;
|
||||
private String clientReqId;
|
||||
private String paymentChannel;
|
||||
|
||||
@@ -28,7 +28,6 @@ public class AuditListener {
|
||||
|
||||
// Ensure isDeleted / deleted exists and is set to false on create
|
||||
setAlways(entity, "isDeleted", Boolean.FALSE);
|
||||
setAlways(entity, "deleted", Boolean.FALSE);
|
||||
}
|
||||
|
||||
@PreUpdate
|
||||
|
||||
@@ -8,7 +8,6 @@ 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.Setter;
|
||||
import lombok.ToString;
|
||||
@@ -17,8 +16,8 @@ import lombok.ToString;
|
||||
@Setter
|
||||
@Entity
|
||||
@ToString
|
||||
@Table(name = "payment_channel")
|
||||
public class PaymentChannel extends Auditable {
|
||||
@Table(name = "bbps_payment_channel")
|
||||
public class PaymentChannel {
|
||||
|
||||
@Id
|
||||
@Column(name = "payment_channel_limit_id")
|
||||
@@ -42,4 +41,4 @@ public class PaymentChannel extends Auditable {
|
||||
@ManyToOne(fetch = FetchType.LAZY)
|
||||
@JoinColumn(name = "biller_id")
|
||||
private BillerDetails biller;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,76 +9,145 @@ import org.springframework.http.*;
|
||||
import org.springframework.validation.FieldError;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.method.HandlerMethod;
|
||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||
|
||||
import com.billpaymentservice.bbps.dto.ResponseModel;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
@ControllerAdvice
|
||||
public class GlobalExceptionHandler {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
|
||||
|
||||
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
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());
|
||||
|
||||
logger.warn("Validation failed: {}", fieldErrors);
|
||||
ResponseModel<List<Map<String, String>>> resp = new ResponseModel<>(
|
||||
"Validation failed for request",
|
||||
"FAILED",
|
||||
HttpStatus.BAD_REQUEST.value(),
|
||||
null
|
||||
/**
|
||||
* 🔥 Common logger formatter for all exceptions
|
||||
*/
|
||||
private String buildErrorContext(Exception ex, HttpServletRequest request, HandlerMethod handlerMethod) {
|
||||
|
||||
// API endpoint
|
||||
String endpoint = (request != null)
|
||||
? request.getMethod() + " " + request.getRequestURI()
|
||||
: "unknown";
|
||||
|
||||
// Controller method
|
||||
String controllerMethod = (handlerMethod != null)
|
||||
? handlerMethod.getBeanType().getSimpleName() + "." + handlerMethod.getMethod().getName()
|
||||
: "NoControllerMethodMatched";
|
||||
|
||||
// Root cause (actual throw point)
|
||||
StackTraceElement root = ex.getStackTrace()[0];
|
||||
String rootCause = root.getClassName() + "." + root.getMethodName() + "():" + root.getLineNumber();
|
||||
|
||||
return String.format(
|
||||
"API: %s | Controller: %s | Thrown From: %s | Exception: %s",
|
||||
endpoint,
|
||||
controllerMethod,
|
||||
rootCause,
|
||||
ex.getClass().getSimpleName()
|
||||
);
|
||||
// put validation errors into data or duplicate field in ResponseModel as required
|
||||
resp.setData(fieldErrors);
|
||||
}
|
||||
|
||||
// ------------------------- VALIDATION EXCEPTION ------------------------
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public ResponseEntity<ResponseModel<?>> handleValidation(
|
||||
MethodArgumentNotValidException ex,
|
||||
HttpServletRequest request,
|
||||
HandlerMethod handlerMethod) {
|
||||
|
||||
String context = buildErrorContext(ex, request, handlerMethod);
|
||||
logger.warn("ValidationException → {}", context);
|
||||
|
||||
List<Map<String, String>> fieldErrors = ex.getBindingResult()
|
||||
.getFieldErrors()
|
||||
.stream()
|
||||
.map(fe -> Map.of("field", fe.getField(), "message", fe.getDefaultMessage()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
ResponseModel<List<Map<String, String>>> resp = new ResponseModel<>(
|
||||
"Validation failed",
|
||||
"FAILED",
|
||||
HttpStatus.BAD_REQUEST.value(),
|
||||
fieldErrors
|
||||
);
|
||||
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resp);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------- NO HANDLER (404 NOT FOUND) ------------------------
|
||||
@ExceptionHandler(NoHandlerFoundException.class)
|
||||
public ResponseEntity<ResponseModel<?>> handleNotFound(NoHandlerFoundException ex) {
|
||||
logger.warn("Endpoint not found: {}", ex.getRequestURL());
|
||||
|
||||
logger.warn("404 Not Found → {}", ex.getRequestURL());
|
||||
|
||||
ResponseModel<?> resp = new ResponseModel<>(
|
||||
"Endpoint not found: " + ex.getRequestURL(),
|
||||
"FAILED",
|
||||
HttpStatus.NOT_FOUND.value(),
|
||||
null
|
||||
"Endpoint not found: " + ex.getRequestURL(),
|
||||
"FAILED",
|
||||
HttpStatus.NOT_FOUND.value(),
|
||||
null
|
||||
);
|
||||
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(resp);
|
||||
}
|
||||
|
||||
// ------------------------- CUSTOM APP EXCEPTION ------------------------
|
||||
@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());
|
||||
public ResponseEntity<ResponseModel<?>> handleAppException(
|
||||
AppException ex,
|
||||
HttpServletRequest request,
|
||||
HandlerMethod handlerMethod) {
|
||||
|
||||
String context = buildErrorContext(ex, request, handlerMethod);
|
||||
logger.warn("AppException → {}", context);
|
||||
|
||||
ResponseModel<?> resp = new ResponseModel<>(
|
||||
ex.getMessage(),
|
||||
ex.getStatus(),
|
||||
ex.getStatusCode(),
|
||||
ex.getData()
|
||||
);
|
||||
|
||||
return ResponseEntity.status(HttpStatus.valueOf(ex.getStatusCode())).body(resp);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------- CUSTOMException ------------------------
|
||||
@ExceptionHandler(CustomException.class)
|
||||
public ResponseEntity<ResponseModel<?>> handleCustomException(CustomException ex) {
|
||||
logger.warn("CustomException: {}", ex.getMessage());
|
||||
public ResponseEntity<ResponseModel<?>> handleCustomException(
|
||||
CustomException ex,
|
||||
HttpServletRequest request,
|
||||
HandlerMethod handlerMethod) {
|
||||
|
||||
String context = buildErrorContext(ex, request, handlerMethod);
|
||||
logger.warn("CustomException → {}", context);
|
||||
|
||||
ResponseModel<?> resp = new ResponseModel<>(
|
||||
ex.getMessage(),
|
||||
"FAILED",
|
||||
HttpStatus.BAD_REQUEST.value(),
|
||||
null
|
||||
ex.getMessage(),
|
||||
"FAILED",
|
||||
HttpStatus.BAD_REQUEST.value(),
|
||||
null
|
||||
);
|
||||
|
||||
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(resp);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------- GENERIC EXCEPTION ------------------------
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<ResponseModel<?>> handleAll(Exception ex) {
|
||||
logger.error("Unhandled exception", ex);
|
||||
public ResponseEntity<ResponseModel<?>> handleAll(
|
||||
Exception ex,
|
||||
HttpServletRequest request,
|
||||
HandlerMethod handlerMethod) {
|
||||
|
||||
String context = buildErrorContext(ex, request, handlerMethod);
|
||||
logger.error("UnhandledException → {}", context, ex);
|
||||
|
||||
ResponseModel<?> response = new ResponseModel<>(
|
||||
"Service temporarily unavailable. Please try again later.",
|
||||
"FAILED",
|
||||
HttpStatus.INTERNAL_SERVER_ERROR.value(),
|
||||
null
|
||||
"Internal Server Error",
|
||||
"FAILED",
|
||||
HttpStatus.INTERNAL_SERVER_ERROR.value(),
|
||||
null
|
||||
);
|
||||
|
||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,6 @@ public class MasterDataServiceImpl implements MasterDataService {
|
||||
|
||||
@Override
|
||||
public ResponseModel getMasterData(MasterRequest masterRequest) {
|
||||
|
||||
String apiName = BBPSConstant.API_GET_MASTER_DATA;
|
||||
String requestId = masterRequest.getReqId();
|
||||
String mid = masterRequest.getMid();
|
||||
@@ -888,7 +887,7 @@ public class MasterDataServiceImpl implements MasterDataService {
|
||||
LOGGER.info("[{}] END | reqId={} | status={}", apiName, requestId, generalResp.getStatus());
|
||||
return responseModel;
|
||||
} catch (JsonProcessingException e) {
|
||||
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
|
||||
LOGGER.error("Error parsing responseData JSON: {} :: class :: method ", e.getMessage());
|
||||
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
|
||||
throw new CustomException("Invalid JSON received from API");
|
||||
}
|
||||
|
||||
@@ -90,11 +90,14 @@ public class PaymentServiceImpl implements PaymentService {
|
||||
@Override
|
||||
public ResponseModel initiatePayment(BillPaymentRequest billPaymentRequest) {
|
||||
String apiName = BBPSConstant.API_INITIATE_PAYMENT;
|
||||
LOGGER.info("[{}] START | reqId={} | mid={}", apiName, billPaymentRequest.getReqId(),
|
||||
billPaymentRequest.getMid());
|
||||
String txnId = helper.generateTxnId(15);
|
||||
String requestId = billPaymentRequest.getReqId();
|
||||
String userId = billPaymentRequest.getClientReqId();
|
||||
String url = paymentUrl + BBPSConstant.PAYMENT_URL;
|
||||
billPaymentRequest.setClientReqId(txnId);
|
||||
|
||||
LOGGER.info("Initiating payment for reqId={} and txnId={} and userId={}", requestId, txnId, userId);
|
||||
|
||||
BharatConnectMaster headersData = beneficiaryDetailsRepository.findByOrgId(BBPSConstant.ORG_ID);
|
||||
|
||||
@@ -92,7 +92,6 @@ public class Helper {
|
||||
|
||||
public static String generateTxnId(int n) {
|
||||
StringBuilder sb = new StringBuilder(n);
|
||||
|
||||
for (int i = 0; i < n; i++) {
|
||||
int index = secureRandom.nextInt(CHARACTERS.length());
|
||||
sb.append(CHARACTERS.charAt(index));
|
||||
|
||||
Reference in New Issue
Block a user