osCommerce 2.2 MS2 PayPal IPN Payment Module v2.3.4.7

Original Authors: Harald Ponce de Leon, Mark Evans osCommerce Team Members

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

v2.3.4.7 updated by AlexStudio and the osC community


For v2.3.4.7 to work properly, there must not be any Shipping Calculations set in the Paypal account profile. Click to read more detail.


This contribution and the documents are released under the GNU General Public License, which means it's free but WITH NO WARRANTY WHATSOEVER! Read THROUGH this install guide first if you encountered any problem. We can't help you if you don't even bother to read this guide.
 

PayPal: http://www.paypal.com

osCommerce: http://www.oscommerce.com

Support Thread: http://forums.oscommerce.com/index.php?showtopic=179917
<Please search in the support thread if you have any problem with this contribution.>

TerraNetwork: http://www.terranetwork.net

Contents

What's New in v2.3.4.7

back to top

Requirements

To use this contribution, you need these things (ask your web host if you don't know):

back to top

Introduction

osCommerce shops require the customer to return from the PayPal site to the shop for order details to be recorded, order emails to be generated and stock quantities to be updated.

In the past shop administrators had problems, where a customer did not return to the site. Shop administrators received a payment notification from PayPal but no order details. The PayPal IPN Module addresses this problem by storing orders prematurely (before payment) in the database with the "Preparing [PayPal IPN]" setting and as soon as a customer pays the order status is automatically updated to the chosen setting (usually "Pending").

This means that even when a customer fails to return to the site, the shop administrator will have a record of the order details even when no order emails are generated. Any remaining orders with status "Preparing [PayPal IPN]" have to be carefully checked and can fall into the following scenarios:

1) Orders in progress

Recent orders with the status "Preparing [PayPal IPN]" can show an order in progress, e.g. by a customer making amendments to his order or going through checkout. Action: None - recently generated orders should be left as they are.

2) Abandoned (unpaid) orders

If a customer chooses to abandon ordering, i.e. not continuing with payment, then a record of the premature (unpaid) order will be stored with the setting "Preparing [PayPal IPN]". Action: Delete - orders over 48 hours old with no payment can be deleted (option to restock must be unticked as "Preparing [PayPal IPN]" orders are not yet deducted from stock).

back to top

Known issues

back to top

How it works

The PayPal IPN module stores orders prematurely in the database to be processed by PayPal IPN notifications. This takes care of customers not returning back to the store to store the order in the database, and allows processing to occur when the PayPal IPN notification is received.

When communicating with the IPN notification, the order information is sent back to PayPal in a secure manner through PHP native OpenSSL capabilities or through cURL when OpenSSL is not available, or through a normal unsecure manner when no secure communication means exists, to confirm the order made. If the result is successful, the order status is updated automatically to show a successful order has been made. Invalid orders are left alone for the store administrator to verify.

This module also has OpenSSL public/private key encryption capabilities to securely send the order information to PayPal during the checkout procedure. More information about this feature can be read here:

Encrypted Web Payments: https://www.paypal.com/us/cgi-bin/webscr?cmd=p/xcl/rec/ewp-intro-outside

This module was built to be as simple as possible without having the need to touch core files for installation and usage.

back to top

Installing the PayPal IPN

If you already have a version of this PayPal IPN module installed, then you will need to remove the IPN from your admin area first (by clicking "remove") before following the steps below.

  1. Copy the files in the directory structure set in the contribution download file to your osCommerce installation directory inc. the new /ext/ folder.
  2. Make any changes you need to the language level files.
  3. In catalog\includes\functions\general.php

    Find the ENDING:


    Insert this BEFORE:
  4. In catalog\shopping_cart.php

    Find this:


    Insert this AFTER:
  5. Go to the Administration Tool->Modules->Payment section at your osCommerce Administration Tool.
  6. Install the PayPal IPN module and configure its parameters. Note: The module is disabled by default so configuration can occur during the operation of a live store.

back to top

Configuration Settings (Shop Admin)

Enable PayPal IPN Module

When enabled, the customer is allowed to choose the PayPal IPN payment method at the checkout procedure.

Gateway Server

The server to use for transaction processing.

The Testing server uses PayPals Sandbox server, and the Live server is used to process real transactions.

Please note that the Testing/Sandbox server is independent to the Live server, and requires it's own seller user account. Accounts can be created for free at https://developer.paypal.com.

Note: This is set to the Testing server by default.

E-Mail Address

The e-mail address of the business account setup at PayPal (the seller e-mail address). The funds gathered from purchased orders paid through the PayPal IPN module will be sent to this PayPal account.

Sort order of display

The order in which the PayPal IPN payment method should be shown on the checkout payment page if more than one payment method is available.

Transaction Currency

