I am trying to integrate Paytm payment gateway with spring-boot as backend an angular as front end. I am able to hit the controller but not able to redirect url to paytm to proceed with payment. Currently I can see Paytm UI load for a moment in the router outlet div and then it disappear immediately. I think there is some issue with angular http call or router outlet. Not sure where is the mistake. Any help is much appreciated.
My spring boot controller code:
@Log4j2
@RestController
@RequestMapping("/booking")
public class BookingController {
@Autowired
private PaytmDetails paytmDetails;
@Value("${paytm.mobile}")
private String paytmMobile;
@Value("${paytm.email}")
private String paytmEmail;
@PostMapping(value = "/make-payment")
public ModelAndView getPaymentRedirect(@RequestParam String orderId, @RequestParam String txnAmount, @RequestParam String customerId) throws Exception {
log.info("1=========");
ModelAndView modelAndView = new ModelAndView("redirect:" + paytmDetails.getPaytmUrl());
log.info("2=========");
TreeMap<String, String> parameters = new TreeMap<>();
paytmDetails.getDetails().forEach((k, v) -> parameters.put(k, v));
parameters.put("MOBILE_NO", paytmMobile);
parameters.put("EMAIL", paytmEmail);
parameters.put("ORDER_ID", orderId);
parameters.put("TXN_AMOUNT", txnAmount);
parameters.put("CUST_ID", customerId);
String checkSum = getCheckSum(parameters);
parameters.put("CHECKSUMHASH", checkSum);
log.info("3=========");
modelAndView.addAllObjects(parameters);
return modelAndView;
}
@PostMapping(value = "/payment-response")
public ModelAndView getPaymentResponseRedirect(HttpServletRequest request) {
ModelAndView modelAndView = new ModelAndView("redirect:http://localhost:8080/#/payment");//my angular payment response landing url
Map<String, String[]> mapData = request.getParameterMap();
TreeMap<String, String> parameters = new TreeMap<String, String>();
String paytmChecksum = "";
for (Entry<String, String[]> requestParamsEntry : mapData.entrySet()) {
if ("CHECKSUMHASH".equalsIgnoreCase(requestParamsEntry.getKey())) {
paytmChecksum = requestParamsEntry.getValue()[0];
} else {
parameters.put(requestParamsEntry.getKey(), requestParamsEntry.getValue()[0]);
}
}
String result;
boolean isValideChecksum = false;
try {
isValideChecksum = validateCheckSum(parameters, paytmChecksum);
if (isValideChecksum && parameters.containsKey("RESPCODE")) {
if (parameters.get("RESPCODE").equals("01")) {
result = "Payment Successful";
} else {
result = "Payment Failed";
}
} else {
result = "Checksum mismatched";
}
} catch (Exception e) {
result = e.toString();
}
modelAndView.addObject("result", result);
parameters.remove("CHECKSUMHASH");
modelAndView.addObject("parameters", parameters);
return modelAndView;
}
private boolean validateCheckSum(TreeMap<String, String> parameters, String paytmChecksum) throws Exception {
return PaytmChecksum.verifySignature(parameters, paytmDetails.getMerchantKey(), paytmChecksum);
}
private String getCheckSum(TreeMap<String, String> parameters) throws Exception {
return PaytmChecksum.generateSignature(parameters, paytmDetails.getMerchantKey());
}
}
My PaytmPojo
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Component
@ConfigurationProperties("paytm.payment.sandbox")
public class PaytmDetails {
private String merchantId;
private String merchantKey;
private String channelId;
private String website;
private String industryTypeId;
private String paytmUrl;
private String callbackUrl;
private Map<String, String> details;
}
Resource file:
paytm.payment.sandbox.merchantId=<test valid paytm MID>
paytm.payment.sandbox.merchantKey=<tes valid paytm MK>
paytm.payment.sandbox.channelId=WEB
paytm.payment.sandbox.industryTypeId=Retail
paytm.payment.sandbox.website=WEBSTAGING
paytm.payment.sandbox.paytmUrl=https://securegw-stage.paytm.in/order/process
paytm.payment.sandbox.callbackUrl=http://localhost:8080/user/booking/payment-response
paytm.payment.sandbox.details.MID=${paytm.payment.sandbox.merchantId}
paytm.payment.sandbox.details.CHANNEL_ID=${paytm.payment.sandbox.channelId}
paytm.payment.sandbox.details.INDUSTRY_TYPE_ID=${paytm.payment.sandbox.industryTypeId}
paytm.payment.sandbox.details.WEBSITE=${paytm.payment.sandbox.website}
paytm.payment.sandbox.details.CALLBACK_URL=${paytm.payment.sandbox.callbackUrl}
paytm.mobile=<paytm login mobile>
paytm.email=<paytm login email>
Angular component class method:
bookProduct() {
this.availabilityService.bookAvailabileProduct(this.orderId, this.txnAmount, this.customerId).subscribe(
res => {
//nothing
}, err => {
this.availabilityErrorMsg = "Backend Error!";
this.availabilityError = true;
}
);
}
Angular service class method:
public bookAvailabileProduct(orderId:any, txnAmount:any, customerId:any): Observable<any> {
return this.http.post("/booking//make-payment?orderId="+orderId+"&txnAmount="+txnAmount+"&customerId="+customerId, null);
}
Current error in HTML console:
Access to XMLHttpRequest at 'https://securegw-stage.paytm.in/order/process?CALLBACK_URL=http%3A%2F%2Flocalhost%3A8080%2Fuser%2Fbooking%2Fpayment-response&CHANNEL_ID=WEB&CHECKSUMHASH=D9DRS%2Bn0TfhKMW%2FY6brrKt5%2BbcTtyuUPlWmQ%2BUNIKr7klkSw%3D&CUST_ID=62f5c339ffc4f516cfeda&EMAIL=shashiranjan.sit%40gmail.com&INDUSTRY_TYPE_ID=Retail&MID=Mo144&MOBILE_NO=9538320000&ORDER_ID=6314be8cff&TXN_AMOUNT=1.0&WEBSITE=WEBSTAGING' (redirected from 'http://localhost:8080/user/booking/make-payment') from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.