10

I'm trying to pay through a UPI hyperlink like

upi://pay?pa=abc@upi&pn=payeeName&tr=1234&tn=Pay%20to%20payeeName&am=1&mam=1&cu=INR&url=https://test.com/payment/orderId=123456
  • I am sending above link through sms
  • When I click on link it shows UPI application list as option
  • I have selected BHIM app (also tried other applications)
  • Then completed payment, till now it works fine.

After the UPI payment is done, the Spring controller which handles the "callback" request to https://test.com/payment/orderId=12345, is not getting called.

So how to get response of UPI Hyperlink payment in Java correctly?

Edit:

This is the controller method. I have also tried @GetMapping instead of @PostMapping.

@PostMapping("/payment")
public ModelAndView credPayment(HttpServletRequest request) {

    String key = request.getParameter("orderId");
    String txnId = request.getParameter("txnId");
    String responseCode = request.getParameter("responseCode");
    String approvalRefNo = request.getParameter("ApprovalRefNo");
    String status = request.getParameter("Status");
    String txnRef = request.getParameter("txnRef");
    System.out.println("Parameter Names");
    while (request.getParameterNames().hasMoreElements()) {
        System.out.println(request.getParameterNames().nextElement());
    }

    System.out.println("Header Names");
    while (request.getHeaderNames().hasMoreElements()) {
        System.out.println(request.getHeaderNames().nextElement());
    }

    System.out.println("txnId : "+txnId);
    System.out.println("responseCode : "+responseCode);
    System.out.println("ApprovalRefNo : "+approvalRefNo);
    System.out.println("Status : "+status);
    System.out.println("txnRef : "+txnRef);

    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("redirect:/");
    return modelAndView;
}
Nilesh Patel
  • 127
  • 2
  • 9
  • is it a GET or a POST request you are expecting? Is the controller behind the link also made? What is the code behind the Controller of "PaymentController.java" ? is there a route? can you call it explicitly by using postman, and sending the expected variables? what Response do you see when you call it yourself? – Jasper Lankhorst Nov 09 '19 at 15:58
  • Payment Done Successfully. I have try both GET and POST for redirect url [https://test.com/payment/orderId=123456] and I can call it explicitly also. I am just doing `System.out.println("Hello");` inside controller – Nilesh Patel Nov 11 '19 at 05:10
  • can you provide code snippet? – Max Peng Nov 19 '19 at 06:58
  • @NileshPatel, can you please confirm that you are really able to call `/payment/orderId=123456` directly from a browser for example? Because based on your examples, it shouldn't be possible - look at the MyTwoCents' answer... – Petr Bodnár Nov 24 '19 at 22:04
  • @Petr Bodnár, I can call `/payment/orderId=123456` from web and its working fine – Nilesh Patel Nov 25 '19 at 05:50
  • @Petr Bodnár, I have tried your answer but it wont work – Nilesh Patel Nov 25 '19 at 05:54
  • @NileshPatel, ok then. Maybe this could help: a) check / describe how you setup & use the UPI, step by step scenario of the behavior (when and how the redirect to `url` is done / expected to be done), b) how you register / allow your `url` to be called, c) check that your server's certificate is valid - have you tried with plain `http` in `url`? – Petr Bodnár Nov 25 '19 at 10:25
  • 1
    - I am sending link through sms - when I click on link it shows UPI application list as option - I have selected BHIM app (also tried other applications) - Then completed payment, till now it works. - After payment completion redirect url should be called. but I don't know they call redirect url or not. If they call url then I am unable to handle it on given code. – Nilesh Patel Nov 27 '19 at 08:49
  • 1
    Hi, @NileshPatel, Can you able to get the transaction status from callback URL. I am also facing the same issue. – KCN Sep 26 '20 at 06:18

4 Answers4

1

The URL parameter in the payment link is not a callback URL. And currently no payment app is using it for that purpose.

The URL is only meant to provide transaction information to the payer.

Alpesh Patil
  • 1,672
  • 12
  • 15
0

If I understood it correctly, your redirect URL is

https://test.com/payment/orderId=123456

And when this is called, you need to get order id value in your controller.

Then try changing your method to something like this:

@GetMapping(value = "/payment/{order}")
public ModelAndView credPayment(@PathVariable("order") String order, HttpServletRequest request) {
    System.out.println(order); // prints orderId=123456
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("redirect:/");
    return modelAndView;
}

Issue:

You have configured your URL mapping as /payment only, so anything after that will get excluded from this mapping, eg: /payment/sdfdsfs

Petr Bodnár
  • 496
  • 3
  • 14
MyTwoCents
  • 7,284
  • 3
  • 24
  • 52
  • Based on the information given in the OP, this is by far the most relevant and useful answer so far. An alternative solution is to use a properly url-encoded form of `https://test.com/payment?orderId=123456` as the value of the `url` parameter passed to the UPI URL. Still, the basic problem and its solution remains the same. – Petr Bodnár Nov 24 '19 at 21:58
0
Uri myAction = Uri.parse("upi://pay?pa=******@****&pn="+"*******"+"&mc="+"&tid="+transaction_ref_id +"&tr="
                +transaction_ref_id +"&tn=Pay%20to%20*****%20*****%20App&am="+"1.00"+"&mam=null&cu=INR&url=https://mystar.com/orderid="+sOrderId);

        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.setData(myAction);
        startActivityForResult(intent, 100);

*******************
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == 100) {
            if (resultCode == RESULT_OK) {
                String res = data.getStringExtra("response");
                if (res.contains("Status=SUCCESS")) {
                    Toast.makeText(context, "Payment successful!", Toast.LENGTH_LONG).show();
                }
                else {
                    Toast.makeText(context, "Payment was not successful! Try again later", Toast.LENGTH_LONG).show();
                }
            }
            else {
                Toast.makeText(context, "Payment was not successful!", Toast.LENGTH_LONG).show();
            }
        }
    }

-1

Your problem is with you method signature. Try to add the response to your method parameter so you can get the response object. Change your method to:

public ModelAndView credPayment(HttpServletRequest request, HttpServletResponse response)
kryger
  • 12,906
  • 8
  • 44
  • 65
Noa
  • 315
  • 1
  • 7
  • 31
  • it should https://stackoverflow.com/questions/4564465/spring-controller-get-request-response If you try to run your request on postman what the response you get? it is not good way to rate -1 for someone offering you a help – Noa Nov 22 '19 at 08:04
  • check this answer as well https://stackoverflow.com/questions/6467848/how-to-get-http-response-code-for-a-url-in-java?rq=1 – Noa Nov 22 '19 at 08:13
  • Have you ever work with UPI hyperlink payment? your link is not about UPI Hyperlink. @Fateh – Nilesh Patel Nov 22 '19 at 08:42
  • it does not matter in the end it is HTTP request, right ? – Noa Nov 22 '19 at 09:12
  • 1
    It does matter because There is question that they are calling our url or not? and if they are calling our url then how to handle that request? – Nilesh Patel Nov 22 '19 at 09:55