Subversion Repositories SmartDukaan

Rev

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

package in.shop2020.payment.service.handler;

import in.shop2020.config.ConfigException;
import in.shop2020.model.v1.order.LineItem;
import in.shop2020.model.v1.order.Order;
import in.shop2020.model.v1.order.Transaction;
import in.shop2020.model.v1.order.TransactionServiceException;
import in.shop2020.model.v1.user.ShoppingCartException;
import in.shop2020.payment.domain.Payment;
import in.shop2020.payments.Attribute;
import in.shop2020.payments.PaymentException;
import in.shop2020.payments.PaymentStatus;
import in.shop2020.thrift.clients.TransactionClient;
import in.shop2020.thrift.clients.config.ConfigClient;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.log4j.Logger;
import org.apache.thrift.TException;

import com.aciworldwide.commerce.gateway.plugins.NotEnoughDataException;
import com.aciworldwide.commerce.gateway.plugins.e24PaymentPipe;
import com.aciworldwide.commerce.gateway.plugins.e24TranPipe;

public class HdfcEmiPaymentHandler implements IPaymentHandler {
    private static final int CAPTURE_STATUS_FOR_CONNECTION_ISSUE = -1;

    private static Logger log = Logger.getLogger(HdfcEmiPaymentHandler.class);

    private static String responseURL;
    private static String errorURL;
    private static final String regex = "[^a-zA-Z0-9\\s\\-\\@\\/\\.]";
    private static final String replacement = " ";
    private static final int MAX_UDF_LENGTH = 30;
    private static final String currencyCode = "356";
        private static final String resourceFileName = "resource.cgn";
        
    private enum ActionType{
        PURCHASE("1"),
        REFUND ("2"),
        AUTH ("4"),
        CAPTURE("5");
        private String value;
        ActionType(String value) {
            this.value = value;
        }
        public String value(){
            return this.value;
        }
    }
    
    public HdfcEmiPaymentHandler() {
        // TODO Auto-generated constructor stub
    }
    
    static{
        File resourceBaseDir = new File("/tmp/emi-resource/");
        if(!resourceBaseDir.exists()){
                resourceBaseDir.mkdir();
                }
        int []  gatewayIds = {5,10,11,12,14};
        for(int gatewayId: gatewayIds){
                String resourceDirPath = "/tmp/emi-resource/" + gatewayId + "/";
                try {
                                InputStream inputStream = Class.class.getResourceAsStream(ConfigClient.getClient().get("emi_payment_resource_file_path") + gatewayId + File.separator + resourceFileName);
                                File resourceDir = new File(resourceDirPath);
                                if(!resourceDir.exists()){
                                        resourceDir.mkdir();
                                }
                                
                                OutputStream outStream = new FileOutputStream(resourceDirPath  + resourceFileName);
                                byte buf[]=new byte[1024];
                                int len;
                                while((len=inputStream.read(buf))>0)
                                        outStream.write(buf,0,len);
                                outStream.close();
                                inputStream.close();
        
                                responseURL = ConfigClient.getClient().get("emi_payment_response_url");
                    errorURL = ConfigClient.getClient().get("emi_payment_error_url");
                } catch (ConfigException e) {
                    log.error("Unable to get data from config server.");
                } catch (FileNotFoundException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                        }
        }
    }
    
