Jump to content


Corporate Sponsors


Latest News: (loading..)

* * * * * 3 votes

Official PayPal IPN Support Thread


4127 replies to this topic

#4021 eww

  • Community Member
  • 2,461 posts
  • Real Name:eww
  • Gender:Not Telling

Posted 18 October 2009, 05:20

got another hit from the same ip today.
i'm almost tempted to block it. it obviously isn't doing anything useful other than testing my ipn.

does anyone know if paypal uses this ip for anything LEGITIMATE related to ipn?

#4022 valerif

  • Community Sponsor
  • 199 posts
  • Real Name:valeri

Posted 20 October 2009, 15:54

View Postsucklebuster, on 17 October 2009, 02:54, said:

I received 2 emails this week with this:



Subject: PayPal IPN Invalid Process


$HTTP_POST_VARS:

test=test

$HTTP_GET_VARS:
receivbed same too

#4023 valerif

  • Community Sponsor
  • 199 posts
  • Real Name:valeri

Posted 20 October 2009, 15:54

View Postsucklebuster, on 17 October 2009, 02:54, said:

I received 2 emails this week with this:



Subject: PayPal IPN Invalid Process


$HTTP_POST_VARS:

test=test

$HTTP_GET_VARS:
received same too

#4024 alsim-fr

  • Community Member
  • 4 posts
  • Real Name:SIMEON

Posted 23 October 2009, 16:54

Hi,

First, thank you for the great contribution.

I just have one question. The email confirmation is only in one language (for me, in french).

I see include(DIR_WS_LANGUAGES . $language . '/' . FILENAME_CHECKOUT_PROCESS); but it seems it consider ever $language = "french" .... why ?

Thank you for your help

#4025 pixclinic

  • Community Member
  • 696 posts
  • Real Name:PIXCLINIC
  • Gender:Male
  • Location:Seattle

Posted 23 October 2009, 16:59

View Postsucklebuster, on 17 October 2009, 02:54, said:

I received 2 emails this week with this:



Subject: PayPal IPN Invalid Process


$HTTP_POST_VARS:

test=test

$HTTP_GET_VARS:

After a phone call to Paypal, an alleged senior IT person told me that there was an known issue with IPN lately but that it had been fixed. Obvioulsly not :-)
It doesn't seem to affect our PayPal orders though. We received a couple of these in the last week, that's it.

#4026 bdepp

  • Community Member
  • 10 posts
  • Real Name:Bryce Deppeler

Posted 16 November 2009, 14:59

I have been struggling with this for hours now... It seems that every time I think I have found a fix (after perusing thousands of messages!), it doesn't work.

Ok, the problem is this: when I return from paypal after confirming the order, my shopping cart still shows the order. This is making people think that there order hasn't gone through, and the item is "Out of Stock" now.

However, The order is properly processed (inv reduced, email sent, IPN results ok) - but the cart is not emptied. And yes, I do return to my cart from paypal, so that is not it...

As for other problems I have encountered, we are also NOT getting the discount applied (paypal_IPN sends amount before discount, even though it shows the discount applied in checkout_confirmation.php page). I'm sure that these problems are probably related.

So, to sum up: how do I get the shopping cart to empty after a successful purchase?

Bryce

#4027 vinz3056

  • Community Member
  • 2 posts
  • Real Name:Vinz

Posted 23 November 2009, 17:36

Hi,

I've got somme pb, my order come back with the status 'PayPal IPN Invalid [Completed]'

I followed the checks to be made, but nothing.

I'm under PHP Version 4.4.3-dev - libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1 - osCommerce Online Merchant v2.2 RC1 W3C Valid FR - PayPal IPN v2.3.4.6


Thanks for your help !

#4028 Arctic Fox

  • Community Member
  • 89 posts
  • Real Name:Арктическая Зимняя Лиса
  • Gender:Not Telling

Posted 07 December 2009, 01:04

I just want to know if there is a Full Version with all the bug fixes.

I've already opened a few files with nothing in them. I don't read Dutch.

#4029 Denkster

  • Community Member
  • 64 posts
  • Real Name:Eveline Bernard

Posted 07 December 2009, 04:25

Hi,

After a lot of study, I succeeded in getting Paypal_IPN working.
I discovered errors in the file /catalog/paypal_ipn.php that was added august 2009 to contribution number 2679.

Below is the whole file in the form which I use.
Please read my release notes in the file header.

I also made the language files for Dutch, ask me if you want them.


The original (English) Install instructions are not included in most of the packages; I found them in the package "PayPal IPN Module 2.3.4.7" of 4 Mar 2009.
Later versions include only a small text in German.

Eveline

<?php
/*
	$Id: paypal_ipn.php,v 1.1.2.2 2005/08/04 06:05:08 Michael Sasek Exp $
	
	osCMax Power E-Commerce
	http://oscdox.com
	
	Copyright  2004 osCommerce
	
	Released under the GNU General Public License
	20091207 Denkster. 	Removed double code, added comment and code formatting; 
						Replaced hard coded German texts by variable names in email texts;  
						Corrected unknown variable in definition for $products_ordered .= ; Changed $currencies->display_price2() to $currencies->display_price()
						Note: general.php is supposed to have the function tep_decode_specialchars()
*/

class paypal_ipn {
var $code, $title, $description, $enabled, $identifier;

  // class constructor
  function paypal_ipn() {
	global $order;
	
	$this->code = 'paypal_ipn';
	$this->title = MODULE_PAYMENT_PAYPAL_IPN_TEXT_TITLE;
	$this->description = MODULE_PAYMENT_PAYPAL_IPN_TEXT_DESCRIPTION;
	$this->sort_order = MODULE_PAYMENT_PAYPAL_IPN_SORT_ORDER;
	$this->enabled = ((MODULE_PAYMENT_PAYPAL_IPN_STATUS == 'True') ? true : false);
	$this->identifier = 'osCommerce PayPal IPN v1.0';
	
	if ((int)MODULE_PAYMENT_PAYPAL_IPN_PREPARE_ORDER_STATUS_ID > 0) {
		$this->order_status = MODULE_PAYMENT_PAYPAL_IPN_PREPARE_ORDER_STATUS_ID;
	}
	
	if (is_object($order)) $this->update_status();
	$this->email_footer = MODULE_PAYMENT_PAYPAL_TEXT_EMAIL_FOOTER;

	if (MODULE_PAYMENT_PAYPAL_IPN_GATEWAY_SERVER == 'Live') {
		$this->form_action_url = 'https://www.paypal.com/cgi-bin/webscr';
	} else {
		$this->form_action_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr';
	}	//end if (is_object
  }	//end function paypal_ipn()


  // class methods
  function update_status() {
	global $order;
	
	if ( ($this->enabled == true) && ((int)MODULE_PAYMENT_PAYPAL_IPN_ZONE > 0) ) {
		$check_flag = false;
		$check_query = tep_db_query("select zone_id from " . TABLE_ZONES_TO_GEO_ZONES . " where geo_zone_id = '" . MODULE_PAYMENT_PAYPAL_IPN_ZONE . "' and zone_country_id = '" . $order->billing['country']['id'] . "' order by zone_id");
		while ($check = tep_db_fetch_array($check_query)) {
			if ($check['zone_id'] < 1) {
				$check_flag = true;
				break;
			} elseif ($check['zone_id'] == $order->billing['zone_id']) {
				$check_flag = true;
				break;
				}
			}
	
			if ($check_flag == false) {
				$this->enabled = false;
			}
		}	//end while
	}	//end if ( ($this->enabled

	function javascript_validation() {
		return false;
	}

