com.konakart.actions.gateways.Eway_auAction.java Source code

Java tutorial

Introduction

Here is the source code for com.konakart.actions.gateways.Eway_auAction.java

Source

//
// (c) 2006 DS Data Systems UK Ltd, All rights reserved.
//
// DS Data Systems and KonaKart and their respective logos, are 
// trademarks of DS Data Systems UK Ltd. All rights reserved.
//
// The information in this document is free software; you can redistribute 
// it and/or modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
// 
// This software is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//

package com.konakart.actions.gateways;

import java.io.ByteArrayInputStream;
import java.net.HttpURLConnection;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import com.konakart.al.KKAppEng;
import com.konakart.app.IpnHistory;
import com.konakart.app.KKException;
import com.konakart.app.NameValue;
import com.konakart.app.OrderUpdate;
import com.konakart.appif.IpnHistoryIf;
import com.konakart.appif.NameValueIf;
import com.konakart.appif.OrderIf;
import com.konakart.appif.OrderUpdateIf;
import com.konakart.appif.PaymentDetailsIf;
import com.konakart.bl.ConfigConstants;
import com.konakart.bl.modules.payment.eway_au.Eway_au;

/**
 * This class is an Action class for sending credit card details to eWay and receiving confirmation
 */
public class Eway_auAction extends BaseGatewayAction {
    /**
     * The <code>Log</code> instance for this application.
     */
    protected Log log = LogFactory.getLog(Eway_auAction.class);

    // Return codes and descriptions
    private static final int RET0 = 0;

    private static final String RET0_DESC = "Transaction OK";

    private static final int RET1 = -1;

    private static final String RET1_DESC = "There was an unexpected Gateway Response. Response = ";

    private static final String RET3_DESC = "There was an unexpected Gateway Response.";

    private static final int RET4 = -4;

    private static final String RET4_DESC = "There was an unexpected exception. Exception message = ";

    // Order history comments. These comments are associated with the order.
    private static final String ORDER_HISTORY_COMMENT_OK = "eWay payment successful. eWay TransactionId = ";

    private static final String ORDER_HISTORY_COMMENT_KO = "eWay payment not successful. eWay Reply = ";

    private static final long serialVersionUID = 1L;