    public static Map<String, String> capturePayment(Payment payment){
        String amount = "" + payment.getAmount();
        String gatewayPaymentId = payment.getGatewayPaymentId();
        log.info("Capturing amount: Rs " + amount + " for payment Id: " + gatewayPaymentId);
        
        String aliasName = null;
                try {
                        aliasName = ConfigClient.getClient().get("emi_payment_alias_name" + payment.getGatewayId());
                } catch (ConfigException e1) {
                        e1.printStackTrace();
                }
                String resourceDirPath = "/tmp/emi-resource/" + payment.getGatewayId() + "/";

        //Prepare resultMap to elicit failure behaviour in case anything goes wrong.
        Map<String, String> resultMap = new HashMap<String, String>();
        resultMap.put(STATUS, Errors.CAPTURE_FAILURE.code);
        resultMap.put(ERR_CODE, Errors.CAPTURE_FAILURE.code);
        resultMap.put(ERROR, Errors.CAPTURE_FAILURE.message);
        
        e24TranPipe pipe = new e24TranPipe();
        pipe.setResourcePath(resourceDirPath);
        pipe.setAlias(aliasName);
        pipe.setAction(ActionType.CAPTURE.value());
        pipe.setAmt(amount);
        pipe.setTrackId("" + payment.getId());
        pipe.setMember("SAHOLIC");
        pipe.setCurrencyCode(currencyCode);
        pipe.setTransId(payment.getGatewayTxnId());
        
        //Check if the values have been set properly
        log.info("Pipe Amount: " + pipe.getAmt());
        log.info("Pipe Action Code: " + pipe.getAction());
        log.info("Pipe Currency Code: " + pipe.getCurrencyCode());
        log.info("Pipe Track Id: " + pipe.getTrackId());
        log.info("Pipe Trans Id:" + pipe.getTransId());
        
        int captureStatus = e24TranPipe.FAILURE;
        try {
            captureStatus = pipe.performTransaction();
            
            log.info("Capture Status: " + captureStatus);
            log.info("Gateway Txn Status: " + pipe.getResult());
            log.info("Debug Msg: " + pipe.getDebugMsg());
            log.info("Auth: " + pipe.getAuth());
            log.info("Ref: " + pipe.getRef());
            log.info("TransId:" + pipe.getTransId());
            log.info("Amount: " + pipe.getAmt());
            
            resultMap.put(STATUS, "" + captureStatus);
            String result = pipe.getResult();
            resultMap.put(GATEWAY_STATUS, result.substring(0, Math.min(result.length(), 20)).trim());       //This will return the result of the transaction. (Successful or Failed)
            if(captureStatus != e24TranPipe.SUCCESS || !"CAPTURED".equals(result)){
                resultMap.put(ERROR, pipe.getErrorMsg());               // In case of any error, we only need to get the error message

                if (captureStatus == CAPTURE_STATUS_FOR_CONNECTION_ISSUE) {
                    resultMap.put(ERR_CODE, Errors.CONN_FAILURE.code);
                }
            }
            else {
                resultMap.put(CAPTURE_AUTH_ID, pipe.getAuth());         // Unique ID generated by Authorizer of the transaction
                resultMap.put(CAPTURE_REF_ID, pipe.getRef());           // Unique reference number generated during the transaction
                resultMap.put(CAPTURE_TXN_ID, pipe.getTransId());       // Unique Transaction ID generated after every successful transaction
                resultMap.put(CAPTURE_AMNT, pipe.getAmt());         // Original Amount of the transaction
            }
        } catch (NotEnoughDataException e) {
            log.error(Errors.CAPTURE_FAILURE.message, e);
            resultMap.put(ERR_CODE, Errors.CAPTURE_FAILURE.code);
            resultMap.put(ERROR, e.getMessage());
        }
                        
        return resultMap;
    }
    
