/*******************************************************************************
 * 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.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 = delegator.findOne("PaymentGatewayPayflowPro", UtilMisc.toMap("paymentGatewayConfigId", paymentGatewayConfigId), false);
                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 = UtilProperties.getPropertyValue(resource, parameterName);
            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
 */
}