	/*function selection() {
	return array('id' => $this->code,
	'module' => $this->title);
	}*/
	function selection() {
	  global $cart_PayPal_Standard_ID;

      if (tep_session_is_registered('cart_PayPal_Standard_ID')) {
        $order_id = substr($cart_PayPal_Standard_ID, strpos($cart_PayPal_Standard_ID, '-')+1);

        $check_query = tep_db_query('select orders_id from ' . TABLE_ORDERS_STATUS_HISTORY . ' where orders_id = "' . (int)$order_id . '" limit 1');

        if (tep_db_num_rows($check_query) < 1) {
          tep_db_query('delete from ' . TABLE_ORDERS . ' where orders_id = "' . (int)$order_id . '"');
          tep_db_query('delete from ' . TABLE_ORDERS_TOTAL . ' where orders_id = "' . (int)$order_id . '"');
          tep_db_query('delete from ' . TABLE_ORDERS_STATUS_HISTORY . ' where orders_id = "' . (int)$order_id . '"');
          tep_db_query('delete from ' . TABLE_ORDERS_PRODUCTS . ' where orders_id = "' . (int)$order_id . '"');
          tep_db_query('delete from ' . TABLE_ORDERS_PRODUCTS_ATTRIBUTES . ' where orders_id = "' . (int)$order_id . '"');
          tep_db_query('delete from ' . TABLE_ORDERS_PRODUCTS_DOWNLOAD . ' where orders_id = "' . (int)$order_id . '"');

          tep_session_unregister('cart_PayPal_Standard_ID');
        }
      }
      return array('id' => $this->code,
                   'module' => $this->title);
  	}	//end function selection()



