Jump to content
  • Checkout
  • Login
  • Get in touch

osCommerce

The e-commerce.

Official PayPal IPN Support Thread


Mark Evans

Recommended Posts

Everything works great except 0ne thing: I only want the billing address send to paypal page because if they enter a shipping address different from the billing, it passess to paypal, then the customer has to re-enter the billing associated with there credit card = cancel order!!

 

I tried and read everything in this thread, can someone be kind enough to paste the code to fix it?

 

Thanks

------

I resolved my issue, a while back, with the billing insted of shipping sent to paypal where the customer does not have to re-enter his billing info which is normally associated with the credit/debit card, and on the paypal confirmation page includes a link if they want to add there shipping address. Can't send both as far as I have reserched.

 

I can't say it will work for you. If anything try it on a test osCommerce first. Save a copy of your original code as well.

 

Here's how I did it, it works for me.

 

In catalog/includes/modules/payment/paypal_ipn

 

I changed this code:

 

// BOF billing address fix by AlexStudio

if ($order->content_type != 'virtual') {

$state_abbr = tep_get_zone_code($order->delivery['country']['id'], $order->delivery['zone_id'], $order->delivery['state']);

} else {

$state_abbr = tep_get_zone_code($order->billing['country']['id'], $order->billing['zone_id'], $order->billing['state']);

}

if (empty($state_abbr)) $state_abbr = 'none';

// EOF billing address fix by AlexStudio

 

$parameters['business'] = MODULE_PAYMENT_PAYPAL_IPN_ID;

 

// let's check what has been defined in the shop admin for the shipping address

// BOF parameters fix by AlexStudio

if ($order->content_type != 'virtual') {

$parameters['address_override'] = '1';

$parameters['no_shipping'] = '2';

$parameters['night_phone_b'] = $order->customer['telephone'];

$parameters['first_name'] = $order->delivery['firstname'];

$parameters['last_name'] = $order->delivery['lastname'];

$parameters['address1'] = $order->delivery['street_address'];

$parameters['address2'] = $order->delivery['suburb'];

$parameters['city'] = $order->delivery['city'];

$parameters['zip'] = $order->delivery['postcode'];

$parameters['state'] = $state_abbr;

$parameters['country'] = $order->delivery['country']['iso_code_2'];

$parameters['email'] = $order->customer['email_address'];

} else {

$parameters['no_shipping'] = '1';

$parameters['night_phone_b'] = $order->customer['telephone'];

$parameters['first_name'] = $order->billing['firstname'];

$parameters['last_name'] = $order->billing['lastname'];

$parameters['address1'] = $order->billing['street_address'];

$parameters['address2'] = $order->billing['suburb'];

$parameters['city'] = $order->billing['city'];

$parameters['zip'] = $order->billing['postcode'];

$parameters['state'] = $state_abbr;

$parameters['country'] = $order->billing['country']['iso_code_2'];

$parameters['email'] = $order->customer['email_address'];

}

 

--------------------------

To this code:

 

// BOF billing address fix by AlexStudio

if ($order->content_type != 'virtual') {

$state_abbr = tep_get_zone_code($order->billing['country']['id'], $order->billing['zone_id'], $order->billing['state']);

} else {

$state_abbr = tep_get_zone_code($order->delivery['country']['id'], $order->delivery['zone_id'], $order->delivery['state']);

}

if (empty($state_abbr)) $state_abbr = 'none';

// EOF billing address fix by AlexStudio

 

$parameters['business'] = MODULE_PAYMENT_PAYPAL_IPN_ID;

 

// let's check what has been defined in the shop admin for the shipping address

// BOF parameters fix by AlexStudio

if ($order->content_type != 'virtual') {

$parameters['address_override'] = '0';

$parameters['no_shipping'] = '2';

$parameters['night_phone_b'] = $order->customer['telephone'];

$parameters['first_name'] = $order->billing['firstname'];

$parameters['last_name'] = $order->billing['lastname'];

$parameters['address1'] = $order->billing['street_address'];

$parameters['address2'] = $order->billing['suburb'];

$parameters['city'] = $order->billing['city'];

$parameters['zip'] = $order->billing['postcode'];

$parameters['state'] = $state_abbr;

$parameters['country'] = $order->billing['country']['iso_code_2'];

$parameters['email'] = $order->customer['email_address'];

} else {

$parameters['no_shipping'] = '1';

$parameters['night_phone_b'] = $order->customer['telephone'];

$parameters['first_name'] = $order->delivery['firstname'];

$parameters['last_name'] = $order->delivery['lastname'];

$parameters['address1'] = $order->delivery['street_address'];

$parameters['address2'] = $order->delivery['suburb'];

$parameters['city'] = $order->delivery['city'];

$parameters['zip'] = $order->delivery['postcode'];

$parameters['state'] = $state_abbr;

$parameters['country'] = $order->delivery['country']['iso_code_2'];

$parameters['email'] = $order->customer['email_address'];

}

 

--------------------------

 

If you noticed, I only switch the billing address and the shipping address placement in "billing address fix by AlexStudio" and in "parameters fix by AlexStudio" and set address override to 0

 

This sends Billing to the page where the customer enters his credit/debit card info and on the "Review your payment" page, adds a link if the customer wishes enter a shipping address.

 

Im using Version PayPal IPN Module v2.3.3 For 2.2MS2

s0nny

Edited by s0nny61
Link to comment
Share on other sites

Answered myself!

 

Yes.

 

Thanks you me.

 

Also ran into some issues with the godaddy account (preparing paypal / ipn and not returning data from paypal issue, but fixed it, Works Great)

 

The fix has been posted in this long thread, I think by AlexStudio

 

Im using Version PayPal IPN Module v2.3.3 For 2.2MS2

 

In Admin Payment Modules Setting

 

cURL Proxy server

http://proxy.shr.secureserver.net:3128

 

And I entered code as follows: curl_setopt($ch, CURLOPT_PROXY, "http://proxy.shr.secureserver.net:3128");

in catalog/ext/modules/payment/paypal_ipn/ipn.php

----------

@fclose($fp);

} elseif ($curl == true) {

$ch = curl_init();

 

// BOF add by AlexStudio

// For the poor souls on GoDaddy and the like, set the connection to go through their proxy

if (trim(MODULE_PAYMENT_PAYPAL_IPN_PROXY_SERVER) != '') {

curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);

curl_setopt($ch, CURLOPT_PROXY, MODULE_PAYMENT_PAYPAL_IPN_PROXY_SERVER);

}

// Eof add by AlexStudio

curl_setopt($ch, CURLOPT_URL, 'https://' . $server . '/cgi-bin/webscr');

curl_setopt($ch, CURLOPT_POST, true);

curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_HEADER, false);

curl_setopt($ch, CURLOPT_TIMEOUT, 30);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

curl_setopt($ch, CURLOPT_PROXY, "http://proxy.shr.secureserver.net:3128");

 

$result = curl_exec($ch);

 

curl_close($ch);

}

 

----------------- Hope the above helps someone with a godaddy account --------

 

Everything works great except 0ne thing: I only want the billing address send to paypal page because if they enter a shipping address different from the billing, it passess to paypal, then the customer has to re-enter the billing associated with there credit card = cancel order!!

 

I tried and read everything in this thread, can someone be kind enough to paste the code to fix it?

 

Thanks

------

I resolved my issue, a while back. I modified to send the billing address insted of the shipping address to paypal so the customer does not have to re-enter his billing info which is normally associated with the credit/debit card, and on the paypal confirmation page includes a link if they want to add a shipping address. Can't send both as far as I have reserched.

 