    public String execute() {
        HttpServletRequest request = ServletActionContext.getRequest();
        HttpServletResponse response = ServletActionContext.getResponse();

        String message = null;
        String errorMessage = null;
        String gatewayResult = null;
        String transactionId = null;

        // Create these outside of try / catch since they are needed in the case of a general
        // exception
        IpnHistoryIf ipnHistory = new IpnHistory();
        ipnHistory.setModuleCode(Eway_au.EWAY_AU_GATEWAY_CODE);
        KKAppEng kkAppEng = null;

        try {
            int custId;

            kkAppEng = this.getKKAppEng(request, response);

            custId = this.loggedIn(request, response, kkAppEng, "Checkout");

            // Check to see whether the user is logged in
            if (custId < 0) {
                return KKLOGIN;
            }

            // Ensure we are using the correct protocol. Redirect if not.
            String redirForward = checkSSL(kkAppEng, request, custId, /* forceSSL */false);
            if (redirForward != null) {
                setupResponseForSSLRedirect(response, redirForward);
                return null;
            }

            // Get the order
            OrderIf order = kkAppEng.getOrderMgr().getCheckoutOrder();
            validateOrder(order, Eway_au.EWAY_AU_GATEWAY_CODE);

            // Set the order id for the ipnHistory object
            ipnHistory.setOrderId(order.getId());

            PaymentDetailsIf pd = order.getPaymentDetails();

            // Create a parameter list for the credit card details.
            List<NameValueIf> parmList = new ArrayList<NameValueIf>();

            parmList.add(new NameValue(Eway_au.EWAY_AU_CARD_NUMBER, URLEncoder.encode(pd.getCcNumber(), "UTF-8")));
            if (pd.isShowCVV()) {
                parmList.add(new NameValue(Eway_au.EWAY_AU_CARD_CVV2, URLEncoder.encode(pd.getCcCVV(), "UTF-8")));
            }

            parmList.add(new NameValue(Eway_au.EWAY_AU_CARD_EXPIRY_MONTH,
                    URLEncoder.encode(pd.getCcExpiryMonth(), "UTF-8")));
            parmList.add(new NameValue(Eway_au.EWAY_AU_CARD_EXPIRY_YEAR,
                    URLEncoder.encode(pd.getCcExpiryYear(), "UTF-8")));

            parmList.add(
                    new NameValue(Eway_au.EWAY_AU_CARDHOLDERS_NAME, URLEncoder.encode(pd.getCcOwner(), "UTF-8")));

            // Do the post
            String gatewayResp = null;
            try {
                gatewayResp = postData(pd, parmList);
            } catch (Exception e) {
                // Save the ipnHistory
                ipnHistory.setGatewayFullResponse(e.getMessage());
                ipnHistory.setKonakartResultDescription(getResultDescription(RET4_DESC + e.getMessage()));
                ipnHistory.setKonakartResultId(RET4);
                ipnHistory.setOrderId(order.getId());
                ipnHistory.setCustomerId(kkAppEng.getCustomerMgr().getCurrentCustomer().getId());
                kkAppEng.getEng().saveIpnHistory(kkAppEng.getSessionId(), ipnHistory);

                // Set the message and return
                String msg = kkAppEng.getMsg("checkout.cc.gateway.error", new String[] { RET3_DESC });
                addActionError(msg);

                // Redirect the user back to the credit card screen
                return "TryAgain";
            }

            gatewayResp = URLDecoder.decode(gatewayResp, "UTF-8");
            if (log.isDebugEnabled()) {
                log.debug("Unformatted GatewayResp = \n" + gatewayResp);
            }

            // Now process the XML response

            int txReturnAmount = 0;

            String txTrxnNumber = "";

            String txTrxnReference = "";

            String txTrxnOption1 = "";

            String txTrxnOption2 = "";

            String txTrxnOption3 = "";

            boolean txTrxnStatus = false;

            String txAuthCode = "";

            String txTrxnError = "";

            double txBeagleScore = -1;

            try {
                DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder builder = builderFactory.newDocumentBuilder();
                ByteArrayInputStream bais = new ByteArrayInputStream(gatewayResp.getBytes());
                Document doc = builder.parse(bais);

                // get the root node
                Node rootnode = doc.getDocumentElement();
                String root = rootnode.getNodeName();

                if (!root.equals("ewayResponse")) {
                    throw new Exception("Bad root element in eWay response: " + root);
                }

                // get all elements
                NodeList list = doc.getElementsByTagName("*");
                for (int i = 0; i < list.getLength(); i++) {
                    Node node = list.item(i);
                    String name = node.getNodeName();
                    if (name.equals("ewayResponse")) {
                        continue;
                    }
                    Text textnode = (Text) node.getFirstChild();
                    String value = "";
                    if (textnode != null) {
                        value = textnode.getNodeValue();
                    }

                    if (name.equals("ewayTrxnError")) {
                        txTrxnError = value;
                    } else if (name.equals("ewayTrxnStatus")) {
                        if (value.toLowerCase().trim().equals("true")) {
                            txTrxnStatus = true;
                        }
                    } else if (name.equals("ewayTrxnNumber")) {
                        txTrxnNumber = value;
                    } else if (name.equals("ewayTrxnOption1")) {
                        txTrxnOption1 = value;
                    } else if (name.equals("ewayTrxnOption2")) {
                        txTrxnOption2 = value;
                    } else if (name.equals("ewayTrxnOption3")) {
                        txTrxnOption3 = value;
                    } else if (name.equals("ewayReturnAmount")) {
                        if (!value.equals("")) {
                            txReturnAmount = Integer.parseInt(value);
                        }
                    } else if (name.equals("ewayAuthCode")) {
                        txAuthCode = value;
                    } else if (name.equals("ewayTrxnReference")) {
                        txTrxnReference = value;
                    } else if (name.equals("ewayBeagleScore")) {
                        if (!value.equals("")) {
                            txBeagleScore = Double.parseDouble(value);
                        }
                    } else {
                        if (log.isWarnEnabled()) {
                            log.warn("Unknown field in eWay response: " + name);
                        }
                    }
                }
            } catch (Exception e) {
                // Problems parsing the XML

                if (log.isWarnEnabled()) {
                    log.warn("Problems parsing eWay response: " + e.getMessage());
                    e.printStackTrace();
                }

                // Save the ipnHistory
                ipnHistory.setGatewayFullResponse(e.getMessage());
                ipnHistory.setKonakartResultDescription(getResultDescription(RET4_DESC + e.getMessage()));
                ipnHistory.setKonakartResultId(RET4);
                ipnHistory.setOrderId(order.getId());
                ipnHistory.setCustomerId(kkAppEng.getCustomerMgr().getCurrentCustomer().getId());
                kkAppEng.getEng().saveIpnHistory(kkAppEng.getSessionId(), ipnHistory);

                // Set the message and return
                String msg = kkAppEng.getMsg("checkout.cc.gateway.error", new String[] { RET3_DESC });
                addActionError(msg);

                // Redirect the user back to the credit card screen
                return "TryAgain";
            }

            gatewayResult = txTrxnStatus ? "Successful" : "Failed";
            ipnHistory.setGatewayResult(gatewayResult);

            transactionId = txTrxnNumber;
            ipnHistory.setGatewayTransactionId(transactionId);

            message = txAuthCode;
            errorMessage = txTrxnError;

            // Put the response in the ipnHistory record
            ipnHistory.setGatewayFullResponse(gatewayResp);

            if (log.isDebugEnabled()) {
                log.debug("eWay response data:\n\t" + " txReturnAmount = " + txReturnAmount + "\n\t txTrxnNumber = "
                        + txTrxnNumber + "\n\t txTrxnReference = " + txTrxnReference + "\n\t txTrxnOption1 = "
                        + txTrxnOption1 + "\n\t txTrxnOption2 = " + txTrxnOption2 + "\n\t txTrxnOption3 = "
                        + txTrxnOption3 + "\n\t txTrxnStatus = " + txTrxnStatus + "\n\t txAuthCode = " + txAuthCode
                        + "\n\t txTrxnError = " + txTrxnError + "\n\t txBeagleScore = " + txBeagleScore);
            }

            // See if we need to send an email, by looking at the configuration
            String sendEmailsConfig = kkAppEng.getConfig(ConfigConstants.SEND_EMAILS);
            boolean sendEmail = false;
            if (sendEmailsConfig != null && sendEmailsConfig.equalsIgnoreCase("true")) {
                sendEmail = true;
            }

            OrderUpdateIf updateOrder = new OrderUpdate();
            updateOrder.setUpdatedById(kkAppEng.getActiveCustId());

            // Determine whether the request was successful or not. If successful, we update the
            // inventory as well as changing the state of the order
            if (gatewayResult.equals("Successful")) {
                /*
                 * Payment approved
                 */
                String comment = ORDER_HISTORY_COMMENT_OK + transactionId;
                kkAppEng.getEng().updateOrder(kkAppEng.getSessionId(), order.getId(),
                        com.konakart.bl.OrderMgr.PAYMENT_RECEIVED_STATUS, /* customerNotified */
                        sendEmail, comment, updateOrder);

                // Update the inventory
                kkAppEng.getOrderMgr().updateInventory(order.getId());

                // Save the ipnHistory
                ipnHistory.setKonakartResultDescription(RET0_DESC);
                ipnHistory.setKonakartResultId(RET0);
                ipnHistory.setOrderId(order.getId());
                ipnHistory.setCustomerId(kkAppEng.getCustomerMgr().getCurrentCustomer().getId());
                kkAppEng.getEng().saveIpnHistory(kkAppEng.getSessionId(), ipnHistory);

                // If we received no exceptions, delete the basket
                kkAppEng.getBasketMgr().emptyBasket();

                if (sendEmail) {
                    sendOrderConfirmationMail(kkAppEng, order.getId(), /* success */true);
                }

                return "Approved";

            } else if (gatewayResult.equals("Failed")) {
                /*
                 * Payment declined
                 */
                String comment = ORDER_HISTORY_COMMENT_KO + errorMessage;
                kkAppEng.getEng().updateOrder(kkAppEng.getSessionId(), order.getId(),
                        com.konakart.bl.OrderMgr.PAYMENT_DECLINED_STATUS, /* customerNotified */
                        sendEmail, comment, updateOrder);

                // Save the ipnHistory
                ipnHistory.setKonakartResultDescription(RET0_DESC);
                ipnHistory.setKonakartResultId(RET0);
                ipnHistory.setCustomerId(kkAppEng.getCustomerMgr().getCurrentCustomer().getId());
                kkAppEng.getEng().saveIpnHistory(kkAppEng.getSessionId(), ipnHistory);

                if (sendEmail) {
                    sendOrderConfirmationMail(kkAppEng, order.getId(), /* success */false);
                }

                String msg = kkAppEng.getMsg("checkout.cc.gateway.error", new String[] { errorMessage });
                addActionError(msg);

                // Redirect the user back to the credit card screen
                return "TryAgain";
            } else {
                /*
                 * We only get to here if there was an error from the gateway
                 */
                String comment = RET1_DESC + message;
                kkAppEng.getEng().updateOrder(kkAppEng.getSessionId(), order.getId(),
                        com.konakart.bl.OrderMgr.PAYMENT_DECLINED_STATUS, /* customerNotified */
                        sendEmail, comment, updateOrder);

                // Save the ipnHistory
                ipnHistory.setKonakartResultDescription(getResultDescription(RET1_DESC + message));
                ipnHistory.setKonakartResultId(RET1);
                ipnHistory.setCustomerId(kkAppEng.getCustomerMgr().getCurrentCustomer().getId());
                kkAppEng.getEng().saveIpnHistory(kkAppEng.getSessionId(), ipnHistory);

                if (sendEmail) {
                    sendOrderConfirmationMail(kkAppEng, order.getId(), /* success */false);
                }

                String msg = kkAppEng.getMsg("checkout.cc.gateway.error",
                        new String[] { RET1_DESC + gatewayResult });
                addActionError(msg);

                // Redirect the user back to the credit card screen
                return "TryAgain";
            }
        } catch (Exception e) {
            try {
                ipnHistory.setKonakartResultDescription(getResultDescription(RET4_DESC + e.getMessage()));
                ipnHistory.setKonakartResultId(RET4);
                if (kkAppEng != null) {
                    kkAppEng.getEng().saveIpnHistory(kkAppEng.getSessionId(), ipnHistory);
                }
            } catch (KKException e1) {
                return super.handleException(request, e1);
            }
            return super.handleException(request, e);
        }
    }

