Subversion Repositories SmartDukaan

Rev

Rev 1905 | Rev 2134 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

package in.shop2020.serving.controllers;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;

import in.shop2020.config.ConfigException;
import in.shop2020.payments.Attribute;
import in.shop2020.payments.Payment;
import in.shop2020.payments.PaymentException;
import in.shop2020.payments.PaymentStatus;
import in.shop2020.serving.services.CommonPaymentService;
import in.shop2020.serving.services.EbsPaymentService;
import in.shop2020.serving.utils.DataLogger;
import in.shop2020.serving.utils.DataLogger.Event;
import in.shop2020.serving.utils.ebs.Base64;
import in.shop2020.serving.utils.ebs.RC4;
import in.shop2020.thrift.clients.PaymentServiceClient;
import in.shop2020.thrift.clients.TransactionServiceClient;
import in.shop2020.thrift.clients.UserContextServiceClient;
import in.shop2020.thrift.clients.config.ConfigClient;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.thrift.TException;

public class EbsPayResponseController implements ServletRequestAware{
        
        private HttpServletRequest request;
        
        private static Logger log = Logger.getLogger(Class.class);
        private static Logger dataLog = DataLogger.getLogger();
        
        private static final String FLAG_KEY = "IsFlagged";
        private static final String TXN_KEY = "TransactionID";
        private static final String AUTH_TXN_ID = "AuthTxnId";
        private static final String CAPTURE_TXN_ID = "CaptureTxnId";
        private static final String CAPTURE_TIME = "CaptureTime";
        
        private static String processingUrl;
        private static String successUrl;
        private static String errorUrl;
        
        /**
         * The secret key used to decode RC4 encoded data.
         */
        private static String accountKey;
        
        private String redirectUrl;
        private String id;
        
        static{
                try {
                        processingUrl = ConfigClient.getClient().get("ebs_processing_url"); 
                        successUrl = ConfigClient.getClient().get("ebs_success_url");
                        errorUrl = ConfigClient.getClient().get("ebs_error_url");
                        accountKey = ConfigClient.getClient().get("ebs_secret_key");
                } catch (ConfigException e) {
                        log.error("Unable to get success and error usr info from config server.");
                }
        }
        
        private Map<String, String> paymentParams = new TreeMap<String, String>();
        
        public String index() {
                StringBuffer data1 = new StringBuffer(request.getParameter("DR"));
                log.info("Received data string: " + data1.toString());
                byte[] result = decodeRecvdData(data1);

                String recvString = parseRecvdData(result);
                updatePaymentParams(recvString);
                
                PaymentServiceClient paymentServiceClient = null;
                TransactionServiceClient transactionServiceClient = null;
                UserContextServiceClient userServiceClient = null;
                try {
                        paymentServiceClient = new PaymentServiceClient();
                        transactionServiceClient = new TransactionServiceClient();
                        userServiceClient = new UserContextServiceClient();
                } catch (Exception e) {
                        log.error("Unable to initialize one of the clients");
                        e.printStackTrace();
                }
                
                
                long merchantPaymentId = Long.parseLong(paymentParams.get("MerchantRefNo"));
                String gatewayPaymentId = paymentParams.get("PaymentID");
                double amount = Double.parseDouble(paymentParams.get("Amount"));
                String isFlagged = paymentParams.get(FLAG_KEY);
                String gatewayTxnStatus = paymentParams.get("ResponseCode");
                String description = paymentParams.get("ResponseMessage");
                String authTxnId = paymentParams.get(TXN_KEY);
                
                
                List<Attribute> attributes = new ArrayList<Attribute>();
                attributes.add(new Attribute(FLAG_KEY, isFlagged));
                attributes.add(new Attribute(AUTH_TXN_ID, authTxnId));
                
                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.printStackTrace();
                } catch (TException e1) {
                        log.error("Thrift exception. Check payment id "+ merchantPaymentId);
                        e1.printStackTrace();
                }
                
                if(!validatePaymentParams(amount, payment)){
                        return "index";
                }
                
