Paytm integration with angular and spring boot

Viewed 55

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.
2 Answers

Instead of sending a model view redirect, you can just pass the URL to your client, and at the client, you can use "window.location.replace()"

Paytm flow (happy day)

We used "JS Checkout" feature of the paytm earlier with modification as above, to support and restrict secret key maintenance at our server.

Related