    /**
     * Use this to truncate the result description so that it fits in the database column OK
     * 
     * @param desc
     *            the result description (which may be too long)
     * @return a truncated result description
     */
    private String getResultDescription(String desc) {
        if (desc == null) {
            return null;
        }

        if (desc.length() < 256) {
            return desc;
        }

        return desc.substring(0, 255);
    }

    /**
     * Create the request from the parameters
     * 
     * @param pd
     *            the PaymentDetails
     * @param ccParmList
     *            the credit card parameters
     */
    protected StringBuffer getGatewayRequest(PaymentDetailsIf pd, List<NameValueIf> ccParmList) {
        HashMap<String, String> hashedParams = hashParameters(pd, ccParmList);

        // Create the message from the parameters in the PaymentDetails object
        StringBuffer sb = new StringBuffer();
        sb.append("<ewaygateway>");
        sb.append("<ewayCustomerID>" + hashedParams.get(Eway_au.EWAY_AU_MERCHANT_ID) + "</ewayCustomerID>");
        sb.append("<ewayTotalAmount>" + hashedParams.get(Eway_au.EWAY_AU_PAYMENT_AMOUNT) + "</ewayTotalAmount>");
        sb.append("<ewayCustomerFirstName></ewayCustomerFirstName>");
        sb.append("<ewayCustomerLastName></ewayCustomerLastName>");
        sb.append("<ewayCustomerEmail>" + hashedParams.get(Eway_au.EWAY_AU_CUST_EMAIL) + "</ewayCustomerEmail>");
        sb.append("<ewayCustomerAddress></ewayCustomerAddress>");
        sb.append("<ewayCustomerPostcode></ewayCustomerPostcode>");
        sb.append("<ewayCustomerInvoiceDescription></ewayCustomerInvoiceDescription>");
        sb.append("<ewayCustomerInvoiceRef></ewayCustomerInvoiceRef>");
        sb.append("<ewayCardHoldersName>" + hashedParams.get(Eway_au.EWAY_AU_CARDHOLDERS_NAME)
                + "</ewayCardHoldersName>");
        sb.append("<ewayCardNumber>" + hashedParams.get(Eway_au.EWAY_AU_CARD_NUMBER) + "</ewayCardNumber>");
        sb.append("<ewayCardExpiryMonth>" + hashedParams.get(Eway_au.EWAY_AU_CARD_EXPIRY_MONTH)
                + "</ewayCardExpiryMonth>");
        sb.append("<ewayCardExpiryYear>" + hashedParams.get(Eway_au.EWAY_AU_CARD_EXPIRY_YEAR)
                + "</ewayCardExpiryYear>");
        sb.append("<ewayTrxnNumber></ewayTrxnNumber>");
        sb.append("<ewayOption1></ewayOption1>");
        sb.append("<ewayOption2></ewayOption2>");
        sb.append("<ewayOption3></ewayOption3>");
        sb.append("<ewayCVN>");
        if (pd.isShowCVV()) {
            sb.append(hashedParams.get(Eway_au.EWAY_AU_CARD_CVV2));
        }
        sb.append("</ewayCVN>");
        sb.append("</ewaygateway>");
        return sb;
    }

    /**
     * Add things specific to eWay to the connection
     */
    @Deprecated
    protected void customizeConnection(HttpURLConnection connection) {
        // connection.setInstanceFollowRedirects(false);
    }
}