/*******************************************************************************
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *******************************************************************************/
package org.ofbiz.accounting.thirdparty.verisign;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import javolution.util.FastMap;

import org.apache.commons.lang.StringUtils;
import org.ofbiz.accounting.payment.PaymentGatewayServices;
import org.ofbiz.base.util.Debug;
import org.ofbiz.base.util.StringUtil;
import org.ofbiz.base.util.UtilDateTime;
import org.ofbiz.base.util.UtilMisc;
import org.ofbiz.base.util.UtilProperties;
import org.ofbiz.base.util.UtilValidate;
import org.ofbiz.base.util.string.FlexibleStringExpander;
import org.ofbiz.entity.Delegator;
import org.ofbiz.entity.GenericEntityException;
import org.ofbiz.entity.GenericValue;
import org.ofbiz.entity.util.EntityUtilProperties;
import org.ofbiz.order.order.OrderReadHelper;
import org.ofbiz.order.shoppingcart.ShoppingCart;
import org.ofbiz.order.shoppingcart.ShoppingCartItem;
import org.ofbiz.product.store.ProductStoreWorker;
import org.ofbiz.service.DispatchContext;
import org.ofbiz.service.GenericServiceException;
import org.ofbiz.service.LocalDispatcher;
import org.ofbiz.service.ServiceUtil;

import paypal.payflow.PayflowAPI;
import paypal.payflow.SDKProperties;
/**
 * PayflowPro - Verisign PayFlow Pro <=> OFBiz Service Module
 */
public class PayflowPro {

    public static final String module = PayflowPro.class.getName();
    public final static String resource = "AccountingUiLabels";

    /**
     * Authorize credit card payment service. Service wrapper around PayFlow Pro API.
     * @param dctx Service Engine DispatchContext.
     * @param context Map context of parameters.
     * @return Response map, including RESPMSG, and RESULT keys.
     */
    public static Map<String, Object> ccProcessor(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        GenericValue paymentPref = (GenericValue) context.get("orderPaymentPreference");
        GenericValue authTrans = (GenericValue) context.get("authTrans");
        String orderId = (String) context.get("orderId");
        String cvv2 = (String) context.get("cardSecurityCode");
        BigDecimal processAmount = (BigDecimal) context.get("processAmount");
        GenericValue party = (GenericValue) context.get("billToParty");
        GenericValue cc = (GenericValue) context.get("creditCard");
        GenericValue payPalPaymentMethod = (GenericValue) context.get("payPalPaymentMethod");
        GenericValue ps = (GenericValue) context.get("billingAddress");
        String paymentGatewayConfigId = (String) context.get("paymentGatewayConfigId");
        String configString = (String) context.get("paymentConfig");

        if (configString == null) {
            configString = "payment.properties";
        }

        boolean isPayPal = false;
        // Are we doing a cc or a paypal payment?
        if ("EXT_PAYPAL".equals(paymentPref.getString("paymentMethodTypeId"))) {
            isPayPal = true;
        }

        Map<String, String> data = FastMap.newInstance();

        boolean isReAuth = false;
        if (isPayPal) {
            data.put("TRXTYPE", "A");
            data.put("TENDER", "P");
            data.put("ORIGID", payPalPaymentMethod.getString("transactionId"));
        } else {
            if (authTrans == null) {
                authTrans = PaymentGatewayServices.getAuthTransaction(paymentPref);
            }

            // set the orderId as comment1 so we can query in PF Manager
            data.put("COMMENT1", orderId);
            data.put("PONUM", orderId);
            data.put("CUSTCODE", party.getString("partyId"));

            // transaction type
            if (comparePaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "preAuth", configString, "payment.verisign.preAuth",  "Y")) {
                data.put("TRXTYPE", "A");
                // only support re-auth for auth types; sale types don't do it
                if (authTrans != null) {
                    String refNum = authTrans.getString("referenceNum");
                    data.put("ORIGID", refNum);
                    isReAuth = true;
                }
            } else {
                data.put("TRXTYPE", "S");
            }

            // credit card tender
            data.put("TENDER", "C");

            // card security code
            if (UtilValidate.isNotEmpty(cvv2)) {
                data.put("CVV2", cvv2);
            }

            // get the payment information
            data.put("ACCT", cc.getString("cardNumber"));

            // name on card
            String name = cc.getString("firstNameOnCard") + " " + cc.getString("lastNameOnCard");
            data.put("FIRSTNAME", cc.getString("firstNameOnCard"));
            data.put("LASTNAME", cc.getString("lastNameOnCard"));
            data.put("COMMENT2", name);
            if (cc.get("expireDate") != null) {
                String exp = cc.getString("expireDate");
                String expDate = exp.substring(0, 2);

                expDate = expDate + exp.substring(exp.length() - 2);
                data.put("EXPDATE", expDate);
            }

            // gather the address info
            if (ps != null) {
                String street = ps.getString("address1") + ((UtilValidate.isNotEmpty(ps.getString("address2"))) ? " " + ps.getString("address2") : "");
                data.put("STREET"+"["+street.length()+"]", street);
                data.put("ZIP", ps.getString("postalCode"));
            }
        }

        // set the amount
        data.put("AMT", processAmount.toString());

        PayflowAPI pfp = init(delegator, paymentGatewayConfigId, configString, context);

        // get the base params
        StringBuilder params = makeBaseParams(delegator, paymentGatewayConfigId, configString);

        // parse the context parameters
        params.append("&").append(parseContext(data));