In catalog/includes/modules/payment/paypal_ipn

 

I changed this code:

 

// BOF billing address fix by AlexStudio

if ($order->content_type != 'virtual') {

$state_abbr = tep_get_zone_code($order->delivery['country']['id'], $order->delivery['zone_id'], $order->delivery['state']);

} else {

$state_abbr = tep_get_zone_code($order->billing['country']['id'], $order->billing['zone_id'], $order->billing['state']);

}

if (empty($state_abbr)) $state_abbr = 'none';

// EOF billing address fix by AlexStudio

 

$parameters['business'] = MODULE_PAYMENT_PAYPAL_IPN_ID;

 

// let's check what has been defined in the shop admin for the shipping address

// BOF parameters fix by AlexStudio

if ($order->content_type != 'virtual') {

$parameters['address_override'] = '1';

$parameters['no_shipping'] = '2';

$parameters['night_phone_b'] = $order->customer['telephone'];

$parameters['first_name'] = $order->delivery['firstname'];

$parameters['last_name'] = $order->delivery['lastname'];

$parameters['address1'] = $order->delivery['street_address'];

$parameters['address2'] = $order->delivery['suburb'];

$parameters['city'] = $order->delivery['city'];

$parameters['zip'] = $order->delivery['postcode'];

$parameters['state'] = $state_abbr;

$parameters['country'] = $order->delivery['country']['iso_code_2'];

$parameters['email'] = $order->customer['email_address'];

} else {

$parameters['no_shipping'] = '1';

$parameters['night_phone_b'] = $order->customer['telephone'];

$parameters['first_name'] = $order->billing['firstname'];

$parameters['last_name'] = $order->billing['lastname'];

$parameters['address1'] = $order->billing['street_address'];

$parameters['address2'] = $order->billing['suburb'];

$parameters['city'] = $order->billing['city'];

$parameters['zip'] = $order->billing['postcode'];

$parameters['state'] = $state_abbr;

$parameters['country'] = $order->billing['country']['iso_code_2'];

$parameters['email'] = $order->customer['email_address'];

}

 

 

--------------------------

To this code:

 

// BOF billing address fix by AlexStudio

if ($order->content_type != 'virtual') {

$state_abbr = tep_get_zone_code($order->billing['country']['id'], $order->billing['zone_id'], $order->billing['state']);

} else {

$state_abbr = tep_get_zone_code($order->delivery['country']['id'], $order->delivery['zone_id'], $order->delivery['state']);

}

if (empty($state_abbr)) $state_abbr = 'none';

// EOF billing address fix by AlexStudio

 

$parameters['business'] = MODULE_PAYMENT_PAYPAL_IPN_ID;

 

// let's check what has been defined in the shop admin for the shipping address

// BOF parameters fix by AlexStudio

if ($order->content_type != 'virtual') {

$parameters['address_override'] = '0';

$parameters['no_shipping'] = '2';

$parameters['night_phone_b'] = $order->customer['telephone'];

$parameters['first_name'] = $order->billing['firstname'];

$parameters['last_name'] = $order->billing['lastname'];

$parameters['address1'] = $order->billing['street_address'];

$parameters['address2'] = $order->billing['suburb'];

$parameters['city'] = $order->billing['city'];

$parameters['zip'] = $order->billing['postcode'];

$parameters['state'] = $state_abbr;

$parameters['country'] = $order->billing['country']['iso_code_2'];

$parameters['email'] = $order->customer['email_address'];

} else {

$parameters['no_shipping'] = '1';

$parameters['night_phone_b'] = $order->customer['telephone'];

$parameters['first_name'] = $order->delivery['firstname'];

$parameters['last_name'] = $order->delivery['lastname'];

$parameters['address1'] = $order->delivery['street_address'];

$parameters['address2'] = $order->delivery['suburb'];

$parameters['city'] = $order->delivery['city'];

$parameters['zip'] = $order->delivery['postcode'];

$parameters['state'] = $state_abbr;

$parameters['country'] = $order->delivery['country']['iso_code_2'];

$parameters['email'] = $order->customer['email_address'];

}

 

 

--------------------------

 

If you noticed, I only switch the billing address and the shipping address placement in "billing address fix by AlexStudio" and in "parameters fix by AlexStudio" and set address override to 0

 

This sends Billing to the page where the customer enters his credit/debit card info and on the "Review your payment" page, adds a link if the customer wishes enter a shipping address.

 

Im using Version PayPal IPN Module v2.3.3 For 2.2MS2

s0nny

 

Sorry about the double post, I was trying to fix my last post!

Edited by s0nny61
Link to comment
Share on other sites

Since you're sending the billing address instead of the shipping, your payments are no longer covered by PayPal's seller protection policy.

Super Download Shop, PayPal Express Checkout IPN, Selling Downloads, Visual Validation (preventing robotic flood), phpBB2 Integration

 

Yes, I'm willing to help, but please ask in the right place. Think twice before trying to PM me, it might be ignored.

Link to comment
Share on other sites

I do realize what you are saying, but when the customers shipping address doesn't match the credit card holders billing address, paypal gives you an error as follows:

(most credit cards match the holders billing address)

billing-shipping-2.jpg

 

Now, where the red line in the above picture is, where it says, enter your billing information, the customer would be inclined to enter there billing address.

 

So if the billing address is sent and matches the credit card holders address, and the billing address fix and parameters are set correct, they can change the "ship to" underlined in red. There is a link that says change. If the customer enters it, then you are covered by PayPal's seller protection policy.

 

billing-shipping-1.jpg

 

Now if the is a way to override where it won't decline either shipping or billing address where it says enter billing information, (I would like to know how). But lets hope the customer doesn't get confused if they read enter billing information.

 

I do pay attention to all you have posted and commend you on all your help. I am not an expert and everything I learned is from right here, you and everyone who I beleive is experienced enough. I back up and test on my test site, if it works, I use it.

 

With all due respect,

s0nny

Link to comment
Share on other sites

...If the customer enters it, then you are covered by PayPal's seller protection policy....
No, you're not. If the shipping address is different from the billing address, the transaction is not eligible to PayPal's seller protection policy. If the shipping and billing addresses are identical, you don't need to change the code at all.

Super Download Shop, PayPal Express Checkout IPN, Selling Downloads, Visual Validation (preventing robotic flood), phpBB2 Integration

 

Yes, I'm willing to help, but please ask in the right place. Think twice before trying to PM me, it might be ignored.

Link to comment
Share on other sites

Hi all,

 

I am having a strange problem with my paypal which I was wondering if any of you had come across before.

 

When I and a few selected others test out my store everything works perfectly and they make a purchase and get a download.

 

However other people when clicking purchase and are taken to paypal are getting this screen:

 

pp.jpg

 

What I don't understand is why some people are getting through fine and others are not. In paypal I have selected make a paypal account optional so people don't need one. I have tried everything I can think of and was wondering if you had any ideas as at the moment the majority of people are unable to purchase anything.

 

Regards,

 

Craig

Link to comment
Share on other sites

No, you're not. If the shipping address is different from the billing address, the transaction is not eligible to PayPal's seller protection policy. If the shipping and billing addresses are identical, you don't need to change the code at all.

 

So no matter what, you have to ship to the address that the credit card holder registered his credit card to, even if he wants to ship to a different address, for instance as a gift.

 

Which you will not be protected.

 

So now I should add to my shipping policies, if a customer chooses to ship to a different address, we will not be held responsible. No refunds and no exchanges.

 

