Rev 4246 | Blame | Compare with Previous | Last modification | View Log | RSS feed
package in.shop2020.serving.controllers;import in.shop2020.config.ConfigException;import in.shop2020.model.v1.order.RechargeOrder;import in.shop2020.model.v1.order.RechargeOrderStatus;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 java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.text.SimpleDateFormat;import java.util.ArrayList;import java.util.Date;import java.util.List;import java.util.Map;import java.util.TreeMap;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{private static String rechargeResultUri;/*** The secret key used to decode RC4 encoded data.*/private static String accountKey;private static String salt;private String eurl;private String surl;/*** 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 = "Amount";public static String PAYMENTID = "PaymentID";public static String ERROR = "Error";public static String MERCHANTREFNO="MerchantRefNo";public static String RESPONSECODE="ResponseCode";public static String SECUREHASH="SecureHash";public static String RESPONSEMESSAGE = "ResponseMessage";public static String ISFLAGGED = "IsFlagged";public static String TRANSACTIONID ="TransactionID";public static String PAYMENTMETHOD = "PaymentMethod";public static String REQUESTID= "RequestID";public static String DATECREATED = "DateCreated";public static String SUCCESS= "0";//responsecode for successfull transaction by hdfc gatewaystatic{try {ConfigClient cc = ConfigClient.getClient();successUrl = cc.get("payment_success_url");errorUrl = cc.get("payment_error_url");rechargeResultUri = cc.get("recharge_result_uri");} catch (ConfigException e) {log.error("Unable to get success and error usr info from config server.");}}String redirectUrl;public HdfcPayResponseController() {}private Map<String, String> paymentParams = new TreeMap<String, String>();/*** 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");eurl = errorUrl;surl = successUrl;updatePaymentParams(request.getParameterMap());PaymentClient paymentServiceClient = null;TransactionClient transactionServiceClient = null;UserClient userServiceClient = null;try {userServiceClient = new UserClient();paymentServiceClient = new PaymentClient();transactionServiceClient = new TransactionClient();} catch (Exception e) {log.error("Unable to initialize one of the clients", e);}long merchantPaymentId = Long.parseLong(paymentParams.get(MERCHANTREFNO));String gatewayPaymentId = paymentParams.get(PAYMENTID);double amount = Double.parseDouble(paymentParams.get(AMOUNT));String gatewayTxnStatus = paymentParams.get(RESPONSECODE);String hash = paymentParams.get(SECUREHASH);String transactionId = paymentParams.get(TRANSACTIONID);String requestId = paymentParams.get(REQUESTID);String error = paymentParams.get(ERROR);List<Attribute> attributes = new ArrayList<Attribute>();Payment payment = null;Long txnId = null;try {payment = paymentServiceClient.getClient().getPayment(merchantPaymentId);txnId = payment.getMerchantTxnId();} 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(payment.getStatus() != PaymentStatus.INIT){// We have already processed a response for this payment. Processing// it again may fail his orders. So, let's ask him to check his// account.return "ebs-pay-response-maybe";}if(payment.isIsDigital()){eurl = rechargeResultUri;surl = rechargeResultUri;}if(!validatePaymentParams(amount, payment, hash)){this.redirectUrl = eurl + "?paymentId=" + merchantPaymentId;return "index";}if(gatewayTxnStatus.equalsIgnoreCase(SUCCESS)){try {attributes.add(new Attribute(DATECREATED, paymentParams.get(DATECREATED)));paymentServiceClient.getClient().updatePaymentDetails(merchantPaymentId, gatewayPaymentId,"", gatewayTxnStatus, "Transaction captured at PG",transactionId, "", requestId, "", PaymentStatus.SUCCESS,new SimpleDateFormat().format(new Date()), attributes);} catch (PaymentException e) {this.redirectUrl = eurl + "?paymentId=" + merchantPaymentId;return "index";} catch (TException e) {this.redirectUrl = eurl + "?paymentId=" + merchantPaymentId;return "index";}if(payment.isIsDigital()){RechargeOrder rechargeOrder = null;try {rechargeOrder = transactionServiceClient.getClient().getRechargeOrdersForTransaction(txnId);} catch (Exception e1) {log.error("Problem with txn client while getting recharge object", e1);this.redirectUrl = eurl + "?paymentId=" + merchantPaymentId;return "index";}try {PaymentClient pcl = new PaymentClient();boolean isCaptured = pcl.getClient().capturePayment(txnId, true);//Retry in case we are not able to capture first timeif(!isCaptured){Thread.sleep(2000);isCaptured = pcl.getClient().capturePayment(txnId, true);}if(!isCaptured){Thread.sleep(2000);isCaptured = pcl.getClient().capturePayment(txnId, true);}if(isCaptured) {transactionServiceClient.getClient().updateRechargeOrderStatus(rechargeOrder.getId(), RechargeOrderStatus.PAYMENT_SUCCESSFUL);} else {transactionServiceClient.getClient().updateRechargeOrderStatus(rechargeOrder.getId(), RechargeOrderStatus.PAYMENT_FAILED);}} catch (Exception e) {log.error("Problem with txn client while trying to recharge", e);}} else {CommonPaymentService.processSuccessfulTxn(txnId, userServiceClient, transactionServiceClient, false);}this.redirectUrl = surl + "?paymentId=" + merchantPaymentId;} else{try {attributes.add(new Attribute(ERROR, error));paymentServiceClient.getClient().updatePaymentDetails(merchantPaymentId, gatewayPaymentId,"", gatewayTxnStatus, "Payment Failed at PG ", "", "", "", "", PaymentStatus.FAILED, new SimpleDateFormat().format(new Date()), attributes);} catch (PaymentException e) {log.error("Unable to mark the payment as failed", e);} catch (TException e) {log.error("Unable to mark the payment as failed", e);}if(!payment.isIsDigital()) {CommonPaymentService.processFailedTxn(txnId, transactionServiceClient);}this.redirectUrl = eurl + "?paymentId=" + merchantPaymentId;}log.info("User will be redirected to: " + surl + "?paymentId=" + merchantPaymentId);return "index";}private boolean validatePaymentParams(double returnedAmount, Payment payment, String hash){boolean hashCheckResult= hash.equals(getSecureHash());hashCheckResult = true;//remove this and implement hash checkif(!(payment != null && Math.abs(payment.getAmount() - returnedAmount) <= 0.50&& hashCheckResult)){// We did not request this payment or the authorised amount is different.log.error("Checks and balance failed on returned data");return false;}return true;}public String getSecureHash(){/*try{//to do implement hash check}catch(Exception nsae){log.error("No such algorithm exception");return null;}*/return "";}private void updatePaymentParams(Map map){for(Object key : map.keySet()){String keyStr = (String)key;String[] vals = (String[])map.get(keyStr);String value = vals[0];System.out.println("Key " + (String)key + " : " + value);paymentParams.put(keyStr, value);}}/* 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 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));}}}