The currency for PayPal to use for the transaction. Selected Currency allows multiple currencies to be accepted, where the customer chosen currency is used for the transaction. If you use this option then you must have enabled acceptance of those currencies in your Pay Pal account settings. If a specific currency is selected (i.e. EUR, USD, ..) and the customer has selected another currency during the checkout procedure, the transaction will be forced to the currency defined by the store administrator.

Payment Zone

If defined, the PayPal IPN payment method will only be available to orders made within the defined zone.

Set Preparing Order Status

As soon as the checkout confirmation page is shown to the customer, the contents of the shopping cart are prematurely stored in the orders table with this defined order status.

If the customer decides to alter the content of their shopping cart (different products, different shipping or billing address, or if the currency has been changed), the order is deleted from the orders table and is reinserted with the updated information.

This only occurs when the checkout confirmation page is shown to the customer, so if the shopping cart has been modified, it will be out of sync with the premature order in the database until the checkout confirmation page is shown again.

If a premature order has been stored in the orders database table and the customer does not make the payment transaction at PayPal, the order will remain in the database until manually removed by the store administrator. This can be done easily by selecting the "Set Preparing Order Status" status on the status filter on the Administration Tool->Customers->Orders page, to show the current existing orders made prematurely.

Please take care when removing premature orders - make sure they are a few days old.

Premature orders will have their order status set to the "Preparing [PayPal IPN]" value but will not contain an entry in the order status history database table until the customer has made the payment transaction at PayPal and has returned back to the store to the checkout process and checkout success pages. (This can be used to differentiate between invalid and valid orders)

Set PayPal Acknowledged Order Status

This is the status the premature order is set to when an IPN notification from PayPal has been received, and has returned the result of VERIFIED.

Notifications with the result of INVALID will not make any modification to the premature order.

VERIFIED orders will automatically have an order status history record inserted containing the PayPal status values in the order comment. This comment will not be sent to the customer via e-mail, but is visible to the customer when they view their order online.

Set PayPal Completed Order Status

This is the status the premature order is set to when an IPN notification from PayPal has been received, has returned the result of VERIFIED and the PayPal payment status is returend as "completed".

Only orders where payment has been received successfully should show with this order status, allowing you e.g. to use it for releasing downloadable content.

Transaction Type

This allows you to define how the transactions should be processed at PayPal - either with each product in the order being passed to PayPal (Per Item), or without the products with just the order totals being passed to PayPal (Aggregate).

The recommended setting is Aggregate. Per item can cause problems, especially when used together with contributions such as CCGV(trad).

Move tax to total

Do you want to move the tax to the total amount? If true PayPal will allways show the total amount including tax. Now working in both 'per item' and 'aggregate' modes, so the choice is all yours.

Page Style

The page style to use which is defined in your PayPal Profile account. PayPal allows you to define page styles from within your PayPal account to display e.g. your logo during checkout. Leave blank for default style.

Debug E-Mail Address

All parameters to an Invalid order is sent to this e-mail address for debugging/verification purposes.

cURL Proxy server

If curl transactions need to go through a proxy, type the address here starting with http://. Otherwise, leave it blank. The current GoDaddy proxy address is http://proxy.shr.secureserver.net:3128

Enable Encrypted Web Payments

When enabled, the order parameters will be encrypted to be sent to PayPal.

Note: This feature requires a working OpenSSL installation on your server, with access rights to the "openssl" program file.

Note: The "openssl" program file is called via PHPs exec() function, which the webserver needs to have access to.

Your Private Key

The location and filename of your private key to use for signing the order data.

Your Public Certificate

The location and filename of your public certificate to use for signing the order data.

PayPal's Public Certificate

The location and filename of the PayPal public key to use for encrypting the order data.

Your PayPal Public Certificate ID

The public certificate ID that PayPal should use to decrypt the encrypted order data.

Note: This is defined at your PayPal Encrypted Payment Settings Profile page.

Working Directory

The working directory to create temporary files. (All created files are automatically deleted when no longer needed)

OpenSSL Location

The location and filename of the OpenSSL "openssl" program file.

back to top

PayPal Payment Status - info in order comment

The information sent back by PayPal is included in the order comment in brackets. The following replies are possible:

For more informatin and a full list of reasons please go to https://www.paypal.com/IntegrationCenter/ic_ipn-pdt-variable-reference.html and scroll down until you see "payment_ status".

Understanding the possible codes will help you to correctly identify the information sent back by PayPal and stored in the order comment.

Example

An order status which looks like this:
11/06/2006 12:49:50 False Pending PayPal IPN Invalid [Pending; address]
11/06/2006 13:20:49 True Processing
11/06/2006 13:24:30 False Pending PayPal IPN Verified [Completed (Unverified; $49.50)]
means that the payment was pending because "The payment is pending because your customer did not include a confirmed shipping address and your Payment Receiving Preferences is set to allow you to manually accept or deny each of these payments". Once the payment was acceped, the order status was updated to "Completed" by PayPal.

