Clean up PaypalCallbackAction
authorMarcel Werk <burntime@woltlab.com>
Tue, 26 Oct 2021 16:52:04 +0000 (18:52 +0200)
committerMarcel Werk <burntime@woltlab.com>
Tue, 26 Oct 2021 16:52:04 +0000 (18:52 +0200)
Closes #4351

wcfsetup/install/files/lib/action/PaypalCallbackAction.class.php

index 6a09dce837dea4d0f84dc4903d11a05138a1b45a..3d32d561778bcb730148240e88c33d7fe5b47ff8 100644 (file)
@@ -2,19 +2,23 @@
 
 namespace wcf\action;
 
+use GuzzleHttp\Psr7\Request;
+use Laminas\Diactoros\Response\EmptyResponse;
+use Psr\Http\Client\ClientExceptionInterface;
 use wcf\data\object\type\ObjectTypeCache;
 use wcf\system\exception\SystemException;
+use wcf\system\io\HttpFactory;
 use wcf\system\payment\type\IPaymentType;
-use wcf\util\HTTPRequest;
 use wcf\util\StringUtil;
 
 /**
  * Handles Paypal callbacks.
  *
  * @author  Marcel Werk
- * @copyright   2001-2019 WoltLab GmbH
+ * @copyright   2001-2021 WoltLab GmbH
  * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
  * @package WoltLabSuite\Core\Action
+ * @see https://developer.paypal.com/docs/api-basics/notifications/ipn/IPNImplementation/
  */
 class PaypalCallbackAction extends AbstractAction
 {
@@ -38,20 +42,25 @@ class PaypalCallbackAction extends AbstractAction
                     $url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
                 }
 
-                $request = new HTTPRequest($url, [], \array_merge(['cmd' => '_notify-validate'], $_POST));
-                $request->execute();
-                $reply = $request->getReply();
-                $content = $reply['body'];
-            } catch (SystemException $e) {
-                @\header('HTTP/1.1 500 Internal Server Error');
+                $request = new Request('POST', $url, [
+                    'form_params' => \array_merge(['cmd' => '_notify-validate'], $_POST),
+                ]);
+                $client = HttpFactory::getDefaultClient();
+                $response = $client->send($request);
+                $content = (string)$response->getBody();
+            } catch (ClientExceptionInterface $e) {
                 throw new SystemException('connection to paypal.com failed: ' . $e->getMessage());
             }
 
             if (\strpos($content, "VERIFIED") === false) {
-                @\header('HTTP/1.1 500 Internal Server Error');
                 throw new SystemException('request not validated');
             }
+        } catch (SystemException $e) {
+            \wcf\functions\exception\logThrowable($e);
+            return new EmptyResponse(500);
+        }
 
+        try {
             // fix encoding
             if (!empty($_POST['charset']) && \strtoupper($_POST['charset']) != 'UTF-8') {
                 foreach ($_POST as &$value) {
@@ -119,10 +128,11 @@ class PaypalCallbackAction extends AbstractAction
 
             $this->executed();
         } catch (SystemException $e) {
-            echo $e->getMessage();
-            $e->getExceptionID(); // log error
-
-            exit;
+            \wcf\functions\exception\logThrowable($e);
         }
+
+        // Request was either successful or failed due to an error that cannot be fixed by
+        // resending the notification. Status code 200 marks the notification as completed for PayPal.
+        return new EmptyResponse(200);
     }
 }