                if(gatewayTxnStatus.equals("0")){
                        //Update payment status as authorized
                        try {
                                paymentServiceClient.getClient().updatePaymentDetails(merchantPaymentId, gatewayPaymentId,
                                                "", gatewayTxnStatus, description, "", "", "", "", PaymentStatus.AUTHORIZED, "", attributes);
                        } catch (PaymentException e) {
                                e.printStackTrace();
                        } catch (TException e) {
                                e.printStackTrace();
                        }

                        Map<String, String> captureResult = EbsPaymentService.capturePayment(amount, gatewayPaymentId);
                        String captureStatus = captureResult.get(EbsPaymentService.STATUS);
                        
                        if("".equals(captureStatus)){
                                //Failure
                                description = captureResult.get(EbsPaymentService.ERROR);
                                String errorCode = captureResult.get(EbsPaymentService.ERR_CODE);
                                try {
                                        paymentServiceClient.getClient().updatePaymentDetails(merchantPaymentId, gatewayPaymentId,
                                                        "", gatewayTxnStatus, description, "", "", "", errorCode, PaymentStatus.FAILED, "", attributes);
                                } catch (PaymentException e) {
                                        log.error("Error while updating failed capture payment attempt: ", e);
                                } catch (TException e) {
                                        log.error("Error while updating failed capture payment attempt: ", e);
                                }
                                dataLog.info(StringUtils.join(new String[] {
                        Event.PAYMENT_FAILURE.name(), Long.toString(merchantPaymentId), gatewayPaymentId,
                        gatewayTxnStatus, description, errorCode },
                        ", "));
                                this.redirectUrl = errorUrl + "?paymentId=" + merchantPaymentId;
                        }else{
                                //Success
                                try {
                                        attributes.add(new Attribute(CAPTURE_TXN_ID, captureResult.get(EbsPaymentService.TXN_ID)));
                                        attributes.add(new Attribute(CAPTURE_TIME, captureResult.get(EbsPaymentService.DATE_TIME)));
                                        
                                        paymentServiceClient.getClient().updatePaymentDetails(merchantPaymentId, gatewayPaymentId,
                                                        "", captureStatus, description, "", "", "", "", PaymentStatus.SUCCESS, "", attributes);
                                } catch (PaymentException e) {
                                        log.error("Error while updating successful capture payment attempt: ", e);
                                } catch (TException e) {
                                        log.error("Error while updating successful capture payment attempt: ", e);
                                }
                                
                                CommonPaymentService.processSuccessfulTxn(txnId, userServiceClient, transactionServiceClient);

                                CommonPaymentService.sendTxnEmail(txnId, transactionServiceClient);
                                dataLog.info(StringUtils.join(new String[] {
                        Event.PAYMENT_SUCCESS.name(), Long.toString(merchantPaymentId), gatewayPaymentId,
                        gatewayTxnStatus, description, captureStatus },
                        ", "));
                                this.redirectUrl = successUrl + "?paymentId=" + merchantPaymentId;                              
                        }
                }else{
                        try {
                                paymentServiceClient.getClient().updatePaymentDetails(merchantPaymentId, gatewayPaymentId,
                                                "", gatewayTxnStatus, description, "", "", "", "", PaymentStatus.FAILED, "", attributes);
                        } catch (PaymentException e) {
                                e.printStackTrace();
                        } catch (TException e) {
                                e.printStackTrace();
                        }
                        
                        CommonPaymentService.processFailedTxn(txnId, transactionServiceClient);
                        dataLog.info(StringUtils.join(new String[] {
                    Event.PAYMENT_FAILURE.name(), Long.toString(merchantPaymentId), gatewayPaymentId,
                    gatewayTxnStatus, description },
                    ", "));

                        this.redirectUrl = errorUrl + "?paymentId=" + merchantPaymentId;
                }
                
                log.info("User will be redirected to: " + this.redirectUrl);
                return "index";
        }
        
        public String show(){
                StringBuffer paymentData = new StringBuffer(request.getParameter("DR"));
                for (int i = 0; i < paymentData.length(); i++) {
                        if (paymentData.charAt(i) == ' ')
                                paymentData.setCharAt(i, '+');
                }
                
                log.info("Received data string: " + paymentData.toString());
                this.redirectUrl = processingUrl + paymentData.toString();
                return "show";
        }
        
        public String getId() {
                return id;
        }

        private boolean validatePaymentParams(double amount, Payment payment){
                long merchantPaymentId = payment.getPaymentId();
                if(payment==null || payment.getAmount()!= amount){
                        // We did not request this payment or the authorised amount is different.
                        log.error("Checks and balance failed on returned data");
                        this.redirectUrl = errorUrl + "?paymentId=" + merchantPaymentId;
                        return false;
                }
                return true;
        }

        private byte[] decodeRecvdData(StringBuffer data1) {
                for (int i = 0; i < data1.length(); i++) {
                        if (data1.charAt(i) == ' ')
                                data1.setCharAt(i, '+');
                }
                
                Base64 base64 = new Base64();
                byte[] data = base64.decode(data1.toString());
                RC4 rc4 = new RC4(accountKey);
                byte[] result = rc4.rc4(data);
                return result;
        }

        private String parseRecvdData(byte[] result) {
                ByteArrayInputStream byteIn = new ByteArrayInputStream(result, 0, result.length);
                DataInputStream dataIn = new DataInputStream(byteIn);
                String recvString1 = "";
                String recvString = "";
                try {
                        recvString1 = dataIn.readLine();
                        int lineCount = 0;
                        while (recvString1 != null) {
                                lineCount++;
                                if (lineCount > 705)
                                        break;
                                recvString += recvString1 + "\n";
                                recvString1 = dataIn.readLine();
                        }
                } catch (IOException e) {
                        e.printStackTrace();
                }
                recvString = recvString.replace("=&", "=--&");
                return recvString;
        }

        private void updatePaymentParams(String str){
                StringTokenizer st = new StringTokenizer(str, "=&");
                String key, value; 
                while(st.hasMoreTokens()) {
                        key = st.nextToken();
                        value = st.nextToken();
                        log.info("Key: " + key + ", Value: " + value);
                        paymentParams.put(key, value);
                }
        }
        
        public String getRedirectUrl(){
                return this.redirectUrl;
        }
        
        @Override
        public void setServletRequest(HttpServletRequest request) {
                this.request = request;
        }

        public Map<String, String> getPaymentParams() {
                return paymentParams;
        }
}