    public static Map<String, String> refundPayment(Payment payment, double amount){
        String ramount = "" + amount;
        String gatewayPaymentId = payment.getGatewayPaymentId();
        log.info("Refunding amount: Rs " + amount + " for payment Id: " + gatewayPaymentId);
        
        String aliasName = null;
                try {
                        aliasName = ConfigClient.getClient().get("emi_payment_alias_name" + payment.getGatewayId());
                } catch (ConfigException e1) {
                        e1.printStackTrace();
                }
                String resourceDirPath = "/tmp/emi-resource/" + payment.getGatewayId() + "/";

        //Prepare resultMap to elicit failure behaviour in case anything goes wrong.
        Map<String, String> resultMap = new HashMap<String, String>();
        resultMap.put(STATUS, Errors.CAPTURE_FAILURE.code);
        resultMap.put(ERR_CODE, Errors.CAPTURE_FAILURE.code);
        resultMap.put(ERROR, Errors.CAPTURE_FAILURE.message);
        
        e24TranPipe pipe = new e24TranPipe();
        pipe.setResourcePath(resourceDirPath);
        pipe.setAlias(aliasName);
        pipe.setAction(ActionType.REFUND.value());
        pipe.setAmt(ramount);
        pipe.setTrackId("" + payment.getId());
        pipe.setMember("SAHOLIC");
        pipe.setCurrencyCode(currencyCode);
        pipe.setTransId(payment.getGatewayTxnId());
        
        //Check if the values have been set properly
        log.info("Pipe Amount: " + pipe.getAmt());
        log.info("Pipe Action Code: " + pipe.getAction());
        log.info("Pipe Currency Code: " + pipe.getCurrencyCode());
        log.info("Pipe Track Id: " + pipe.getTrackId());
        log.info("Pipe Trans Id:" + pipe.getTransId());
        
        int refundStatus = e24TranPipe.FAILURE;
        try {
            refundStatus = pipe.performTransaction();
            
            log.info("Refund Status: " + refundStatus);
            log.info("Gateway Txn Status: " + pipe.getResult());
            log.info("Debug Msg: " + pipe.getDebugMsg());
            log.info("Auth: " + pipe.getAuth());
            log.info("Ref: " + pipe.getRef());
            log.info("TransId:" + pipe.getTransId());
            log.info("Amount: " + pipe.getAmt());
            
            resultMap.put(STATUS, "" + refundStatus);
            String result = pipe.getResult();
            resultMap.put(GATEWAY_STATUS, result.substring(0, Math.min(result.length(), 20)).trim());       //This will return the result of the transaction. (Successful or Failed)
            if(refundStatus != e24TranPipe.SUCCESS || !"CAPTURED".equals(result)){
                resultMap.put(ERROR, pipe.getErrorMsg());               // In case of any error, we only need to get the error message

                if (refundStatus == CAPTURE_STATUS_FOR_CONNECTION_ISSUE) {
                    resultMap.put(ERR_CODE, Errors.CONN_FAILURE.code);
                }
            }
            else {
                resultMap.put(REFUND_AUTH_ID, pipe.getAuth());         // Unique ID generated by Authorizer of the transaction
                resultMap.put(REFUND_REF_ID, pipe.getRef());           // Unique reference number generated during the transaction
                resultMap.put(REFUND_TXN_ID, pipe.getTransId());       // Unique Transaction ID generated after every successful transaction
                resultMap.put(REFUND_AMNT, pipe.getAmt());         // Original Amount of the transaction
            }
        } catch (NotEnoughDataException e) {
            log.error(Errors.CAPTURE_FAILURE.message, e);
            resultMap.put(ERR_CODE, Errors.CAPTURE_FAILURE.code);
            resultMap.put(ERROR, e.getMessage());
        }
                        
        return resultMap;
    }
    
    
    public static String initializeHdfcPayment(Payment payment, PaymentServiceHandler handler) throws Exception{
        long merchantPaymentId = payment.getId();
        double amount = payment.getAmount();
        e24PaymentPipe pipe = new e24PaymentPipe();
        
        try {
            initializePayment(pipe, merchantPaymentId, amount, payment.getGatewayId());
        } catch (ShoppingCartException e1) {
            log.error("Error while creating hdfc payment.", e1);
            throw e1;    //Payment couldn't be initialized. Will be redirected to the shipping page.
        } catch (TException e1) {
            log.error("Error while creating hdfc payment.", e1);
            throw e1;   //Payment couldn't be initialized. Will be redirected to the shipping page.
        }
        
        List<Attribute> attributes = null;
        try {
            attributes = getAttributesAndSetUdfs(pipe, payment.getMerchantTxnId());
        } catch (TransactionServiceException e1) {
            log.error("Error while setting udfs to payment.", e1);
            throw e1;   //Payment couldn't be initialized. Will be redirected to the shipping page.
        } catch (TException e1) {
            log.error("Error while setting udfs to payment.", e1);
            throw e1;   //Payment couldn't be initialized. Will be redirected to the shipping page.
        }
        
        try {
            if(pipe.performPaymentInitialization() != e24PaymentPipe.SUCCESS) {
                log.error("Error sending Payment Initialization Request: ");
                handler.updatePaymentDetails(merchantPaymentId, null, "", "", pipe.getErrorMsg(), "", "", "", "", PaymentStatus.INIT, "", attributes);
            } else {
                log.info("Payment Initialization Request processed successfully for payment Id: " + merchantPaymentId);
                String paymentID = pipe.getPaymentId();
                handler.updatePaymentDetails(merchantPaymentId, paymentID, "", "", "", "", "", "", "", PaymentStatus.INIT, "", attributes);
                
                String payURL = pipe.getPaymentPage();
                return payURL + "?PaymentID=" + paymentID;
            }
        } catch (NotEnoughDataException e) {
            log.error("Error while initializing payment.", e);
        }catch (Exception e) {
            log.error("Error while initializing payment.", e);
        }
        //If the code reaches here, the payment initialization was not successful and we've not returned the redirect URL.
        //Throw the exception so that any failovers can happen.
        throw new PaymentException(115, "Unable to initialize HDFC payment");
    }
    