	  /*function pre_confirmation_check() {
	  return false;
	  }*/
	  function pre_confirmation_check() {
		  global $cartID, $cart;
	
		  if (empty($cart->cartID)) {
			$cartID = $cart->cartID = $cart->generate_cart_id();
		  }
	
		  if (!tep_session_is_registered('cartID')) {
			tep_session_register('cartID');
		  }
	  }	//end function pre_confirmation_check()



function confirmation() {
  global $cartID, $cart_PayPal_Standard_ID, $customer_id, $languages_id, $order, $order_total_modules;

  //if (tep_session_is_registered('cartID')) {
  if (array_key_exists('cartID', $_SESSION)) {
  	$insert_order = false;

  	if (tep_session_is_registered('cart_PayPal_Standard_ID')) {
      $order_id = substr($cart_PayPal_Standard_ID, strpos($cart_PayPal_Standard_ID, '-')+1);
          
	  $curr_check = tep_db_query("select currency from " . TABLE_ORDERS . " where orders_id = '" . (int)$order_id . "'");
	  $curr = tep_db_fetch_array($curr_check);

	  if ( ($curr['currency'] != $order->info['currency']) || ($cartID != substr($cart_PayPal_Standard_ID, 0, strlen($cartID))) ) {
		$check_query = tep_db_query('select orders_id from ' . TABLE_ORDERS_STATUS_HISTORY . ' where orders_id = "' . (int)$order_id . '" limit 1');
		
		if (tep_db_num_rows($check_query) < 1) {
			tep_db_query('delete from ' . TABLE_ORDERS . ' where orders_id = "' . (int)$order_id . '"');
			tep_db_query('delete from ' . TABLE_ORDERS_TOTAL . ' where orders_id = "' . (int)$order_id . '"');
			tep_db_query('delete from ' . TABLE_ORDERS_STATUS_HISTORY . ' where orders_id = "' . (int)$order_id . '"');
			tep_db_query('delete from ' . TABLE_ORDERS_PRODUCTS . ' where orders_id = "' . (int)$order_id . '"');
			tep_db_query('delete from ' . TABLE_ORDERS_PRODUCTS_ATTRIBUTES . ' where orders_id = "' . (int)$order_id . '"');
			tep_db_query('delete from ' . TABLE_ORDERS_PRODUCTS_DOWNLOAD . ' where orders_id = "' . (int)$order_id . '"');
		}	//end if (tep_db_num_rows
	
		$insert_order = true;
	  }	//end if ( ($curr
  	} else {
	  $insert_order = true;
  	}	//end if tep_session_is_registered

	if ($insert_order == true) {
	  $order_totals = array();
	  if (is_array($order_total_modules->modules)) {
		reset($order_total_modules->modules);
		while (list(, $value) = each($order_total_modules->modules)) {
			$class = substr($value, 0, strrpos($value, '.'));
			if ($GLOBALS[$class]->enabled) {
				for ($i=0, $n=sizeof($GLOBALS[$class]->output); $i<$n; $i++) {
				  if (tep_not_null($GLOBALS[$class]->output[$i]['title']) && tep_not_null($GLOBALS[$class]->output[$i]['text'])) {
					$order_totals[] = array('code' => $GLOBALS[$class]->code,
								'title' => $GLOBALS[$class]->output[$i]['title'],
								'text' => $GLOBALS[$class]->output[$i]['text'],
								'value' => $GLOBALS[$class]->output[$i]['value'],
								'sort_order' => $GLOBALS[$class]->sort_order);
				  }	//end if tep_not_null
				}	//end for
			}	//end if class enabled
		}	//end while
	  }	//end if is array
// Vor CAO
	  $sql_data_array = array('customers_id' => $customer_id,
		'customers_name' => $order->customer['firstname'] . ' ' . $order->customer['lastname'],
		'customers_company' => $order->customer['company'],
		'customers_street_address' => $order->customer['street_address'],
		'customers_suburb' => $order->customer['suburb'],
		'customers_city' => $order->customer['city'],
		'customers_postcode' => $order->customer['postcode'],
		'customers_state' => $order->customer['state'],
		'customers_country' => $order->customer['country']['title'],
		'customers_telephone' => $order->customer['telephone'],
		'customers_email_address' => $order->customer['email_address'],
		'customers_address_format_id' => $order->customer['format_id'],
		'delivery_name' => $order->delivery['firstname'] . ' ' . $order->delivery['lastname'],
		'delivery_company' => $order->delivery['company'],
		'delivery_street_address' => $order->delivery['street_address'],
		'delivery_suburb' => $order->delivery['suburb'],
		'delivery_city' => $order->delivery['city'],
		'delivery_postcode' => $order->delivery['postcode'],
		'delivery_state' => $order->delivery['state'],
		'delivery_country' => $order->delivery['country']['title'],
		'delivery_address_format_id' => $order->delivery['format_id'],
		'billing_name' => $order->billing['firstname'] . ' ' . $order->billing['lastname'],
		'billing_company' => $order->billing['company'],
		'billing_street_address' => $order->billing['street_address'],
		'billing_suburb' => $order->billing['suburb'],
		'billing_city' => $order->billing['city'],
		'billing_postcode' => $order->billing['postcode'],
		'billing_state' => $order->billing['state'],
		'billing_country' => $order->billing['country']['title'],
		'billing_address_format_id' => $order->billing['format_id'],
		'payment_method' => $order->info['payment_method'],
		'cc_type' => $order->info['cc_type'],
		'cc_owner' => $order->info['cc_owner'],
		'cc_number' => $order->info['cc_number'],
		'cc_expires' => $order->info['cc_expires'],
		'date_purchased' => 'now()',
		'orders_status' => $order->info['order_status'],
		'currency' => $order->info['currency'],
		'currency_value' => $order->info['currency_value']);
	
	  tep_db_perform(TABLE_ORDERS, $sql_data_array);
	
	  $insert_id = tep_db_insert_id();
	
	  for ($i=0, $n=sizeof($order_totals); $i<$n; $i++) {
		$sql_data_array = array('orders_id' => $insert_id,
			'title' => $order_totals[$i]['title'],
			'text' => $order_totals[$i]['text'],
			'value' => $order_totals[$i]['value'],
			'class' => $order_totals[$i]['code'],
			'sort_order' => $order_totals[$i]['sort_order']);
		
		tep_db_perform(TABLE_ORDERS_TOTAL, $sql_data_array);
	  }
	
	  for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {
		$sql_data_array = array('orders_id' => $insert_id,
			'products_id' => tep_get_prid($order->products[$i]['id']),
			'products_model' => $order->products[$i]['model'],
			'products_name' => $order->products[$i]['name'],
			'products_price' => $order->products[$i]['price'],
			'final_price' => $order->products[$i]['final_price'],
			'products_tax' => $order->products[$i]['tax'],
			'products_quantity' => $order->products[$i]['qty']);
		
		tep_db_perform(TABLE_ORDERS_PRODUCTS, $sql_data_array);
		
		$order_products_id = tep_db_insert_id();
	
//------insert customer choosen option to order--------
        $attributes_exist = '0';
        if (isset($order->products[$i]['attributes'])) {
              $attributes_exist = '1';
              for ($j=0, $n2=sizeof($order->products[$i]['attributes']); $j<$n2; $j++) {
                if (DOWNLOAD_ENABLED == 'true') {
                  $attributes_query = "select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix, pad.products_attributes_maxdays, pad.products_attributes_maxcount , pad.products_attributes_filename
                                       from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa
                                       left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
                                       on pa.products_attributes_id=pad.products_attributes_id
                                       where pa.products_id = '" . $order->products[$i]['id'] . "'
                                       and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "'
                                       and pa.options_id = popt.products_options_id
                                       and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "'
                                       and pa.options_values_id = poval.products_options_values_id
                                       and popt.language_id = '" . $languages_id . "'
                                       and poval.language_id = '" . $languages_id . "'";
                  $attributes = tep_db_query($attributes_query);
                } else {
                  $attributes = tep_db_query("select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa where pa.products_id = '" . $order->products[$i]['id'] . "' and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' and pa.options_id = popt.products_options_id and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' and pa.options_values_id = poval.products_options_values_id and popt.language_id = '" . $languages_id . "' and poval.language_id = '" . $languages_id . "'");
                }
                $attributes_values = tep_db_fetch_array($attributes);

                $sql_data_array = array('orders_id' => $insert_id,
                                        'orders_products_id' => $order_products_id,
                                        'products_options' => $attributes_values['products_options_name'],
                                        'products_options_values' => $attributes_values['products_options_values_name'],
                                        'options_values_price' => $attributes_values['options_values_price'],
                                        'price_prefix' => $attributes_values['price_prefix']);

                tep_db_perform(TABLE_ORDERS_PRODUCTS_ATTRIBUTES, $sql_data_array);
                if ((DOWNLOAD_ENABLED == 'true') && isset($attributes_values['products_attributes_filename']) && tep_not_null($attributes_values['products_attributes_filename'])) {
				  /* BOF replacing for super download shop
                    $sql_data_array = array('orders_id' => $insert_id,
                                          'orders_products_id' => $order_products_id,
                                          'orders_products_filename' => $attributes_values['products_attributes_filename'],
                                          'download_maxdays' => $attributes_values['products_attributes_maxdays'],
                                          'download_count' => $attributes_values['products_attributes_maxcount']);
                    tep_db_perform(TABLE_ORDERS_PRODUCTS_DOWNLOAD, $sql_data_array);
				  */
				  if (DOWNLOADS_CONTROLLER_FILEGROUP_STATUS != 'Yes' || !strstr($attributes_values['products_attributes_filename'], 'Group_Files-')) {
					$sql_data_array = array(
						'orders_id' => $insert_id, 
						'orders_products_id' => $order_products_id, 
						'orders_products_filename' => $attributes_values['products_attributes_filename'], 
						'download_maxdays' => $attributes_values['products_attributes_maxdays'], 
						'download_count' => $attributes_values['products_attributes_maxcount']);
					tep_db_perform(TABLE_ORDERS_PRODUCTS_DOWNLOAD, $sql_data_array);
				  } else {
					$filegroup_array = explode('Group_Files-', $attributes_values['products_attributes_filename']);
					$filegroup_id = $filegroup_array[1];
					$groupfiles_query = tep_db_query(
						"select download_group_filename
						from " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD_GROUPS_FILES . "
						where download_group_id = '" . (int)$filegroup_id . "'");
					while ($groupfile_array = tep_db_fetch_array($groupfiles_query)) {
					  $sql_data_array = array(
					  	'orders_id' => $insert_id, 
						'orders_products_id' => $order_products_id, 
						'orders_products_filename' => $groupfile_array['download_group_filename'], 
						'download_maxdays' => $attributes_values['products_attributes_maxdays'], 
						'download_count' => $attributes_values['products_attributes_maxcount']);
					  tep_db_perform(TABLE_ORDERS_PRODUCTS_DOWNLOAD, $sql_data_array);
					}	//end while
				  }		//end if (DOWNLOADS_CONTROLLER_FILEGROUP_STATUS
				  // EOF replace for super download shop
                }		//end if ((DOWNLOAD_ENABLED
              }			//end for attributes
             }			//end if (isset
			//------insert customer choosen option eof ----
		}	//end for products

		// FS start
          $GLOBALS['cart_PayPal_Standard_ID'] = $cartID . '-' . $insert_id;
		// FS stop          
          tep_session_register('cart_PayPal_Standard_ID');
	}	//end if ($insert_order
  }	//end if (array_key_exists

return false;
}	//end function before_process()



function process_button() {
	global $customer_id, $order, $languages_id, $currencies, $currency, $cart_PayPal_Standard_ID, $shipping;
	global $sendto;
	
	if (MODULE_PAYMENT_PAYPAL_IPN_CURRENCY == 'Selected Currency') {
		$my_currency = $currency;
	} else {
		$my_currency = substr(MODULE_PAYMENT_PAYPAL_IPN_CURRENCY, 5);
	}
	if (!in_array($my_currency, array('AUD', 'CAD', 'CHF', 'CZK', 'DKK', 'EUR', 'GBP', 'HKD', 'HUF', 'JPY', 'NOK', 'NZD', 'PLN', 'SEK', 'SGD', 'USD'))) {
			$my_currency = 'USD';
	}
	
	$parameters = array();
	
	if ( (MODULE_PAYMENT_PAYPAL_IPN_TRANSACTION_TYPE == 'Per Item') && (MODULE_PAYMENT_PAYPAL_IPN_EWP_STATUS == 'False') ) {
		$parameters['cmd'] = '_cart';
		$parameters['upload'] = '1';
		////////////
		//handling
		//Von Ihnen erhobene Bearbeitungsgebuehren. Dieser Betrag ist unabhngig von der Menge. Derselbe Betrag wird berechnet, egal wie viele Posten die Bestellung umfasst.
		//Standardwert: keine Bearbeitungsgebuehren
	
		if (MODULE_ORDER_TOTAL_PAYPAL_TAX_CLASS > 0) {
					$cod_tax = tep_get_tax_rate(MODULE_ORDER_TOTAL_PAYPAL_TAX_CLASS, $order->billing['country']['id'], $order->billing['zone_id']);
					$cod_tax_description = tep_get_tax_description(MODULE_ORDER_TOTAL_PAYPAL_TAX_CLASS, $order->billing['country']['id'], $order->billing['zone_id']);
		}
		
	
		if (MODULE_PAYMENT_PAYPAL_FIX_FEE != '0') {
			$handling_amount = MODULE_PAYMENT_PAYPAL_FIX_FEE;
			$handling = $handling_amount;
		} else {
			$handling_amount = ($order->info['subtotal'] * MODULE_PAYMENT_PAYPAL_FEE);
			$handling = round(($handling_amount - $order->info['subtotal']),2);
		}
		//
		$_handling_tax = '1.'.$cod_tax;
		$handling = ($handling * $_handling_tax);
		//
		$parameters['handling'] = $handling;  //Bearbeitungsgebhren
		
		//////////
		for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {
			$item = $i+1;
			
			$_products_tax = ('1.'.$order->products[$i]['tax']);
			$tax_value = ($_products_tax * $order->products[$i]['final_price']) - $order->products[$i]['final_price'];
			$_bruttopreis_item = $_products_tax * $order->products[$i]['final_price'];
			
			$parameters['item_name_' . $item] = ' Art.nr.: ' . $order->products[$i]['model'] .' '. $order->products[$i]['name']. 'GEB:'.$parameters['handling'];
			$parameters['amount_' . $item] = number_format($_bruttopreis_item * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency));
			// Tax not Display. It not funktion
			$parameters['quantity_' . $item] = $order->products[$i]['qty'];
			$parameters['handling'] = $handling;  //Bearbeitungsgebhren
			if ($i == 0) {
				if (DISPLAY_PRICE_WITH_TAX == 'true') {
					$shipping_cost = $order->info['shipping_cost'];
				} else {
					$module = substr($shipping['id'], 0, strpos($shipping['id'], '_'));
					$shipping_tax = tep_get_tax_rate($GLOBALS[$module]->tax_class, $order->delivery['country']['id'], $order->delivery['zone_id']);
					$shipping_cost = $order->info['shipping_cost'] + tep_calculate_tax($order->info['shipping_cost'], $shipping_tax);
				}
				$shipping_cost = $shipping_cost + $handling;
				$parameters['shipping_' . $item] = number_format($shipping_cost * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency));
			}
	
			if (isset($order->products[$i]['attributes'])) {
				for ($j=0, $n2=sizeof($order->products[$i]['attributes']); $j<$n2; $j++) {
					if (DOWNLOAD_ENABLED == 'true') {
						$attributes_query = "select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix, pad.products_attributes_maxdays, pad.products_attributes_maxcount , pad.products_attributes_filename
							from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa
							left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
							on pa.products_attributes_id=pad.products_attributes_id
							where pa.products_id = '" . $order->products[$i]['id'] . "'
							and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "'
							and pa.options_id = popt.products_options_id
							and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "'
							and pa.options_values_id = poval.products_options_values_id
							and popt.language_id = '" . $languages_id . "'
							and poval.language_id = '" . $languages_id . "'";
						$attributes = tep_db_query($attributes_query);
					} else {
						$attributes = tep_db_query("select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa where pa.products_id = '" . $order->products[$i]['id'] . "' and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' and pa.options_id = popt.products_options_id and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' and pa.options_values_id = poval.products_options_values_id and popt.language_id = '" . $languages_id . "' and poval.language_id = '" . $languages_id . "'");
					}
					$attributes_values = tep_db_fetch_array($attributes);
				
					// Unfortunately PayPal only accepts two attributes per product, so the
					// third attribute onwards will not be shown at PayPal
					$parameters['on' . $j . '_' . $item] = $attributes_values['products_options_name'];
					$parameters['os' . $j . '_' . $item] = $attributes_values['products_options_values_name'];
					
				}
			}
		}
	
		$parameters['num_cart_items'] = $item;
	} else {
		$parameters['cmd'] = '_xclick';
		$parameters['item_name'] = STORE_NAME.' Kunden-Nr.: ' . $_SESSION['customer_id'];
		$parameters['item_name'] .= '  Kundenname: '.$order->customer['firstname'] . ' ' . $order->customer['lastname'];
		// handling
		// Von Ihnen erhobene Bearbeitungsgebuehren. Dieser Betrag ist unabhaengig von der Menge. Derselbe Betrag wird berechnet, egal wie viele Posten die Bestellung umfasst.
		//Standardwert: keine Bearbeitungsgebuehren 
		if (MODULE_PAYMENT_PAYPAL_FIX_FEE != '0') {
			$handling_amount = MODULE_PAYMENT_PAYPAL_FIX_FEE;
			$handling = $handling_amount;
		} else {
			$handling_amount = ($order->info['total'] * MODULE_PAYMENT_PAYPAL_FEE);
			$handling = round(($handling_amount - $order->info['total']),2);
		}
		$parameters['handling'] = $handling;  //Bearbeitungsgebuehren
		////
		// Versand ohne Zuschlag fuer zahlweise paypal
		$parameters['shipping'] = number_format($order->info['shipping_cost'] * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency));
		//
		// Versand mit Zuschlag fuer zahlweise paypal
		if(MOVE_TAX_TO_TOTAL_AMOUNT == 'True') {
			// PandA.nl move tax to total amount
			$parameters['tax'] = 0;
		} else {
		// default
			$parameters['tax'] = number_format($order->info['tax'] * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency));
		}
	}
	
	$parameters['business'] = MODULE_PAYMENT_PAYPAL_IPN_ID;
	if(MOVE_TAX_TO_TOTAL_AMOUNT == 'True') {
		// PandA.nl move tax to total amount
		$parameters['amount'] = number_format((($order->info['total'] - $order->info['shipping_cost'] - $handling )  * $currencies->get_value($my_currency)), $currencies->get_decimal_places($my_currency));
	} else {
		// default
		$parameters['amount'] = number_format((($order->info['total'] - $order->info['shipping_cost'] - $handling - $order->info['tax']) * $currencies->get_value($my_currency)), $currencies->get_decimal_places($my_currency));
	}
	
	/////
	$parameters['currency_code'] = $my_currency;
	$parameters['invoice'] = substr($cart_PayPal_Standard_ID, strpos($cart_PayPal_Standard_ID, '-')+1);
	$parameters['custom'] = $customer_id;
	$parameters['no_shipping'] = '1';
	$parameters['no_note'] = '1';
	$parameters['handling'] = $handling;  //Bearbeitungsgebhren
	$parameters['notify_url'] = tep_href_link('ext/modules/payment/paypal_ipn/paypal_ipn.php', '', 'SSL', false, false);
	$parameters['return'] = tep_href_link(FILENAME_CHECKOUT_PROCESS, '', 'SSL');
	$parameters['cancel_return'] = tep_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL');
	$parameters['bn'] = $this->identifier;
	
	if (tep_not_null(MODULE_PAYMENT_PAYPAL_IPN_PAGE_STYLE)) {
		$parameters['page_style'] = MODULE_PAYMENT_PAYPAL_IPN_PAGE_STYLE;
	}
	
	
	//// Encryption
	if (MODULE_PAYMENT_PAYPAL_IPN_EWP_STATUS == 'True') {
		$parameters['cert_id'] = MODULE_PAYMENT_PAYPAL_IPN_EWP_CERT_ID;
		
		$random_string = rand(100000, 999999) . '-' . $customer_id . '-';
		
		$data = '';
		while (list($key, $value) = each($parameters)) {
			$data .= $key . '=' . $value . "\n";
		}
		
		$fp = fopen(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'data.txt', 'w');
		fwrite($fp, $data);
		fclose($fp);
		
		unset($data);
		
		if (function_exists('openssl_pkcs7_sign') && function_exists('openssl_pkcs7_encrypt')) {
			openssl_pkcs7_sign(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'data.txt', MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'signed.txt', file_get_contents(MODULE_PAYMENT_PAYPAL_IPN_EWP_PUBLIC_KEY), file_get_contents(MODULE_PAYMENT_PAYPAL_IPN_EWP_PRIVATE_KEY), array('From' => MODULE_PAYMENT_PAYPAL_IPN_ID), PKCS7_BINARY);
			
			unlink(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'data.txt');
			
			// remove headers from the signature
			$signed = file_get_contents(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'signed.txt');
			$signed = explode("\n\n", $signed);
			$signed = base64_decode($signed[1]);
			
			$fp = fopen(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'signed.txt', 'w');
			fwrite($fp, $signed);
			fclose($fp);
			
			unset($signed);
			
			openssl_pkcs7_encrypt(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'signed.txt', MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'encrypted.txt', file_get_contents(MODULE_PAYMENT_PAYPAL_IPN_EWP_PAYPAL_KEY), array('From' => MODULE_PAYMENT_PAYPAL_IPN_ID), PKCS7_BINARY);
			
			unlink(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'signed.txt');
			
			// remove headers from the encrypted result
			$data = file_get_contents(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'encrypted.txt');
			$data = explode("\n\n", $data);
			$data = '-----BEGIN PKCS7-----' . "\n" . $data[1] . "\n" . '-----END PKCS7-----';
			
			unlink(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'encrypted.txt');
		} else {
			exec(MODULE_PAYMENT_PAYPAL_IPN_EWP_OPENSSL . ' smime -sign -in ' . MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'data.txt -signer ' . MODULE_PAYMENT_PAYPAL_IPN_EWP_PUBLIC_KEY . ' -inkey ' . MODULE_PAYMENT_PAYPAL_IPN_EWP_PRIVATE_KEY . ' -outform der -nodetach -binary > ' . MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'signed.txt');
			unlink(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'data.txt');
			
			exec(MODULE_PAYMENT_PAYPAL_IPN_EWP_OPENSSL . ' smime -encrypt -des3 -binary -outform pem ' . MODULE_PAYMENT_PAYPAL_IPN_EWP_PAYPAL_KEY . ' < ' . MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'signed.txt > ' . MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'encrypted.txt');
			unlink(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'signed.txt');
			
			$fh = fopen(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'encrypted.txt', 'rb');
			$data = fread($fh, filesize(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'encrypted.txt'));
			fclose($fh);
			
			unlink(MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY . '/' . $random_string . 'encrypted.txt');
		}
	
		$process_button_string = tep_draw_hidden_field('cmd', '_s-xclick') .
		tep_draw_hidden_field('encrypted', $data);
		
		unset($data);
	} else {
		while (list($key, $value) = each($parameters)) {
			echo tep_draw_hidden_field($key, $value);
		}
	}
	
	return $process_button_string;
  }	//end function process_button()




 function before_process() {
  global $customer_id, $order, $order_totals, $sendto, $billto, $languages_id, $payment, $currencies, $cart, $cart_PayPal_Standard_ID;
  global $$payment;

  $order_id = substr($cart_PayPal_Standard_ID, strpos($cart_PayPal_Standard_ID, '-')+1);

  $check_query = tep_db_query("select orders_status from " . TABLE_ORDERS . " where orders_id = '" . (int)$order_id . "'");
  if (tep_db_num_rows($check_query)) {
	$check = tep_db_fetch_array($check_query);

	if ($check['orders_status'] == MODULE_PAYMENT_PAYPAL_IPN_PREPARE_ORDER_STATUS_ID) {
	  $sql_data_array = array('orders_id' => $order_id,
							  'orders_status_id' => MODULE_PAYMENT_PAYPAL_IPN_PREPARE_ORDER_STATUS_ID,
							  'date_added' => 'now()',
							  'customer_notified' => '0',
							  'comments' => '');

	  tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);
	}
  }

  tep_db_query("update " . TABLE_ORDERS . " set orders_status = '" . (MODULE_PAYMENT_PAYPAL_IPN_ORDER_STATUS_ID > 0 ? (int)MODULE_PAYMENT_PAYPAL_IPN_ORDER_STATUS_ID : (int)DEFAULT_ORDERS_STATUS_ID) . "', last_modified = now() where orders_id = '" . (int)$order_id . "'");

  $sql_data_array = array('orders_id' => $order_id,
						  'orders_status_id' => (MODULE_PAYMENT_PAYPAL_IPN_ORDER_STATUS_ID > 0 ? (int)MODULE_PAYMENT_PAYPAL_IPN_ORDER_STATUS_ID : (int)DEFAULT_ORDERS_STATUS_ID),
						  'date_added' => 'now()',
						  'customer_notified' => (SEND_EMAILS == 'true') ? '1' : '0',
						  'comments' => $order->info['comments']);

  tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);