s0nny

Link to comment
Share on other sites

No, you're not. If the shipping address is different from the billing address, the transaction is not eligible to PayPal's seller protection policy. If the shipping and billing addresses are identical, you don't need to change the code at all.

 

I just called PayPal and you are correct AlexStudio.

 

It's like this, if you ship to "any other address" other than the credit card's billing address, you are not eligible to PayPal's seller protection policy. So the option to ship to an other address is a squash in all reality if you want to be protected.

 

So know I may need to add to my shipping policies about shipping to an address that is not tied to the credit card.

 

I will still need to leave the code to what I changed it to though, to pass billing insted of shipping address, because it won't accept any other address than the credit cards billing address.

 

Well, at least all this makes it clear and there is a crude solution.

 

s0nny

Link to comment
Share on other sites

Hello everybody,

 

thanks for this great contrib! I love it and it works great except for the footer. As I'm not very new to osCommerce I read the whole thread (especially page 90 to 110) to find a solution. I tried all the proposals written there but I didn't get it working. :(

 

Perhaps somebody could provide me the deciding hint.

 

Note: I was thinking I'm using version 1.4 as CCGV should not work with version 2.x but obviously I'm using version 2.1.0.0 as you can see in the header of these files and CCGV is working great for me ...

 

 

ipn.php

 

<?php

/*

$Id: paypal_ipn.php,v 2.1.0.0 13/01/2007 16:30:21 Edith Karnitsch Exp $

 

Copyright © 2004 osCommerce

Released under the GNU General Public License

 

Original Authors: Harald Ponce de Leon, Mark Evans

Updates by PandA.nl, Navyhost, Zoeticlight, David, gravyface, AlexStudio, windfjf, Monika in Germany and Terra

 

*/

 

chdir('../../../../');

require('includes/application_top.php');

include(DIR_WS_LANGUAGES . $language . '/' . FILENAME_CHECKOUT_PROCESS);

 

$parameters = 'cmd=_notify-validate';

 

foreach ($_POST as $key => $value) {

$parameters .= '&' . $key . '=' . urlencode(stripslashes($value));

}

 

if (MODULE_PAYMENT_PAYPAL_IPN_GATEWAY_SERVER == 'Live') {

$server = 'www.paypal.com';

} else {

$server = 'www.sandbox.paypal.com';

}

 

$fsocket = false;

$curl = false;

$result = false;

 

if ( (PHP_VERSION >= 4.3) && ($fp = @fsockopen('ssl://' . $server, 443, $errno, $errstr, 30)) ) {

$fsocket = true;

} elseif (function_exists('curl_exec')) {

$curl = true;

} elseif ($fp = @fsockopen($server, 80, $errno, $errstr, 30)) {

$fsocket = true;

}

 

if ($fsocket == true) {

$header = 'POST /cgi-bin/webscr HTTP/1.0' . "\r\n" .

'Host: ' . $server . "\r\n" .

'Content-Type: application/x-www-form-urlencoded' . "\r\n" .

'Content-Length: ' . strlen($parameters) . "\r\n" .

'Connection: close' . "\r\n\r\n";

 

@fputs($fp, $header . $parameters);

 

$string = '';

while (!@feof($fp)) {

$res = @fgets($fp, 1024);

$string .= $res;

 

if ( ($res == 'VERIFIED') || ($res == 'INVALID') ) {

$result = $res;

 

break;

}

}

 

@fclose($fp);

} elseif ($curl == true) {

$ch = curl_init();

 

curl_setopt($ch, CURLOPT_URL, 'https://' . $server . '/cgi-bin/webscr');

curl_setopt($ch, CURLOPT_POST, true);

curl_setopt($ch, CURLOPT_POSTFIELDS, $parameters);

curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_HEADER, false);

curl_setopt($ch, CURLOPT_TIMEOUT, 30);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);

 

$result = curl_exec($ch);

 

curl_close($ch);

}

 

if ($result == 'VERIFIED') {

if (isset($_POST['invoice']) && is_numeric($_POST['invoice']) && ($_POST['invoice'] > 0)) {

$order_query = tep_db_query("select currency, currency_value from " . TABLE_ORDERS . " where orders_id = '" . $_POST['invoice'] . "' and customers_id = '" . (int)$_POST['custom'] . "'");

if (tep_db_num_rows($order_query) > 0) {

$order_db = tep_db_fetch_array($order_query);

 

// let's re-create the required arrays

require(DIR_WS_CLASSES . 'order.php');

$order = new order($_POST['invoice']);

 

require(DIR_WS_CLASSES . 'payment.php');

$payment_modules = new payment(paypal_ipn);

 

// let's update the order status

$total_query = tep_db_query("select value from " . TABLE_ORDERS_TOTAL . " where orders_id = '" . $_POST['invoice'] . "' and class = 'ot_total' limit 1");

$total = tep_db_fetch_array($total_query);

 

$comment_status = $_POST['payment_status'] . ' (' . ucfirst($_POST['payer_status']) . '; ' . $currencies->format($_POST['mc_gross'], false, $_POST['mc_currency']) . ')';

 

if ($_POST['payment_status'] == 'Pending') {

$comment_status .= '; ' . $_POST['pending_reason'];

} elseif ( ($_POST['payment_status'] == 'Reversed') || ($_POST['payment_status'] == 'Refunded') ) {

$comment_status .= '; ' . $_POST['reason_code'];

} elseif ( ($_POST['payment_status'] == 'Completed') && (MODULE_PAYMENT_PAYPAL_IPN_SHIPPING == 'True') ) {

$comment_status .= ", \n" . PAYPAL_ADDRESS . ": " . $_POST['address_name'] . ", " . $_POST['address_street'] . ", " . $_POST['address_city'] . ", " . $_POST['address_zip'] . ", " . $_POST['address_state'] . ", " . $_POST['address_country'] . ", " . $_POST['address_country_code'] . ", " . $_POST['address_status'];

}

 

$order_status_id = DEFAULT_ORDERS_STATUS_ID;

 

// modified AlexStudio's Rounding error bug fix

// variances of up to 0.05 on either side (plus / minus) are ignored

if (

(((number_format($total['value'] * $order_db['currency_value'], $currencies->get_decimal_places($order_db['currency']))) - $_POST['mc_gross']) <= 0.05)

&&

(((number_format($total['value'] * $order_db['currency_value'], $currencies->get_decimal_places($order_db['currency']))) - $_POST['mc_gross']) >= -0.05)

) {

 

// previous validation

// if ($_POST['mc_gross'] == number_format($total['value'] * $order_db['currency_value'], $currencies->get_decimal_places($order_db['currency']))) {

 

// Terra -> modified update. If payment status is "completed" than a completed order status is chosen based on the admin settings

if ( (MODULE_PAYMENT_PAYPAL_IPN_COMP_ORDER_STATUS_ID > 0) && ($_POST['payment_status'] == 'Completed') ) {

$order_status_id = MODULE_PAYMENT_PAYPAL_IPN_COMP_ORDER_STATUS_ID;

} elseif (MODULE_PAYMENT_PAYPAL_IPN_ORDER_STATUS_ID > 0) {

$order_status_id = MODULE_PAYMENT_PAYPAL_IPN_ORDER_STATUS_ID;

}

 

}

 

// Let's see what the PayPal payment status is and set the notification accordingly

// more info: https://www.paypal.com/IntegrationCenter/ic...-reference.html

if ( ($_POST['payment_status'] == 'Pending') || ($_POST['payment_status'] == 'Completed')) {

$customer_notified = '1';

} else {

$customer_notified = '0';

}

 

 

tep_db_query("update " . TABLE_ORDERS . " set orders_status = '" . $order_status_id . "', last_modified = now() where orders_id = '" . $_POST['invoice'] . "'");

 

$sql_data_array = array('orders_id' => $_POST['invoice'],

'orders_status_id' => $order_status_id,

'date_added' => 'now()',

'customer_notified' => $customer_notified,

'comments' => 'PayPal IPN Verified [' . $comment_status . ']');

 

tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);

 

// If the order is pending, then we want to send a notification email to the customer

 

 

// If the order is completed, then we want to send the order email and update the stock

if ($_POST['payment_status'] == 'Completed') { // START STATUS == COMPLETED LOOP

 

// initialized for the email confirmation

$products_ordered = '';

$total_tax = 0;

 

 

// let's update the stock

#######################################################

for ($i=0, $n=sizeof($order->products); $i<$n; $i++) { // PRODUCT LOOP STARTS HERE

// 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']) . "'");

}

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']) . "'");

}

}

}

 