        // transmit the request
        //if (Debug.verboseOn()) Debug.logVerbose("Sending to Verisign: " + params.toString(), module);
        String resp;
        if (!comparePaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "enableTransmit", configString, "payment.verisign.enable_transmit",  "false")) {
            resp = pfp.submitTransaction(params.toString(), pfp.generateRequestId());
        } else {
            resp = "RESULT=0&AUTHCODE=T&PNREF=" + (new Date()).getTime() + "&RESPMSG=Testing";
        }

        if (Debug.verboseOn()) {
            Debug.logVerbose("Response from Verisign: " + resp, module);
        }
        if (isPayPal) {
            // Attach the avs info returned in doExpressCheckout and stored in PayPalPaymentMethod
            resp += "&AVSADDR=" + payPalPaymentMethod.getString("avsAddr") + "&AVSZIP=" + payPalPaymentMethod.getString("avsZip");
        }

        // check the response
        Map<String, Object> result = ServiceUtil.returnSuccess();
        parseAuthResponse(delegator, paymentGatewayConfigId, resp, result, configString, isReAuth, isPayPal);
        result.put("processAmount", processAmount);
        return result;
    }

    public static Map<String, Object> ccCapture(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        GenericValue paymentPref = (GenericValue) context.get("orderPaymentPreference");
        GenericValue authTrans = (GenericValue) context.get("authTrans");
        BigDecimal amount = (BigDecimal) context.get("captureAmount");
        String paymentGatewayConfigId = (String) context.get("paymentGatewayConfigId");
        String configString = (String) context.get("paymentConfig");
        Locale locale = (Locale) context.get("locale");
        if (configString == null) {
            configString = "payment.properties";
        }

        boolean isPayPal = false;
        // Are we doing a cc or a paypal payment?
        if ("EXT_PAYPAL".equals(paymentPref.getString("paymentMethodTypeId"))) {
            isPayPal = true;
        }

        if (authTrans == null) {
            authTrans = PaymentGatewayServices.getAuthTransaction(paymentPref);
        }

        if (authTrans == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
                    "AccountingPaymentTransactionAuthorizationNotFoundCannotCapture", locale));
        }

        // auth ref number
        String refNum = authTrans.getString("referenceNum");
        Map<String, String> data = UtilMisc.toMap("ORIGID", refNum);

        // tx type (Delayed Capture)
        data.put("TRXTYPE", "D");

        if (isPayPal) {
            // paypal tender
            data.put("TENDER", "P");
            data.put("CAPTURECOMPLETE", "N");
        } else {
            // credit card tender
            data.put("TENDER", "C");

            // get the orderID
            String orderId = paymentPref.getString("orderId");
            data.put("COMMENT1", orderId);
        }


        // amount to capture
        data.put("AMT", amount.toString());

        PayflowAPI pfp = init(delegator, paymentGatewayConfigId, configString, context);

        // get the base params
        StringBuilder params = makeBaseParams(delegator, paymentGatewayConfigId, configString);

        // parse the context parameters
        params.append("&").append(parseContext(data));

        // transmit the request
        if (Debug.verboseOn()) Debug.logVerbose("Sending to Verisign: " + params.toString(), module);
        String resp;
        if (!comparePaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "enableTransmit", configString, "payment.verisign.enable_transmit",  "false")) {
            resp = pfp.submitTransaction(params.toString(), pfp.generateRequestId());
        } else {
            resp = "RESULT=0&AUTHCODE=T&PNREF=" + (new Date()).getTime() + "&RESPMSG=Testing";
        }

        if (Debug.verboseOn()) Debug.logVerbose("Response from Verisign: " + resp, module);

        // check the response
        Map<String, Object> result = ServiceUtil.returnSuccess();
        parseCaptureResponse(resp, result);
        result.put("captureAmount", amount);
        return result;
    }

    public static Map<String, Object> ccVoid(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        GenericValue paymentPref = (GenericValue) context.get("orderPaymentPreference");
        GenericValue authTrans = (GenericValue) context.get("authTrans");
        BigDecimal amount = (BigDecimal) context.get("releaseAmount");
        String paymentGatewayConfigId = (String) context.get("paymentGatewayConfigId");
        String configString = (String) context.get("paymentConfig");
        Locale locale = (Locale) context.get("locale");
        if (configString == null) {
            configString = "payment.properties";
        }

        if (authTrans == null) {
            authTrans = PaymentGatewayServices.getAuthTransaction(paymentPref);
        }

        if (authTrans == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
                    "AccountingPaymentTransactionAuthorizationNotFoundCannotRelease", locale));
        }

        boolean isPayPal = false;
        // Are we doing a cc or a paypal payment?
        if ("EXT_PAYPAL".equals(paymentPref.getString("paymentMethodTypeId"))) {
            isPayPal = true;
        }

        // auth ref number
        String refNum = authTrans.getString("referenceNum");
        Map<String, String> data = UtilMisc.toMap("ORIGID", refNum);

        // tx type (Void)
        data.put("TRXTYPE", "V");

        // get the orderID
        String orderId = paymentPref.getString("orderId");

        if (isPayPal) {
            data.put("TENDER", "P");

            data.put("NOTE", orderId);
        } else {
            // credit card tender
            data.put("TENDER", "C");

            data.put("COMMENT1", orderId);

            // amount to void
            data.put("AMT", amount.toString());
        }


        PayflowAPI pfp = init(delegator, paymentGatewayConfigId, configString, context);

        // get the base params
        StringBuilder params = makeBaseParams(delegator, paymentGatewayConfigId, configString);

        // parse the context parameters
        params.append("&").append(parseContext(data));

        // transmit the request
        if (Debug.verboseOn()) Debug.logVerbose("Sending to Verisign: " + params.toString(), module);
        String resp;
        if (!comparePaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "enableTransmit", configString, "payment.verisign.enable_transmit",  "false")) {
            resp = pfp.submitTransaction(params.toString(), pfp.generateRequestId());
        } else {
            resp = "RESULT=0&AUTHCODE=T&PNREF=" + (new Date()).getTime() + "&RESPMSG=Testing";
        }

        if (Debug.verboseOn()) Debug.logVerbose("Response from Verisign: " + resp, module);

        // check the response
        Map<String, Object> result = ServiceUtil.returnSuccess();
        parseVoidResponse(resp, result);
        result.put("releaseAmount", amount);
        return result;
    }

    public static Map<String, Object> ccRefund(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        GenericValue paymentPref = (GenericValue) context.get("orderPaymentPreference");
        BigDecimal amount = (BigDecimal) context.get("refundAmount");
        String paymentGatewayConfigId = (String) context.get("paymentGatewayConfigId");
        String configString = (String) context.get("paymentConfig");
        Locale locale = (Locale) context.get("locale");
        if (configString == null) {
            configString = "payment.properties";
        }

        GenericValue captureTrans = PaymentGatewayServices.getCaptureTransaction(paymentPref);

        if (captureTrans == null) {
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
                    "AccountingPaymentTransactionAuthorizationNotFoundCannotRefund", locale));
        }

        boolean isPayPal = false;
        // Are we doing a cc or a paypal payment?
        if ("EXT_PAYPAL".equals(paymentPref.getString("paymentMethodTypeId"))) {
            isPayPal = true;
        }

        // auth ref number
        String refNum = captureTrans.getString("referenceNum");
        Map<String, String> data = UtilMisc.toMap("ORIGID", refNum);

        // tx type (Credit)
        data.put("TRXTYPE", "C");

        // get the orderID
        String orderId = paymentPref.getString("orderId");

        if (isPayPal) {
            data.put("TENDER", "P");

            data.put("MEMO", orderId);
            // PayPal won't allow us to refund more than the capture amount
            BigDecimal captureAmount = captureTrans.getBigDecimal("amount");
            amount = amount.min(captureAmount);
        } else {
            // credit card tender
            data.put("TENDER", "C");

            data.put("COMMENT1", orderId);
        }

        // amount to capture
        data.put("AMT", amount.toString());

        PayflowAPI pfp = init(delegator, paymentGatewayConfigId, configString, context);

        // get the base params
        StringBuilder params = makeBaseParams(delegator, paymentGatewayConfigId, configString);

        // parse the context parameters
        params.append("&").append(parseContext(data));

        // transmit the request
        if (Debug.verboseOn()) Debug.logVerbose("Sending to Verisign: " + params.toString(), module);
        String resp;
        if (!comparePaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "enableTransmit", configString, "payment.verisign.enable_transmit",  "false")) {
            resp = pfp.submitTransaction(params.toString(), pfp.generateRequestId());
        } else {
            resp = "RESULT=0&AUTHCODE=T&PNREF=" + (new Date()).getTime() + "&RESPMSG=Testing";
        }

        if (Debug.verboseOn()) Debug.logVerbose("Response from Verisign: " + resp, module);

        // check the response
        Map<String, Object> result = ServiceUtil.returnSuccess();
        parseRefundResponse(resp, result);
        result.put("refundAmount", amount);
        return result;
    }


    public static Map<String, Object> setExpressCheckout(DispatchContext dctx, Map<String, ? extends Object> context) {
        Delegator delegator = dctx.getDelegator();
        ShoppingCart cart = (ShoppingCart) context.get("cart");
        Locale locale = cart.getLocale();
        GenericValue payPalPaymentSetting = ProductStoreWorker.getProductStorePaymentSetting(delegator, cart.getProductStoreId(), "EXT_PAYPAL", null, true);
        String paymentGatewayConfigId = payPalPaymentSetting.getString("paymentGatewayConfigId");
        String configString = "payment.properties";

        if (cart == null || cart.items().size() <= 0) {
            return ServiceUtil.returnError(UtilProperties.getMessage("AccountingErrorUiLabels", 
                    "AccountingPayPalShoppingCartIsEmpty", locale));
        }

        Map<String, String> data = FastMap.newInstance();

        data.put("TRXTYPE", "O");
        data.put("TENDER", "P");
        data.put("ACTION", "S");
        String token = (String) cart.getAttribute("payPalCheckoutToken");
        if (UtilValidate.isNotEmpty(token)) {
            data.put("TOKEN", token);
        }
        data.put("RETURNURL", getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "returnUrl", configString, "payment.verisign.returnUrl"));
        data.put("CANCELURL", getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "cancelReturnUrl", configString, "payment.verisign.cancelReturnUrl"));

        try {
            addCartDetails(data, cart);
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(UtilProperties.getMessage(resource, 
                    "AccountingPayflowErrorRetreivingCartDetails", locale));
        }

        PayflowAPI pfp = init(delegator, paymentGatewayConfigId, null, context);

        // get the base params
        StringBuilder params = makeBaseParams(delegator, paymentGatewayConfigId, null);

        // parse the context parameters
        params.append("&").append(parseContext(data));

        // transmit the request
        if (Debug.verboseOn()) Debug.logVerbose("Sending to Verisign: " + params.toString(), module);
        String resp;
        if (!comparePaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "enableTransmit", configString, "payment.verisign.enable_transmit",  "false")) {
            resp = pfp.submitTransaction(params.toString(), pfp.generateRequestId());
        } else {
            resp = "RESULT=0&TOKEN=" + (new Date()).getTime() + "&RESPMSG=Testing";
        }

        if (Debug.verboseOn()) Debug.logVerbose("Response from Verisign: " + resp, module);

        Map<String, String> responseMap = parseResponse(resp);
        String result = responseMap.get("RESULT");
        if (!"0".equals(result)) {
            String respMsg = responseMap.get("RESPMSG");
            Debug.logError("A problem occurred while requesting an express checkout token from paypal: Result = " + result + ", Message = " + respMsg, module);
            return ServiceUtil.returnError(UtilProperties.getMessage("AccountingErrorUiLabels", 
                    "AccountingPayPalCommunicationError", locale));
        }
        token = responseMap.get("TOKEN");
        cart.setAttribute("payPalCheckoutToken", token);
        return ServiceUtil.returnSuccess();
    }

    private static void addCartDetails(Map<String, String> parameterMap, ShoppingCart cart) throws GenericEntityException {
        parameterMap.put("CURRENCY", cart.getCurrency());
        int line = 0;
        for (ShoppingCartItem item : cart.items()) {
            //paramMap.put("L_NUMBER" + line, item.getProductId());
            parameterMap.put("L_NAME" + line, item.getName());
            parameterMap.put("L_DESC" + line, item.getDescription());
            parameterMap.put("L_AMT" + line, item.getBasePrice().setScale(2).toPlainString());
            parameterMap.put("L_QTY" + line, item.getQuantity().toBigInteger().toString());
            line++;
            BigDecimal otherAdjustments = item.getOtherAdjustments();
            if (otherAdjustments.compareTo(BigDecimal.ZERO) != 0) {
                parameterMap.put("L_NAME" + line, item.getName() + " Adjustments");
                parameterMap.put("L_DESC" + line, "Adjustments for item: " + item.getName());
                parameterMap.put("L_AMT" + line, otherAdjustments.setScale(2).toPlainString());
                parameterMap.put("L_QTY" + line, "1");
                line++;
            }
        }
        BigDecimal otherAdjustments = cart.getOrderOtherAdjustmentTotal();
        if (otherAdjustments.compareTo(BigDecimal.ZERO) != 0) {
            parameterMap.put("L_NAME" + line, "Order Adjustments");
            parameterMap.put("L_AMT" + line, otherAdjustments.setScale(2).toPlainString());
            parameterMap.put("L_QTY" + line, "1");
            line++;
        }
        parameterMap.put("ITEMAMT", cart.getSubTotal().add(otherAdjustments).setScale(2).toPlainString());
        parameterMap.put("TAXAMT", cart.getTotalSalesTax().setScale(2).toPlainString());
        parameterMap.put("FREIGHTAMT", cart.getTotalShipping().setScale(2).toPlainString());
        parameterMap.put("AMT", cart.getGrandTotal().setScale(2).toPlainString());

        if (!cart.shippingApplies()) {
            parameterMap.put("NOSHIPPING", "1");
        } else {
            GenericValue shippingAddress = cart.getShippingAddress();
            parameterMap.put("ADDROVERRIDE", "1");
            parameterMap.put("SHIPTOSTREET", StringUtils.left(shippingAddress.getString("address1"), 30));
            parameterMap.put("SHIPTOSTREET2", StringUtils.left(shippingAddress.getString("address2"), 30));
            parameterMap.put("SHIPTOCITY", StringUtils.left(shippingAddress.getString("city"), 40));
            if (shippingAddress.getString("stateProvinceGeoId") != null && !"_NA_".equals(shippingAddress.getString("stateProvinceGeoId"))) {
                GenericValue stateProvinceGeo = shippingAddress.getRelatedOne("StateProvinceGeo", false);
                parameterMap.put("SHIPTOSTATE", StringUtils.left(stateProvinceGeo.getString("geoCode"), 40));
            }
            parameterMap.put("SHIPTOZIP", StringUtils.left(shippingAddress.getString("postalCode"), 16));
            GenericValue countryGeo = shippingAddress.getRelatedOne("CountryGeo", false);
            parameterMap.put("SHIPTOCOUNTRY", StringUtils.left(countryGeo.getString("geoCode"), 2));
        }
    }

    public static Map<String, Object> getExpressCheckout(DispatchContext dctx, Map<String, Object> context) {
        LocalDispatcher dispatcher = dctx.getDispatcher();
        Delegator delegator = dctx.getDelegator();
        ShoppingCart cart = (ShoppingCart) context.get("cart");
        Locale locale = cart.getLocale();
        GenericValue payPalPaymentSetting = ProductStoreWorker.getProductStorePaymentSetting(delegator, cart.getProductStoreId(), "EXT_PAYPAL", null, true);
        String paymentGatewayConfigId = payPalPaymentSetting.getString("paymentGatewayConfigId");
        String configString = "payment.properties";

        Map<String, String> data = FastMap.newInstance();
        data.put("TRXTYPE", "O");
        data.put("TENDER", "P");
        data.put("ACTION", "G");
        String token = (String) cart.getAttribute("payPalCheckoutToken");
        if (UtilValidate.isNotEmpty(token)) {
            data.put("TOKEN", token);
        }

        PayflowAPI pfp = init(delegator, paymentGatewayConfigId, null, context);

        // get the base params
        StringBuilder params = makeBaseParams(delegator, paymentGatewayConfigId, null);

        // parse the context parameters
        params.append("&").append(parseContext(data));

        // transmit the request
        if (Debug.verboseOn()) Debug.logVerbose("Sending to Verisign: " + params.toString(), module);
        String resp;
        if (!comparePaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "enableTransmit", configString, "payment.verisign.enable_transmit",  "false")) {
            resp = pfp.submitTransaction(params.toString(), pfp.generateRequestId());
        } else {
            resp = "RESULT=0&PAYERID=" + (new Date()).getTime() + "&RESPMSG=Testing";
        }

        Map<String, String> responseMap = parseResponse(resp);
        if (!"0".equals(responseMap.get("RESULT"))) {
            Debug.logError("A problem occurred while requesting the checkout details from paypal: Result = " + responseMap.get("RESULT") + ", Message = " + responseMap.get("RESPMSG"), module);
            return ServiceUtil.returnError(UtilProperties.getMessage("AccountingErrorUiLabels", 
                    "AccountingPayPalCommunicationError", locale));
        }

        Map<String, Object> inMap = FastMap.newInstance();
        inMap.put("userLogin", cart.getUserLogin());
        inMap.put("partyId", cart.getOrderPartyId());
        inMap.put("contactMechId", cart.getShippingContactMechId());
        inMap.put("fromDate", UtilDateTime.nowTimestamp());
        inMap.put("payerId", responseMap.get("PAYERID"));
        inMap.put("expressCheckoutToken", token);
        inMap.put("payerStatus", responseMap.get("PAYERSTATUS"));
        inMap.put("avsAddr", responseMap.get("AVSADDR"));
        inMap.put("avsZip", responseMap.get("AVSZIP"));
        inMap.put("correlationId", responseMap.get("CORRELATIONID"));
        Map<String, Object> outMap = null;
        try {
            outMap = dispatcher.runSync("createPayPalPaymentMethod", inMap);
        } catch (GenericServiceException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
        String paymentMethodId = (String) outMap.get("paymentMethodId");

        cart.clearPayments();
        cart.addPaymentAmount(paymentMethodId, cart.getGrandTotal(), true);

        return ServiceUtil.returnSuccess();

    }

    public static Map<String, Object> doExpressCheckout(DispatchContext dctx, Map<String, Object> context) {
        LocalDispatcher dispatcher = dctx.getDispatcher();
        Delegator delegator = dctx.getDelegator();
        GenericValue userLogin = (GenericValue) context.get("userLogin");
        GenericValue paymentPref = (GenericValue) context.get("orderPaymentPreference");
        OrderReadHelper orh = new OrderReadHelper(delegator, paymentPref.getString("orderId"));
        GenericValue payPalPaymentSetting = ProductStoreWorker.getProductStorePaymentSetting(delegator, orh.getProductStoreId(), "EXT_PAYPAL", null, true);
        String paymentGatewayConfigId = payPalPaymentSetting.getString("paymentGatewayConfigId");
        String configString = "payment.properties";
        GenericValue payPalPaymentMethod = null;
        try {
            payPalPaymentMethod = paymentPref.getRelatedOne("PaymentMethod", false);
            payPalPaymentMethod = payPalPaymentMethod.getRelatedOne("PayPalPaymentMethod", false);
        } catch (GenericEntityException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
        BigDecimal processAmount = paymentPref.getBigDecimal("maxAmount");

        Map<String, String> data = FastMap.newInstance();
        data.put("TRXTYPE", "O");
        data.put("TENDER", "P");
        data.put("PAYERID", payPalPaymentMethod.getString("payerId"));
        data.put("TOKEN", payPalPaymentMethod.getString("expressCheckoutToken"));
        data.put("ACTION", "D");
        // set the amount
        data.put("AMT", processAmount.setScale(2).toPlainString());

        PayflowAPI pfp = init(delegator, paymentGatewayConfigId, null, context);

        // get the base params
        StringBuilder params = makeBaseParams(delegator, paymentGatewayConfigId, null);

        // parse the context parameters
        params.append("&").append(parseContext(data));

        // transmit the request
        if (Debug.verboseOn()) Debug.logVerbose("Sending to Verisign: " + params.toString(), module);
        String resp;
        if (!comparePaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "enableTransmit", configString, "payment.verisign.enable_transmit",  "false")) {
            resp = pfp.submitTransaction(params.toString(), pfp.generateRequestId());
        } else {
            resp = "RESULT=0&PAYERID=" + (new Date()).getTime() + "&RESPMSG=Testing";
        }

        Map<String, String> responseMap = parseResponse(resp);

        Map<String, Object> inMap = FastMap.newInstance();
        inMap.put("userLogin", userLogin);
        inMap.put("paymentMethodId", payPalPaymentMethod.get("paymentMethodId"));
        inMap.put("transactionId", responseMap.get("PNREF"));
        Map<String, Object> outMap = null;
        try {
            outMap = dispatcher.runSync("updatePayPalPaymentMethod", inMap);
        } catch (GenericServiceException e) {
            Debug.logError(e, module);
            return ServiceUtil.returnError(e.getMessage());
        }
        if (ServiceUtil.isError(outMap)) {
            Debug.logError(ServiceUtil.getErrorMessage(outMap), module);
            return outMap;
        }
        return ServiceUtil.returnSuccess();
    }

    private static Map<String, String> parseResponse(String resp) {
        Debug.logInfo("Verisign response string: " + resp, module);
        Map<String, String> parameters = FastMap.newInstance();
        List<String> params = StringUtil.split(resp, "&");
        for (String str : params) {
            if (str.length() > 0) {
                List<String> kv = StringUtil.split(str, "=");
                String k = kv.get(0);
                String v = kv.get(1);

                if (k != null && v != null)
                    parameters.put(k, v);
            }
        }
        return parameters;
    }
    private static void parseAuthResponse(Delegator delegator, String paymentGatewayConfigId, String resp, Map<String, Object> result, String resource, boolean isReAuth, boolean isPayPal) {
        Map<String, String> parameters = parseResponse(resp);

        // txType
        boolean isSale = !comparePaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "preAuth", resource, "payment.verisign.preAuth", "Y");

        // avs checking - ignore on re-auth
        boolean avsCheckOkay = true;
        String avsCode = null;
        if (!isReAuth) {
            boolean checkAvs = comparePaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "checkAvs", resource, "payment.verisign.checkAvs", "Y");
            if (checkAvs && !isSale) {
                String addAvs = (String) parameters.get("AVSADDR");
                String zipAvs = (String) parameters.get("AVSZIP");
                avsCode = addAvs + zipAvs;
                if (addAvs == null || "N".equals(addAvs) || zipAvs == null || "N".equals(zipAvs)) {
                    avsCheckOkay = false;
                }
            }
        }

        // cvv2 checking - ignore on re-auth or paypal
        boolean cvv2CheckOkay = true;
        String cvvCode = null;
        if (!isReAuth && !isPayPal) {
            boolean checkCvv2 = comparePaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "checkCvv2", resource, "payment.verisign.checkCvv2", "Y");
            if (checkCvv2 && !isSale) {
                cvvCode = (String) parameters.get("CVV2MATCH");
                if (cvvCode == null || "N".equals(cvvCode)) {
                    cvv2CheckOkay = false;
                }
            }
        }

        String respCode = (String) parameters.get("RESULT");
        int codeInt = -999; // custom response code -- not from payflow docs
        try {
            codeInt = Integer.parseInt(respCode);
        } catch (NumberFormatException e) {
            Debug.logError(e, "Unable to parse response code; not a number!", module);
        }


        result.put("authRefNum", parameters.get("PNREF"));

        if (codeInt == 0 && avsCheckOkay && cvv2CheckOkay) {
            result.put("authResult", Boolean.TRUE);
            result.put("authCode", parameters.get("AUTHCODE"));
        } else if (codeInt < 0) {
            // communications error
            Debug.logWarning("In PayflowPro failing authorization; respCode/RESULT=" + respCode + ", avsCheckOkay=" + avsCheckOkay + ", cvv2CheckOkay=" + cvv2CheckOkay + "; AUTHCODE=" + parameters.get("AUTHCODE"), module);
            result.put("authResult", Boolean.FALSE);
            result.put("authRefNum", respCode);
        } else if (codeInt == 0) {
            Debug.logWarning("In PayflowPro approved, but invalid flags; respCode/RESULT=" + respCode + ", avsCheckOkay=" + avsCheckOkay + ", cvv2CheckOkay=" + cvv2CheckOkay + "; AUTHCODE=" + parameters.get("AUTHCODE"), module);
            result.put("authResult", Boolean.TRUE);
            result.put("authCode", parameters.get("AUTHCODE"));
        } else {
            // other error
            Debug.logWarning("In PayflowPro failing authorization; respCode/RESULT=" + respCode + ", avsCheckOkay=" + avsCheckOkay + ", cvv2CheckOkay=" + cvv2CheckOkay + "; AUTHCODE=" + parameters.get("AUTHCODE"), module);
            result.put("authResult", Boolean.FALSE);

            // now check certain special conditions and report back through the generic params
            if ("12".equals(respCode)) {
                result.put("resultDeclined", Boolean.TRUE);
            } else if ("50".equals(respCode)) {
                result.put("resultNsf", Boolean.TRUE);
            } else if ("23".equals(respCode)) {
                result.put("resultBadCardNumber", Boolean.TRUE);
            } else if ("24".equals(respCode)) {
                result.put("resultBadExpire", Boolean.TRUE);
            }
        }
        result.put("cvCode", cvvCode);
        result.put("avsCode", avsCode);
        result.put("authFlag", parameters.get("RESULT"));
        result.put("authMessage", parameters.get("RESPMSG"));
    }

    private static void parseCaptureResponse(String resp, Map<String, Object> result) {
        Map<String, String> parameters = parseResponse(resp);

        String respCode = (String) parameters.get("RESULT");
        int codeInt = -999; // custom response code -- not from payflow docs
        try {
            codeInt = Integer.parseInt(respCode);
        } catch (NumberFormatException e) {
            Debug.logError(e, "Unable to parse response code; not a number!", module);
        }

        if (codeInt == 0) {
            result.put("captureResult", Boolean.TRUE);
            result.put("captureCode", parameters.get("AUTHCODE"));
        } else if (codeInt < 0) {
            // communications error
            Debug.logWarning("In PayflowPro failing capture; respCode/RESULT=" + respCode + "; PNREF=" + parameters.get("PNREF") + "; AUTHCODE=" + parameters.get("AUTHCODE"), module);
            result.put("captureResult", Boolean.FALSE);
            result.put("captureRefNum", respCode);
        } else {
            Debug.logWarning("In PayflowPro failing capture; respCode/RESULT=" + respCode + "; PNREF=" + parameters.get("PNREF") + "; AUTHCODE=" + parameters.get("AUTHCODE"), module);
            result.put("captureResult", Boolean.FALSE);
        }
        result.put("captureRefNum", parameters.get("PNREF"));
        result.put("captureFlag", parameters.get("RESULT"));
        result.put("captureMessage", parameters.get("RESPMSG"));
    }

    private static void parseVoidResponse(String resp, Map<String, Object> result) {
        Map<String, String> parameters = parseResponse(resp);

        String respCode = (String) parameters.get("RESULT");
        int codeInt = -999; // custom response code -- not from payflow docs
        try {
            codeInt = Integer.parseInt(respCode);
        } catch (NumberFormatException e) {
            Debug.logError(e, "Unable to parse response code; not a number!", module);
        }

        if (codeInt == 0) {
            result.put("releaseResult", Boolean.TRUE);
            result.put("releaseCode", parameters.get("AUTHCODE"));
        } else if (codeInt < 0) {
            // communications error
            Debug.logWarning("In PayflowPro failing void; respCode/RESULT=" + respCode + "; PNREF=" + parameters.get("PNREF") + "; AUTHCODE=" + parameters.get("AUTHCODE"), module);
            result.put("releaseResult", Boolean.FALSE);
            result.put("releaseRefNum", respCode);
        } else {
            Debug.logWarning("In PayflowPro failing void; respCode/RESULT=" + respCode + "; PNREF=" + parameters.get("PNREF") + "; AUTHCODE=" + parameters.get("AUTHCODE"), module);
            result.put("releaseResult", Boolean.FALSE);
        }
        result.put("releaseRefNum", parameters.get("PNREF"));
        result.put("releaseFlag", parameters.get("RESULT"));
        result.put("releaseMessage", parameters.get("RESPMSG"));
    }

    private static void parseRefundResponse(String resp, Map<String, Object> result) {
        Map<String, String> parameters = parseResponse(resp);

        String respCode = (String) parameters.get("RESULT");
        int codeInt = -999; // custom response code -- not from payflow docs
        try {
            codeInt = Integer.parseInt(respCode);
        } catch (NumberFormatException e) {
            Debug.logError(e, "Unable to parse response code; not a number!", module);
        }

        if (codeInt == 0) {
            result.put("refundResult", Boolean.TRUE);
            result.put("refundCode", parameters.get("AUTHCODE"));
        } else if (codeInt < 0) {
            // communications error
            Debug.logWarning("In PayflowPro failing refund; respCode/RESULT=" + respCode + "; PNREF=" + parameters.get("PNREF") + "; AUTHCODE=" + parameters.get("AUTHCODE"), module);
            result.put("refundResult", Boolean.FALSE);
            result.put("refundRefNum", respCode);
        } else {
            Debug.logWarning("In PayflowPro failing refund; respCode/RESULT=" + respCode + "; PNREF=" + parameters.get("PNREF") + "; AUTHCODE=" + parameters.get("AUTHCODE"), module);
            result.put("refundResult", Boolean.FALSE);
        }
        result.put("refundRefNum", parameters.get("PNREF"));
        result.put("refundFlag", parameters.get("RESULT"));
        result.put("refundMessage", parameters.get("RESPMSG"));
    }

    private static String parseContext(Map<String, ? extends Object> context) {
        StringBuilder buf = new StringBuilder();
        Set<String> keySet = context.keySet();
        Iterator<String> i = keySet.iterator();

        while (i.hasNext()) {
            String name = (String) i.next();
            Object valueObj = context.get(name);

            if (valueObj == null || (valueObj instanceof String) && ((String) valueObj).length() == 0) {
                // not valid; do nothing
            } else {
                String value = valueObj.toString();

                // Payflow expects an unencoded name/value pair string
                buf.append(name).append("=");
                buf.append(value);
                if (i.hasNext())
                    buf.append("&");
            }
        }
        return buf.toString();
    }

    private static StringBuilder makeBaseParams(Delegator delegator, String paymentGatewayConfigId, String resource) {
        StringBuilder buf = new StringBuilder();

        try {
            buf.append("PARTNER=");
            buf.append(getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "partner", resource, "payment.verisign.partner", "VeriSign"));
            buf.append("&");
            buf.append("VENDOR=");
            buf.append(getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "vendor", resource, "payment.verisign.vendor", "nobody"));
            buf.append("&");
            buf.append("USER=");
            buf.append(getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "userId", resource, "payment.verisign.user", "nobody"));
            buf.append("&");
            buf.append("PWD=");
            buf.append(getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "pwd", resource, "payment.verisign.pwd", "password"));
        } catch (Exception e) {
            Debug.logError(e, module);
            return null;
        }
        return buf;
    }

    private static PayflowAPI init(Delegator delegator, String paymentGatewayConfigId, String resource, Map<String, ? extends Object> context) {
        // No more used
        // String certsPath = FlexibleStringExpander.expandString(getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "certsPath", resource, "payment.verisign.certsPath", "pfcerts"), context);
        String hostAddress = getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "hostAddress", resource, "payment.verisign.hostAddress", "pilot-payflowpro.paypal.com");
        Integer hostPort = Integer.decode(getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "hostPort", resource, "payment.verisign.hostPort", "443"));
        Integer timeout = Integer.decode(getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "timeout", resource, "payment.verisign.timeout", "80"));
        String proxyAddress = getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "proxyAddress", resource, "payment.verisign.proxyAddress", "");
        Integer proxyPort = Integer.decode(getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "proxyPort", resource, "payment.verisign.proxyPort", "80"));
        String proxyLogon = getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "proxyLogon", resource, "payment.verisign.proxyLogon", "");
        String proxyPassword = getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "proxyPassword", resource, "payment.verisign.proxyPassword", "");
        String logFileName = FlexibleStringExpander.expandString(getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "logFileName", resource, "payment.verisign.logFileName", ""), context);
        Integer loggingLevel = Integer.decode(getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "loggingLevel", resource, "payment.verisign.loggingLevel", "6"));
        Integer maxLogFileSize = Integer.decode(getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "maxLogFileSize", resource, "payment.verisign.maxLogFileSize", "1000000"));
        boolean stackTraceOn = "Y".equalsIgnoreCase(getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, "stackTraceOn", resource, "payment.verisign.stackTraceOn", "N"));

        PayflowAPI pfp = new PayflowAPI(hostAddress, hostPort.intValue(), timeout.intValue(), proxyAddress,
                proxyPort.intValue(), proxyLogon, proxyPassword);
        SDKProperties.setLogFileName(logFileName);
        SDKProperties.setLoggingLevel(loggingLevel);
        SDKProperties.setMaxLogFileSize(maxLogFileSize);
        SDKProperties.setStackTraceOn(stackTraceOn);
        return pfp;
    }

    private static String getPaymentGatewayConfigValue(Delegator delegator, String paymentGatewayConfigId, String paymentGatewayConfigParameterName,
                                                       String resource, String parameterName) {
        String returnValue = "";
        if (UtilValidate.isNotEmpty(paymentGatewayConfigId)) {
            try {
                GenericValue payflowPro = EntityQuery.use(delegator).from("PaymentGatewayPayflowPro").where("paymentGatewayConfigId", paymentGatewayConfigId).queryOne();
                if (UtilValidate.isNotEmpty(payflowPro)) {
                    Object payflowProField = payflowPro.get(paymentGatewayConfigParameterName);
                    if (payflowProField != null) {
                        returnValue = payflowProField.toString().trim();
                    }
                }
            } catch (GenericEntityException e) {
                Debug.logError(e, module);
            }
        } else {
            String value = EntityUtilProperties.getPropertyValue(resource, parameterName, delegator);
            if (value != null) {
                returnValue = value.trim();
            }
        }
        return returnValue;
    }

    private static String getPaymentGatewayConfigValue(Delegator delegator, String paymentGatewayConfigId, String paymentGatewayConfigParameterName,
                                                       String resource, String parameterName, String defaultValue) {
        String returnValue = getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, paymentGatewayConfigParameterName, resource, parameterName);
        if (UtilValidate.isEmpty(returnValue)) {
            returnValue = defaultValue;
        }
        return returnValue;
    }

    private static boolean comparePaymentGatewayConfigValue(Delegator delegator, String paymentGatewayConfigId, String paymentGatewayConfigParameterName,
                                                        String resource, String parameterName, String compareValue) {
        boolean returnValue = false;

        String value = getPaymentGatewayConfigValue(delegator, paymentGatewayConfigId, paymentGatewayConfigParameterName, resource, parameterName, compareValue);
        if (UtilValidate.isNotEmpty(value)) {
            returnValue = value.trim().equalsIgnoreCase(compareValue);
        }
        return returnValue;
    }

