You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by jo...@apache.org on 2006/08/13 11:05:09 UTC

svn commit: r431154 - in /incubator/ofbiz/trunk/applications/accounting: servicedef/ src/org/ofbiz/accounting/payment/ src/org/ofbiz/accounting/thirdparty/cybersource/ src/org/ofbiz/accounting/thirdparty/verisign/

Author: jonesde
Date: Sun Aug 13 02:05:07 2006
New Revision: 431154

URL: http://svn.apache.org/viewvc?rev=431154&view=rev
Log:
Some additions to help with CC decline or bad info recovery options like return flags for bad expire date, nsf, and bad card number to help enable automated response to these; added testing services for these different conditions; added initial implementation of the feature to try incrementing expire date years for the current card date plus 2, 3, then 4 years if option enabled in ProductStore.autoOrderCcTryExp and if the order is an auto-order, ie OrderHeader.autoOrderShoppingListId is not empty

Modified:
    incubator/ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml
    incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java
    incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/cybersource/IcsPaymentServices.java
    incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/verisign/PayflowPro.java

Modified: incubator/ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml
URL: http://svn.apache.org/viewvc/incubator/ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml?rev=431154&r1=431153&r2=431154&view=diff
==============================================================================
--- incubator/ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml (original)
+++ incubator/ofbiz/trunk/applications/accounting/servicedef/services_paymentmethod.xml Sun Aug 13 02:05:07 2006
@@ -342,6 +342,10 @@
         <attribute name="paymentConfig" type="String" mode="IN" optional="true"/>
         <attribute name="authResult" type="Boolean" mode="OUT" optional="true"/>
         <attribute name="captureResult" type="Boolean" mode="OUT" optional="true"/>
+        <attribute name="resultDeclined" type="Boolean" mode="OUT" optional="true"/>
+        <attribute name="resultNsf" type="Boolean" mode="OUT" optional="true"/>
+        <attribute name="resultBadExpire" type="Boolean" mode="OUT" optional="true"/>
+        <attribute name="resultBadCardNumber" type="Boolean" mode="OUT" optional="true"/>
         <attribute name="authCode" type="String" mode="OUT" optional="true"/>
         <attribute name="authAltRefNum" type="String" mode="OUT" optional="true"/>
         <attribute name="authRefNum" type="String" mode="OUT" optional="false"/>
@@ -464,6 +468,7 @@
         <description>Credit Card Processing</description>
         <implements service="ccAuthInterface"/>
     </service>
+
     <service name="alwaysApproveCCProcessor" engine="java"
              location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="alwaysApproveProcessor">
         <description>Credit Card Processing</description>
@@ -474,16 +479,38 @@
         <description>Credit Card Processing</description>
         <implements service="ccAuthInterface"/>
     </service>
+
     <service name="alwaysDeclineCCProcessor" engine="java"
             location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="alwaysDeclineProcessor">
         <description>Credit Card Processing</description>
         <implements service="ccAuthInterface"/>
     </service>
+    <service name="alwaysNsfCCProcessor" engine="java"
+        location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="alwaysNsfProcessor">
+        <description>Credit Card Processing</description>
+        <implements service="ccAuthInterface"/>
+    </service>
+    <service name="alwaysBadExpireCCProcessor" engine="java"
+        location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="alwaysBadExpireProcessor">
+        <description>Credit Card Processing</description>
+        <implements service="ccAuthInterface"/>
+    </service>
+    <service name="badExpireEvenCCProcessor" engine="java"
+        location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="badExpireEvenProcessor">
+        <description>Credit Card Processing</description>
+        <implements service="ccAuthInterface"/>
+    </service>
+    <service name="alwaysBadCardNumberCCProcessor" engine="java"
+        location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="alwaysBadCardNumberProcessor">
+        <description>Credit Card Processing</description>
+        <implements service="ccAuthInterface"/>
+    </service>
     <service name="alwaysFailCCProcessor" engine="java"
             location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="alwaysFailProcessor">
         <description>Credit Card Processing</description>
         <implements service="ccAuthInterface"/>
     </service>
+
     <service name="testCCCapture" engine="java"
             location="org.ofbiz.accounting.payment.PaymentGatewayServices" invoke="testCapture">
         <description>Credit Card Test Capture</description>