// 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']) . "'");

 

 

 

// Let's get all the info together for the email

$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;

 

// Let's get the attributes

$products_ordered_attributes = '';

if ( (isset($order->products[$i]['attributes'])) && (sizeof($order->products[$i]['attributes']) > 0) ) {

for ($j=0, $n2=sizeof($order->products[$i]['attributes']); $j<$n2; $j++) {

$products_ordered_attributes .= "\n\t" . $order->products[$i]['attributes'][$j]['option'] . ' ' . $order->products[$i]['attributes'][$j]['value'];

}

}

 

// Let's format the products model

$products_model = '';

if ( !empty($order->products[$i]['model']) ) {

$products_model = ' (' . $order->products[$i]['model'] . ')';

}

 

// Let's put all the product info together into a string

$products_ordered .= $order->products[$i]['qty'] . ' x ' . $order->products[$i]['name'] . $products_model . ' = ' . $currencies->display_price($order->products[$i]['final_price'], $order->products[$i]['tax'], $order->products[$i]['qty']) . $products_ordered_attributes . "\n";

 

 

} // PRODUCT LOOP ENDS HERE

#######################################################

 

 

// lets start with the email confirmation

// BOF content type fix by AlexStudio

$content_type = '';

$content_count = 0;

// BOF order comment fix

$comment_query = tep_db_query("select comments from " . TABLE_ORDERS_STATUS_HISTORY . " where orders_id = '" . $_POST['invoice'] . "'");

$comment_array = tep_db_fetch_array($comment_query);

$comments = $comment_array['comments'];

// EOF order comment fix

 

if (DOWNLOAD_ENABLED == 'true') {

$content_query = tep_db_query("select * from " . TABLE_ORDERS_PRODUCTS_DOWNLOAD . " where orders_id = '" . (int)$_POST['invoice'] . "'");

$content_count = tep_db_num_rows($content_query);

if ($content_count > 0) {

$content_type = 'virtual';

}

}

switch ($content_type) {

case 'virtual':

if ($content_count != sizeof($order->products)) $content_type = 'mixed';

break;

default:

$content_type = 'physical';

break;

}

// EOF content type fix by AlexStudio

// $order variables have been changed from checkout_process to work with the variables from the function query () instead of cart () in the order class

// folgende Zeile ersetzt 16092008

// anfang teil 1 ersetzt 19092008 http://www.oscommerce.com/forums/index.php?showtopic=251510

$comment_query = tep_db_query("select comments from " . TABLE_ORDERS_STATUS_HISTORY . " where orders_id = '" . $_POST['invoice'] . "'");

$commentfetch = tep_db_fetch_array($comment_query);

$comments = $commentfetch['comments'];

// ende teil 1 ersetzt 19092008

$email_order = "Guten Tag ".$order->customer['name'].",\n\nvielen Dank für Ihre Bestellung bei ".STORE_NAME.".\nSie bekommen bei jeder Statusänderung Ihrer Bearbeitung eine automatisch generierte Email.\n\nNachfolgend finden Sie Ihre Bestelldetails:\n" .

// EMAIL_SEPARATOR . "\n" .

// EMAIL_TEXT_ORDER_NUMBER . ' ' . $_POST['invoice'] . "\n" .

// EMAIL_TEXT_INVOICE_URL . ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $_POST['invoice'], '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";

// }

// anfang teil 2 ersetzt 19092008

EMAIL_SEPARATOR . "\n" .

EMAIL_TEXT_ORDER_NUMBER . ' ' . $_POST['invoice'] . "\n" .

EMAIL_TEXT_INVOICE_URL . ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $_POST['invoice'], 'SSL', false) . "\n" .

EMAIL_TEXT_DATE_ORDERED . ' ' . strftime(DATE_FORMAT_LONG) . "\n\n";

if ($comments) {

$email_order .= $comments . "\n\n";

}

// ende teil 2 ersetzt 19092008

$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_format($order->delivery['format_id'], $order->delivery, 0, '', "\n") . "\n";

}

 

$email_order .= "\n" . EMAIL_TEXT_BILLING_ADDRESS . "\n" .

EMAIL_SEPARATOR . "\n" .

tep_address_format($order->billing['format_id'], $order->billing, 0, '', "\n") . "\n\n";

if (is_object($$payment)) {

// folgende Zeile ersetzt 16092008

// $email_order .= EMAIL_TEXT_PAYMENT_METHOD . "\n" .

$email_order .= MODULE_PAYMENT_PAYPAL_IPN_TEXT_TITLE . "\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";

}

// folgende Zeile eingefuegt 16092008 und geaendert 18092008

// $email_order .= MODULE_PAYMENT_PAYPAL_IPN_TEXT_EMAIL_FOOTER . "\n";

$email_order .= EMAIL_TEXT_FOOTER . "\n";

}

tep_mail($order->customer['name'], $order->customer['email_address'], EMAIL_TEXT_SUBJECT, $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_order, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);

}

 

//emptying cart for everyone! by Monika in Germany

tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET . " where customers_id = '" . (int)$_POST['custom'] . "'");

tep_db_query("delete from " . TABLE_CUSTOMERS_BASKET_ATTRIBUTES . " where customers_id = '" . (int)$_POST['custom'] . "'");

//end emptying cart for everyone

 

 

} // END STATUS == COMPLETED LOOP

 

if ($_POST['payment_status'] == 'Pending') { // START STATUS == PENDING LOOP

 

$email_order = "Guten Tag ".$order->customer['name'].",\n\nvielen Dank für Ihre Bestellung bei ".STORE_NAME.".\nSie bekommen bei jeder Statusänderung Ihrer Bearbeitung eine automatisch generierte Email.\n\nNachfolgend finden Sie Ihre Bestelldetails:\n" .

EMAIL_SEPARATOR . "\n" .

EMAIL_TEXT_ORDER_NUMBER . ' ' . $_POST['invoice'] . "\n" .

EMAIL_TEXT_INVOICE_URL . ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $_POST['invoice'], 'SSL', false) . "\n" .

EMAIL_TEXT_DATE_ORDERED . ' ' . strftime(DATE_FORMAT_LONG) . "\n\n" .

EMAIL_SEPARATOR . "\n" .

EMAIL_PAYPAL_PENDING_NOTICE . "\n\n";

 