    private static List<Attribute> getAttributesAndSetUdfs(e24PaymentPipe pipe, long txnId) throws TransactionServiceException, TException{
        StringBuilder orderDetails = new StringBuilder();
        StringBuilder billingAddress = new StringBuilder();
        String email = "";
        String contactNumber = "";
        
        //get udfs
        Transaction transaction;
        TransactionClient transactionServiceClient = null;
        try {
            transactionServiceClient = new TransactionClient();
        } catch (Exception e) {
            log.error("Unable to get transaction details", e);
        }
        
        in.shop2020.model.v1.order.TransactionService.Client txnClient = transactionServiceClient.getClient();
        transaction = txnClient.getTransaction(txnId);
        orderDetails.append(transaction.getOrdersSize() + " ");
        for (Order order : transaction.getOrders()) {
            contactNumber= order.getCustomer_mobilenumber();
            email = order.getCustomer_email();
            billingAddress.append(" ");
            if(order.getCustomer_pincode()!=null){
                billingAddress.append(order.getCustomer_pincode());
            }
            if(order.getCustomer_city()!=null){
                billingAddress.append(" " + order.getCustomer_city());
            }
            if(order.getCustomer_address1()!=null){
                billingAddress.append(" " + order.getCustomer_address1());
            }
            if(order.getCustomer_address2()!=null){
                billingAddress.append(" " + order.getCustomer_address2());
            }
            if(order.getCustomer_state()!=null){
                billingAddress.append(" " + order.getCustomer_state());
            }
            

            for(LineItem line: order.getLineitems()){
                if(line.getBrand() != null){
                    orderDetails.append(line.getBrand());
                }
                if(line.getModel_name() != null){
                    orderDetails.append(line.getModel_name()); 
                }
                if(line.getModel_number() != null){
                    orderDetails.append(line.getModel_number());
                }
                if(line.getColor() != null){
                    orderDetails.append(line.getColor());
                }
                orderDetails.append(" ");
            }
            
        }
        
        Random random = new Random();
        String merchantInfo = ""+random.nextLong(); 
        
        String udf1 = formatUdf(orderDetails.toString()); 
        String udf2 = formatUdf(email);
        String udf3 = formatUdf(contactNumber);
        String udf4 = formatUdf(billingAddress.toString());
        String udf5 = merchantInfo;

        log.info("udf1:"  + udf1);
        log.info("udf2:"  + udf2);
        log.info("udf3:"  + udf3);
        log.info("udf4:"  + udf4);
        log.info("udf5:"  + udf5);
        

        pipe.setUdf1(udf1);      // UDF 1 - Order details
        pipe.setUdf2(udf2);      // UDF 2 - Email ID
        pipe.setUdf3(udf3);      // UDF 3 - Contact Number. 
        pipe.setUdf4(udf4);      // UDF 4 - Billing Address
        pipe.setUdf5(udf5);      // UDF 5 - Merchant specific
        
        List<Attribute> attributes = new ArrayList<Attribute>();
        Attribute attribute1 = new Attribute("udf1",udf1);
        Attribute attribute2 = new Attribute("udf2",udf2);
        Attribute attribute3 = new Attribute("udf3",udf3);
        Attribute attribute4 = new Attribute("udf4",udf4);
        Attribute attribute5 = new Attribute("udf5",udf5);
        
        attributes.add(attribute1);
        attributes.add(attribute2);
        attributes.add(attribute3);
        attributes.add(attribute4);
        attributes.add(attribute5);
        
        return attributes;
    }
    
    private static void initializePayment(e24PaymentPipe pipe, long merchantPaymentId, double amounta, long gatewayId) throws ShoppingCartException, TException{
        String aliasName = null;
                try {
                        aliasName = ConfigClient.getClient().get("emi_payment_alias_name" + gatewayId);
                } catch (ConfigException e1) {
                        e1.printStackTrace();
                }
                String resourceDirPath = "/tmp/emi-resource/" + gatewayId + "/";
        String amount = (new Double(amounta)).toString();
        
        //Following is the code which initilize e24PaymentPipe with proper value
        pipe.setResourcePath(resourceDirPath); //mandatory 
        String as = pipe.getResourcePath();
        log.info("Resource= " +as);
        
        pipe.setAlias(aliasName);           //mandatory 
        String ab=pipe.getAlias();
        log.info("Alias= " +ab);
    
        pipe.setAction(ActionType.AUTH.value());            //mandatory 
        String ac=pipe.getAction();
        log.info("Action= " +ac);
    
        pipe.setResponseURL( responseURL ); //mandatory
        String at=pipe.getResponseURL();
        log.info("ResponseURL= "+at);
    
        //pipe.setErrorURL( errorURL + "?paymentId=" + merchantPaymentId );     //mandatory
        pipe.setErrorURL( errorURL);
        String ak=pipe.getErrorURL();
        log.info("ErrorURL= " + ak);
    
    
        pipe.setAmt(amount);        
        String ap=pipe.getAmt();
        log.info("Amt= " + ap);
    
        pipe.setCurrency(currencyCode);
        String a=pipe.getCurrency();
        log.info("Currency= " + a);
    
        pipe.setLanguage("USA");
        String p=pipe.getLanguage();
        log.info("Language= "+ p);
        
        pipe.setTrackId((new Long(merchantPaymentId)).toString());
    }
    
    private static String formatUdf(String udfString){
        udfString = udfString.replaceAll(regex, replacement);
        if(udfString.length() > MAX_UDF_LENGTH){
            udfString = udfString.substring(0, MAX_UDF_LENGTH);
        }
        return udfString;
    }
}