back to top

PayPal Account Configuration

Shipping Calculations

In order to send shipping/handling cost correctly to Paypal, you should not setup any Shipping Calculations in PayPal account Profile. Inactivating the settings will not work!! You must leave the Shipping Calculations blank!!


AutoReturn

You do NOT need to enable Auto Return in your PayPal account as this information is sent automatically by the IPN module.

If you do wish to activate it, then the return path is the pathway to the checkout_process.php file. Sample pathways are:

Note: Only enable AutoReturn if you have only shop linked to your PayPal account!

IPN

You do NOT need to enable the IPN in your PayPal account as all the required information is sent by the module.

If you do wish to activate it, then the notify URL is the pathway to the /ext/modules/payment/paypal_ipn/ipn.php file.

Duplicate order problem

The PayPal IPN sends a parameter "invoice" to PayPal. This parameter is equal to the order ID (1,2,3,4 etc). However, PayPal requires the invoice parameter to be unique so if you have already sent an order ID with the same number, then it will be refused. Sending the same order ID can e.g. happen if you have two osCom shops linked to one PayPal account - the PayPal account cannot distinguish between different shops / domains / databases, it just looks at the number and says "hey, that's already been paid!"

To disable the multiple order id checking to to your PayPal account - > "Profile" - > "Payment Receiving Preferences". In there you will have the option:

Block accidental payments:
You may prevent accidental payments by blocking duplicate invoice IDs
Yes, block multiple payments per invoice ID
No, allow multiple payments per invoice ID
Select "No".

PayPal will now allow all orders to be paid, even if the order ID has already been paid previously. A potential problem is if customers pay an invoice twice by mistake (e.g. refreshing browser, hitting button twice etc.).

back to top

Setting up Encrypted Web Payments

If you have SSL enabled, then you won't need to set up encrypted web payments as the payment module automatically uses SSL if available.

To set up yor encrypted web payments, log in to your PayPal account, click on "Profile - > Encrypted Payment Settings". Click on "Download" to download PayPal’s public certificate. Create your own certificate and upload it to PayPal.

To create your own certificate, you can use openssl:
Create a private key: openssl genrsa -out my-prvkey.pem 1024
Create the public certificate: openssl req -new -key my-prvkey.pem -x509 -days 365 -out my-pubcert.pem

When you upload your certificate, PayPal returns to you a "PayPal Public Certificate ID”=". This is one of the parameters that osC requires.

More info on this can be found at https://www.paypal.com/en_US/pdf/PP_WebsitePaymentsStandard_IntegrationGuide.pdf - If you have problems with encryped web payments I strongly recommend reading the relevant chapter in the PDF guide as it gives extensive guidance!

You can optionally block all non-encrypted payments: go to Profile > Website Payment Preferences, and choose “on” in “Block Non-encrypted Website Payment”

back to top

Integrating with other Contributions

Note: Rule of thumb - whenever you make ANY change to checkout_process.php you MUST manually merge the change into paypal_ipn.php and ipn.php

The PayPal IPN works different from other payment modules and bypasses the checkout_process file. Which means that any contribution which modifies the checkout_process.php file will require some manual coding TLC in paypal_ipn.php and ipn.php.

From version 1.3 of this module, the PayPal IPN Payment Module is compatible with the Register Globals Patch v1.4 - you do not need to make any modifications for this.

Version 2.0 introduces a new code base so any fixes posted for versions 1.x probably won't work without modification.

back to top

Frequently Asked Questions