tep_mail($order->customer['name'], $order->customer['email_address'], EMAIL_TEXT_SUBJECT, $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_order, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);

}

} // END STATUS == PENDING LOOP

 

}

}

} else {

if (tep_not_null(MODULE_PAYMENT_PAYPAL_IPN_DEBUG_EMAIL)) {

$email_body = '$_POST:' . "\n\n";

foreach ($_POST as $key => $value) {

$email_body .= $key . '=' . $value . "\n";

}

$email_body .= "\n" . '$_GET:' . "\n\n";

foreach ($_GET as $key => $value) {

$email_body .= $key . '=' . $value . "\n";

}

 

tep_mail('', MODULE_PAYMENT_PAYPAL_IPN_DEBUG_EMAIL, 'PayPal IPN Invalid Process', $email_body, STORE_OWNER, STORE_OWNER_EMAIL_ADDRESS);

}

 

if (isset($_POST['invoice']) && is_numeric($_POST['invoice']) && ($_POST['invoice'] > 0)) {

$check_query = tep_db_query("select orders_id from " . TABLE_ORDERS . " where orders_id = '" . $_POST['invoice'] . "' and customers_id = '" . (int)$_POST['custom'] . "'");

if (tep_db_num_rows($check_query) > 0) {

$comment_status = $_POST['payment_status'];

 

if ($_POST['payment_status'] == 'Pending') {

$comment_status .= '; ' . $_POST['pending_reason'];

} elseif ( ($_POST['payment_status'] == 'Reversed') || ($_POST['payment_status'] == 'Refunded') ) {

$comment_status .= '; ' . $_POST['reason_code'];

}

 

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

 

$sql_data_array = array('orders_id' => $_POST['invoice'],

'orders_status_id' => (MODULE_PAYMENT_PAYPAL_IPN_ORDER_STATUS_ID > 0) ? MODULE_PAYMENT_PAYPAL_IPN_ORDER_STATUS_ID : DEFAULT_ORDERS_STATUS_ID,

'date_added' => 'now()',

'customer_notified' => '0',

'comments' => 'PayPal IPN Invalid [' . $comment_status . ']');

 

tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);

}

}

}

 

require('includes/application_bottom.php');

?>

 

 

includes/modules/payment/paypal_ip.php

 

<?php

/*

$Id: paypal_ipn.php,v 2.1.0.0 13/01/2007 16:30:28 Edith Karnitsch Exp $

 

Copyright © 2004 osCommerce

Released under the GNU General Public License

 

Original Authors: Harald Ponce de Leon, Mark Evans

Updates by PandA.nl, Navyhost, Zoeticlight, David, gravyface, AlexStudio, windfjf and Terra

 

*/

 

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->email_footer = MODULE_PAYMENT_PAYPAL_IPN_TEXT_EMAIL_FOOTER;

$this->identifier = 'osCommerce PayPal IPN v2.1';

 

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();

 

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';

}

}

 

// 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;

}

}

}

 

function javascript_validation() {

return false;

}

 

function selection() {

return array('id' => $this->code,

'module' => $this->title);

}

 

function pre_confirmation_check() {

return false;

}

 

function confirmation() {

global $cartID, $cart_PayPal_IPN_ID, $customer_id, $languages_id, $order, $order_total_modules;

 

// if (tep_session_is_registered('cartID')) {

// PandA.nl: register_globals fix

if (array_key_exists('cartID', $_SESSION)) {

$insert_order = false;

 

if (tep_session_is_registered('cart_PayPal_IPN_ID')) {

$order_id = substr($cart_PayPal_IPN_ID, strpos($cart_PayPal_IPN_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_IPN_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');

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

 

$update_order = false;//1.4

 

//if (tep_db_num_rows($check_query) < 1) {

//tep_db_query('delete from ' . TABLE_ORDERS . ' where orders_id = "' . (int)$order_id . '"');

if (tep_db_num_rows($check_query) == 1) { //1.4

$update_order = true; //1.4

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 . '"');

}

 

$insert_order = true;

//}

} else {

$insert_order = true;

}

 

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);

}

}

}

}

}

 

$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']);

 

//+1.4

if ( $update_order ){

tep_db_perform(TABLE_ORDERS, $sql_data_array, 'update', 'orders_id = "' . (int)$order_id . '"');

$insert_id = (int)$order_id;

} else {

//-1.4

tep_db_perform(TABLE_ORDERS, $sql_data_array);

 

$insert_id = tep_db_insert_id();

}//1.4

 

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);

}

//+1.4

$sql_data_array = array('orders_id' => $insert_id,

'orders_status_id' => $order->info['order_status'],

'date_added' => 'now()',

'customer_notified' => '0',

'comments' => $order->info['comments']);

tep_db_perform(TABLE_ORDERS_STATUS_HISTORY, $sql_data_array);

//-1.4

 

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();

 

$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'])) {

$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);

}

}

}

}

 

tep_session_register('cart_PayPal_IPN_ID');

// Terra register globals fix

$_SESSION['cart_PayPal_IPN_ID'] = $cartID . '-' . $insert_id;

}

}

 

return false;

}

 

function process_button() {

global $customer_id, $order, $languages_id, $currencies, $currency, $cart_PayPal_IPN_ID, $shipping;

 

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';

 

for ($i=0, $n=sizeof($order->products); $i<$n; $i++) {

$item = $i+1;

 

$tax_value = ($order->products[$i]['tax'] / 100) * $order->products[$i]['final_price'];

 

$parameters['item_name_' . $item] = $order->products[$i]['name'];

$parameters['amount_' . $item] = number_format($order->products[$i]['final_price'] * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency));

$parameters['tax_' . $item] = number_format($tax_value * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency));

$parameters['quantity_' . $item] = $order->products[$i]['qty'];

 

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);

}

 

$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;

 

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']) * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency));

} else {

// default

$parameters['amount'] = number_format(($order->info['total'] - $order->info['shipping_cost'] - $order->info['tax']) * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency));

}

 

} else {

$parameters['cmd'] = '_ext-enter';

$parameters['redirect_cmd'] = '_xclick';

$parameters['item_name'] = STORE_NAME;

$parameters['shipping'] = '0';

if(MOVE_TAX_TO_TOTAL_AMOUNT == 'True') {

// PandA.nl move tax to total amount

$parameters['amount'] = number_format($order->info['total'] * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency));

} else {

// default

$parameters['amount'] = number_format(($order->info['total'] - $order->info['tax']) * $currencies->get_value($my_currency), $currencies->get_decimal_places($my_currency));

}

}

 

// billing information fix by gravyface

// for pre-populating the fiels if customer has no PayPal account

// only works if force shipping address is set to FALSE

$state_abbr = tep_get_zone_code($order->delivery['country']['id'], $order->delivery['zone_id'], $order->delivery['state']);

$name = $order->delivery['firstname'] . ' ' . $order->delivery['lastname'];

 

$parameters['business'] = MODULE_PAYMENT_PAYPAL_IPN_ID;

 

// let's check what has been defined in the shop admin for the shipping address

if (MODULE_PAYMENT_PAYPAL_IPN_SHIPPING == 'True') {

// all that matters is that we send the variables

// what they contain is irrelevant as PayPal overwrites it with the customer's confirmed PayPal address

// so what we send is probably not what we'll get back

$parameters['no_shipping'] = '2';

$parameters['address_name'] = $name;

$parameters['address_street'] = $order->delivery['street_address'];

$parameters['address_city'] = $order->delivery['city'];

$parameters['address_zip'] = $order->delivery['postcode'];

$parameters['address_state'] = $state_abbr;

$parameters['address_country_code'] = $order->delivery['country']['iso_code_2'];

$parameters['address_country'] = $order->delivery['country']['title'];

$parameters['payer_email'] = $order->customer['email_address'];

} else {

$parameters['no_shipping'] = '1';

$parameters['H_PhoneNumber'] = $order->customer['telephone'];

$parameters['first_name'] = $order->delivery['firstname'];

$parameters['last_name'] = $order->delivery['lastname'];

$parameters['address1'] = $order->delivery['street_address'];

$parameters['address2'] = $order->delivery['suburb'];

$parameters['city'] = $order->delivery['city'];

$parameters['zip'] = $order->delivery['postcode'];

$parameters['state'] = $state_abbr;

$parameters['country'] = $order->delivery['country']['iso_code_2'];

$parameters['email'] = $order->customer['email_address'];

}

 

