001: /*******************************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: *******************************************************************************/package org.ofbiz.accounting.thirdparty.verisign;
019:
020: import java.util.Iterator;
021: import java.util.List;
022: import java.util.Map;
023: import java.util.Set;
024:
025: import com.Verisign.payment.PFProAPI;
026:
027: import org.apache.commons.collections.map.LinkedMap;
028: import org.ofbiz.accounting.payment.PaymentGatewayServices;
029: import org.ofbiz.base.util.Debug;
030: import org.ofbiz.base.util.StringUtil;
031: import org.ofbiz.base.util.UtilMisc;
032: import org.ofbiz.base.util.UtilProperties;
033: import org.ofbiz.base.util.UtilValidate;
034: import org.ofbiz.entity.GenericValue;
035: import org.ofbiz.service.DispatchContext;
036: import org.ofbiz.service.ServiceUtil;
037:
038: /**
039: * PayflowPro - Verisign PayFlow Pro <=> OFBiz Service Module
040: */
041: public class PayflowPro {
042:
043: public static final String module = PayflowPro.class.getName();
044:
045: /**
046: * Authorize credit card payment service. Service wrapper around PayFlow Pro API.
047: * @param dctx Service Engine DispatchContext.
048: * @param context Map context of parameters.
049: * @return Response map, including RESPMSG, and RESULT keys.
050: */
051: public static Map ccProcessor(DispatchContext dctx, Map context) {
052: GenericValue paymentPref = (GenericValue) context
053: .get("orderPaymentPreference");
054: GenericValue authTrans = (GenericValue) context
055: .get("authTrans");
056: String orderId = (String) context.get("orderId");
057: String cvv2 = (String) context.get("cardSecurityCode");
058: Double processAmount = (Double) context.get("processAmount");
059: GenericValue party = (GenericValue) context.get("billToParty");
060: GenericValue cc = (GenericValue) context.get("creditCard");
061: GenericValue ps = (GenericValue) context.get("billingAddress");
062: String configString = (String) context.get("paymentConfig");
063: if (configString == null) {
064: configString = "payment.properties";
065: }
066:
067: if (authTrans == null) {
068: authTrans = PaymentGatewayServices
069: .getAuthTransaction(paymentPref);
070: }
071:
072: // set the orderId as comment1 so we can query in PF Manager
073: boolean isReAuth = false;
074: Map data = UtilMisc.toMap("COMMENT1", orderId);
075: data.put("PONUM", orderId);
076: data.put("CUSTCODE", party.getString("partyId"));
077:
078: // transaction type
079: if (UtilProperties.propertyValueEqualsIgnoreCase(configString,
080: "payment.verisign.preAuth", "Y")) {
081: data.put("TRXTYPE", "A");
082: // only support re-auth for auth types; sale types don't do it
083: if (authTrans != null) {
084: String refNum = authTrans.getString("referenceNum");
085: data.put("ORIGID", refNum);
086: isReAuth = true;
087: }
088: } else {
089: data.put("TRXTYPE", "S");
090: }
091:
092: // credit card tender
093: data.put("TENDER", "C");
094:
095: // card security code
096: if (UtilValidate.isNotEmpty(cvv2)) {
097: data.put("CVV2", cvv2);
098: }
099:
100: // set the amount
101: data.put("AMT", processAmount.toString());
102:
103: // get the payment information
104: data.put("ACCT", cc.getString("cardNumber"));
105:
106: // name on card
107: String name = cc.getString("firstNameOnCard") + " "
108: + cc.getString("lastNameOnCard");
109: data.put("FIRSTNAME", cc.getString("firstNameOnCard"));
110: data.put("LASTNAME", cc.getString("lastNameOnCard"));
111: data.put("COMMENT2", name);
112: if (cc.get("expireDate") != null) {
113: String exp = cc.getString("expireDate");
114: String expDate = exp.substring(0, 2);
115:
116: expDate = expDate + exp.substring(exp.length() - 2);
117: data.put("EXPDATE", expDate);
118: }
119:
120: // gather the address info
121: if (ps != null) {
122: String street = ps.getString("address1")
123: + (ps.get("address2") != null
124: && ps.getString("address2").length() > 0 ? " "
125: + ps.getString("address2")
126: : "");
127:
128: data.put("STREET", street);
129: data.put("ZIP", ps.getString("postalCode"));
130: }
131:
132: PFProAPI pn = init(configString);
133:
134: // get the base params
135: StringBuffer params = makeBaseParams(configString);
136:
137: // parse the context parameters
138: params.append("&" + parseContext(data));
139:
140: // transmit the request
141: if (Debug.verboseOn())
142: Debug.logVerbose("Sending to Verisign: "
143: + params.toString(), module);
144: String resp = pn.SubmitTransaction(params.toString());
145:
146: if (Debug.verboseOn())
147: Debug.logVerbose("Response from Verisign: " + resp, module);
148:
149: // reset for next use
150: pn.DestroyContext();
151:
152: // check the response
153: Map result = ServiceUtil.returnSuccess();
154: parseAuthResponse(resp, result, configString, isReAuth);
155: result.put("processAmount", processAmount);
156: return result;
157: }
158:
159: public static Map ccCapture(DispatchContext dctx, Map context) {
160: GenericValue paymentPref = (GenericValue) context
161: .get("orderPaymentPreference");
162: GenericValue authTrans = (GenericValue) context
163: .get("authTrans");
164: Double amount = (Double) context.get("captureAmount");
165: String configString = (String) context.get("paymentConfig");
166: if (configString == null) {
167: configString = "payment.properties";
168: }
169:
170: if (authTrans == null) {
171: authTrans = PaymentGatewayServices
172: .getAuthTransaction(paymentPref);
173: }
174:
175: if (authTrans == null) {
176: return ServiceUtil
177: .returnError("No authorization transaction found for the OrderPaymentPreference; cannot capture");
178: }
179:
180: // auth ref number
181: String refNum = authTrans.getString("referenceNum");
182: Map data = UtilMisc.toMap("ORIGID", refNum);
183:
184: // tx type (Delayed Capture)
185: data.put("TRXTYPE", "D");
186:
187: // credit card tender
188: data.put("TENDER", "C");
189:
190: // get the orderID
191: String orderId = paymentPref.getString("orderId");
192: data.put("COMMENT1", orderId);
193:
194: // amount to capture
195: data.put("AMT", amount.toString());
196:
197: PFProAPI pn = init(configString);
198:
199: // get the base params
200: StringBuffer params = makeBaseParams(configString);
201:
202: // parse the context parameters
203: params.append("&" + parseContext(data));
204:
205: // transmit the request
206: if (Debug.verboseOn())
207: Debug.logVerbose("Sending to Verisign: "
208: + params.toString(), module);
209: String resp = pn.SubmitTransaction(params.toString());
210:
211: if (Debug.verboseOn())
212: Debug.logVerbose("Response from Verisign: " + resp, module);
213:
214: // reset for next use
215: pn.DestroyContext();
216:
217: // check the response
218: Map result = ServiceUtil.returnSuccess();
219: parseCaptureResponse(resp, result, configString);
220: result.put("captureAmount", amount);
221: return result;
222: }
223:
224: public static Map ccVoid(DispatchContext dctx, Map context) {
225: GenericValue paymentPref = (GenericValue) context
226: .get("orderPaymentPreference");
227: GenericValue authTrans = (GenericValue) context
228: .get("authTrans");
229: Double amount = (Double) context.get("releaseAmount");
230: String configString = (String) context.get("paymentConfig");
231: if (configString == null) {
232: configString = "payment.properties";
233: }
234:
235: if (authTrans == null) {
236: authTrans = PaymentGatewayServices
237: .getAuthTransaction(paymentPref);
238: }
239:
240: if (authTrans == null) {
241: return ServiceUtil
242: .returnError("No authorization transaction found for the OrderPaymentPreference; cannot capture");
243: }
244:
245: // auth ref number
246: String refNum = authTrans.getString("referenceNum");
247: Map data = UtilMisc.toMap("ORIGID", refNum);
248:
249: // tx type (Void)
250: data.put("TRXTYPE", "V");
251:
252: // credit card tender
253: data.put("TENDER", "C");
254:
255: // get the orderID
256: String orderId = paymentPref.getString("orderId");
257: data.put("COMMENT1", orderId);
258:
259: // amount to capture
260: data.put("AMT", amount.toString());
261:
262: PFProAPI pn = init(configString);
263:
264: // get the base params
265: StringBuffer params = makeBaseParams(configString);
266:
267: // parse the context parameters
268: params.append("&" + parseContext(data));
269:
270: // transmit the request
271: if (Debug.verboseOn())
272: Debug.logVerbose("Sending to Verisign: "
273: + params.toString(), module);
274: String resp = pn.SubmitTransaction(params.toString());
275:
276: if (Debug.verboseOn())
277: Debug.logVerbose("Response from Verisign: " + resp, module);
278:
279: // reset for next use
280: pn.DestroyContext();
281:
282: // check the response
283: Map result = ServiceUtil.returnSuccess();
284: parseVoidResponse(resp, result, configString);
285: result.put("releaseAmount", amount);
286: return result;
287: }
288:
289: public static Map ccRefund(DispatchContext dctx, Map context) {
290: GenericValue paymentPref = (GenericValue) context
291: .get("orderPaymentPreference");
292: Double amount = (Double) context.get("refundAmount");
293: String configString = (String) context.get("paymentConfig");
294: if (configString == null) {
295: configString = "payment.properties";
296: }
297:
298: GenericValue captureTrans = PaymentGatewayServices
299: .getCaptureTransaction(paymentPref);
300:
301: if (captureTrans == null) {
302: return ServiceUtil
303: .returnError("No capture transaction found for the OrderPaymentPreference; cannot refund");
304: }
305:
306: // auth ref number
307: String refNum = captureTrans.getString("referenceNum");
308: Map data = UtilMisc.toMap("ORIGID", refNum);
309:
310: // tx type (Credit)
311: data.put("TRXTYPE", "C");
312:
313: // credit card tender
314: data.put("TENDER", "C");
315:
316: // get the orderID
317: String orderId = paymentPref.getString("orderId");
318: data.put("COMMENT1", orderId);
319:
320: // amount to capture
321: data.put("AMT", amount.toString());
322:
323: PFProAPI pn = init(configString);
324:
325: // get the base params
326: StringBuffer params = makeBaseParams(configString);
327:
328: // parse the context parameters
329: params.append("&" + parseContext(data));
330:
331: // transmit the request
332: if (Debug.verboseOn())
333: Debug.logVerbose("Sending to Verisign: "
334: + params.toString(), module);
335: String resp = pn.SubmitTransaction(params.toString());
336:
337: if (Debug.verboseOn())
338: Debug.logVerbose("Response from Verisign: " + resp, module);
339:
340: // reset for next use
341: pn.DestroyContext();
342:
343: // check the response
344: Map result = ServiceUtil.returnSuccess();
345: parseRefundResponse(resp, result, configString);
346: result.put("refundAmount", amount);
347: return result;
348: }
349:
350: private static void parseAuthResponse(String resp, Map result,
351: String resource, boolean isReAuth) {
352: Debug.logInfo("Verisign response string: " + resp, module);
353: Map parameters = new LinkedMap();
354: List params = StringUtil.split(resp, "&");
355: Iterator i = params.iterator();
356:
357: while (i.hasNext()) {
358: String str = (String) i.next();
359:
360: if (str.length() > 0) {
361: List kv = StringUtil.split(str, "=");
362: Object k = kv.get(0);
363: Object v = kv.get(1);
364:
365: if (k != null && v != null)
366: parameters.put(k, v);
367: }
368: }
369:
370: // txType
371: boolean isSale = !UtilProperties.propertyValueEqualsIgnoreCase(
372: resource, "payment.verisign.preAuth", "Y");
373:
374: // avs checking - ignore on re-auth
375: boolean avsCheckOkay = true;
376: String avsCode = null;
377: if (!isReAuth) {
378: boolean checkAvs = UtilProperties
379: .propertyValueEqualsIgnoreCase(resource,
380: "payment.verisign.checkAvs", "Y");
381: if (checkAvs && !isSale) {
382: String addAvs = (String) parameters.get("AVSADDR");
383: String zipAvs = (String) parameters.get("AVSZIP");
384: avsCode = addAvs + zipAvs;
385: if (addAvs == null || "N".equals(addAvs)
386: || zipAvs == null || "N".equals(zipAvs)) {
387: avsCheckOkay = false;
388: }
389: }
390: }
391:
392: // cvv2 checking - ignore on re-auth
393: boolean cvv2CheckOkay = true;
394: String cvvCode = null;
395: if (!isReAuth) {
396: boolean checkCvv2 = UtilProperties
397: .propertyValueEqualsIgnoreCase(resource,
398: "payment.verisign.checkCvv2", "Y");
399: if (checkCvv2 && !isSale) {
400: cvvCode = (String) parameters.get("CVV2MATCH");
401: if (cvvCode == null || "N".equals(cvvCode)) {
402: cvv2CheckOkay = false;
403: }
404: }
405: }
406:
407: String respCode = (String) parameters.get("RESULT");
408: if ("0".equals(respCode) && avsCheckOkay && cvv2CheckOkay) {
409: result.put("authResult", Boolean.TRUE);
410: result.put("authCode", parameters.get("AUTHCODE"));
411: } else {
412: Debug.logWarning(
413: "In PayflowPro failing authorization; respCode/RESULT="
414: + respCode + ", avsCheckOkay="
415: + avsCheckOkay + ", cvv2CheckOkay="
416: + cvv2CheckOkay + "; AUTHCODE="
417: + parameters.get("AUTHCODE"), module);
418: result.put("authResult", Boolean.FALSE);
419:
420: // now check certain special conditions and report back through the generic params
421: if ("12".equals(respCode)) {
422: result.put("resultDeclined", Boolean.TRUE);
423: } else if ("50".equals(respCode)) {
424: result.put("resultNsf", Boolean.TRUE);
425: } else if ("23".equals(respCode)) {
426: result.put("resultBadCardNumber", Boolean.TRUE);
427: } else if ("24".equals(respCode)) {
428: result.put("resultBadExpire", Boolean.TRUE);
429: }
430: }
431: result.put("cvCode", cvvCode);
432: result.put("avsCode", avsCode);
433: result.put("authRefNum", parameters.get("PNREF"));
434: result.put("authFlag", parameters.get("RESULT"));
435: result.put("authMessage", parameters.get("RESPMSG"));
436: }
437:
438: private static void parseCaptureResponse(String resp, Map result,
439: String resource) {
440: Map parameters = new LinkedMap();
441: List params = StringUtil.split(resp, "&");
442: Iterator i = params.iterator();
443:
444: while (i.hasNext()) {
445: String str = (String) i.next();
446:
447: if (str.length() > 0) {
448: List kv = StringUtil.split(str, "=");
449: Object k = kv.get(0);
450: Object v = kv.get(1);
451:
452: if (k != null && v != null)
453: parameters.put(k, v);
454: }
455: }
456: String respCode = (String) parameters.get("RESULT");
457:
458: if (respCode.equals("0")) {
459: result.put("captureResult", Boolean.TRUE);
460: result.put("captureCode", parameters.get("AUTHCODE"));
461: } else {
462: result.put("captureResult", Boolean.FALSE);
463: }
464: result.put("captureRefNum", parameters.get("PNREF"));
465: result.put("captureFlag", parameters.get("RESULT"));
466: result.put("captureMessage", parameters.get("RESPMSG"));
467: }
468:
469: private static void parseVoidResponse(String resp, Map result,
470: String resource) {
471: Map parameters = new LinkedMap();
472: List params = StringUtil.split(resp, "&");
473: Iterator i = params.iterator();
474:
475: while (i.hasNext()) {
476: String str = (String) i.next();
477:
478: if (str.length() > 0) {
479: List kv = StringUtil.split(str, "=");
480: Object k = kv.get(0);
481: Object v = kv.get(1);
482:
483: if (k != null && v != null)
484: parameters.put(k, v);
485: }
486: }
487: String respCode = (String) parameters.get("RESULT");
488:
489: if (respCode.equals("0")) {
490: result.put("releaseResult", Boolean.TRUE);
491: result.put("releaseCode", parameters.get("AUTHCODE"));
492: } else {
493: result.put("releaseResult", Boolean.FALSE);
494: }
495: result.put("releaseRefNum", parameters.get("PNREF"));
496: result.put("releaseFlag", parameters.get("RESULT"));
497: result.put("releaseMessage", parameters.get("RESPMSG"));
498: }
499:
500: private static void parseRefundResponse(String resp, Map result,
501: String resource) {
502: Map parameters = new LinkedMap();
503: List params = StringUtil.split(resp, "&");
504: Iterator i = params.iterator();
505:
506: while (i.hasNext()) {
507: String str = (String) i.next();
508:
509: if (str.length() > 0) {
510: List kv = StringUtil.split(str, "=");
511: Object k = kv.get(0);
512: Object v = kv.get(1);
513:
514: if (k != null && v != null)
515: parameters.put(k, v);
516: }
517: }
518: String respCode = (String) parameters.get("RESULT");
519:
520: if (respCode.equals("0")) {
521: result.put("refundResult", Boolean.TRUE);
522: result.put("refundCode", parameters.get("AUTHCODE"));
523: } else {
524: result.put("refundResult", Boolean.FALSE);
525: }
526: result.put("refundRefNum", parameters.get("PNREF"));
527: result.put("refundFlag", parameters.get("RESULT"));
528: result.put("refundMessage", parameters.get("RESPMSG"));
529: }
530:
531: private static String parseContext(Map context) {
532: StringBuffer buf = new StringBuffer();
533: Set keySet = context.keySet();
534: Iterator i = keySet.iterator();
535:
536: while (i.hasNext()) {
537: Object name = i.next();
538: Object value = context.get(name);
539:
540: if (value != null && (value instanceof String)
541: && ((String) value).length() == 0)
542: continue;
543: buf.append(name + "=");
544: buf.append(value);
545: if (i.hasNext())
546: buf.append("&");
547: }
548: return buf.toString();
549: }
550:
551: private static StringBuffer makeBaseParams(String resource) {
552: StringBuffer buf = new StringBuffer();
553:
554: try {
555: buf.append("PARTNER=");
556: buf.append(UtilProperties.getPropertyValue(resource,
557: "payment.verisign.partner", "VeriSign"));
558: buf.append("&");
559: buf.append("VENDOR=");
560: buf.append(UtilProperties.getPropertyValue(resource,
561: "payment.verisign.vendor", "nobody"));
562: buf.append("&");
563: buf.append("USER=");
564: buf.append(UtilProperties.getPropertyValue(resource,
565: "payment.verisign.user", "nobody"));
566: buf.append("&");
567: buf.append("PWD=");
568: buf.append(UtilProperties.getPropertyValue(resource,
569: "payment.verisign.pwd", "password"));
570: } catch (Exception e) {
571: Debug.logError(e, module);
572: return null;
573: }
574: return buf;
575: }
576:
577: private static PFProAPI init(String resource) {
578: String certsPath = UtilProperties.getPropertyValue(resource,
579: "payment.verisign.certsPath", "pfcerts");
580: String hostAddress = UtilProperties.getPropertyValue(resource,
581: "payment.verisign.hostAddress",
582: "test-payflow.verisign.com");
583: Integer hostPort = Integer.decode(UtilProperties
584: .getPropertyValue(resource,
585: "payment.verisign.hostPort", "443"));
586: Integer timeout = Integer.decode(UtilProperties
587: .getPropertyValue(resource, "payment.verisign.timeout",
588: "80"));
589: String proxyAddress = UtilProperties.getPropertyValue(resource,
590: "payment.verisign.proxyAddress", "");
591: Integer proxyPort = Integer.decode(UtilProperties
592: .getPropertyValue(resource,
593: "payment.verisign.proxyPort", "80"));
594: String proxyLogon = UtilProperties.getPropertyValue(resource,
595: "payment.verisign.proxyLogon", "");
596: String proxyPassword = UtilProperties.getPropertyValue(
597: resource, "payment.verisign.proxyPassword", "");
598:
599: PFProAPI pn = new PFProAPI();
600:
601: // Set the certificate path
602: pn.SetCertPath(certsPath);
603: // Call the client.
604: pn.CreateContext(hostAddress, hostPort.intValue(), timeout
605: .intValue(), proxyAddress, proxyPort.intValue(),
606: proxyLogon, proxyPassword);
607: return pn;
608: }
609:
610: /*
611: * RESULT values (and RESPMSG text)
612: *
613: 0 Approved
614: 1 User authentication failed. Error is caused by one or more of the following:
615: Login information is incorrect. Verify that USER, VENDOR, PARTNER, and
616: PASSWORD have been entered correctly. See Table 3.2 on page 26 for additional
617: information and field descriptions.
618: Invalid Processor information entered. Contact merchant bank to verify.
619: "Allowed IP Address" security feature implemented. The transaction is coming
620: from an unknown IP address. See VeriSign Manager online help for details on how
621: to use Manager to update the allowed IP addresses.
622: You are using a test (not active) account to submit a transaction to the live VeriSign
623: servers. Change the URL from test-payflow.verisign.com to payflow.verisign.com.
624: 2 Invalid tender type. Your merchant bank account does not support the following
625: credit card type that was submitted.
626: 3 Invalid transaction type. Transaction type is not appropriate for this transaction. For
627: example, you cannot credit an authorization-only transaction.
628: 4 Invalid amount format. Use the format: Ò#####.##Ó Do not include currency
629: symbols or commas.
630: 5 Invalid merchant information. Processor does not recognize your merchant account
631: information. Contact your bank account acquirer to resolve this problem.
632: 6 Invalid or unsupported currency code
633: 7 Field format error. Invalid information entered. See RESPMSG.
634: 8 Not a transaction server
635: 9 Too many parameters or invalid stream
636: 10 Too many line items
637: 11 Client time-out waiting for response
638: 12 Declined. Check the credit card number, expiration date, and transaction information to
639: make sure they were entered correctly. If this does not resolve the problem, have the
640: customer call their card issuing bank to resolve.
641: 13 Referral. Transaction cannot be approved electronically but can be approved with a
642: verbal authorization. Contact your merchant bank to obtain an authorization and submit
643: a manual Voice Authorization transaction.
644: 14 Invalid Client Certification ID. Check the HTTP header. If the tag, X-VPS-VIT-
645: CLIENT-CERTIFICATION-ID, is missing, RESULT code 14 is returned.
646: 19 Original transaction ID not found. The transaction ID you entered for this
647: transaction is not valid. See RESPMSG.
648: 20 Cannot find the customer reference number
649: 22 Invalid ABA number
650:
651: 23 Invalid account number. Check credit card number and re-submit.
652: 24 Invalid expiration date. Check and re-submit.
653: 25 Invalid Host Mapping. You are trying to process a tender type such as Discover Card,
654: but you are not set up with your merchant bank to accept this card type.
655: 26 Invalid vendor account
656: 27 Insufficient partner permissions
657: 28 Insufficient user permissions
658: 29 Invalid XML document. This could be caused by an unrecognized XML tag or a bad
659: XML format that cannot be parsed by the system.
660: 30 Duplicate transaction
661: 31 Error in adding the recurring profile
662: 32 Error in modifying the recurring profile
663: 33 Error in canceling the recurring profile
664: 34 Error in forcing the recurring profile
665: 35 Error in reactivating the recurring profile
666: 36 OLTP Transaction failed
667: 37 Invalid recurring profile ID
668: 50 Insufficient funds available in account
669: 99 General error. See RESPMSG.
670: 100 Transaction type not supported by host
671: 101 Time-out value too small
672: 102 Processor not available
673: 103 Error reading response from host
674: 104 Timeout waiting for processor response. Try your transaction again.
675: 105 Credit error. Make sure you have not already credited this transaction, or that this
676: transaction ID is for a creditable transaction. (For example, you cannot credit an
677: authorization.)
678: 106 Host not available
679: 107 Duplicate suppression time-out
680:
681: 108 Void error. See RESPMSG. Make sure the transaction ID entered has not already been
682: voided. If not, then look at the Transaction Detail screen for this transaction to see if it
683: has settled. (The Batch field is set to a number greater than zero if the transaction has
684: been settled). If the transaction has already settled, your only recourse is a reversal
685: (credit a payment or submit a payment for a credit).
686: 109 Time-out waiting for host response
687: 111 Capture error. Either an attempt to capture a transaction that is not an authorization
688: transaction type, or an attempt to capture an authorization transaction that has already
689: been captured.
690: 112 Failed AVS check. Address and ZIP code do not match. An authorization may still
691: exist on the cardholderÕs account.
692: 113 Merchant sale total will exceed the sales cap with current transaction. ACH
693: transactions only.
694: 114 Card Security Code (CSC) Mismatch. An authorization may still exist on the
695: cardholderÕs account.
696: 115 System busy, try again later
697: 116 VPS Internal error. Failed to lock terminal number
698: 117 Failed merchant rule check. One or more of the following three failures occurred:
699: An attempt was made to submit a transaction that failed to meet the security settings
700: specified on the Payflow Pro Java SDK Security Settings page. If the transaction
701: exceeded the Maximum Amount security setting, then no values are returned for AVS
702: or CSC.
703: AVS validation failed. The AVS return value should appear in the RESPMSG.
704: CSC validation failed. The CSC return value should appear in the RESPMSG.
705: 118 Invalid keywords found in string fields
706: 122 Merchant sale total will exceed the credit cap with current transaction. ACH
707: transactions only.
708: 125 Fraud Protection Services Filter Ñ Declined by filters
709:
710: 126 Fraud Protection Services Filter Ñ Flagged for review by filters
711: Important Note: Result code 126 indicates that a transaction triggered a fraud filter.
712: This is not an error, but a notice that the transaction is in a review status. The
713: transaction has been authorized but requires you to review and to manually accept the
714: transaction before it will be allowed to settle.
715: Result code 126 is intended to give you an idea of the kind of transaction that is
716: considered suspicious to enable you to evaluate whether you can benefit from using the
717: Fraud Protection Services.
718: To eliminate result 126, turn the filters off.
719: For more information, see the UserÕs Guide for Payflow Pro With Fraud Protection
720: Services or UserÕs Guide for Payflow Link Guide With Fraud Protection Services.
721: 127 Fraud Protection Services Filter Ñ Not processed by filters
722: 128 Fraud Protection Services Filter Ñ Declined by merchant after being flagged for
723: review by filters
724: 131 Version 1 Payflow Pro SDK client no longer supported. Upgrade to the most recent
725: version of the Payflow Pro client.
726: 150 Issuing bank timed out
727: 151 Issuing bank unavailable
728: 1000 Generic host error. This is a generic message returned by your credit card processor.
729: The RESPMSG will contain more information describing the error.
730: 1001 Buyer Authentication Service unavailable
731: 1002 Buyer Authentication Service Ñ Transaction timeout
732: 1003 Buyer Authentication Service Ñ Invalid client version
733: 1004 Buyer Authentication Service Ñ Invalid timeout value
734: 1011 Buyer Authentication Service unavailable
735: 1012 Buyer Authentication Service unavailable
736: 1013 Buyer Authentication Service unavailable
737: 1014 Buyer Authentication Service Ñ Merchant is not enrolled for Buyer
738: Authentication Service (3-D Secure).
739: 1016 Buyer Authentication Service Ñ 3-D Secure error response received. Instead of
740: receiving a PARes response to a Validate Authentication transaction, an error response
741: was received.
742: 1017 Buyer Authentication Service Ñ 3-D Secure error response is invalid. An error
743: response is received and the response is not well formed for a Validate Authentication
744: transaction.
745:
746: 1021 Buyer Authentication Service Ñ Invalid card type
747: 1022 Buyer Authentication Service Ñ Invalid or missing currency code
748: 1023 Buyer Authentication Service Ñ merchant status for 3D secure is invalid
749: 1041 Buyer Authentication Service Ñ Validate Authentication failed: missing or
750: invalid PARES
751: 1042 Buyer Authentication Service Ñ Validate Authentication failed: PARES format is
752: invalid
753: 1043 Buyer Authentication Service Ñ Validate Authentication failed: Cannot find
754: successful Verify Enrollment
755: 1044 Buyer Authentication Service Ñ Validate Authentication failed: Signature
756: validation failed for PARES
757: 1045 Buyer Authentication Service Ñ Validate Authentication failed: Mismatched or
758: invalid amount in PARES
759: 1046 Buyer Authentication Service Ñ Validate Authentication failed: Mismatched or
760: invalid acquirer in PARES
761: 1047 Buyer Authentication Service Ñ Validate Authentication failed: Mismatched or
762: invalid Merchant ID in PARES
763: 1048 Buyer Authentication Service Ñ Validate Authentication failed: Mismatched or
764: invalid card number in PARES
765: 1049 Buyer Authentication Service Ñ Validate Authentication failed: Mismatched or
766: invalid currency code in PARES
767: 1050 Buyer Authentication Service Ñ Validate Authentication failed: Mismatched or
768: invalid XID in PARES
769: 1051 Buyer Authentication Service Ñ Validate Authentication failed: Mismatched or
770: invalid order date in PARES
771: 1052 Buyer Authentication Service Ñ Validate Authentication failed: This PARES was
772: already validated for a previous Validate Authentication transaction
773:
774: */
775:
776: /* RESULT for communication errors (less than 0)
777: *
778: -1 Failed to connect to host
779: -2 Failed to resolve hostname
780: -5 Failed to initialize SSL context
781: -6 Parameter list format error: & in name
782: -7 Parameter list format error: invalid [ ] name length clause
783: -8 SSL failed to connect to host
784: -9 SSL read failed
785: -10 SSL write failed
786: -11 Proxy authorization failed
787: -12 Timeout waiting for response
788: -13 Select failure
789: -14 Too many connections
790: -15 Failed to set socket options
791: -20 Proxy read failed
792: -21 Proxy write failed
793: -22 Failed to initialize SSL certificate
794: -23 Host address not specified
795: -24 Invalid transaction type
796: -25 Failed to create a socket
797: -26 Failed to initialize socket layer
798: -27 Parameter list format error: invalid [ ] name length clause
799: -28 Parameter list format error: name
800: -29 Failed to initialize SSL connection
801: -30 Invalid timeout value
802:
803: -31 The certificate chain did not validate, no local certificate found
804: -32 The certificate chain did not validate, common name did not match URL
805: - 40 Unexpected Request ID found in request.
806: - 41 Required Request ID not found in request
807: - 42 Required Response ID not found in request
808: - 43 Unexpected Response ID found in request
809: - 44 Response ID not found in the response received from the server
810: -99 Out of memory
811: -100 Parameter list cannot be empty
812: -103 Context initialization failed
813: -104 Unexpected transaction state
814: -105 Invalid name value pair request
815: -106 Invalid response format
816: -107 This XMLPay version is not supported
817: -108 The server certificate chain did not validate
818: -109 Unable to do logging
819: -111 The following error occurred while initializing from message file: <Details of
820: the error message>
821: -113 Unable to round and truncate the currency value simultaneously
822: */
823: }
|