Integrating PayUmoney Webhooks with your Java backend

Upasana | July 27, 2018 | 3 min read | 1,187 views | Payumoney Integration


Why you need Webhooks?

Webhook is a HTTP callback. The callback is done to a url specified while creating a webhook. The webhook callbacks are event driven i.e. a callback to a webhook will be done whenever the event (payment success, failure, refund, etc) associated with the webhook occurs.

Webhooks make sure that any intermittent payment failures (due to spike in server load, hitting back button during payment by customer, etc.) are handled gracefully and payments get processed without manual intervention. Webhooks makes entire payment process resilient to failures, thus reduces manual support.

How does PayUMoney webhook work?

First of all, we need to login into payumoney dashboard at the below link

Then goto Payumoney → Dashboard → Settings → Webhook Settings

payumoney webhook setting
Payumoney webhook settings screen

Now configure the webhook details, the URL that payumoney need to hit for callbacks, etc.

Webhook callback request format

Payumoney webhook official format for response can be download from here: https://github.com/payumoney-india/Webhooks/raw/master/Transaction_POST_Format.pdf

Java + Spring Server Side Integration

Lets implement a webhook URL that payumoney will invoke after a succesful payment. First of all we will create a Java Model that maps to webhook response attributes.

/src/main/java/foo/PayuPayload.java
import com.fasterxml.jackson.annotation.JsonProperty;

public class PayuPayload {
    private String hash;
    @JsonProperty("merchantTransactionId")
    private String merchantTransactionId;
    private String paymentId;
    private String paymentMode;
    private String status;
    private String amount;
    @JsonProperty("error_Message")
    private String error_Message;
    private String customerName;
    private String customerEmail;
    private String customerPhone;

    private String notificationId;
    private String additionalCharges;
    private String productInfo;
    @JsonProperty("split_info")
    private String split_info;
    private String udf1;
    private String udf2;
    private String udf3;

    private String bankCode;
    private String netAmountDebit;
    private String bankRefNum;
    private String mihpayid;

    //Getter,Setter ommitted for brevity

Now we will need a rest controller that can handle webhook POST request.

/src/main/java/foo/PayUMoneyPaymentController.java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.shunya.ecommerce.payment.model.PayuPayload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.io.IOException;

@Controller
@RequestMapping(value = "/gateway")
public class PayUMoneyPaymentController {
    private static final Logger logger = LoggerFactory.getLogger(PayUMoneyPaymentController.class);

    @PostMapping(value = "/payu/success-webhook")
    @ResponseStatus(HttpStatus.OK)
    public void handleWebhookSuccess(HttpEntity<String> httpEntity) throws IOException {
        final String payuResponseBody = httpEntity.getBody();
        logger.info("Dumping webhook the parameters. - {} ", payuResponseBody);
        final PayuPayload payload = new ObjectMapper().readValue(payuResponseBody, PayuPayload.class);
        logger.info(payload.toString());
        payuMoneyService.process(payload.getMerchantTransactionId(), payload);   (1)
    }

}
1 payuMoneyService is the transactional backend service that takes appropriate action for the webhook data for e.g. it can process an order.

Important Points

Design for Idempotency

Webhook callbacks should be idempotent in nature i.e. even if the same method is called multiple time, it should hadle it gracefully. It should never process the same order multiple times.

Ignore from Spring Security

If you have configured Spring Security in your project, you will have to ignore this webhook endpoint using the below configuration

/src/main/java/config/SecurityConfig.java
@Override
public void configure(WebSecurity web) throws Exception {
    super.configure(web);
    // @formatter:off
    web.ignoring().antMatchers("/gateway/payu/success-webhook");
    // @formatter:on
}
Always use HTTPS

You should always use SSL for http communication to make it secure. If you do not want to buy a certificate, you can try Lets Encrypt SSL certificate authority which provides it free of cost.

References

Introducing PayUMoney webhooks – get callbacks to your server - https://blog.payumoney.com/introducing-payumoney-webhooks-get-callbacks-to-your-server/

Download Git Repository

You can down entire codebase from my Github repository https://github.com/cancerian0684/payumoney-webhook-spring-boot

Contact me for more details

You can always contact me for more details.


Top articles in this category:
  1. Integrating PayUmoney with your Java Server Side
  2. how to enable asciimath formula using mathjax in asciidoctorJ
  3. Using Asciidoctor in Java and Spring Boot
  4. 2factor SMS in Spring Boot App
  5. Reverting default shell to bash from Zsh in Mac OS Catalina
  6. Asciidoc: How to use nofollow option in asciidoc document

Recommended books for interview preparation:

Find more on this topic:
Buy interview books

Java & Microservices interview refresher for experienced developers.