$parameters['currency_code'] = $my_currency;

$parameters['invoice'] = substr($cart_PayPal_IPN_ID, strpos($cart_PayPal_IPN_ID, '-')+1);

$parameters['custom'] = $customer_id;

$parameters['no_note'] = '1';

$parameters['notify_url'] = tep_href_link('ext/modules/payment/paypal_ipn/ipn.php', '', 'SSL', false, false);

//$parameters['notify_url'] = tep_href_link('ext/modules/payment/paypal_ipn/ipn.php', 'language=' . $_SESSION['language'], 'SSL', false, false);

$parameters['cbt'] = CONFIRMATION_BUTTON_TEXT;

$parameters['return'] = tep_href_link(FILENAME_CHECKOUT_PROCESS, '', 'SSL');

$parameters['cancel_return'] = tep_href_link(FILENAME_CHECKOUT_PAYMENT, '', 'SSL');

$parameters['bn'] = $this->identifier;

$parameters['lc'] = $order->customer['country']['iso_code_2'];

 

 

if (tep_not_null(MODULE_PAYMENT_PAYPAL_IPN_PAGE_STYLE)) {

$parameters['page_style'] = MODULE_PAYMENT_PAYPAL_IPN_PAGE_STYLE;

}

 

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;

}

 

function before_process() {

global $cart;

 

$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_IPN_ID');

 

tep_redirect(tep_href_link(FILENAME_CHECKOUT_SUCCESS, '', 'SSL'));

}

 

function after_process() {

return false;

}

 

function output_error() {

return false;

}

 

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;

}

 

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', '1', '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, 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', '2', '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 ('Sort order of display.', 'MODULE_PAYMENT_PAYPAL_IPN_SORT_ORDER', '0', 'Sort order of display. Lowest is displayed first.', '6', '3', 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 ('Force shipping address?', 'MODULE_PAYMENT_PAYPAL_IPN_SHIPPING', 'False', 'If TRUE the address details for the PayPal Seller Protection Policy are sent but customers without a PayPal account must re-enter their details. If set to FALSE order is not eligible for Seller Protection but customers without acount will have their address fiels pre-populated.', '6', '4', '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 ('E-Mail Address', 'MODULE_PAYMENT_PAYPAL_IPN_ID', '', 'The e-mail address to use for the PayPal IPN service', '6', '5', 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', '10', 'tep_cfg_select_option(array(\'Selected Currency\',\'Only AUD\',\'Only CAD\',\'Only CHF\',\'Only CZK\',\'Only DKK\',\'Only EUR\',\'Only GBP\',\'Only HKD\',\'Only HUF\',\'Only JPY\',\'Only NOK\',\'Only NZD\',\'Only PLN\',\'Only SEK\',\'Only SGD\',\'Only USD\'), ', 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', '11', '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', '12', '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', '13', '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 Completed Order Status', 'MODULE_PAYMENT_PAYPAL_IPN_COMP_ORDER_STATUS_ID', '0', 'Set the status of orders which are confirmed as paid (completed) to this value', '6', '13', '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', 'Aggregate', 'Send individual items to PayPal or aggregate all as one total item?', '6', '14', 'tep_cfg_select_option(array(\'Per Item\',\'Aggregate\'), ', 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 instead of Per Item to function)', '6', '15', 'tep_cfg_select_option(array(\'True\', \'False\'), ', now())");

// eof 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, 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', '20', 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', '21', 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', '30', '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', '31', 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', '32', 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', '33', 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', '34', 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', '35', 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', '36', now())");

 

}

 

function remove() {

tep_db_query("delete from " . TABLE_CONFIGURATION . " where configuration_key in ('" . implode("', '", $this->keys()) . "')");

}

 

function keys() {

// PandA.nl move tax to total amount added: ", 'MOVE_TAX_TO_TOTAL_AMOUNT'"

return array('MODULE_PAYMENT_PAYPAL_IPN_STATUS', 'MODULE_PAYMENT_PAYPAL_IPN_GATEWAY_SERVER', 'MODULE_PAYMENT_PAYPAL_IPN_ID', 'MODULE_PAYMENT_PAYPAL_IPN_SORT_ORDER', 'MODULE_PAYMENT_PAYPAL_IPN_CURRENCY', 'MODULE_PAYMENT_PAYPAL_IPN_ZONE', 'MODULE_PAYMENT_PAYPAL_IPN_SHIPPING', 'MODULE_PAYMENT_PAYPAL_IPN_PREPARE_ORDER_STATUS_ID', 'MODULE_PAYMENT_PAYPAL_IPN_ORDER_STATUS_ID', 'MODULE_PAYMENT_PAYPAL_IPN_COMP_ORDER_STATUS_ID', 'MODULE_PAYMENT_PAYPAL_IPN_TRANSACTION_TYPE', 'MOVE_TAX_TO_TOTAL_AMOUNT', 'MODULE_PAYMENT_PAYPAL_IPN_PAGE_STYLE', 'MODULE_PAYMENT_PAYPAL_IPN_DEBUG_EMAIL', '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');

}

}

?>

 

 

includes/languages/german/modules/payment/paypal_ipn.php

 

<?php

/*

$Id: paypal_ipn.php,v 2.1.0.0 13/01/2007 16:30:45 Edith Karnitsch Exp $

 

Copyright © 2004 osCommerce

Released under the GNU General Public License

 

Original Authors: Harald Ponce de Leon, Mark Evans

Updates by PandA.nl, Navyhost, Zoeticlight, David, gravyface, AlexStudio, windfjf and Terra

 

*/

 

define('MODULE_PAYMENT_PAYPAL_IPN_TEXT_TITLE', 'Kreditkarte / Lastschrift (via PayPal)');

define('MODULE_PAYMENT_PAYPAL_IPN_TEXT_DESCRIPTION', 'PayPal IPN');

 

// Sets the text for the "continue" button on the PayPal Payment Complete Page

// Maximum of 60 characters!

define('CONFIRMATION_BUTTON_TEXT', 'Weiter zu meinem Shop');

 

define('EMAIL_PAYPAL_PENDING_NOTICE', 'Your payment is currently pending. We will send you a copy of your order once the payment has cleared.');

 

define('EMAIL_TEXT_SUBJECT', 'Bestellung');

define('EMAIL_TEXT_ORDER_NUMBER', 'Bestellnummer:');

define('EMAIL_TEXT_INVOICE_URL', 'Detailierte Bestellübersicht:');

define('EMAIL_TEXT_DATE_ORDERED', 'Bestelldatum:');

define('EMAIL_TEXT_PRODUCTS', 'Artikel');

define('EMAIL_TEXT_SUBTOTAL', 'Zwischensumme:');

define('EMAIL_TEXT_TAX', 'MwSt.');

define('EMAIL_TEXT_SHIPPING', 'Versandkosten:');

define('EMAIL_TEXT_TOTAL', 'Summe: ');

define('EMAIL_TEXT_DELIVERY_ADDRESS', 'Lieferanschrift');

define('EMAIL_TEXT_BILLING_ADDRESS', 'Rechnungsanschrift');

define('EMAIL_TEXT_PAYMENT_METHOD', 'Zahlungsweise');

 

define('EMAIL_SEPARATOR', '------------------------------------------------------');

define('TEXT_EMAIL_VIA', 'durch');

 

define('PAYPAL_ADDRESS', 'Customer PayPal address');

 

/* If you want to include a message with the order email, enter text here: */

/* Use \n for line breaks */

define('MODULE_PAYMENT_PAYPAL_IPN_TEXT_EMAIL_FOOTER', 'Der Versand Ihrer Bestellung erfolgt - nach Bestellannahme - in den nächsten Werktagen!' . "\n\n" .'Mit freundlichen Grüßen' . "\n" .' ... ');

define('EMAIL_TEXT_FOOTER', 'Der Versand Ihrer Bestellung erfolgt - nach Bestellannahme - in den nächsten Werktagen!' . "\n\n" .'Mit freundlichen Grüßen' . "\n" .' ... ');

?>

 

 

Perhaps somebody could help me finding the error to get this working - finally ;)

 

 

Thanks in advance

 

SirBerberitz

Cheers

 

+++ http://www.muehlkoppe.de +++

Link to comment
Share on other sites

Hi, thanks for the great job and sorry for my english.

 

I am having a strange issue with a paypal_ipn_2.4.5 version

 

Everything is going well in the customer side, but it doesn't receive the confirmation mail from the store

 

I don't receive the confirmation mail from the store on the admin side but I receive the payment confirmation from Paypal

 

There is the debug (v 2.3.3)

 

PP TEST start
PP TEST PayPal is accessing the ipn file
PP TEST we have successfuly loaded application top and language file
PP TEST PayPal IPN module successfully loaded
PP TEST we are assembling the reply: cmd=_notify-validate&mc_gross=3.90&protection_eligibility=None&address_status=unconfirmed&payer_id=SK3VUDC48VJNE&tax=0.00&address_street=there_was_the_address&payment_date=14%3A08%3A32+Sep+22%2C+2008+PDT&payment_status=Completed&charset=windows-1252&address_zip=zip_code&first_name=Nicolas&mc_fee=0.38&address_country_code=FR&address_name=Nicolas+RIAS&notify_version=2.5&custom=740&payer_status=verified&business=mail_address&address_country=France&address_city=Anglet&quantity=1&verify_sign=A4nS7c8NGYVTCR33hXFRNJaV.m3UAknJMpwQMHCT2SbPkhfPj0RESP8j&payer_email=customer_email&txn_id=3G979696EK087712G&payment_type=instant&last_name=RIAS&address_state=&receiver_email=mail_address&payment_fee=&receiver_id=LJJ9J3T2FLXW8&txn_type=web_accept&item_name=store_name&mc_currency=EUR&item_number=&residence_country=FR&payment_gross=&shipping=0.00
PP TEST PayPal server is www.paypal.com
PP TEST option1 - fsocket is true, port 443
PP TEST option1+3 we start to send string
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 we're receiving PayPal reply
PP TEST option1+3 REPLY: VERIFIED
PP TEST result is VERIFIED
PP TEST order id is: 
PP TEST order id problem - cannot verify order id
PP TEST end

 

 

Obviously the orders_id is missing

As today I was just updating the database manually, adding the right orders_id where it was needed but it's getting harder now.

 

So if someone has just a little idea it will be great

 

Thanks a lot :blush:

 

Cheers

 

Nicolas

 

MySQL - 4.1.22

if needed I can give the entire files (checkout_process.php, ipn.php and paypal_ipn.php)

Link to comment
Share on other sites

Hi again, I failed to edit my previous post so I made a new one.

 

There are more infos on my configuration

 

I am using : paypal_ipn 2.3.4.5 with

MySQL - 4.1.22 - Oscommerce MS2 updated

Paypal_ipn module configuration : aggregate - move tax... : true

 

Reading the 170 first pages of this thread (for now) and the 2.3.3 installation guide) I have done some fixes :

 

