diff --git a/paypal_payment_ipn_test/paypal_payment_ipn_test.module b/paypal_payment_ipn_test/paypal_payment_ipn_test.module
index 5ea6ee4..b5bb659 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();
+}
+
+/**
+ * Dummy finish callback for paypal_payments
+ *
+ * @param Payment $payment 
+ */
+function paypal_pament_ipn_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
+++ b/paypal_payment_pps/paypal_payment_pps.info
@@ -7,6 +7,7 @@ core = 7.x
 PHP = 5.3
 files[] = includes/PayPalPaymentPPSPaymentMethodController.inc
 files[] = tests/PayPalPaymentPPSPaymentExecution.test
+files[] = tests/PayPalPaymentPPSPaymentIPNExecution.test
 files[] = tests/PayPalPaymentPPSPaymentMethodCRUD.test
 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 3fc9f48..f39f5c2 100644
--- a/paypal_payment_pps/paypal_payment_pps.module
+++ b/paypal_payment_pps/paypal_payment_pps.module
@@ -256,9 +256,11 @@ function paypal_payment_pps_form_redirect_access(Payment $payment, $account = NU
  */
 function paypal_payment_pps_return() {
   $ipn_variables = $_POST;
-  $ipn = new PayPalPaymentIPN($ipn_variables);
-  PayPalPaymentIPNController::save($ipn);
-  PayPalPaymentIPNController::process($ipn_variables);
+  if (PayPalPaymentIPNController::validate($_POST)) {
+    $ipn = new PayPalPaymentIPN($ipn_variables);
+    PayPalPaymentIPNController::save($ipn);
+    PayPalPaymentIPNController::process($ipn_variables);
+  }
   $payment = entity_load_single('payment', PayPalPaymentIPNController::PID($ipn_variables['invoice']));
   $payment->finish();
 }
@@ -269,7 +271,17 @@ function paypal_payment_pps_return() {
  * @return bool
  */
 function paypal_payment_pps_return_access() {
-  return PayPalPaymentIPNController::validate($_POST);
+  global $user;
+  $ipn_variables = $_POST;
+  if (!isset($ipn_variables['invoice'])) {
+    return FALSE;
+  }
+  $pid = PayPalPaymentIPNController::PID($ipn_variables['invoice']);
+  if (!$pid) {
+    return FALSE;
+  }
+  $payment = entity_load_single('payment', $pid);
+  return $payment->uid == $user->uid;
 }
 
 /**
diff --git a/paypal_payment_pps/tests/PayPalPaymentPPSPaymentIPNExecution.test b/paypal_payment_pps/tests/PayPalPaymentPPSPaymentIPNExecution.test
new file mode 100644
index 0000000..a140ff7
--- /dev/null
+++ b/paypal_payment_pps/tests/PayPalPaymentPPSPaymentIPNExecution.test
@@ -0,0 +1,111 @@
+<?php
+
+/**
+ * @file
+ * Contains class PayPalPaymentPPSPaymentIPNExecution.
+ */
+
+/**
+ * Tests payment execution.
+ */
+class PayPalPaymentPPSPaymentIPNExecution extends PayPalPaymentIPNWebTestCase {
+
+  static function getInfo() {
+    return array(
+      'name' => 'Payment execution with IPN',
+      'group' => 'PayPal Payments Standard',
+      'description' => 'Test paypal standard payment with IPN listener',
+      // do not add paypal_payment_pps_test because then there are url
+      // rewriting confilicts with the paypal_payment_ipn_test module
+      'dependencies' => array('paypal_payment_pps', 'paypal_payment_ipn_test'),
+    );
+  }
+
+  function setUp(array $modules = array()) {
+    parent::setUp(array_merge($modules, array('paypal_payment_pps', 'paypal_payment_ipn_test')));
+  }
+
+  /**
+   * Tests payment execution.
+   */
+  function testPaymentIPNExecution() {
+    
+    $account = $this->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(
+      CURLOPT_POST => TRUE,
+      CURLOPT_POSTFIELDS => $ipn_variables,
+      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);
+    
+    // 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(
+      CURLOPT_POST => TRUE,
+      CURLOPT_POSTFIELDS => $ipn_variables,
+      CURLOPT_URL => url('paypal_payment_pps/return', array('absolute' => TRUE)),
+    ));
+    $response = $this->drupalGetContent();
+    
+    $this->assertFalse($response);
+    $this->verbose($response);
+    $this->assertResponse(200);
+    // $this->assertURL('<front>');
+    
+  }
+  
+  /**
+   * Create, save, and return a Payment.
+   *
+   * @param integer $uid
+   *   The user ID of the payment's owner.
+   * @param PaymentMethod $payment_method
+   *   An optional payment method to set. Defaults to PaymentMethodUnavailable.
+   *
+   * @return Payment
+   */
+  static function paymentCreate($uid, PaymentMethod $payment_method = NULL) {
+    $payment_method = $payment_method ? $payment_method : new PaymentMethodUnavailable;
+    $payment = new Payment(array(
+      'currency_code' => 'XXX',
+      'description' => 'This is the payment description',
+      'finish_callback' => 'paypal_pament_ipn_finish_callback',
+      'method' => $payment_method,
+      'uid' => $uid,
+    ));
+    $payment->setLineItem(new PaymentLineItem(array(
+      'name' => 'foo',
+      'amount' => 1.0,
+      'tax_rate' => 0.1,
+    )));
+
+    return $payment;
+  }
+  
+}
\ No newline at end of file
