001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.shopping.action;
016    
017    import com.liferay.portal.kernel.io.unsync.UnsyncBufferedReader;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.util.HttpUtil;
021    import com.liferay.portal.kernel.util.ParamUtil;
022    import com.liferay.portal.kernel.util.UnsyncPrintWriterPool;
023    import com.liferay.portal.service.ServiceContext;
024    import com.liferay.portal.service.ServiceContextFactory;
025    import com.liferay.portal.util.PortalUtil;
026    import com.liferay.portlet.shopping.NoSuchOrderException;
027    import com.liferay.portlet.shopping.model.ShoppingOrder;
028    import com.liferay.portlet.shopping.service.ShoppingOrderLocalServiceUtil;
029    import com.liferay.portlet.shopping.util.ShoppingPreferences;
030    import com.liferay.portlet.shopping.util.ShoppingUtil;
031    
032    import java.io.InputStreamReader;
033    import java.io.PrintWriter;
034    
035    import java.net.URL;
036    import java.net.URLConnection;
037    
038    import java.util.Enumeration;
039    
040    import javax.servlet.http.HttpServletRequest;
041    import javax.servlet.http.HttpServletResponse;
042    
043    import org.apache.struts.action.Action;
044    import org.apache.struts.action.ActionForm;
045    import org.apache.struts.action.ActionForward;
046    import org.apache.struts.action.ActionMapping;
047    
048    /**
049     * @author Brian Wing Shun Chan
050     */
051    public class PayPalNotificationAction extends Action {
052    
053            @Override
054            public ActionForward execute(
055                            ActionMapping actionMapping, ActionForm actionForm,
056                            HttpServletRequest request, HttpServletResponse response)
057                    throws Exception {
058    
059                    String invoice = null;
060    
061                    try {
062                            if (_log.isDebugEnabled()) {
063                                    _log.debug("Receiving notification from PayPal");
064                            }
065    
066                            String query = "cmd=_notify-validate";
067    
068                            Enumeration<String> enu = request.getParameterNames();
069    
070                            while (enu.hasMoreElements()) {
071                                    String name = enu.nextElement();
072    
073                                    String value = request.getParameter(name);
074    
075                                    query = query + "&" + name + "=" + HttpUtil.encodeURL(value);
076                            }
077    
078                            if (_log.isDebugEnabled()) {
079                                    _log.debug("Sending response to PayPal " + query);
080                            }
081    
082                            URL url = new URL("https://www.paypal.com/cgi-bin/webscr");
083    
084                            URLConnection urlc = url.openConnection();
085    
086                            urlc.setDoOutput(true);
087                            urlc.setRequestProperty(
088                                    "Content-Type","application/x-www-form-urlencoded");
089    
090                            PrintWriter pw = UnsyncPrintWriterPool.borrow(
091                                    urlc.getOutputStream());
092    
093                            pw.println(query);
094    
095                            pw.close();
096    
097                            UnsyncBufferedReader unsyncBufferedReader =
098                                    new UnsyncBufferedReader(
099                                            new InputStreamReader(urlc.getInputStream()));
100    
101                            String payPalStatus = unsyncBufferedReader.readLine();
102    
103                            unsyncBufferedReader.close();
104    
105                            String itemName = ParamUtil.getString(request, "item_name");
106                            String itemNumber = ParamUtil.getString(request, "item_number");
107                            invoice = ParamUtil.getString(request, "invoice");
108                            String txnId = ParamUtil.getString(request, "txn_id");
109                            String paymentStatus = ParamUtil.getString(
110                                    request, "payment_status");
111                            double paymentGross = ParamUtil.getDouble(request, "mc_gross");
112                            String receiverEmail = ParamUtil.getString(
113                                    request, "receiver_email");
114                            String payerEmail = ParamUtil.getString(request, "payer_email");
115    
116                            if (_log.isDebugEnabled()) {
117                                    _log.debug("Receiving response from PayPal");
118                                    _log.debug("Item name " + itemName);
119                                    _log.debug("Item number " + itemNumber);
120                                    _log.debug("Invoice " + invoice);
121                                    _log.debug("Transaction ID " + txnId);
122                                    _log.debug("Payment status " + paymentStatus);
123                                    _log.debug("Payment gross " + paymentGross);
124                                    _log.debug("Receiver email " + receiverEmail);
125                                    _log.debug("Payer email " + payerEmail);
126                            }
127    
128                            if (payPalStatus.equals("VERIFIED") && validate(request)) {
129                                    ServiceContext serviceContext =
130                                            ServiceContextFactory.getInstance(request);
131    
132                                    ShoppingOrderLocalServiceUtil.completeOrder(
133                                            invoice, txnId, paymentStatus, paymentGross, receiverEmail,
134                                            payerEmail, true, serviceContext);
135                            }
136                            else if (payPalStatus.equals("INVALID")) {
137                            }
138    
139                            return null;
140                    }
141                    catch (Exception e) {
142                            PortalUtil.sendError(e, request, response);
143    
144                            return null;
145                    }
146            }
147    
148            protected boolean validate(HttpServletRequest request) throws Exception {
149    
150                    // Invoice
151    
152                    String ppInvoice = ParamUtil.getString(request, "invoice");
153    
154                    ShoppingOrder order = ShoppingOrderLocalServiceUtil.getOrder(ppInvoice);
155    
156                    ShoppingPreferences shoppingPrefs = ShoppingPreferences.getInstance(
157                            order.getCompanyId(), order.getGroupId());
158    
159                    // Receiver email address
160    
161                    String ppReceiverEmail = ParamUtil.getString(request, "receiver_email");
162    
163                    String payPalEmailAddress = shoppingPrefs.getPayPalEmailAddress();
164    
165                    if (!payPalEmailAddress.equals(ppReceiverEmail)) {
166                            return false;
167                    }
168    
169                    // Payment gross
170    
171                    double ppGross = ParamUtil.getDouble(request, "mc_gross");
172    
173                    double orderTotal = ShoppingUtil.calculateTotal(order);
174    
175                    if (orderTotal != ppGross) {
176                            return false;
177                    }
178    
179                    // Payment currency
180    
181                    String ppCurrency = ParamUtil.getString(request, "mc_currency");
182    
183                    String currencyId = shoppingPrefs.getCurrencyId();
184    
185                    if (!currencyId.equals(ppCurrency)) {
186                            return false;
187                    }
188    
189                    // Transaction ID
190    
191                    String ppTxnId = ParamUtil.getString(request, "txn_id");
192    
193                    try {
194                            ShoppingOrderLocalServiceUtil.getPayPalTxnIdOrder(ppTxnId);
195    
196                            return false;
197                    }
198                    catch (NoSuchOrderException nsoe) {
199                    }
200    
201                    return true;
202            }
203    
204            private static Log _log = LogFactoryUtil.getLog(
205                    PayPalNotificationAction.class);
206    
207    }