/*
 * RESULT values (and RESPMSG text)
 *
0 Approved
1 User authentication failed. Error is caused by one or more of the following:
Login information is incorrect. Verify that USER, VENDOR, PARTNER, and
PASSWORD have been entered correctly. See Table 3.2 on page 26 for additional
information and field descriptions.
Invalid Processor information entered. Contact merchant bank to verify.
"Allowed IP Address" security feature implemented. The transaction is coming
from an unknown IP address. See VeriSign Manager online help for details on how
to use Manager to update the allowed IP addresses.
You are using a test (not active) account to submit a transaction to the live VeriSign
servers. Change the URL from pilot-payflowpro.paypal.com to payflowpro.paypal.com.
2 Invalid tender type. Your merchant bank account does not support the following
credit card type that was submitted.
3 Invalid transaction type. Transaction type is not appropriate for this transaction. For
example, you cannot credit an authorization-only transaction.
4 Invalid amount format. Use the format: #####.##  Do not include currency
symbols or commas.
5 Invalid merchant information. Processor does not recognize your merchant account
information. Contact your bank account acquirer to resolve this problem.
6 Invalid or unsupported currency code
7 Field format error. Invalid information entered. See RESPMSG.
8 Not a transaction server
9 Too many parameters or invalid stream
10 Too many line items
11 Client time-out waiting for response
12 Declined. Check the credit card number, expiration date, and transaction information to
make sure they were entered correctly. If this does not resolve the problem, have the
customer call their card issuing bank to resolve.
13 Referral. Transaction cannot be approved electronically but can be approved with a
verbal authorization. Contact your merchant bank to obtain an authorization and submit
a manual Voice Authorization transaction.
14 Invalid Client Certification ID. Check the HTTP header. If the tag, X-VPS-VIT-
CLIENT-CERTIFICATION-ID, is missing, RESULT code 14 is returned.
19 Original transaction ID not found. The transaction ID you entered for this
transaction is not valid. See RESPMSG.
20 Cannot find the customer reference number
22 Invalid ABA number

23 Invalid account number. Check credit card number and re-submit.
24 Invalid expiration date. Check and re-submit.
25 Invalid Host Mapping. You are trying to process a tender type such as Discover Card,
but you are not set up with your merchant bank to accept this card type.
26 Invalid vendor account
27 Insufficient partner permissions
28 Insufficient user permissions
29 Invalid XML document. This could be caused by an unrecognized XML tag or a bad
XML format that cannot be parsed by the system.
30 Duplicate transaction
31 Error in adding the recurring profile
32 Error in modifying the recurring profile
33 Error in canceling the recurring profile
34 Error in forcing the recurring profile
35 Error in reactivating the recurring profile
36 OLTP Transaction failed
37 Invalid recurring profile ID
50 Insufficient funds available in account
99 General error. See RESPMSG.
100 Transaction type not supported by host
101 Time-out value too small
102 Processor not available
103 Error reading response from host
104 Timeout waiting for processor response. Try your transaction again.
105 Credit error. Make sure you have not already credited this transaction, or that this
transaction ID is for a creditable transaction. (For example, you cannot credit an
authorization.)
106 Host not available
107 Duplicate suppression time-out

108 Void error. See RESPMSG. Make sure the transaction ID entered has not already been
voided. If not, then look at the Transaction Detail screen for this transaction to see if it
has settled. (The Batch field is set to a number greater than zero if the transaction has
been settled). If the transaction has already settled, your only recourse is a reversal
(credit a payment or submit a payment for a credit).
109 Time-out waiting for host response
111 Capture error. Either an attempt to capture a transaction that is not an authorization
transaction type, or an attempt to capture an authorization transaction that has already
been captured.
112 Failed AVS check. Address and ZIP code do not match. An authorization may still
exist on the cardholder account.
113 Merchant sale total will exceed the sales cap with current transaction. ACH
transactions only.
114 Card Security Code (CSC) Mismatch. An authorization may still exist on the
cardholder account.
115 System busy, try again later
116 VPS Internal error. Failed to lock terminal number
117 Failed merchant rule check. One or more of the following three failures occurred:
An attempt was made to submit a transaction that failed to meet the security settings
specified on the Payflow Pro Java SDK Security Settings page. If the transaction
exceeded the Maximum Amount security setting, then no values are returned for AVS
or CSC.
AVS validation failed. The AVS return value should appear in the RESPMSG.
CSC validation failed. The CSC return value should appear in the RESPMSG.
118 Invalid keywords found in string fields
122 Merchant sale total will exceed the credit cap with current transaction. ACH
transactions only.
125 Fraud Protection Services Filter _ Declined by filters

126 Fraud Protection Services Filter _ Flagged for review by filters
Important Note: Result code 126 indicates that a transaction triggered a fraud filter.
This is not an error, but a notice that the transaction is in a review status. The
transaction has been authorized but requires you to review and to manually accept the
transaction before it will be allowed to settle.
Result code 126 is intended to give you an idea of the kind of transaction that is
considered suspicious to enable you to evaluate whether you can benefit from using the
Fraud Protection Services.
To eliminate result 126, turn the filters off.
For more information, see the User Guide for Payflow Pro With Fraud Protection
Services or User Guide for Payflow Link Guide With Fraud Protection Services.
127 Fraud Protection Services Filter _ Not processed by filters
128 Fraud Protection Services Filter _ Declined by merchant after being flagged for
review by filters
131 Version 1 Payflow Pro SDK client no longer supported. Upgrade to the most recent
version of the Payflow Pro client.
150 Issuing bank timed out
151 Issuing bank unavailable
1000 Generic host error. This is a generic message returned by your credit card processor.
The RESPMSG will contain more information describing the error.
1001 Buyer Authentication Service unavailable
1002 Buyer Authentication Service _ Transaction timeout
1003 Buyer Authentication Service _ Invalid client version
1004 Buyer Authentication Service _ Invalid timeout value
1011 Buyer Authentication Service unavailable
1012 Buyer Authentication Service unavailable
1013 Buyer Authentication Service unavailable
1014 Buyer Authentication Service _ Merchant is not enrolled for Buyer
Authentication Service (3-D Secure).
1016 Buyer Authentication Service _ 3-D Secure error response received. Instead of
receiving a PARes response to a Validate Authentication transaction, an error response
was received.
1017 Buyer Authentication Service _ 3-D Secure error response is invalid. An error
response is received and the response is not well formed for a Validate Authentication
transaction.

1021 Buyer Authentication Service _ Invalid card type
1022 Buyer Authentication Service _ Invalid or missing currency code
1023 Buyer Authentication Service _ merchant status for 3D secure is invalid
1041 Buyer Authentication Service _ Validate Authentication failed: missing or
invalid PARES
1042 Buyer Authentication Service _ Validate Authentication failed: PARES format is
invalid
1043 Buyer Authentication Service _ Validate Authentication failed: Cannot find
successful Verify Enrollment
1044 Buyer Authentication Service _ Validate Authentication failed: Signature
validation failed for PARES
1045 Buyer Authentication Service _ Validate Authentication failed: Mismatched or
invalid amount in PARES
1046 Buyer Authentication Service _ Validate Authentication failed: Mismatched or
invalid acquirer in PARES
1047 Buyer Authentication Service _ Validate Authentication failed: Mismatched or
invalid Merchant ID in PARES
1048 Buyer Authentication Service _ Validate Authentication failed: Mismatched or
invalid card number in PARES
1049 Buyer Authentication Service _ Validate Authentication failed: Mismatched or
invalid currency code in PARES
1050 Buyer Authentication Service _ Validate Authentication failed: Mismatched or
invalid XID in PARES
1051 Buyer Authentication Service _ Validate Authentication failed: Mismatched or
invalid order date in PARES
1052 Buyer Authentication Service _ Validate Authentication failed: This PARES was
already validated for a previous Validate Authentication transaction

 */