I have no SSL and don't want to set up Encrypted Web Payments. Are paypal ok with me sending data unprotected?
Yes, in the Order Integration Guide (PDF) PayPal states that "Because credit card and bank information is not transmitted in Instant Payment Notification (IPN), PayPal does not require Secure Sockets Layer (SSL) to encrypt IPN transmissions." But note that there is a hack where customers can change the order value of unencryped payments, so make sure that the PayPal payment and the order value match.
Notice: It seems that PayPal has changed their behavior since September 2007, stores without SSL nor cURL lib installed started receiving PayPal Invalid Process emails, orders status, best sellers list and stock quantities stopped updating. If you don't have SSL, cURL lib is required for IPN to work with.
When I click Continue on the CONFIRM page, I go to my Test Store just fine, but the total shows $0. Any thoughts?
Check your currency - the 0 value usually occurs if your shop & your PayPal account have different currency restrictions or if you use the wrong abbreviation for the currency in your shop. Canada for exmaple must be CAD (and not CAN). A complete list of supported curency codes is here: Supported Currencies.
Page Style - The page style to use for the transaction procedure (defined at your PayPal Profile page). Should I touch anything here?
Only if you want to, otherwise leave blank. This setting allows you style the PayPal pages with your logo etc. Check your PayPal account help section for more information.
Set PayPal Acknowledged Order Status - Set the status of orders made with this payment module to this value - Which one? For now I have defualt is that ok?
Yes, default is fine, otherwise choose any value you wish from the drop-down. That's entirely your choice.
My orders sometimes say[Completed (Verified; $ and sometimes it says [Completed (Unverified; $)]. What does this mean and how does a order become verified?
Completed is means the money are already in your account, verified or unverified means whether the customer has a verified or unverfied paypal account.
I've got contribution ABC and now it doesn't work with the PayPal IPN!
This is a common complaint on the support thread. Please read the notes regarding contribution integration in this guide. As explained, the PayPal IPN bypasses checkout_process.php so any modifications made to this file will need to be integreated into paypal_ipn.php and ipn.php instead. This isn't a cookie cutter exercise and a reasonable knowledge of PHP and MySQL are highly desirable. Additional notes for developers are added at end of this document.
The OsCommerce version I'm running doesn't have a EXT directory. Do I need this ext directory? And what are the CHMOD instructions?
Yes, you need to create this directory - just upload the entire /ext/ folder to your site to ensure that you have the correct directory structure. CHMOD is 755 for folders, 644 for the file.

back to top

Troubleshooting

If payments are being received at PayPal but the stock level/orders status is not updated and confirmation emails are not sent, then IPN (Instant Payment Notification) is not working.
Follow the check list below for trouble shooting:
  • Make sure you have copied the ext folder to your server under your catalog directory.
  • Try to open catalog/ext/modules/payment/paypal_ipn/ipn.php in internet browser (http://yourdomain.com/catalog/ext/modules/payment/paypal_ipn/ipn.php
    change the words marked in red corresponding to your store). A blank page will show up if there is no problem accessing this script. If you can't access this script (access denied or file not found), nor can PayPal call back to it. Do not password protect the ext folder, and make sure the access permission is set to 644.
  • If your server has register globals off and you need to turn it on by using a custom php.ini file, you need to put that php.ini under the ext folder as well. IPN won't work if register globals turned off.
  • Check if you have a shared/dedicated SSL, or your server has cURL lib installed. IPN won't work if you don't have any of these.
  • Check if your server requires cURL connections to route through a proxy server. If this is the case, you need to setup the cURL proxy address.
  • If none of the tips above works, post your problem in detail to the support thread. Please include the PHP version, cURL version, osCommerce version and PayPal IPN version.

If orders are not returning data back from PayPal, then it is possible that "Register Globals" is not set On. A php.ini file must be present in the catalog/ext/modules/payment/paypal_ipn folder.


If email confirmations are sent with character anomalies and aren't formatted properly, then you may need to add the nl2br() tag to your tep_mail functions.

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


back to top

Support

Community support for this module is provided on the osCommerce forum: http://forums.oscommerce.com/index.php?act=ST&f=7&t=179917

There's also a useful thread by AlexStudio about PayPal IPN, SSLs & Encrypted Web Payments and Download Controller: http://forums.oscommerce.com/index.php?showtopic=177853&st=0&p=730503.

Please do not PM or email myself (Terra) unless you are looking for paid support via my osCom hosting & development company www.terranetwork.net.

back to top

Developer Notes

ipn.php

ipn.php handles the information returend by PayPal. Whenever the payment status changes, ipn.php is accessed and the order updated. Since version 2.0 the ipn.php also handles stock updates and sending of order emails. Please note that the ipn.php is accessed every time the status changes - e.g. when an echeck clears or a payment is refunded.

As the ipn.php is outside the customer's session id, we don't have all the arrays from checkout_process.php. What we have is:

To check what an array contains, you can send it as an email. Add the following code to ipn.php e.g. around line 91 (and change the email address to one of your own):
// DEBUG let's check the array
$order_email = print_r($_POST,true) . "\n\n" . EMAIL_SEPARATOR . "\n\n" . print_r($_order,true);
mail('youremail@yourdomain.com', 'Debug Test Array', $order_email);
// DEBUG DEBUG DEBUG

paypal_ipn.php

paypal_ipn.php handles the pre-storing of the order and sending the parameters to PayPal.

checkout_process.php

paypal_ipn.php bypases checkout_process by loading a redirect into the before_process. No code in checkout_process.php after the before_process() is used (around line 50).

Payment processes

osCommerce uses a number of functions in the checkout process to include code from the payment module. The following list gives you the function name and the page which contains it:

PayPal Resources

Pre-populate form field variables

IPN Variables

Developer PDF documentation

back to top