--- paypal_payment-pps_HTTP_404_on_return_uri-2052361-33.patch 2014-06-03 16:39:29.000000000 +0200 +++ paypal_payment-pps_HTTP_404_on_return_uri-2052361-36.patch 2014-06-06 16:05:27.704209704 +0200 @@ -1,5 +1,42 @@ +diff --git a/paypal_payment_ipn/includes/PayPalPaymentIPNController.inc b/paypal_payment_ipn/includes/PayPalPaymentIPNController.inc +index 7eac9a8..96ee687 100644 +--- a/paypal_payment_ipn/includes/PayPalPaymentIPNController.inc ++++ b/paypal_payment_ipn/includes/PayPalPaymentIPNController.inc +@@ -139,20 +139,18 @@ abstract class PayPalPaymentIPNController { + if (isset($ipn_variables['txn_id'])) { + // Make sure this IPN was not processed before. + $ipn = PayPalPaymentIPNController::load($ipn_variables['txn_id']); +- if (!$ipn) { +- // Check if the IPN matches a Payment. +- if (isset($ipn_variables['invoice'])) { +- $pid = self::PID($ipn_variables['invoice']); +- if ($pid) { +- $payment = entity_load_single('payment', $pid); +- if ($payment) { +- // Allow payment method controllers to completely take over validation. +- if ($payment->method->controller instanceof PayPalPaymentIPNPaymentMethodControllerInterface) { +- return $payment->method->controller->PayPalValidateIPNVariables($payment, $ipn_variables); +- } +- else { +- return TRUE; +- } ++ // Check if the IPN matches a Payment. ++ if (isset($ipn_variables['invoice'])) { ++ $pid = self::PID($ipn_variables['invoice']); ++ if ($pid) { ++ $payment = entity_load_single('payment', $pid); ++ if ($payment) { ++ // Allow payment method controllers to completely take over validation. ++ if ($payment->method->controller instanceof PayPalPaymentIPNPaymentMethodControllerInterface) { ++ return $payment->method->controller->PayPalValidateIPNVariables($payment, $ipn_variables); ++ } ++ else { ++ return TRUE; + } + } + } diff --git a/paypal_payment_ipn/paypal_payment_ipn.module b/paypal_payment_ipn/paypal_payment_ipn.module -index e2f6a0c..aad1374 100644 +index e2f6a0c..7417b9e 100644 --- a/paypal_payment_ipn/paypal_payment_ipn.module +++ b/paypal_payment_ipn/paypal_payment_ipn.module @@ -26,16 +26,38 @@ function paypal_payment_ipn_menu() { @@ -30,11 +67,11 @@ + if (PayPalPaymentIPNController::load($ipn_variables['txn_id'])) { + // The transaction record has already been created and processed. + return; - } ++ } + $ipn = new PayPalPaymentIPN($ipn_variables); + PayPalPaymentIPNController::save($ipn); + PayPalPaymentIPNController::process($ipn_variables); - } ++} + +/** + * Decode incoming IPN data. @@ -46,18 +83,19 @@ + $ipn_variables = array(); + foreach ($post_data as $key => $value) { + $ipn_variables[$key] = rawurldecode($value); -+ } + } + return $ipn_variables; -+} -\ No newline at end of file + } diff --git a/paypal_payment_ipn_test/paypal_payment_ipn_test.module b/paypal_payment_ipn_test/paypal_payment_ipn_test.module -index 5ea6ee4..04a5a97 100644 +index 5ea6ee4..731a7a0 100644 --- a/paypal_payment_ipn_test/paypal_payment_ipn_test.module +++ b/paypal_payment_ipn_test/paypal_payment_ipn_test.module @@ -60,4 +60,13 @@ function paypal_payment_ipn_test_paypal_server() { print 'INVALID'; } drupal_exit(); +-} +\ No newline at end of file +} + +/** @@ -67,8 +105,7 @@ + */ +function paypal_payment_ipn_test_finish_callback(Payment $payment) { + $payment->payment_test_finish_callback = TRUE; - } -\ No newline at end of file ++} diff --git a/paypal_payment_pps/paypal_payment_pps.info b/paypal_payment_pps/paypal_payment_pps.info index e8aa8f9..0ea3dd8 100644 --- a/paypal_payment_pps/paypal_payment_pps.info @@ -82,7 +119,7 @@ files[] = tests/PayPalPaymentPPSPaymentMethodUI.test files[] = tests/PayPalPaymentWebTestCase.test diff --git a/paypal_payment_pps/paypal_payment_pps.module b/paypal_payment_pps/paypal_payment_pps.module -index 9b659bc..c15240a 100644 +index 9b659bc..508e49d 100644 --- a/paypal_payment_pps/paypal_payment_pps.module +++ b/paypal_payment_pps/paypal_payment_pps.module @@ -251,10 +251,12 @@ function paypal_payment_pps_form_redirect_access(Payment $payment, $account = NU @@ -97,7 +134,7 @@ + $ipn_variables = paypal_payment_ipn_get_decoded_data($_POST); + // Make sure that ipn data is handled. Normally this is already done when IPN + // calls back in using PAYPAL_IPN_LISTENER_PATH -+ paypal_payment_ipn_process($ipn_variables); ++ paypal_payment_ipn_process_data($ipn_variables); + // Now load the payment and perform finishing steps. $payment = entity_load_single('payment', PayPalPaymentIPNController::PID($ipn_variables['invoice'])); $payment->finish(); @@ -119,9 +156,8 @@ /** diff --git a/paypal_payment_pps/tests/PayPalPaymentPPSPaymentIPNExecution.test b/paypal_payment_pps/tests/PayPalPaymentPPSPaymentIPNExecution.test -new file mode 100644 -index 0000000..66ecd5c ---- /dev/null +index e69de29..306b229 100644 +--- a/paypal_payment_pps/tests/PayPalPaymentPPSPaymentIPNExecution.test +++ b/paypal_payment_pps/tests/PayPalPaymentPPSPaymentIPNExecution.test @@ -0,0 +1,111 @@ +drupalCreateUser(); -+ ++ + $method_controller = payment_method_controller_load('PayPalPaymentPPSPaymentMethodController'); + $payment_method = $this->paymentMethodCreate($account->uid, $method_controller); + entity_save('payment_method', $payment_method); -+ ++ + $payment = $this->paymentCreate($account->uid, $payment_method); + entity_save('payment', $payment); -+ ++ + // must access the created payment entity, and access the real PID + // call the PAYPAL_IPN_LISTENER_PATH, see that ipn record exists + $ipn_variables = $this->mockIPNVariables($payment->pid, TRUE); + $ipn_variables['business'] = $payment->method->controller_data['email_address']; -+ ++ + $url = PayPalPaymentIPNController::URL(); + + $this->curlExec(array( @@ -178,18 +213,21 @@ + CURLOPT_URL => $url, + )); + $response = $this->drupalGetContent(); -+ ++ + $this->assertFalse($response); -+ $this->verbose($response); + $this->assertResponse(200); -+ ++ + // test that an IPN has been saved + $this->assertTrue(PayPalPaymentIPNController::load($ipn_variables['txn_id'])); -+ ++ + // login the user, other whise access control in + // paypal_payment_pps_return_access() fails + $this->drupalLogin($account); -+ ++ ++ // Will paypal_payment_pps_return_access() grant us access? ++ $this->assertTrue(PayPalPaymentIPNController::validate($ipn_variables)); ++ $this->assertTrue(PayPalPaymentIPNController::PID($ipn_variables['invoice'])); ++ + // call the return url in paypal_payment_pps.module and see that it + // succeeds, this mimiks click on "Return to Shop-Page" in paypal + $this->curlExec(array( @@ -198,14 +236,12 @@ + CURLOPT_URL => url('paypal_payment_pps/return', array('absolute' => TRUE)), + )); + $response = $this->drupalGetContent(); -+ ++ + $this->assertFalse($response); -+ $this->verbose($response); + $this->assertResponse(200); + // $this->assertURL(''); -+ + } -+ ++ + /** + * Create, save, and return a Payment. + * @@ -221,7 +257,7 @@ + $payment = new Payment(array( + 'currency_code' => 'XXX', + 'description' => 'This is the payment description', -+ 'finish_callback' => 'paypal_pament_ipn_test_finish_callback', ++ 'finish_callback' => 'paypal_payment_ipn_test_finish_callback', + 'method' => $payment_method, + 'uid' => $uid, + ));