/* RESULT for communication errors (less than 0)
 *
-1 Failed to connect to host
-2 Failed to resolve hostname
-5 Failed to initialize SSL context
-6 Parameter list format error: & in name
-7 Parameter list format error: invalid [ ] name length clause
-8 SSL failed to connect to host
-9 SSL read failed
-10 SSL write failed
-11 Proxy authorization failed
-12 Timeout waiting for response
-13 Select failure
-14 Too many connections
-15 Failed to set socket options
-20 Proxy read failed
-21 Proxy write failed
-22 Failed to initialize SSL certificate
-23 Host address not specified
-24 Invalid transaction type
-25 Failed to create a socket
-26 Failed to initialize socket layer
-27 Parameter list format error: invalid [ ] name length clause
-28 Parameter list format error: name
-29 Failed to initialize SSL connection
-30 Invalid timeout value

-31 The certificate chain did not validate, no local certificate found
-32 The certificate chain did not validate, common name did not match URL
- 40 Unexpected Request ID found in request.
- 41 Required Request ID not found in request
- 42 Required Response ID not found in request
- 43 Unexpected Response ID found in request
- 44 Response ID not found in the response received from the server
-99 Out of memory
-100 Parameter list cannot be empty
-103 Context initialization failed
-104 Unexpected transaction state
-105 Invalid name value pair request
-106 Invalid response format
-107 This XMLPay version is not supported
-108 The server certificate chain did not validate
-109 Unable to do logging
-111 The following error occurred while initializing from message file: <Details of
the error message>
-113 Unable to round and truncate the currency value simultaneously
 */
}
