added pollbackpayment status

This commit is contained in:
Lincpay Tech
2025-12-03 17:29:10 +05:30
parent e4e1310325
commit 78c38e6d74
9 changed files with 168 additions and 10 deletions
+7 -1
View File
@@ -159,6 +159,12 @@
<version>0.11.5</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.17.1</version>
</dependency>
<!-- Test -->
<dependency>
@@ -166,7 +172,7 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Configuration Processor -->
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -0,0 +1,29 @@
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 com.billpaymentservice.bbps.dto.ResponseModel;
import com.billpaymentservice.bbps.dto.request.PaymentStartUserRequest;
import com.billpaymentservice.bbps.dto.request.PollBackRequest;
import com.billpaymentservice.bbps.service.PollBackService;
@RequestMapping("/payment")
public class PaymentPollBackController {
private final PollBackService pollBackService;
public PaymentPollBackController(PollBackService pollBackService) {
this.pollBackService = pollBackService;
}
@PostMapping(value = "/pollback", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseModel> startIntentPayment(@Validated @RequestBody PollBackRequest pollBackRequest) {
ResponseModel response = pollBackService.managePollBack(pollBackRequest);
return ResponseEntity.ok(response);
}
}
@@ -43,10 +43,8 @@ public class PaymentStartController {
@PostMapping(value = "/startIntentPayment", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<ResponseModel> startIntentPayment(@Validated @RequestBody PaymentStartUserRequest paymentStartUserRequest) {
if (this.paymentStartService == null) {
// Defensive: if bean not injected, return failure
return ResponseEntity.badRequest().body(new ResponseModel("PaymentStartService not available", "FAILED", 400, null));
}
ResponseEntity.badRequest().body(new ResponseModel("PaymentStartService not available", "FAILED", 400, null));
ResponseModel response = paymentStartService.startIntentPayment(paymentStartUserRequest);
return ResponseEntity.ok(response);
}
@@ -0,0 +1,13 @@
package com.billpaymentservice.bbps.dto;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class PaymentPollBackResponse {
private String txnId;
private String orderId;
private String txnStatus;
}
@@ -0,0 +1,10 @@
package com.billpaymentservice.bbps.dto.request;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class PollBackRequest extends BaseClass{
private String orderId;
}
@@ -0,0 +1,11 @@
package com.billpaymentservice.bbps.service;
import com.billpaymentservice.bbps.dto.ResponseModel;
import com.billpaymentservice.bbps.dto.request.PaymentStartUserRequest;
import com.billpaymentservice.bbps.dto.request.PollBackRequest;
public interface PollBackService {
public ResponseModel managePollBack(PollBackRequest pollBackRequest);
}
@@ -8,6 +8,9 @@ import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Optional;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
@@ -332,10 +335,15 @@ public class PaymentStartServiceImpl implements PaymentStartService {
httpService.postFormRequest(uatPaymentUrlweb, formPayload);
LOGGER.info("Payment Start Response: {}", responseMap);
int httpCode = Integer.parseInt(responseMap.getOrDefault("respCode", "500"));
String respBody = responseMap.getOrDefault("data", "");
/*
* Map<String, String> parsedHtml = parseHtmlResponse(respBody);
*
* for(Map.Entry<String, String> entry : parsedHtml.entrySet()) {
* LOGGER.info("Parsed HTML - {} : {}", entry.getKey(), entry.getValue()); }
*/
helper.updateOutboundLogResponse(outboundLog, respBody);
// ---- HTTP FAILURE ----
@@ -356,7 +364,7 @@ public class PaymentStartServiceImpl implements PaymentStartService {
// Save record with HTML (persist original request and HTML response)
String responseTypeWeb = "HTML";
String rawResponseWeb = respBody == null ? "" : respBody;
// bbpsMapperHelper.savePaymentStartRecord(request, null, txnId, orderNo, requestJson, rawResponseWeb, responseTypeWeb);
bbpsMapperHelper.savePaymentStartRecord(request, null, txnId, orderNo, requestJson, rawResponseWeb, responseTypeWeb);
// Return HTML directly in API response
Map<String, String> result = new HashMap<>();
@@ -373,7 +381,7 @@ public class PaymentStartServiceImpl implements PaymentStartService {
@Override
public ResponseModel handleStartCallback(CallbackRequest callbackRequest) {
String apiName = "HANDLE_START_CALLBACK";
LOGGER.info("[{}] START | payload={}", apiName, callbackRequest);
LOGGER.info("[{}] START ", apiName);
if (callbackRequest == null) {
LOGGER.warn("Callback payload is null");
@@ -391,7 +399,7 @@ public class PaymentStartServiceImpl implements PaymentStartService {
return new ResponseModel("Decryption failed", "207", 200, null);
}
LOGGER.info("Decrypted callback data: {}", decrypted);
LOGGER.info("Decrypted data");
// Parse decrypted JSON
Map<String, Object> payloadMap;
@@ -468,6 +476,29 @@ public class PaymentStartServiceImpl implements PaymentStartService {
return new ResponseModel("Callback processed", merchantStatus, 200, null);
}
public Map<String, String> parseHtmlResponse(String html) {
Map<String, String> map = new HashMap<>();
try {
Document doc = Jsoup.parse(html);
Element txnId = doc.selectFirst("input[name=txnId]");
Element amount = doc.selectFirst("input[name=amount]");
Element mid = doc.selectFirst("input[name=mid]");
if (txnId != null) map.put("txnId", txnId.attr("value"));
if (amount != null) map.put("amount", amount.attr("value"));
if (mid != null) map.put("mid", mid.attr("value"));
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
}
@@ -0,0 +1,59 @@
package com.billpaymentservice.bbps.serviceImpl;
import org.springframework.stereotype.Service;
import com.billpaymentservice.bbps.dto.PaymentPollBackResponse;
import com.billpaymentservice.bbps.dto.ResponseModel;
import com.billpaymentservice.bbps.dto.request.PaymentStartUserRequest;
import com.billpaymentservice.bbps.dto.request.PollBackRequest;
import com.billpaymentservice.bbps.entites.PaymentStartRecord;
import com.billpaymentservice.bbps.repository.PaymentStartRecordRepository;
import com.billpaymentservice.bbps.service.PollBackService;
import com.billpaymentservice.bbps.util.Helper;
@Service
public class PollBackServiceImpl implements PollBackService {
private final PaymentStartRecordRepository paymentStartRecordRepository;
private final Helper helper;
PollBackServiceImpl(PaymentStartRecordRepository paymentStartRecordRepository,
Helper helper) {
this.paymentStartRecordRepository = paymentStartRecordRepository;
this.helper = helper;
}
@Override
public ResponseModel managePollBack(PollBackRequest request) {
String requestId = request.getReqId();
String apiName = "PollBackRequest";
String txnId = helper.generateTxnId(15);
// Validate MID
helper.validateMerchant(request.getMid());
// Fetch payment record
PaymentStartRecord paymentStartRecord = paymentStartRecordRepository
.findByOrderNo(request.getOrderId())
.orElseThrow(() -> new RuntimeException(
"No payment record found for ReqID: " + requestId));
// Prepare response
PaymentPollBackResponse response = new PaymentPollBackResponse();
response.setOrderId(paymentStartRecord.getOrderNo());
response.setTxnId(paymentStartRecord.getTxnId());// Correct mapping
response.setTxnStatus(paymentStartRecord.getTxnStatus()); // Correct mapping
return new ResponseModel(
"Poll Back processed successfully",
"SUCCESS",
200,
response
);
}
}
@@ -1094,6 +1094,7 @@ public class BillerMapperHelper {
record.setTxnId(apiResponse.getResponseData().getTxnId());
record.setQrString(apiResponse.getResponseData().getQrString());
record.setCreatedOn(apiResponse.getResponseData().getCreatedOn());
record.setTxnStatus("PENDING");
}
// store the original request body and raw response