1. Fix for the empty state field in paypal_ipn.php

 

	  
	if (empty($state_abbr)) $state_abbr = 'none';

 

2 . the fix for the MS2 bug in both the admin and catalog compatibilty files

 

 

As mentionned in my previous post (and proved by the debug log), the ipn.php part seems OK

The only problem is that the orders_id does not exists ( in fact it is equal to 0 in my orders_total, orders_products and orders_status_history tables but set to the right orders_id in my orders table)

 

So I think that maybe my problem comes from the paypal_ipn.php part (because others payment module works great)

 

Thanks again :rolleyes:

Link to comment
Share on other sites

How can I get the customer number on the confirmation email. I tryed this but that is not working

 

$email_order = STORE_NAME . "\n" . 
					 EMAIL_SEPARATOR . "\n" . 
					 EMAIL_TEXT_CUSTOMER_ID . ' ' . $customer_id . "\n" .
					 EMAIL_TEXT_ORDER_NUMBER . ' ' . $_POST['invoice'] . "\n" .
					 EMAIL_TEXT_INVOICE_URL . ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $_POST['invoice'], 'SSL', false) . "\n" .
					 EMAIL_TEXT_DATE_ORDERED . ' ' . strftime(DATE_FORMAT_LONG) . "\n\n" . 
					 EMAIL_SEPARATOR . "\n" .
					 EMAIL_PAYPAL_PENDING_NOTICE . "\n\n";

Link to comment
Share on other sites

Hi platte,

 

How can I get the customer number on the confirmation email. I tryed this but that is not working

 

Try the above code, it should work.

 

$email_order = STORE_NAME . "\n" . 
					 EMAIL_SEPARATOR . "\n" . 
					 EMAIL_TEXT_CUSTOMER_ID . ' ' . (int)$_POST['custom'] . "\n" .
					 EMAIL_TEXT_ORDER_NUMBER . ' ' . $_POST['invoice'] . "\n" .
					 EMAIL_TEXT_INVOICE_URL . ' ' . tep_href_link(FILENAME_ACCOUNT_HISTORY_INFO, 'order_id=' . $_POST['invoice'], 'SSL', false) . "\n" .
					 EMAIL_TEXT_DATE_ORDERED . ' ' . strftime(DATE_FORMAT_LONG) . "\n\n" . 
					 EMAIL_SEPARATOR . "\n" .
					 EMAIL_PAYPAL_PENDING_NOTICE . "\n\n";

Link to comment
Share on other sites

Hi again,

 

after many hours reading the ENTIRE thread, many hours doing some testing, I am now pretty sure that my problem of orders_id ( see my two posts before) come from this part of paypal_ipn.php around line 200: it is in the confirmation() function

 

		  tep_db_perform(TABLE_ORDERS, $sql_data_array);

	  $insert_id = tep_db_insert_id();

 

It seems that tep_db_insert_id() doesn't return any value (so $insert_id = 0)

 

For memory I am using PHP 5.2.4 with MySQL 4.1.22 and curl enabled (libcurl/7.15.5 OpenSSL/0.9.8c zlib/1.2.3 libidn/0.6.5 ) on an up-to-date MS2.2

I use the last paypal_ipn.php posted by AlexStudio.

Ok, I have an issue with curl but I don't think it matters as proved in my debug ipn.php log in previous post

 

When using another payment module, the same part of code in checkout process give me the good orders_id and everything is going well.

