Rev 3616 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
package in.shop2020.serving.controllers;import in.shop2020.config.ConfigException;import in.shop2020.payments.Attribute;import in.shop2020.payments.Payment;import in.shop2020.payments.PaymentException;import in.shop2020.payments.PaymentService.Client;import in.shop2020.payments.PaymentStatus;import in.shop2020.serving.services.CommonPaymentService;import in.shop2020.thrift.clients.PaymentClient;import in.shop2020.thrift.clients.TransactionClient;import in.shop2020.thrift.clients.UserClient;import in.shop2020.thrift.clients.config.ConfigClient;import java.io.IOException;import javax.servlet.http.HttpServletRequest;import org.apache.struts2.interceptor.ServletRequestAware;import org.apache.thrift.TException;import org.apache.log4j.Logger;/*** This controller processes payment data received on the back channel from* HDFC. Since this request doesn't have any cookies associated with it, we* can't extend the BaseController which is intercepted by UserInterceptor. Thus* to get the parameters from the request, it implements the ServletRequestAware* interface.** @author Rajveer, Chandranshu* @*/public class HdfcPayResponseController implements ServletRequestAware{/*** Enum of all statuses that can be returned by the HDFC gateway** @author Chandranshu**/private enum PaymentReturnStatus{APPROVED("APPROVED"),NOT_APPROVED("NOT APPROVED"),CAPTURED("CAPTURED"),NOT_CAPTURED ("NOT CAPTURED"),CANCELLED ("CANCELLED"),DENIED_BY_RISK("DENIED BY RISK"),HOST_TIMEOUT("HOST TIMEOUT");private String value;PaymentReturnStatus(String value) {this.value = value;}public String value(){return this.value;}}HttpServletRequest request;//private static Logger log = LoggerFactory.getLogger(HdfcPayResponseController.class);private static Logger log = Logger.getLogger(Class.class);public static String successUrl;public static String errorUrl;public static String AMOUNT = "amt";public static String TRACKID = "trackid";public static String RESULT = "result";public static String AUTH = "auth";public static String TRANID = "tranid";public static String PAYMENTID = "paymentid";public static String REF = "ref";public static String POSTDATE = "postdate";public static String ERROR = "Error";public static String ERRORTEXT = "ErrorText";public static String UDF5 = "udf5";static{try {successUrl = ConfigClient.getClient().get("payment_success_url");errorUrl = ConfigClient.getClient().get("payment_error_url");} catch (ConfigException e) {log.error("Unable to get success and error usr info from config server.");}}String redirectUrl;public HdfcPayResponseController() {}/*** Sets the redirectUrl instance variable which is used in the view to* redirect the customer to the success or failure page.** @return index in all cases.* @throws IOException* @throws SecurityException*/public String create() throws IOException, SecurityException{log.info("Inside hdfc pay response Create");PaymentClient paymentServiceClient = null;TransactionClient transactionServiceClient = null;UserClient userServiceClient = null;try{paymentServiceClient = new PaymentClient();transactionServiceClient = new TransactionClient();userServiceClient = new UserClient();}catch(Exception e){//Nothing to worry. lets move forwardlog.error("Unable to initialize one of the clients", e);}Long txnId = null;String paymentId = request.getParameter(PAYMENTID);String result = request.getParameter(RESULT);String trackId = request.getParameter(TRACKID);long merchantPaymentId = Long.parseLong(trackId);String amount = request.getParameter(AMOUNT);String errorText = request.getParameter(ERRORTEXT);//FIXME dump them somewhereString udf5=request.getParameter(UDF5);//FIXME hdfc is sending comma separated amount, which is very disappointing. May be we get more surprises moving forward.amount= amount.replace(",", "");//Setting redirect URL to the error URL value by default.this.redirectUrl = errorUrl + "?paymentId=" + merchantPaymentId;Client paymentClient = paymentServiceClient.getClient();Payment payment = null;try {payment = paymentClient.getPayment(merchantPaymentId);txnId = payment.getMerchantTxnId();if(!validatePaymentParams(paymentId, amount, udf5, payment))return "index";} catch (PaymentException e1) {log.error("Payment exception. It is serious, check merchant payment id + " + merchantPaymentId, e1);} catch (TException e1) {log.error("Thrift exception. Check payment id "+ merchantPaymentId, e1);}if (result != null && result.trim().equals(PaymentReturnStatus.APPROVED.value())) {log.info("Payment " + merchantPaymentId + " authorized successfully. Updating the database.");String description = "Payment authorized";updatePaymentDetails(merchantPaymentId, description, PaymentStatus.AUTHORIZED, request, paymentClient);CommonPaymentService.processSuccessfulTxn(txnId, userServiceClient, transactionServiceClient, false);this.redirectUrl = successUrl + "?paymentId=" + merchantPaymentId;} else {updatePaymentDetails(merchantPaymentId, errorText, PaymentStatus.FAILED, request, paymentClient);CommonPaymentService.processFailedTxn(txnId, transactionServiceClient);this.redirectUrl = errorUrl + "?paymentId=" + merchantPaymentId;}return "index";}private boolean validatePaymentParams(String paymentId, String amount, String udf5, Payment payment) {long merchantPaymentId = payment.getPaymentId();String dbUdf5="";double dbAmount = payment.getAmount();for(Attribute attribute: payment.getAttributes()){if(attribute.getName().trim().equalsIgnoreCase(UDF5)){dbUdf5 = attribute.getValue();}}// verify 3 things: udf5, amount and paymentid//FIXME should we first dump the data and then verify these things. ??double returnedAmount = Double.parseDouble(amount);log.info(paymentId+ ":"+ payment.getGatewayPaymentId() + "\n" + returnedAmount + ":" + dbAmount + "\n" + dbUdf5 + ":" + udf5 );if(!(paymentId.equalsIgnoreCase(payment.getGatewayPaymentId()) && (Math.abs(dbAmount - returnedAmount) <= 0.50) && udf5.equalsIgnoreCase(dbUdf5))){log.error("Checks and balance failed on returned data");this.redirectUrl = errorUrl + "?paymentId="+merchantPaymentId;return false;}return true;}private void updatePaymentDetails(long merchantPaymentId, String message, PaymentStatus status, HttpServletRequest req, Client paymentClient) {String paymentId = request.getParameter(PAYMENTID);String result = request.getParameter(RESULT);String postdate = request.getParameter(POSTDATE);String tranId = request.getParameter(TRANID);String auth = request.getParameter(AUTH);String ref = request.getParameter(REF);String sessionId = request.getSession().getId();String errorNo = request.getParameter(ERROR);try {paymentClient.updatePaymentDetails(merchantPaymentId, paymentId, sessionId, result, message, tranId, auth, ref, errorNo, status, postdate, null);} catch (PaymentException e1) {log.error("Unable to update payment details in our database.", e1);} catch (TException e1) {log.error("Unable to update payment details in our database. Thrift exception.", e1);}}public String getRedirectUrl(){return this.redirectUrl;}@Overridepublic void setServletRequest(HttpServletRequest request) {this.request = request;for(Object param: request.getParameterMap().keySet()){log.info("PARAMS: " + param + " = "+ request.getParameter((String)param));}}}