improved the error handling and updated link paymentstartrecord and transactionmaster

This commit is contained in:
Lincpay Tech
2025-12-15 12:25:40 +05:30
parent b3c507338e
commit eeb326a221
12 changed files with 266 additions and 230 deletions
@@ -11,6 +11,11 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.OneToOne;
import jakarta.persistence.FetchType;
@AllArgsConstructor
@NoArgsConstructor
@Entity
@@ -80,4 +85,8 @@ public class PaymentStartRecord extends Auditable {
@Column(name = "callback_received_on")
private String callbackReceivedOn;
@OneToOne(mappedBy = "paymentStartRecord", fetch = FetchType.LAZY)
@JsonIgnore
private TransactionMaster transactionMaster;
}
@@ -2,6 +2,7 @@ package com.billpaymentservice.bbps.entites;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.CascadeType;
@@ -9,6 +10,8 @@ import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.persistence.OneToOne;
import jakarta.persistence.OneToMany;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
@@ -149,6 +152,12 @@ public class TransactionMaster extends Auditable {
@OneToMany(mappedBy = "transactionMaster", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<CustomerParamTransaction> customerParams;
// ✅ Relation with PaymentStartRecord (one-to-one)
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "payment_ref_id", referencedColumnName = "txn_id", insertable = false, updatable = false)
@JsonIgnore
private PaymentStartRecord paymentStartRecord;
@Column(name = "plan_id")
private String planId;
@@ -27,4 +27,7 @@ public interface TransactionMasterRepository extends JpaRepository<TransactionMa
@Query("SELECT t FROM TransactionMaster t WHERE t.txnId = :txnId")
List<TransactionMaster> findByTxnId(@Param("txnId") String txnId);
}
// Find TransactionMaster(s) by the payment_ref_id column (references PaymentStartRecord.txn_id)
List<TransactionMaster> findByPaymentRefId(String paymentRefId);
}
@@ -1,4 +1,3 @@
package com.billpaymentservice.bbps.serviceImpl;
import java.util.Map;
@@ -153,7 +152,8 @@ public class AgentServiceImpl implements AgentService {
} catch (JsonProcessingException e) {
LOGGER.error("JSON Parsing Error: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
// Use standardized user-facing message and status, keep internal details in remarks
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -206,7 +206,7 @@ public class AgentServiceImpl implements AgentService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing BillById JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -265,7 +265,7 @@ public class AgentServiceImpl implements AgentService {
catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON for billId={} : {}", billId, e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -349,7 +349,7 @@ public class AgentServiceImpl implements AgentService {
} catch (JsonProcessingException e) {
LOGGER.error("JSON Parsing Error: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -404,7 +404,7 @@ public class AgentServiceImpl implements AgentService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing BillById JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -465,7 +465,7 @@ public class AgentServiceImpl implements AgentService {
} catch (com.fasterxml.jackson.core.JsonProcessingException e) {
LOGGER.error("Error parsing ValidateByBillId JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
// ================================== Bill fetch and Bill Validate by Client Req
@@ -494,7 +494,12 @@ public class AgentServiceImpl implements AgentService {
helper.validateMerchant(billValidateByClientIdRequest.getMid());
Optional<BillInitiate> billInitiate = billIntiateRepository.findByReqId(clientReqId);
if (billInitiate.isEmpty()) {
throw new CustomException(BBPSConstant.NO_BILL_FOUND);
new CustomException(
BBPSConstant.NO_BILL_FOUND, // message // status
BBPSConstant.FAILED_STATUS,
BBPSConstant.HTTP_NOT_FOUND, // statusCode
"Bill not found in database for given clientReqId"
);
}
String fullUrl = agentDtaUrl + BBPSConstant.BILL_VALIDATE_BY_CLIENT_REQ_ID + billInitiate.get().getTxnId();
@@ -531,7 +536,7 @@ public class AgentServiceImpl implements AgentService {
} catch (JsonProcessingException e) {
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -552,7 +557,12 @@ public class AgentServiceImpl implements AgentService {
Optional<BillInitiate> billInitiate = billIntiateRepository.findByReqId(clientReqId);
if (billInitiate.isEmpty()) {
throw new CustomException(BBPSConstant.NO_BILL_FOUND);
throw new CustomException(
BBPSConstant.NO_BILL_FOUND, // message // status
BBPSConstant.FAILED_STATUS,
BBPSConstant.HTTP_NOT_FOUND, // statusCode
"Bill not found in database for given clientReqId"
);
}
String fullUrl = agentDtaUrl + BBPSConstant.BILL_VALIDATE_BY_CLIENT_REQ_ID + billInitiate.get().getTxnId();
@@ -588,7 +598,7 @@ public class AgentServiceImpl implements AgentService {
} catch (JsonProcessingException e) {
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -207,7 +207,7 @@ public class ComplainServiceImpl implements ComplainService {
} catch (JsonProcessingException e) {
LOGGER.error("JSON Parsing Error: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -290,7 +290,7 @@ public class ComplainServiceImpl implements ComplainService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing JSON in complaint status API: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -356,7 +356,7 @@ public class ComplainServiceImpl implements ComplainService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing Complaint Id JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -420,7 +420,7 @@ public class ComplainServiceImpl implements ComplainService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing Complaint Id JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -532,7 +532,7 @@ public class ComplainServiceImpl implements ComplainService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing Complaint Id JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -599,7 +599,7 @@ public class ComplainServiceImpl implements ComplainService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing Complaint Id JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -164,7 +164,8 @@ public class MasterDataServiceImpl implements MasterDataService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
// Use user-friendly message constant and keep internal details in remarks
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
@@ -227,7 +228,8 @@ public class MasterDataServiceImpl implements MasterDataService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
// Unified constant for invalid JSON
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -298,7 +300,7 @@ public class MasterDataServiceImpl implements MasterDataService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -364,7 +366,7 @@ public class MasterDataServiceImpl implements MasterDataService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -431,7 +433,7 @@ public class MasterDataServiceImpl implements MasterDataService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -507,7 +509,7 @@ public class MasterDataServiceImpl implements MasterDataService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -570,7 +572,7 @@ public class MasterDataServiceImpl implements MasterDataService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -636,7 +638,7 @@ public class MasterDataServiceImpl implements MasterDataService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -700,7 +702,7 @@ public class MasterDataServiceImpl implements MasterDataService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -757,7 +759,7 @@ public class MasterDataServiceImpl implements MasterDataService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -829,7 +831,7 @@ public class MasterDataServiceImpl implements MasterDataService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage());
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -887,8 +889,8 @@ public class MasterDataServiceImpl implements MasterDataService {
} catch (JsonProcessingException e) {
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");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
}
}
@@ -127,7 +127,12 @@ public class PaymentServiceImpl implements PaymentService {
helper.updateInboundLogFailure(inboundLog, BBPSConstant.EMPTY_RESPONSE_FROM_BBPS,
BBPSConstant.FAILED_STR);
LOGGER.warn("Empty response received from BBPS for txnId={}", txnId);
throw new CustomException(BBPSConstant.EMPTY_RESPONSE_FROM_BBPS);
throw new CustomException(
BBPSConstant.EMPTY_RESPONSE_FROM_BBPS, // message
BBPSConstant.FAILED_STATUS, // status
502, // statusCode
"BBPS upstream returned empty response"
);
}
Map<String, Object> dataMap = objectMapper.readValue(responseData,
@@ -183,7 +188,7 @@ public class PaymentServiceImpl implements PaymentService {
} catch (JsonProcessingException e) {
LOGGER.error("JSON Parsing Error in initiatePayment: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -261,7 +266,7 @@ public class PaymentServiceImpl implements PaymentService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing transaction status JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -327,7 +332,7 @@ public class PaymentServiceImpl implements PaymentService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing responseData JSON: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
@@ -347,7 +352,12 @@ public class PaymentServiceImpl implements PaymentService {
Optional<PaymentInitiate> paymentInitiate = paymentIntiateRepository.findByReqId(clientReqId);
if (paymentInitiate.isEmpty()) {
throw new CustomException(BBPSConstant.NO_BILL_FOUND);
throw new CustomException(
BBPSConstant.NO_BILL_FOUND, // message // status
BBPSConstant.FAILED_STATUS,
BBPSConstant.HTTP_NOT_FOUND, // statusCode
"Bill not found in database for given clientReqId"
);
}
String url = paymentUrl + BBPSConstant.CHECK_TRANSACTION_BY_CLIENT_REQ_ID_URL
@@ -405,9 +415,8 @@ public class PaymentServiceImpl implements PaymentService {
} catch (JsonProcessingException e) {
LOGGER.error("Error parsing JSON in transaction status API: {}", e.getMessage(), e);
helper.updateInboundLogFailure(inboundLog, e.getMessage(), BBPSConstant.JSON_ERROR);
throw new CustomException("Invalid JSON received from API");
throw new CustomException(BBPSConstant.MSG_INVALID_JSON_FROM_UPSTREAM, "FAILED", BBPSConstant.INVALID_JSON_STATUS_CODE, e.getMessage());
}
}
}
}
@@ -195,6 +195,9 @@ public class BBPSConstant extends BBPS_RESPONSE_COD_CONSTANT {
public static final String MSG_EMPTY_RESPONSE_PG = "Empty response from PG";
public static final String MSG_INVALID_JSON_FROM_API = "Invalid JSON received from payment API";
public static final String MSG_TXN_PROCESSING = "Transaction processing";
// User-facing message for malformed responses from upstream services (used with status code 603)
// Short, non-leaking and actionable message
public static final String MSG_INVALID_JSON_FROM_UPSTREAM = "Temporary upstream data error. Please try again later.";
public static final String MSG_WARNING_FROM_MERCHANT = "Warning from merchant";
public static final String MSG_FRAUD_REJECTED = "Fraud Rejected";
public static final String MSG_DECRYPTION_FAILED = "Decryption failed";
@@ -220,4 +223,6 @@ public class BBPSConstant extends BBPS_RESPONSE_COD_CONSTANT {
public static final String USER_UNAUTHORIZED_STR = "401";
public static final String OK_STR = "200";
// Newly added constant for invalid JSON status code
}
@@ -1,5 +1,7 @@
package com.billpaymentservice.bbps.util;
public class BBPS_RESPONSE_COD_CONSTANT {
public static final int INVALID_JSON_STATUS_CODE = 603;
}