I am sure of that fact because I used some error_log debugging to verify it.

 

Help, please :blink:

 

Thanks

 

Nicolas

Link to comment
Share on other sites

Ok I finally found with the help of Shoprun on the french osc forum :o)

 

I just have to modify the tep_db_insert_id() function in /includes/function/database.php and as well in the admin side

 

function tep_db_insert_id($link = 'db_link') {
global $$link;
return mysql_insert_id( $$link );
}

 

Thanks

 

Nicolas

Link to comment
Share on other sites

Is there any solution for paying but non-returning customers yet ?

(if paypal-membership is optional, and paypal does not return customer because they want to steal him/her)

-Order is created, and IPN received , but if customer do not choose to return, and no confirmation-email is sent, and the stock is not reduced...

Link to comment
Share on other sites

Hi Nixo.

 

Could you please elaborate a bit more on what modifications you had to make in order for Paypal to show your the order #? I've been ignoring the issue for a while now, but I sure would love to have it fixed.

 

Thank you.

 

ski

 

Ok I finally found with the help of Shoprun on the french osc forum :o)

 

I just have to modify the tep_db_insert_id() function in /includes/function/database.php and as well in the admin side

 

function tep_db_insert_id($link = 'db_link') {
global $$link;
return mysql_insert_id( $$link );
}

 

Thanks

 

Nicolas

Link to comment
Share on other sites

Hi there, I am new to osCommerce, and I have just installed the PayPal IPN as per the instructions on the download, but when I tested it, I got the 'invalid process' email, and all it shows in the body of the email is just '$_post: <blank> and $_GET: <blank>'. I am not sure what's wrong, I have tried it for a while, but not getting anywhere, hopefully someone could help me and point me to the right direction. Here are some information for the software installed on the server:

 

- using a shared ssl and cURL lib is installed on the server

- oscommerce 2.2MS2

- PHP 5.16

- PAYPAL_IPN version 2.3.4.5

- disabled 'auto-return' and 'IPN' in PayPal

- no shipping calculation

- disabled 'ENCRYPTED WEB PAYMENTS'

 

I have copied all the files from the contribution to the right directory, including the 'ext' folder. osCommerce is installed in the 'domain name/oscommerce' folder.

 

Thanks in advance.

Link to comment
Share on other sites

Is there any solution for paying but non-returning customers yet ?

(if paypal-membership is optional, and paypal does not return customer because they want to steal him/her)

-Order is created, and IPN received , but if customer do not choose to return, and no confirmation-email is sent, and the stock is not reduced...

 

I really want to know this also! This is a big problem and needs to been fixed asap

Edited by oenka
Link to comment
Share on other sites

Hi ski2bbad,

 

Hi Nixo.

 

Could you please elaborate a bit more on what modifications you had to make in order for Paypal to show your the order #? I've been ignoring the issue for a while now, but I sure would love to have it fixed.

 

Thank you.

 

ski

 

All that I have done is modifying the tep_db_insert_id() function in both the admin and catalog side ( ie: in catalog/includes/function/database.php and in admin/includes/function/database.php)

 

Replace :

 

function tep_db_insert_id() {
return mysql_insert_id();
}

 

by

 

function tep_db_insert_id($link = 'db_link') {
global $$link;
return mysql_insert_id( $$link );
}

 

 

That's it

 

Nicolas

Link to comment
Share on other sites

Hi Nixo.

 

Thank you very much for the reply. I will try your fix and post the results here later. My only problem has been the lack of the Order # on Paypal. I did check the database and found that my orders_total, orders_products and orders_status_history tables is being correctly populated with the order_id there, but somehow that order_id is not being passed on to Paypal. Since I do have a couple of stores I use a single letter (i.e. M) to identify each store as suggested by Terra so that there aren't duplicate orders. However, oddly enough that single letter does show on Paypal but not the number (order_id) that follows the letter. In any event I will try this and see what happens.

 

Thank you again for sharing your fix.

 

Best regards,

 

ski

 

 

NOTE: No changes had been made on the Paypal mod and the order id just vanished from my orders without me doing a single thing. Very weird. Must be the dreaded Godaddy ghost!

 

Hi ski2bbad,

 

All that I have done is modifying the tep_db_insert_id() function in both the admin and catalog side ( ie: in catalog/includes/function/database.php and in admin/includes/function/database.php)

 

Nicolas

Link to comment
Share on other sites

My new problem is this:

- someone orders the last product in stock and the "Allow Checkout" is set to false.

- after successful order and payment the customer is returned to shopping_cart.php instead of checkout_confirmation.php

- at the shopping_cart.php the red message appears on the bottom saying that the item selected is not available in the desired quantity etc.

 

Has anyone else had this problem or do you know where it could be fixed?

 

Has anyone else seen this problem?

 

 

Is there any solution for paying but non-returning customers yet ?

(if paypal-membership is optional, and paypal does not return customer because they want to steal him/her)

-Order is created, and IPN received , but if customer do not choose to return, and no confirmation-email is sent, and the stock is not reduced...

 

I would also like to find a fix for this problem...

Link to comment
Share on other sites

OK I have had IPN working flawlessly for 8+ months and then all of a sudden 2 months ago it has been giving me trouble with addresses containing international characters. For example if a customer has a "ö" in their name or address anywhere everything is fine until they are transfered to paypal. Paypal says it is an unknown character and to please contact the merchant. So i end up losing that order. PLEASE someone tell me what is wrong here! This has been driving me nuts. I'm assuming this is on the paypal end maybe?

Link to comment
Share on other sites

Hi Jayman11

 

OK I have had IPN working flawlessly for 8+ months and then all of a sudden 2 months ago it has been giving me trouble with addresses containing international characters. For example if a customer has a "ö" in their name or address anywhere everything is fine until they are transfered to paypal. Paypal says it is an unknown character and to please contact the merchant. So i end up losing that order. PLEASE someone tell me what is wrong here! This has been driving me nuts. I'm assuming this is on the paypal end maybe?

 

First, you should tell us which version of paypal_ipn you are using, it might help.

 

If you are using a version <2.3.3 , update it, so you will have this line where you can setup the right charset you use

 

Around line 500

 

	  /********************************************************************************
*************
  *	Currently these are the supported charsets:											 *
  *	big5, euc-jp, euc-kr, euc-tw, gb2312, hz-gb-2312, ibm-862, iso-2022-cn, iso-2022-jp,	*
  *	iso-2022-kr, iso-8859-1, iso-8859-2, iso-8859-3, iso-8859-4, iso-8859-5, iso-8859-6,	*
  *	iso-8859-7, iso-8859-8, iso-8859-9, iso-8859-13, iso-8859-15, ko18-r, shift_jis,		*
  *	utf-7, utf-8, utf-16, utf-16be, utf-16le, utf-16_platformendian, utf-16_oppositeendian, *
  *	utf-32, utf-32be, utf-32le, utf-32_platformendian, utf-32_oppositeendian, usa-ascii,	*
  *	windows-1250, windows-1251, windows-1252, windows-1253, windows-1254, windows-1255,	 *
  *	windows-1256, windows-1257, windows-1258, windows-874, windows-949, x-mac-greek,		*
  *	x-mac-turkish, x-mac-centraleurroman, x-mac-cyrillic, ebcdic-cp-us, ibm-1047			*
  ***************************************************************************
*******************/
  $parameters['charset'] = "iso-8859-2"; // Modify this line if you have problems with the character set.
// EOF parameters fix by AlexStudio

 

Hope this will help

 

Nicolas

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...