001: /*
002: * $Id: PayflowPro.java,v 1.1 2003/08/18 19:37:43 jonesde Exp $
003: *
004: * Copyright (c) 2001, 2002 The Open For Business Project - www.ofbiz.org
005: *
006: * Permission is hereby granted, free of charge, to any person obtaining a
007: * copy of this software and associated documentation files (the "Software"),
008: * to deal in the Software without restriction, including without limitation
009: * the rights to use, copy, modify, merge, publish, distribute, sublicense,
010: * and/or sell copies of the Software, and to permit persons to whom the
011: * Software is furnished to do so, subject to the following conditions:
012: *
013: * The above copyright notice and this permission notice shall be included
014: * in all copies or substantial portions of the Software.
015: *
016: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
017: * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
018: * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
019: * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
020: * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
021: * OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
022: * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
023: *
024: */
025: package org.ofbiz.accounting.thirdparty.verisign;
026:
027: import java.text.NumberFormat;
028: import java.util.HashMap;
029: import java.util.Iterator;
030: import java.util.List;
031: import java.util.Map;
032: import java.util.Set;
033:
034: import org.ofbiz.base.util.Debug;
035: import org.ofbiz.base.util.OrderedMap;
036: import org.ofbiz.base.util.StringUtil;
037: import org.ofbiz.base.util.UtilMisc;
038: import org.ofbiz.base.util.UtilProperties;
039: import org.ofbiz.entity.GenericValue;
040: import org.ofbiz.service.DispatchContext;
041:
042: import com.Verisign.payment.PFProAPI;
043:
044: /**
045: * PayflowPro - Verisign PayFlow Pro <=> OFBiz Service Module
046: *
047: * @author <a href="mailto:jaz@ofbiz.org">Andy Zeneski</a>
048: * @version $Revision: 1.1 $
049: * @since 2.0
050: */
051: public class PayflowPro {
052:
053: public static final String module = PayflowPro.class.getName();
054:
055: /**
056: * Authorize credit card payment service. Service wrapper around PayFlow Pro API.
057: * @param dctx Service Engine DispatchContext.
058: * @param context Map context of parameters.
059: * @return Response map, including RESPMSG, and RESULT keys.
060: */
061: public static Map ccProcessor(DispatchContext dctx, Map context) {
062: Map result = new HashMap();
063: String orderId = (String) context.get("orderId");
064: Double processAmount = (Double) context.get("processAmount");
065: GenericValue cc = (GenericValue) context.get("creditCard");
066: GenericValue ps = (GenericValue) context.get("billingAddress");
067: String configString = (String) context.get("paymentConfig");
068: if (configString == null)
069: configString = "payment.properties";
070:
071: Map data = UtilMisc.toMap("COMMENT1", orderId);
072:
073: if (UtilProperties.propertyValueEqualsIgnoreCase(configString,
074: "payment.verisign.preAuth", "Y"))
075: data.put("TRXTYPE", "A");
076: else
077: data.put("TRXTYPE", "S");
078: data.put("TENDER", "C");
079:
080: NumberFormat nf = NumberFormat.getCurrencyInstance();
081: String totalStr = nf.format(processAmount);
082:
083: if (Debug.verboseOn())
084: Debug.logVerbose("Charging amount: " + totalStr, module);
085: if (totalStr != null) {
086: data.put("AMT", totalStr.substring(1));
087: }
088:
089: // get the payment information
090: data.put("ACCT", cc.getString("cardNumber"));
091: data.put("COMMENT2", cc.getString("nameOnCard"));
092: if (cc.get("expireDate") != null) {
093: String exp = cc.getString("expireDate");
094: String expDate = exp.substring(0, 2);
095:
096: expDate = expDate + exp.substring(exp.length() - 2);
097: data.put("EXPDATE", expDate);
098: }
099:
100: // gather the address info
101: if (ps != null) {
102: String street = ps.getString("address1")
103: + (ps.get("address2") != null
104: && ps.getString("address2").length() > 0 ? " "
105: + ps.getString("address2")
106: : "");
107:
108: data.put("STREET", street);
109: data.put("ZIP", ps.getString("postalCode"));
110: }
111:
112: PFProAPI pn = init(configString);
113:
114: // get the base params
115: StringBuffer params = makeBaseParams(configString);
116:
117: // parse the context parameters
118: params.append("&" + parseContext(data));
119:
120: // transmit the request
121: if (Debug.verboseOn())
122: Debug.logVerbose("Sending to Verisign: "
123: + params.toString(), module);
124: String resp = pn.SubmitTransaction(params.toString());
125:
126: if (Debug.verboseOn())
127: Debug.logVerbose("Response from Verisign: " + resp, module);
128:
129: // reset for next use
130: pn.DestroyContext();
131:
132: // check the response
133: parseResponse(resp, result, configString);
134: result.put("processAmount", processAmount);
135: return result;
136: }
137:
138: private static void parseResponse(String resp, Map result,
139: String resource) {
140: boolean checkAVS = UtilProperties
141: .propertyValueEqualsIgnoreCase(resource,
142: "payment.verisign.checkAvs", "Y");
143: Map parameters = new OrderedMap();
144: List params = StringUtil.split(resp, "&");
145: Iterator i = params.iterator();
146:
147: while (i.hasNext()) {
148: String str = (String) i.next();
149:
150: if (str.length() > 0) {
151: List kv = StringUtil.split(str, "=");
152: Object k = kv.get(0);
153: Object v = kv.get(1);
154:
155: if (k != null && v != null)
156: parameters.put(k, v);
157: }
158: }
159: String respCode = (String) parameters.get("RESULT");
160:
161: if (respCode.equals("0")) {
162: result.put("authResult", new Boolean(true));
163: result.put("authCode", parameters.get("AUTHCODE"));
164: } else {
165: result.put("authResult", new Boolean(false));
166: }
167: result.put("authRefNum", parameters.get("PNREF"));
168: result.put("authFlag", parameters.get("RESULT"));
169: result.put("authMessage", parameters.get("RESPMSG"));
170: }
171:
172: private static String parseContext(Map context) {
173: StringBuffer buf = new StringBuffer();
174: Set keySet = context.keySet();
175: Iterator i = keySet.iterator();
176:
177: while (i.hasNext()) {
178: Object name = i.next();
179: Object value = context.get(name);
180:
181: if (value != null && (value instanceof String)
182: && ((String) value).length() == 0)
183: continue;
184: buf.append(name + "=");
185: buf.append(value);
186: if (i.hasNext())
187: buf.append("&");
188: }
189: return buf.toString();
190: }
191:
192: private static StringBuffer makeBaseParams(String resource) {
193: StringBuffer buf = new StringBuffer();
194:
195: try {
196: buf.append("PARTNER=");
197: buf.append(UtilProperties.getPropertyValue(resource,
198: "payment.verisign.partner", "VeriSign"));
199: buf.append("&");
200: buf.append("VENDOR=");
201: buf.append(UtilProperties.getPropertyValue(resource,
202: "payment.verisign.vendor", "nobody"));
203: buf.append("&");
204: buf.append("USER=");
205: buf.append(UtilProperties.getPropertyValue(resource,
206: "payment.verisign.user", "nobody"));
207: buf.append("&");
208: buf.append("PWD=");
209: buf.append(UtilProperties.getPropertyValue(resource,
210: "payment.verisign.pwd", "password"));
211: } catch (Exception e) {
212: return null;
213: }
214: return buf;
215: }
216:
217: private static PFProAPI init(String resource) {
218: String certsPath = UtilProperties.getPropertyValue(resource,
219: "payment.verisign.certsPath", "certs");
220: String hostAddress = UtilProperties.getPropertyValue(resource,
221: "payment.verisign.hostAddress",
222: "test-payflow.verisign.com");
223: Integer hostPort = Integer.decode(UtilProperties
224: .getPropertyValue(resource,
225: "payment.verisign.hostPort", "443"));
226: Integer timeout = Integer.decode(UtilProperties
227: .getPropertyValue(resource, "payment.verisign.timeout",
228: "80"));
229: String proxyAddress = UtilProperties.getPropertyValue(resource,
230: "payment.verisign.proxyAddress", "");
231: Integer proxyPort = Integer.decode(UtilProperties
232: .getPropertyValue(resource,
233: "payment.verisign.proxyPort", "80"));
234: String proxyLogon = UtilProperties.getPropertyValue(resource,
235: "payment.verisign.proxyLogon", "");
236: String proxyPassword = UtilProperties.getPropertyValue(
237: resource, "payment.verisign.proxyPassword", "");
238:
239: PFProAPI pn = new PFProAPI();
240:
241: // Set the certificate path
242: pn.SetCertPath(certsPath);
243: // Call the client.
244: pn.CreateContext(hostAddress, hostPort.intValue(), timeout
245: .intValue(), proxyAddress, proxyPort.intValue(),
246: proxyLogon, proxyPassword);
247: return pn;
248: }
249: }
|