// initialized for the email confirmation
  $products_ordered = '';
  $subtotal = 0;
  $total_tax = 0;

  for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {
// Stock Update - Joao Correia
	if (STOCK_LIMITED == 'true') {
	  if (DOWNLOAD_ENABLED == 'true') {
		$stock_query_raw = "SELECT products_quantity, pad.products_attributes_filename
				FROM " . TABLE_PRODUCTS . " p
				LEFT JOIN " . TABLE_PRODUCTS_ATTRIBUTES . " pa
				ON p.products_id=pa.products_id
				LEFT JOIN " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
				ON pa.products_attributes_id=pad.products_attributes_id
				WHERE p.products_id = '" . tep_get_prid($order->products[$i]['id']) . "'";
		// Will work with only one option for downloadable products
		// otherwise, we have to build the query dynamically with a loop
		$products_attributes = $order->products[$i]['attributes'];
		if (is_array($products_attributes)) {
		  $stock_query_raw .= " AND pa.options_id = '" . $products_attributes[0]['option_id'] . "' AND pa.options_values_id = '" . $products_attributes[0]['value_id'] . "'";
		}
		$stock_query = tep_db_query($stock_query_raw);
	  } else {
		$stock_query = tep_db_query("select products_quantity from " . TABLE_PRODUCTS . " where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
	  }	//end if download_enabled
	  if (tep_db_num_rows($stock_query) > 0) {
		$stock_values = tep_db_fetch_array($stock_query);
		// do not decrement quantities if products_attributes_filename exists
		if ((DOWNLOAD_ENABLED != 'true') || (!$stock_values['products_attributes_filename'])) {
		  $stock_left = $stock_values['products_quantity'] - $order->products[$i]['qty'];
		} else {
		  $stock_left = $stock_values['products_quantity'];
		}
		tep_db_query("update " . TABLE_PRODUCTS . " set products_quantity = '" . $stock_left . "' where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
		if ( ($stock_left < 1) && (STOCK_ALLOW_CHECKOUT == 'false') ) {
		  tep_db_query("update " . TABLE_PRODUCTS . " set products_status = '0' where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");
		}
	  }	//end if stock > 0
	}	//end if stock_limited

	// Update products_ordered (for bestsellers list)
  	tep_db_query("update " . TABLE_PRODUCTS . " set products_ordered = products_ordered + " . sprintf('%d', $order->products[$i]['qty']) . " where products_id = '" . tep_get_prid($order->products[$i]['id']) . "'");


//------insert customer choosen option to order--------
	$attributes_exist = '0';
	$products_ordered_attributes = '';
	if (isset($order->products[$i]['attributes'])) {
		$attributes_exist = '1';
		for ($j=0, $n2=sizeof($order->products[$i]['attributes']); $j<$n2; $j++) {
		  if (DOWNLOAD_ENABLED == 'true') {
			$attributes_query = "select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix, pad.products_attributes_maxdays, pad.products_attributes_maxcount , pad.products_attributes_filename
				from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa
				left join " . TABLE_PRODUCTS_ATTRIBUTES_DOWNLOAD . " pad
				on pa.products_attributes_id=pad.products_attributes_id
				where pa.products_id = '" . $order->products[$i]['id'] . "'
				and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "'
				and pa.options_id = popt.products_options_id
				and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "'
				and pa.options_values_id = poval.products_options_values_id
				and popt.language_id = '" . $languages_id . "'
				and poval.language_id = '" . $languages_id . "'";
			$attributes = tep_db_query($attributes_query);
		  } else {
			$attributes = tep_db_query("select popt.products_options_name, poval.products_options_values_name, pa.options_values_price, pa.price_prefix from " . TABLE_PRODUCTS_OPTIONS . " popt, " . TABLE_PRODUCTS_OPTIONS_VALUES . " poval, " . TABLE_PRODUCTS_ATTRIBUTES . " pa where pa.products_id = '" . $order->products[$i]['id'] . "' and pa.options_id = '" . $order->products[$i]['attributes'][$j]['option_id'] . "' and pa.options_id = popt.products_options_id and pa.options_values_id = '" . $order->products[$i]['attributes'][$j]['value_id'] . "' and pa.options_values_id = poval.products_options_values_id and popt.language_id = '" . $languages_id . "' and poval.language_id = '" . $languages_id . "'");
		  }	//end if download_enabled
		  $attributes_values = tep_db_fetch_array($attributes);
		
		  $products_ordered_attributes .= "\n\t" . $attributes_values['products_options_name'] . ' ' . tep_decode_specialchars($order->products[$i]['attributes'][$j]['value']);
		}	//end for attributes
	}	//end if isset
	
	//------insert customer choosen option eof ----
	$total_weight += ($order->products[$i]['qty'] * $order->products[$i]['weight']);
	$total_tax += tep_calculate_tax($total_products_price, $products_tax) * $order->products[$i]['qty'];
	$total_cost += $total_products_price;
	
	$products_ordered .= $order->products[$i]['qty'] . ' x ' . $order->products[$i]['name'] . ' (' . $order->products[$i]['model'] . ') = ' . $currencies->display_price($order->products[$i]['final_price'], $order->products[$i]['tax'], $order->products[$i]['qty']) . $products_ordered_attributes .  "\n";
	
  }	//end for (loop through products)
	
  // lets start with the email confirmation
	$email_order =		STORE_NAME 					. "\n" .
						EMAIL_SEPARATOR 			. "\n" .
						EMAIL_TEXT_ORDER_NUMBER 	. '' . $order_id . "\n" .
						EMAIL_TEXT_INVOICE_URL 		. ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $order_id, 'SSL', false) . "\n" .
						EMAIL_TEXT_DATE_ORDERED 	. ' ' . strftime(DATE_FORMAT_LONG) . "\n\n";
	if ($order->info['comments']) {
		$email_order .= tep_db_output($order->info['comments']) . "\n\n";
	}
	$email_order .= 	EMAIL_TEXT_PRODUCTS 		. "\n" .
						EMAIL_SEPARATOR 			. "\n" .
						$products_ordered 			.
						EMAIL_SEPARATOR 			. "\n";
	
	for ($i=0, $n=sizeof($order_totals); $i<$n; $i++) {
		$email_order .= strip_tags($order_totals[$i]['title']) . ' ' . 
						strip_tags($order_totals[$i]['text']) . "\n";
	}
	
	if ($order->content_type != 'virtual') {
		$email_order .= "\n" . 
						EMAIL_TEXT_DELIVERY_ADDRESS . "\n" .
						EMAIL_SEPARATOR 			. "\n" .
						tep_address_label($customer_id, $sendto, 0, '', "\n") . "\n";
	}
	$email_order .= 	"\n" . 
						EMAIL_TEXT_BILLING_ADDRESS 	. "\n" .
						EMAIL_SEPARATOR 			. "\n" .
						tep_address_label($customer_id, $billto, 0, '', "\n") . "\n\n";
	
	if (is_object($$payment)) {
		$email_order .= EMAIL_TEXT_PAYMENT_METHOD 	. "\n" .
						EMAIL_SEPARATOR 			. "\n";
		$payment_class = $$payment;
		$email_order .= $payment_class->title 		. "\n\n";
		if ($payment_class->email_footer) {
			$email_order .= $payment_class->email_footer . "\n\n";
		}
	}

	tep_mail($order->customer['firstname'] . ' ' . $order->customer['lastname'], $order->customer['email_address'], EMAIL_TEXT_SUBJECT . EMAIL_TEXT_ORDER_NUMBER . ': ' . $order_id, $email_order, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
	
	// send emails to other people
	if (SEND_EXTRA_ORDER_EMAILS_TO != '') {
		tep_mail('', SEND_EXTRA_ORDER_EMAILS_TO, EMAIL_TEXT_SUBJECT . EMAIL_TEXT_ORDER_NUMBER . ': ' . $order_id, $email_order, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);
	}
	
	// load the after_process function from the payment modules
	$this->after_process();
	
	$cart->reset(true);
	
	// unregister session variables used during checkout
	tep_session_unregister('sendto');
	tep_session_unregister('billto');
	tep_session_unregister('shipping');
	tep_session_unregister('payment');
	tep_session_unregister('comments');
	
	tep_session_unregister('cart_PayPal_Standard_ID');
	
	tep_redirect(tep_href_link(FILENAME_CHECKOUT_SUCCESS, '', 'SSL'));

}	//end function before_process()



function after_process() {
	return false;
}	//end function after_process()

function output_error() {
	return false;
}	//end function output_error()

function check() {
	if (!isset($this->_check)) {
		$check_query = tep_db_query("select configuration_value from " . TABLE_CONFIGURATION . " where configuration_key = 'MODULE_PAYMENT_PAYPAL_IPN_STATUS'");
		$this->_check = tep_db_num_rows($check_query);
	}
	return $this->_check;
}	//end function check()

function install() {
	$check_query = tep_db_query("select orders_status_id from " . TABLE_ORDERS_STATUS . " where orders_status_name = 'Preparing [PayPal IPN]' limit 1");
	
	if (tep_db_num_rows($check_query) < 1) {
		$status_query = tep_db_query("select max(orders_status_id) as status_id from " . TABLE_ORDERS_STATUS);
		$status = tep_db_fetch_array($status_query);
		
		$status_id = $status['status_id']+1;
		
		$languages = tep_get_languages();
		
		foreach ($languages as $lang) {
			tep_db_query("insert into " . TABLE_ORDERS_STATUS . " (orders_status_id, language_id, orders_status_name) values ('" . $status_id . "', '" . $lang['id'] . "', 'Preparing [PayPal IPN]')");
		}
	} else {
		$check = tep_db_fetch_array($check_query);
		
		$status_id = $check['orders_status_id'];
	}
	
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable PayPal IPN Module', 'MODULE_PAYMENT_PAYPAL_IPN_STATUS', 'False', 'Do you want to accept PayPal IPN payments?', '6', '3', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");
// bof PandA.nl move tax to total amount
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Move tax to total amount', 'MOVE_TAX_TO_TOTAL_AMOUNT', 'True', 'Do you want to move the tax to the total amount? If true PayPal will allways show the total amount including tax. (needs Aggregate i.s.o. Per Item to function)', '6', '4', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");
// eof PandA.nl move tax to total amount
	
// fr fee
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('PayPal Fee', 'MODULE_PAYMENT_PAYPAL_FEE" . $i."', '0', 'Insert a % PayPal feel - 1.04 = 4%', '6', '0', now())");
	
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('PayPal Fix Fee', 'MODULE_PAYMENT_PAYPAL_FIX_FEE" . $i."', '0', 'Insert a PayPal fix feel', '6', '0', now())");
// Ende fr fee
	
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('E-Mail Address', 'MODULE_PAYMENT_PAYPAL_IPN_ID', '', 'The e-mail address to use for the PayPal IPN service', '6', '4', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Transaction Currency', 'MODULE_PAYMENT_PAYPAL_IPN_CURRENCY', 'Selected Currency', 'The currency to use for transactions', '6', '6', 'tep_cfg_select_option(array(\'Selected Currency\',\'Only CHF\',\'Only CAD\',\'Only EUR\',\'Only GBP\',\'Only JPY\'), ', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Sort order of display.', 'MODULE_PAYMENT_PAYPAL_IPN_SORT_ORDER', '0', 'Sort order of display. Lowest is displayed first.', '6', '0', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, use_function, set_function, date_added) values ('Payment Zone', 'MODULE_PAYMENT_PAYPAL_IPN_ZONE', '0', 'If a zone is selected, only enable this payment method for that zone.', '6', '2', 'tep_get_zone_class_title', 'tep_cfg_pull_down_zone_classes(', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set Preparing Order Status', 'MODULE_PAYMENT_PAYPAL_IPN_PREPARE_ORDER_STATUS_ID', '" . $status_id . "', 'Set the status of prepared orders made with this payment module to this value', '6', '0', 'tep_cfg_pull_down_order_statuses(', 'tep_get_order_status_name', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, use_function, date_added) values ('Set PayPal Acknowledged Order Status', 'MODULE_PAYMENT_PAYPAL_IPN_ORDER_STATUS_ID', '0', 'Set the status of orders made with this payment module to this value', '6', '0', 'tep_cfg_pull_down_order_statuses(', 'tep_get_order_status_name', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Transaction Type', 'MODULE_PAYMENT_PAYPAL_IPN_TRANSACTION_TYPE', 'Per Item', 'Send individual items to PayPal or aggregate all as one total item?', '6', '6', 'tep_cfg_select_option(array(\'Per Item\',\'Aggregate\'), ', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Gateway Server', 'MODULE_PAYMENT_PAYPAL_IPN_GATEWAY_SERVER', 'Testing', 'Use the testing (sandbox) or live gateway server for transactions?', '6', '6', 'tep_cfg_select_option(array(\'Testing\',\'Live\'), ', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Page Style', 'MODULE_PAYMENT_PAYPAL_IPN_PAGE_STYLE', '', 'The page style to use for the transaction procedure (defined at your PayPal Profile page)', '6', '4', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Debug E-Mail Address', 'MODULE_PAYMENT_PAYPAL_IPN_DEBUG_EMAIL', '', 'All parameters of an Invalid IPN notification will be sent to this email address if one is entered.', '6', '4', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, set_function, date_added) values ('Enable Encrypted Web Payments', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_STATUS', 'False', 'Do you want to enable Encrypted Web Payments?', '6', '3', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Your Private Key', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_PRIVATE_KEY', '', 'The location of your Private Key to use for signing the data. (*.pem)', '6', '4', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Your Public Certificate', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_PUBLIC_KEY', '', 'The location of your Public Certificate to use for signing the data. (*.pem)', '6', '4', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('PayPals Public Certificate', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_PAYPAL_KEY', '', 'The location of the PayPal Public Certificate for encrypting the data.', '6', '4', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Your PayPal Public Certificate ID', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_CERT_ID', '', 'The Certificate ID to use from your PayPal Encrypted Payment Settings Profile.', '6', '4', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('Working Directory', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY', '', 'The working directory to use for temporary files. (trailing slash needed)', '6', '4', now())");
	tep_db_query("insert into " . TABLE_CONFIGURATION . " (configuration_title, configuration_key, configuration_value, configuration_description, configuration_group_id, sort_order, date_added) values ('OpenSSL Location', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_OPENSSL', '/usr/bin/openssl', 'The location of the openssl binary file.', '6', '4', now())");

}	//end function install()

function remove() {
	tep_db_query("delete from " . TABLE_CONFIGURATION . " where configuration_key in ('" . implode("', '", $this->keys()) . "')");
}	//end function remove()

function keys() {
// PandA.nl move tax to total amount added: ", 'MOVE_TAX_TO_TOTAL_AMOUNT'"
	return array('MODULE_PAYMENT_PAYPAL_IPN_STATUS', 'MOVE_TAX_TO_TOTAL_AMOUNT', 'MODULE_PAYMENT_PAYPAL_IPN_ID', 'MODULE_PAYMENT_PAYPAL_IPN_CURRENCY','MODULE_PAYMENT_PAYPAL_FEE', 'MODULE_PAYMENT_PAYPAL_FIX_FEE', 'MODULE_PAYMENT_PAYPAL_IPN_ZONE', 'MODULE_PAYMENT_PAYPAL_IPN_PREPARE_ORDER_STATUS_ID', 'MODULE_PAYMENT_PAYPAL_IPN_ORDER_STATUS_ID', 'MODULE_PAYMENT_PAYPAL_IPN_GATEWAY_SERVER', 'MODULE_PAYMENT_PAYPAL_IPN_TRANSACTION_TYPE', 'MODULE_PAYMENT_PAYPAL_IPN_PAGE_STYLE', 'MODULE_PAYMENT_PAYPAL_IPN_DEBUG_EMAIL', 'MODULE_PAYMENT_PAYPAL_IPN_SORT_ORDER', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_STATUS', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_PRIVATE_KEY', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_PUBLIC_KEY', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_PAYPAL_KEY', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_CERT_ID', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_WORKING_DIRECTORY', 'MODULE_PAYMENT_PAYPAL_IPN_EWP_OPENSSL');
}	//end function keys()
}	//end class Paypal_ipn


?>


#4030 theclem35

  • Community Member
  • 1 posts
  • Real Name:clement

Posted 18 December 2009, 17:05

Hello,

I've a problem with IPN. When I config payment and click on the button to come back on my shop, it says my order was successfully recorded.
It's the case but ...
Payment status is already on pending, no information in comments from paypal.

I've turned ON register globals and add a php.ini file in the paypal ipn ext folder but it's the same thing.

Configuration :
- Local installation (Windows XP)
- Wamp server with : Apache 2.2.11 // PHP 5.2.5 // MySQL 5.1.36
- OSC 2.2rc2a
- Paypal IPN v2.3.4.6

Thanks for help !

Edited by theclem35, 18 December 2009, 17:06.


#4031 satish

  • Community Member
  • 5,315 posts
  • Real Name:Satish Mantri
  • Gender:Male
  • Location:Nagpur(India)

Posted 20 December 2009, 07:32

Payment status is already on pending, no information in comments from paypal.

This means that IPN is not reaching Your site.As IPN code is supposed to update order status and send email.

The probable reasons:
Improper IPN path.
IPN profile setting in Paypal disabled.

SO first step is make sure IPN are reaching where they should.

Satish
Ask for osCommerce value addon suggestion tips for your site.
Check My About US For who am I and what My company does.


#4032 Moonsin

  • Community Member
  • 3 posts
  • Real Name:Tecumseh Fox

Posted 05 January 2010, 18:53

View Postchamber715, on 04 September 2009, 18:18, said:

Hi, I'm using the Paypal IPN 2.3.4.7. I think I installed in correctly, but when I get to the paypal page, it shows a zero total and asks for an amount to be entered. Has anyone else encountered this issue and is there a fix? Basically, what am I doing wrong?

I am having the same problem. Any fix?

#4033 DANYEYI

  • Community Member
  • 43 posts
  • Real Name:daniel posteraro

Posted 22 January 2010, 11:15

hi there,

i have just installed the paypal ipn addon version 2.3.4.7 (4th march 09) it works and i can recieve payments but the order status is not updating and not sending out emails.

i have searched the forums and there are many similar posts.

how can i fix this? i have no idea whats causing the problem. when i look at the IPN history in my paypal account and then message id i get retrying errors and the Notification URL is showing up as :https://www.mysite.co.uk/ipn.php?language=english i thought the ipn.php was supposed to be loacted in the ext/etc/etc?

i also have a dedicated ssl on the site if that makes a difference? the encrypted option is set to off.

thanks in advance

dan

#4034 Moonsin

  • Community Member
  • 3 posts
  • Real Name:Tecumseh Fox

Posted 03 February 2010, 14:28

Having the same problem as in the post above. Not receiving any e-mails and the Comments field also remains blank. This is a serious problem for my shop.

As for my previous problem, fixed it by changing the Transaction Type.

#4035 www.in.no

  • Community Member
  • 235 posts
  • Real Name:Arild Evensen

Posted 07 February 2010, 09:18

Hi,
I having problems downloading tha latest version of this addon.

Paypal_IPN 3.0 next Version GER

It keeps coming up as blocked file and i can not extract. The other files i can download and extract as normal. Unblocking the file is not working as well.

Any suggestions.

#4036 www.in.no

  • Community Member
  • 235 posts
  • Real Name:Arild Evensen

Posted 07 February 2010, 10:14

Never mind, i found that PayPal IPN Module 2.3.4.7 is the latest for english language. The later ones are germen only.

#4037 oldcelt

  • Community Member
  • 102 posts
  • Real Name:Ken Wheeler

Posted 08 February 2010, 12:25

View Postwww.in.no, on 07 February 2010, 10:14, said:

Never mind, i found that PayPal IPN Module 2.3.4.7 is the latest for english language. The later ones are germen only.

I'm a bit confused. osCrc2a has a Paypal module (catalog>ext>modules>payment>paypal>standard_ipn.php). Isn't this all that's needed for IPN?

Ken

#4038 totalnumpty

  • Community Member
  • 242 posts
  • Real Name:Gaz
  • Gender:Male
  • Location:U.K.

Posted 08 February 2010, 14:50

View Postoldcelt, on 08 February 2010, 12:25, said:

I'm a bit confused. osCrc2a has a Paypal module (catalog>ext>modules>payment>paypal>standard_ipn.php). Isn't this all that's needed for IPN?

Ken


Ken - your confusion is understandable, but your assumption is wrong.

How it works is like this -

- Once the customer has entered checkout and chosen shipping, and shipping options (gift wrap, insurance etc), the next step is the payment method

- checkout_payments.php checks the customer address against the tax zones (geographic areas) for each payment method you have installed
- if the customer is in the allowed geo-zone for PayPal, it offers payPal as a payment method
- if the customer chooses PayPal, and goes to order confirmation, then checkout_confirmation.php assembles all the customer and order details and basically asks the customer if it is all correct, or if they want to edit anything. If they confirm it, then all that data is passed to /includes/modules/paypal_ipn.php
- /includes/modules/paypal_ipn.php then passes that data to PayPal and redirects the customer to the PayPal website to sign in and choose funding source etc. This part of the IPN also passes to PayPal the data return path for confirming payment has been transferred to the merchant's PayPal account.
- once the customer has done what's needed, and PayPal have moved the money to the Merchant's PayPal account, then the PayPal IPN server squirts a data stream back to your site - but the returned data goes to /ext/.../paypal_ipn.php NOT to /includes/modules/paypal_ipn.php

- /ext/.../paypal_ipn.php then records the payment details into the database and updates the order status and transaction record, I think it also confirms back to PayPal that the payment data was received from them, and failing to do so is one common cause of payment failures.

So the IPN has two parts -
- the first paypal_ipn.php which is the payment methods module, and sends the customer and order details to PayPal, this is in /includes/modules/
- the second paypal_ipn.php which is the response receiver and order updater, this one is in the /ext.../ folder

There is a third file in /includes/languages/{language-name}/modules/payments/paypal_ipn.php which controls the displayed language strings for the checkout pages and the admin payment modules page.

So .... nope, the /ext/.../paypal_ipn.php is not all that osC needs - it needs all three files for any individual payment processor's IPN in order for that payment processor's IPN to function - regardless of which payment processor you're using (e.g. MoneyBookers, NoChex, AlertPay, ppPay etc.n Google Checkout is a little different, as is Amazon Payments, but the idea is similar). Each set of files will be named after the payment processor they handle - e.g. MoneyBookers.php and so on.

Hope that helps?

Gaz



If any of the above is wrong, can someone post the correct process or logic - I think there's a few people get stuck with how the IPN's work.
Wearing a seatbelt prevents head injuries when the computer crashes - - - Yeah Right!!! - not in this office.

#4039 oldcelt

  • Community Member
  • 102 posts
  • Real Name:Ken Wheeler

Posted 08 February 2010, 16:49

View Posttotalnumpty, on 08 February 2010, 14:50, said:

Ken - your confusion is understandable, but your assumption is wrong.

How it works is like this -

- if the customer chooses PayPal, and goes to order confirmation, then checkout_confirmation.php assembles all the customer and order details and basically asks the customer if it is all correct, or if they want to edit anything. If they confirm it, then all that data is passed to /includes/modules/paypal_ipn.php

Whoa - stop right there! In osC2rc2a there is no such code file as /includes/modules/paypal_ipn.php! So, having installed paypal website payments standard, I appear to have everything set up? All I appear to need to do is set up my profile to return to catalog/ext/modules/payment/paypal/standard_ipn.php?

Ken

#4040 totalnumpty

  • Community Member
  • 242 posts
  • Real Name:Gaz
  • Gender:Male
  • Location:U.K.

Posted 08 February 2010, 20:21

View Postoldcelt, on 08 February 2010, 16:49, said:

Whoa - stop right there! In osC2rc2a there is no such code file as /includes/modules/paypal_ipn.php! So, having installed paypal website payments standard, I appear to have everything set up? All I appear to need to do is set up my profile to return to catalog/ext/modules/payment/paypal/standard_ipn.php?

Ken

OK, fair call - my bad, I was using generally understood shorthand pathing ... try this - /includes/modules/payment/paypal_ipn.php

Just for the record in RC2a ...

catalog/ext/modules/payment/paypal/standard_ipn.php
hooks up with
catalog/includes/modules/payment/paypal_standard.php
and
catalog/includes/languages/english/modules/payment/paypal_standard.php

Therefore as I originally answered - No your premise of the single file in /ext/.... is still incorrect, and my original answer SHOULD have given you enough information to track down the other two files of the trio. The overall process I described remains the same for the standard_ipn in RC2a, it's just handled slightly differently by the code.

Lastly, there perfectly well could be an /includes/modules/paypal_ipn.php in RC2a on a NON STANDARD install, which is actually the norm for osC sites - i.e. NON-standard (nobody uses it straight from the box and runs with it that way as a production site - that's just begging for hackers to visit your install).

Quote

All I appear to need to do is set up my profile to return to catalog/ext/modules/payment/paypal/standard_ipn.php?

You could do - if you only have one website, will only ever have one website, and that one website will only ever be the sole source of payments into your PayPal account (i.e. no instant payment buttons, no auction sites, no WordPress eShops etc etc etc) - otherwise, read the help files and the instructions - within osC, and at PayPal - enter your /ext/... path in there and EVERY IPN or PayPal Express callback confirmation from your PayPal account will be sent to your website, many will be irresolvable (because they did not originate from the IPN on your site) and could cause server resource abuse due to SQL query loops and timeouts, and your hosting account could get suspended (I've heard several stories of it happening).

If you ask for advice, listen to experience, and read between the lines if it's not an exact fit with your situation. Adapt what you're told to what you're experiencing ... and I do hope that's not "teaching granny to suck eggs"?

Alternatively - follow the osC forum credo - and post your full site and server spec with version numbers, plus screen shots of errors etc, then people who help you are not firing blindly and generically when they offer that help.
Wearing a seatbelt prevents head injuries when the computer crashes - - - Yeah Right!!! - not in this office.