Modified: incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java
URL: http://svn.apache.org/viewvc/incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java?rev=431154&r1=431153&r2=431154&view=diff
==============================================================================
--- incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java (original)
+++ incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/payment/PaymentGatewayServices.java Sun Aug 13 02:05:07 2006
@@ -32,6 +32,7 @@
 import org.ofbiz.accounting.invoice.InvoiceWorker;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.GeneralException;
+import org.ofbiz.base.util.StringUtil;
 import org.ofbiz.base.util.UtilDateTime;
 import org.ofbiz.base.util.UtilMisc;
 import org.ofbiz.base.util.UtilNumber;
@@ -307,10 +308,6 @@
     }
 
 
-    private static Map authPayment(LocalDispatcher dispatcher, GenericValue userLogin, OrderReadHelper orh, GenericValue paymentPref, double totalRemaining, boolean reauth) throws GeneralException {
-        return authPayment(dispatcher, userLogin, orh, paymentPref, totalRemaining, reauth, null);
-    }
-
     private static Map authPayment(LocalDispatcher dispatcher, GenericValue userLogin, OrderReadHelper orh, GenericValue paymentPreference, double totalRemaining, boolean reauth, Double overrideAmount) throws GeneralException {
         String paymentConfig = null;
         String serviceName = null;
@@ -339,22 +336,24 @@
 
         // get the visit record to obtain the client's IP address
         GenericValue orderHeader = orh.getOrderHeader();
-        if (orderHeader != null) {
-            String visitId = orderHeader.getString("visitId");
-            GenericValue visit = null;
-            if (visitId != null) {
-                try {
-                    visit = orderHeader.getDelegator().findByPrimaryKey("Visit", UtilMisc.toMap("visitId", visitId));
-                } catch (GenericEntityException e) {
-                    Debug.logError(e, module);
-                }
-            }
+        //if (orderHeader == null) {}
 
-            if (visit != null && visit.get("clientIpAddress") != null) {
-                processContext.put("customerIpAddress", visit.getString("clientIpAddress"));
+        String visitId = orderHeader.getString("visitId");
+        GenericValue visit = null;
+        if (visitId != null) {
+            try {
+                visit = orderHeader.getDelegator().findByPrimaryKey("Visit", UtilMisc.toMap("visitId", visitId));
+            } catch (GenericEntityException e) {
+                Debug.logError(e, module);
             }
         }
 
+        if (visit != null && visit.get("clientIpAddress") != null) {
+            processContext.put("customerIpAddress", visit.getString("clientIpAddress"));
+        }
+
+        GenericValue productStore = orderHeader.getRelatedOne("ProductStore");
+
         processContext.put("userLogin", userLogin);
         processContext.put("orderId", orh.getOrderId());
         processContext.put("orderItems", orh.getOrderItems());
@@ -399,20 +398,65 @@
         if (Debug.verboseOn()) Debug.logVerbose("Charging amount: " + processAmount, module);
         processContext.put("processAmount", processAmount);
 
-        // invoke the processor.
+        // invoke the processor
         Map processorResult = null;
         try {
-            // invoke the payment processor; allow 5 minute transaction timeout and require a new tx; we'll capture the error and pass back nicely.
-            processorResult = dispatcher.runSync(serviceName, processContext, TX_TIME, true);
-        } catch (GenericServiceException gse) {
-            Debug.logError(gse, "Error occurred on: " + serviceName + " => " + processContext, module);
-            throw new GeneralException("Problems invoking payment processor! Will retry later. Order ID is: [" + orh.getOrderId() + "", gse);
+            // invoke the payment processor; allow 5 minute transaction timeout and require a new tx; we'll capture the error and pass back nicely
+            
+            GenericValue creditCard = (GenericValue) processContext.get("creditCard");
+            
+            // only try other exp dates if orderHeader.autoOrderShoppingListId is not empty, productStore.autoOrderCcTryExp=Y and this payment is a creditCard
+            boolean tryOtherExpDates = "Y".equals(productStore.getString("autoOrderCcTryExp")) && creditCard != null && UtilValidate.isNotEmpty(orderHeader.getString("autoOrderShoppingListId"));
+
+            // if we are not trying other expire dates OR if we are and the date is after today, then run the service
+            if (!tryOtherExpDates || UtilValidate.isDateAfterToday(creditCard.getString("expireDate"))) {
+                processorResult = dispatcher.runSync(serviceName, processContext, TX_TIME, true);
+            }
+            
+            // try other expire dates if the expireDate is not after today, or if we called the auth service and resultBadExpire = true 
+            if (tryOtherExpDates && (!UtilValidate.isDateAfterToday(creditCard.getString("expireDate")) || (processorResult != null && Boolean.TRUE.equals((Boolean) processorResult.get("resultBadExpire"))))) {
+                // try adding 2, 3, 4 years later with the same month
+                String expireDate = creditCard.getString("expireDate");
+                int dateSlash1 = expireDate.indexOf("/");
+                String month = expireDate.substring(0, dateSlash1);
+                String year = expireDate.substring(dateSlash1 + 1);
+                
+                // start adding 2 years, if comes back with resultBadExpire try again up to twice incrementing one year
+                year = StringUtil.addToNumberString(year, 2);
+                // note that this is set in memory only for now, not saved to the database unless successful
+                creditCard.set("expireDate", month + "/" + year);
+                // don't need to set back in the processContext, it's already there: processContext.put("creditCard", creditCard);
+                processorResult = dispatcher.runSync(serviceName, processContext, TX_TIME, true);
+
+                // note that these additional tries will only be done if the service return is not an error, in that case we let it pass through to the normal error handling
+                if (!ServiceUtil.isError(processorResult) && Boolean.TRUE.equals((Boolean) processorResult.get("resultBadExpire"))) {
+                    // okay, try one more year...
+                    year = StringUtil.addToNumberString(year, 1);
+                    creditCard.set("expireDate", month + "/" + year);
+                    processorResult = dispatcher.runSync(serviceName, processContext, TX_TIME, true);
+                }
+                
+                if (!ServiceUtil.isError(processorResult) && Boolean.TRUE.equals((Boolean) processorResult.get("resultBadExpire"))) {
+                    // okay, try one more year... and this is the last try
+                    year = StringUtil.addToNumberString(year, 1);
+                    creditCard.set("expireDate", month + "/" + year);
+                    processorResult = dispatcher.runSync(serviceName, processContext, TX_TIME, true);
+                }
+                
+                // at this point if we have a successful result, let's save the new creditCard expireDate
+                if (!ServiceUtil.isError(processorResult) && Boolean.TRUE.equals((Boolean) processorResult.get("authResult"))) {
+                    creditCard.store();
+                }
+            }
+        } catch (GenericServiceException e) {
+            Debug.logError(e, "Error occurred on: " + serviceName + " => " + processContext, module);
+            throw new GeneralException("Problems invoking payment processor! Will retry later. Order ID is: [" + orh.getOrderId() + "", e);
         }
 
         if (processorResult != null) {
             // check for errors from the processor implementation
             if (ServiceUtil.isError(processorResult)) {
-                Debug.logError("Processor failed; will retry later : " + processorResult.get(ModelService.ERROR_MESSAGE), module);
+                Debug.logError("Processor failed; will retry later: " + processorResult.get(ModelService.ERROR_MESSAGE), module);
                 // log the error message as a gateway response when it fails
                 saveError(dispatcher, userLogin, paymentPreference, processorResult, "PRDS_PAY_AUTH", "PGT_AUTHORIZE");
                 // this is the one place where we want to return null because the calling method will look for this
@@ -1018,7 +1062,7 @@
                         delegator.create(newPref);
 
                         // authorize the new preference
-                        processorResult = authPayment(dispatcher, userLogin, orh, newPref, newAmount, false);
+                        processorResult = authPayment(dispatcher, userLogin, orh, newPref, newAmount, false, null);
                         if (processorResult != null) {
                             // process the auth results
                             boolean authResult = processResult(dctx, processorResult, userLogin, newPref);
@@ -1129,7 +1173,7 @@
         if (!PaymentGatewayServices.checkAuthValidity(paymentPref, paymentConfig)) {
             try {
                 // re-auth required before capture
-                Map processorResult = PaymentGatewayServices.authPayment(dispatcher, userLogin, orh, paymentPref, amount, true);
+                Map processorResult = PaymentGatewayServices.authPayment(dispatcher, userLogin, orh, paymentPref, amount, true, null);
 
                 boolean authResult = false;
                 if (processorResult != null) {
@@ -1456,7 +1500,7 @@
             Debug.log("reauth with amount: " + amount, module);
             if (orh != null) {
                 // first lets re-auth the card
-                Map authPayRes = authPayment(dispatcher, userLogin, orh, paymentPreference, amount.doubleValue(), true);
+                Map authPayRes = authPayment(dispatcher, userLogin, orh, paymentPreference, amount.doubleValue(), true, null);
                 Debug.log("authPayRes: " + authPayRes, module);
                 if (authPayRes != null) {
                     Boolean authResp = (Boolean) authPayRes.get("authResult");
@@ -2268,7 +2312,7 @@
     }
 
     /**
-     * Always decline processor.
+     * Always decline processor
      */
     public static Map alwaysDeclineProcessor(DispatchContext dctx, Map context) {
         Map result = ServiceUtil.returnSuccess();
@@ -2281,6 +2325,79 @@
         result.put("authRefNum", new Long(nowTime).toString());
         result.put("authAltRefNum", new Long(nowTime).toString());
         result.put("authFlag", "D");
+        result.put("authMessage", "This is a test processor; no payments were captured or authorized");
+        return result;
+    }
+
+    /**
+     * Always NSF (not sufficient funds) processor
+     */
+    public static Map alwaysNsfProcessor(DispatchContext dctx, Map context) {
+        Map result = ServiceUtil.returnSuccess();
+        Double processAmount = (Double) context.get("processAmount");
+        long nowTime = new Date().getTime();
+        Debug.logInfo("Test Processor NSF Credit Card", module);
+
+        result.put("authResult", Boolean.FALSE);
+        result.put("resultNsf", Boolean.TRUE);
+        result.put("processAmount", processAmount);
+        result.put("authRefNum", new Long(nowTime).toString());
+        result.put("authAltRefNum", new Long(nowTime).toString());
+        result.put("authFlag", "N");
+        result.put("authMessage", "This is a test processor; no payments were captured or authorized");
+        return result;
+    }
+
+    /**
+     * Always fail/bad expire date processor
+     */
+    public static Map alwaysBadExpireProcessor(DispatchContext dctx, Map context) {
+        Map result = ServiceUtil.returnSuccess();
+        Double processAmount = (Double) context.get("processAmount");
+        long nowTime = new Date().getTime();
+        Debug.logInfo("Test Processor Bad Expire Date Credit Card", module);
+
+        result.put("authResult", Boolean.FALSE);
+        result.put("resultBadExpire", Boolean.TRUE);
+        result.put("processAmount", processAmount);
+        result.put("authRefNum", new Long(nowTime).toString());
+        result.put("authAltRefNum", new Long(nowTime).toString());
+        result.put("authFlag", "E");
+        result.put("authMessage", "This is a test processor; no payments were captured or authorized");
+        return result;
+    }
+
+    /**
+     * Fail/bad expire date when year is even processor
+     */
+    public static Map badExpireEvenProcessor(DispatchContext dctx, Map context) {
+        GenericValue creditCard = (GenericValue) context.get("creditCard");
+        String expireDate = creditCard.getString("expireDate");
+        String lastNumberStr = expireDate.substring(expireDate.length() - 1);
+        int lastNumber = Integer.parseInt(lastNumberStr);
+        
+        if ((float) lastNumber / 2.0 == 0.0) {
+            return alwaysBadExpireProcessor(dctx, context);
+        } else {
+            return alwaysApproveProcessor(dctx, context);
+        }
+    }
+
+    /**
+     * Always bad card number processor
+     */
+    public static Map alwaysBadCardNumberProcessor(DispatchContext dctx, Map context) {
+        Map result = ServiceUtil.returnSuccess();
+        Double processAmount = (Double) context.get("processAmount");
+        long nowTime = new Date().getTime();
+        Debug.logInfo("Test Processor Bad Card Number Credit Card", module);
+
+        result.put("authResult", Boolean.FALSE);
+        result.put("resultBadCardNumber", Boolean.TRUE);
+        result.put("processAmount", processAmount);
+        result.put("authRefNum", new Long(nowTime).toString());
+        result.put("authAltRefNum", new Long(nowTime).toString());
+        result.put("authFlag", "N");
         result.put("authMessage", "This is a test processor; no payments were captured or authorized");
         return result;
     }

Modified: incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/cybersource/IcsPaymentServices.java
URL: http://svn.apache.org/viewvc/incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/cybersource/IcsPaymentServices.java?rev=431154&r1=431153&r2=431154&view=diff
==============================================================================
--- incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/cybersource/IcsPaymentServices.java (original)
+++ incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/cybersource/IcsPaymentServices.java Sun Aug 13 02:05:07 2006
@@ -549,10 +549,11 @@
         String decision = getDecision(reply);
         if ("ACCEPT".equalsIgnoreCase(decision)) {
             result.put("authCode", reply.get("ccAuthReply_authorizationCode"));
-            result.put("authResult", new Boolean(true));
+            result.put("authResult", Boolean.TRUE);
         } else {
             result.put("authCode", decision);
-            result.put("authResult", new Boolean(false));
+            result.put("authResult", Boolean.FALSE);
+            // TODO: based on reasonCode populate the following flags as applicable: resultDeclined, resultNsf, resultBadExpire, resultBadCardNumber
         }
 
         if (reply.get("ccAuthReply_amount") != null) {
@@ -574,9 +575,9 @@
     private static void processCaptureResult(Map reply, Map result) {
         String decision = getDecision(reply);
         if ("ACCEPT".equalsIgnoreCase(decision)) {
-            result.put("captureResult", new Boolean(true));
+            result.put("captureResult", Boolean.TRUE);
         } else {
-            result.put("captureResult", new Boolean(false));
+            result.put("captureResult", Boolean.FALSE);
         }
 
         if (reply.get("ccCaptureReply_amount") != null) {
@@ -594,9 +595,9 @@
     private static void processReleaseResult(Map reply, Map result) {
         String decision = getDecision(reply);
         if ("ACCEPT".equalsIgnoreCase(decision)) {
-            result.put("releaseResult", new Boolean(true));
+            result.put("releaseResult", Boolean.TRUE);
         } else {
-            result.put("releaseResult", new Boolean(false));
+            result.put("releaseResult", Boolean.FALSE);
         }
 
         if (reply.get("ccAuthReversalReply_amount") != null) {
@@ -614,9 +615,9 @@
     private static void processRefundResult(Map reply, Map result) {
         String decision = getDecision(reply);
         if ("ACCEPT".equalsIgnoreCase(decision)) {
-            result.put("refundResult", new Boolean(true));
+            result.put("refundResult", Boolean.TRUE);
         } else {
-            result.put("refundResult", new Boolean(false));
+            result.put("refundResult", Boolean.FALSE);
         }
 
         if (reply.get("ccCreditReply_amount") != null) {
@@ -634,9 +635,9 @@
     private static void processCreditResult(Map reply, Map result) {
         String decision = (String) reply.get("decision");
         if ("ACCEPT".equalsIgnoreCase(decision)) {
-            result.put("creditResult", new Boolean(true));
+            result.put("creditResult", Boolean.TRUE);
         } else {
-            result.put("creditResult", new Boolean(false));
+            result.put("creditResult", Boolean.FALSE);
         }
 
         if (reply.get("ccCreditReply_amount") != null) {

Modified: incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/verisign/PayflowPro.java
URL: http://svn.apache.org/viewvc/incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/verisign/PayflowPro.java?rev=431154&r1=431153&r2=431154&view=diff
==============================================================================
--- incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/verisign/PayflowPro.java (original)
+++ incubator/ofbiz/trunk/applications/accounting/src/org/ofbiz/accounting/thirdparty/verisign/PayflowPro.java Sun Aug 13 02:05:07 2006
@@ -35,10 +35,6 @@
 
 /**
  * PayflowPro - Verisign PayFlow Pro <=> OFBiz Service Module
- *
- * @author     <a href="mailto:jaz@ofbiz.org">Andy Zeneski</a>
- * @version    $Rev$
- * @since      2.0
  */
 public class PayflowPro {
 
@@ -371,12 +367,23 @@
         }
 
         String respCode = (String) parameters.get("RESULT");
-        if (respCode.equals("0") && avsCheckOkay && cvv2CheckOkay) {
+        if ("0".equals(respCode) && avsCheckOkay && cvv2CheckOkay) {
             result.put("authResult", Boolean.TRUE);
             result.put("authCode", parameters.get("AUTHCODE"));
         } else {
             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);
@@ -532,5 +539,218 @@
         pn.CreateContext(hostAddress, hostPort.intValue(), timeout.intValue(), proxyAddress, proxyPort.intValue(), proxyLogon, proxyPassword);
         return pn;
     }
-}
 
+/*
+ * 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 test-payflow.verisign.com to payflow.verisign.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Õs 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Õs 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Õs Guide for Payflow Pro With Fraud Protection 
+Services or UserÕs 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 
+ */
+}