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.worldpay;
019:
020: import java.io.IOException;
021: import java.util.Enumeration;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.Locale;
025: import java.util.Map;
026:
027: import javax.servlet.ServletContext;
028: import javax.servlet.ServletException;
029: import javax.servlet.ServletOutputStream;
030: import javax.servlet.ServletRequest;
031: import javax.servlet.http.HttpSession;
032:
033: import org.ofbiz.base.util.Debug;
034: import org.ofbiz.base.util.GeneralException;
035: import org.ofbiz.base.util.StringUtil;
036: import org.ofbiz.base.util.UtilMisc;
037: import org.ofbiz.webapp.view.JPublishWrapper;
038: import org.ofbiz.entity.GenericDelegator;
039: import org.ofbiz.entity.GenericEntityException;
040: import org.ofbiz.entity.GenericValue;
041: import org.ofbiz.entity.transaction.GenericTransactionException;
042: import org.ofbiz.entity.transaction.TransactionUtil;
043: import org.ofbiz.order.order.OrderChangeHelper;
044: import org.ofbiz.service.ModelService;
045: import org.ofbiz.service.DispatchContext;
046: import org.ofbiz.service.GenericServiceException;
047: import org.ofbiz.service.LocalDispatcher;
048: import org.ofbiz.service.ServiceDispatcher;
049:
050: import com.worldpay.select.SelectDefs;
051: import com.worldpay.select.merchant.SelectServlet;
052: import com.worldpay.select.merchant.SelectServletRequest;
053: import com.worldpay.select.merchant.SelectServletResponse;
054:
055: /**
056: * WorldPay Select Pro Response Servlet
057: */
058: public class SelectRespServlet extends SelectServlet implements
059: SelectDefs {
060:
061: public static final String module = SelectRespServlet.class
062: .getName();
063: protected JPublishWrapper jp = null;
064:
065: protected void doRequest(SelectServletRequest request,
066: SelectServletResponse response) throws ServletException,
067: IOException {
068: Debug.logInfo("Response received from worldpay..", module);
069:
070: String localLocaleStr = request.getParameter("M_localLocale");
071: String webSiteId = request.getParameter("M_webSiteId");
072: String delegatorName = request.getParameter("M_delegatorName");
073: String dispatchName = request.getParameter("M_dispatchName");
074: String userLoginId = request.getParameter("M_userLoginId");
075: String confirmTemplate = request
076: .getParameter("M_confirmTemplate");
077:
078: // get the ServletContext
079: ServletContext context = (ServletContext) request
080: .getAttribute("servletContext");
081: if (this .jp == null) {
082: this .jp = (JPublishWrapper) context
083: .getAttribute("jpublishWrapper");
084: if (this .jp == null) {
085: this .jp = new JPublishWrapper(context);
086: }
087: }
088:
089: // get the delegator
090: GenericDelegator delegator = GenericDelegator
091: .getGenericDelegator(delegatorName);
092:
093: // get the dispatcher
094: ServiceDispatcher serviceDisp = ServiceDispatcher.getInstance(
095: dispatchName, delegator);
096: DispatchContext dctx = serviceDisp
097: .getLocalContext(dispatchName);
098: LocalDispatcher dispatcher = dctx.getDispatcher();
099:
100: // get the userLogin
101: GenericValue userLogin = null;
102: try {
103: userLogin = delegator.findByPrimaryKey("UserLogin",
104: UtilMisc.toMap("userLoginId", userLoginId));
105: } catch (GenericEntityException e) {
106: Debug.logError(e, "Cannot get admin UserLogin entity",
107: module);
108: callError(request);
109: }
110:
111: // get the client locale
112: List localeSplit = StringUtil.split(localLocaleStr, "_");
113: Locale localLocale = new Locale((String) localeSplit.get(0),
114: (String) localeSplit.get(1));
115:
116: // get the properties file
117: String configString = null;
118: try {
119: GenericValue webSitePayment = delegator.findByPrimaryKey(
120: "WebSitePaymentSetting", UtilMisc.toMap(
121: "webSiteId", webSiteId,
122: "paymentMethodTypeId", "EXT_WORLDPAY"));
123: if (webSitePayment != null)
124: configString = webSitePayment
125: .getString("paymentConfiguration");
126: } catch (GenericEntityException e) {
127: Debug.logWarning(e, "Cannot find webSitePayment Settings",
128: module);
129: }
130: if (configString == null)
131: configString = "payment.properties";
132: Debug.logInfo("Got the payment configuration", module);
133:
134: String orderId = request.getParameter(SelectDefs.SEL_cartId);
135: String authAmount = request
136: .getParameter(SelectDefs.SEL_authAmount);
137: String transStatus = request
138: .getParameter(SelectDefs.SEL_transStatus);
139:
140: // get the order header
141: GenericValue orderHeader = null;
142: try {
143: orderHeader = delegator.findByPrimaryKey("OrderHeader",
144: UtilMisc.toMap("orderId", orderId));
145: } catch (GenericEntityException e) {
146: Debug
147: .logError(
148: e,
149: "Cannot get the order header for the returned orderId",
150: module);
151: callError(request);
152: }
153:
154: // the order total MUST match the auth amount or we do not process
155: Double wpTotal = new Double(authAmount);
156: Double orderTotal = orderHeader != null ? orderHeader
157: .getDouble("grandTotal") : null;
158: if (orderTotal != null && wpTotal != null) {
159: if (orderTotal.doubleValue() != wpTotal.doubleValue()) {
160: Debug.logError("AuthAmount (" + wpTotal
161: + ") does not match OrderTotal (" + orderTotal
162: + ")", module);
163: callError(request);
164: }
165: }
166:
167: // store some stuff for calling existing events
168: HttpSession session = request.getSession(true);
169: session.setAttribute("userLogin", userLogin);
170:
171: request.setAttribute("delegator", delegator);
172: request.setAttribute("dispatcher", dispatcher);
173: request.setAttribute("orderId", orderId);
174: request.setAttribute("notifyEmail", request
175: .getParameter("M_notifyEmail"));
176: request.setAttribute("confirmEmail", request
177: .getParameter("M_confirmEmail"));
178: request.setAttribute("_CONTROL_PATH_", request
179: .getParameter("M_controlPath"));
180:
181: // attempt to start a transaction
182: boolean beganTransaction = false;
183: try {
184: beganTransaction = TransactionUtil.begin();
185: } catch (GenericTransactionException gte) {
186: Debug.logError(gte, "Unable to begin transaction", module);
187: }
188:
189: boolean okay = false;
190: if (transStatus.equalsIgnoreCase("Y")) {
191: // order was approved
192: Debug.logInfo("Order #" + orderId + " approved", module);
193: okay = OrderChangeHelper.approveOrder(dispatcher,
194: userLogin, orderId);
195: } else {
196: // order was cancelled
197: Debug.logInfo("Order #" + orderId + " cancelled", module);
198: okay = OrderChangeHelper.cancelOrder(dispatcher, userLogin,
199: orderId);
200: }
201:
202: if (okay) {
203: // set the payment preference
204: okay = setPaymentPreferences(delegator, userLogin, orderId,
205: request);
206: }
207:
208: if (okay) {
209: try {
210: TransactionUtil.commit(beganTransaction);
211: } catch (GenericTransactionException gte) {
212: Debug.logError(gte, "Unable to commit transaction",
213: module);
214: }
215: } else {
216: try {
217: TransactionUtil
218: .rollback(
219: beganTransaction,
220: "Failure in Worldpay callback/response processing.",
221: null);
222: } catch (GenericTransactionException gte) {
223: Debug.logError(gte, "Unable to rollback transaction",
224: module);
225: }
226: }
227:
228: // attempt to release the offline hold on the order (workflow)
229: OrderChangeHelper.releaseInitialOrderHold(dispatcher, orderId);
230:
231: // call the email confirm service
232: Map emailContext = UtilMisc.toMap("orderId", orderId);
233: try {
234: Map emailResult = dispatcher.runSync(
235: "sendOrderConfirmation", emailContext);
236: } catch (GenericServiceException e) {
237: Debug.logError(e, "Problems sending email confirmation",
238: module);
239: }
240:
241: // set up the output stream for the response
242: response.setContentType("text/html");
243: ServletOutputStream out = response.getOutputStream();
244: String content = "Error getting confirm content";
245: if (confirmTemplate != null) {
246: // render the thank-you / confirm page
247: try {
248: content = jp.render(confirmTemplate, request, response);
249: } catch (GeneralException e) {
250: Debug.logError(e, "Trouble rendering confirm page",
251: module);
252: }
253: }
254: out.println(content);
255: out.flush();
256: }
257:
258: private boolean setPaymentPreferences(GenericDelegator delegator,
259: GenericValue userLogin, String orderId,
260: ServletRequest request) {
261: List paymentPrefs = null;
262: boolean okay = true;
263: try {
264: Map paymentFields = UtilMisc.toMap("orderId", orderId,
265: "statusId", "PAYMENT_NOT_RECEIVED");
266: paymentPrefs = delegator.findByAnd(
267: "OrderPaymentPreference", paymentFields);
268: } catch (GenericEntityException e) {
269: Debug.logError(e,
270: "Cannot get payment preferences for order #"
271: + orderId, module);
272: }
273: if (paymentPrefs != null && paymentPrefs.size() > 0) {
274: Iterator i = paymentPrefs.iterator();
275: while (okay && i.hasNext()) {
276: GenericValue pref = (GenericValue) i.next();
277: okay = setPaymentPreference(pref, userLogin, request);
278: }
279: }
280: return okay;
281: }
282:
283: private boolean setPaymentPreference(
284: GenericValue paymentPreference, GenericValue userLogin,
285: ServletRequest request) {
286: String transId = request.getParameter(SelectDefs.SEL_transId);
287: String transTime = request
288: .getParameter(SelectDefs.SEL_transTime);
289: String transStatus = request
290: .getParameter(SelectDefs.SEL_transStatus);
291: String avsCode = request.getParameter("AVS"); // why is this not in SelectDefs??
292: String authCode = request.getParameter(SelectDefs.SEL_authCode);
293: String authAmount = request
294: .getParameter(SelectDefs.SEL_authAmount);
295: String rawAuthMessage = request
296: .getParameter(SelectDefs.SEL_rawAuthMessage);
297:
298: // Need these for create payment service
299: LocalDispatcher dispatcher = (LocalDispatcher) request
300: .getAttribute("dispatcher");
301:
302: if (transStatus.equalsIgnoreCase("Y")) {
303: paymentPreference.set("authCode", authCode);
304: paymentPreference.set("statusId", "PAYMENT_RECEIVED");
305: } else {
306: paymentPreference.set("statusId", "PAYMENT_CANCELLED");
307: }
308: Long transTimeLong = new Long(transTime);
309: java.sql.Timestamp authDate = new java.sql.Timestamp(
310: transTimeLong.longValue());
311:
312: paymentPreference.set("avsCode", avsCode);
313: paymentPreference.set("authRefNum", transId);
314: paymentPreference.set("authDate", authDate);
315: paymentPreference.set("authFlag", transStatus);
316: paymentPreference.set("authMessage", rawAuthMessage);
317: paymentPreference.set("maxAmount", new Double(authAmount));
318:
319: // create a payment record too -- this method does not store the object so we must here
320: Map results = null;
321: try {
322: results = dispatcher
323: .runSync(
324: "createPaymentFromPreference",
325: UtilMisc
326: .toMap(
327: "userLogin",
328: userLogin,
329: "orderPaymentPreferenceId",
330: paymentPreference
331: .get("orderPaymentPreferenceId"),
332: "comments",
333: "Payment received via WorldPay"));
334: } catch (GenericServiceException e) {
335: Debug
336: .logError(
337: e,
338: "Failed to execute service createPaymentFromPreference",
339: module);
340: request.setAttribute("_ERROR_MESSAGE_", e.getMessage());
341: return false;
342: }
343:
344: if ((results == null)
345: || (results.get(ModelService.RESPONSE_MESSAGE)
346: .equals(ModelService.RESPOND_ERROR))) {
347: Debug.logError((String) results
348: .get(ModelService.ERROR_MESSAGE), module);
349: request.setAttribute("_ERROR_MESSAGE_", (String) results
350: .get(ModelService.ERROR_MESSAGE));
351: return false;
352: }
353:
354: try {
355: paymentPreference.store();
356: paymentPreference.getDelegator().create(paymentPreference);
357: } catch (GenericEntityException e) {
358: Debug.logError(e,
359: "Cannot set payment preference/payment info",
360: module);
361: return false;
362: }
363: return true;
364: }
365:
366: private void callError(ServletRequest request)
367: throws ServletException {
368: Enumeration e = request.getParameterNames();
369: Debug.logError("###### SelectRespServlet Error:", module);
370: while (e.hasMoreElements()) {
371: String name = (String) e.nextElement();
372: String value = request.getParameter(name);
373: Debug.logError("### Parameter: " + name + " => " + value,
374: module);
375: }
376: Debug.logError("###### The order was not processed!", module);
377: throw new ServletException("Order Error");
378: }
379: }
|