PHPackages                             josaliba/paypal-ipn-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. josaliba/paypal-ipn-bundle

ActiveSymfony-bundle[Payment Processing](/categories/payments)

josaliba/paypal-ipn-bundle
==========================

A Symfony2 bundle for retrieving and logging PayPal Instant Payment Notifications (PayPal IPNs)

0313PHP

Since Jun 18Pushed 8y ago1 watchersCompare

[ Source](https://github.com/josaliba/symfony2-paypal-ipn)[ Packagist](https://packagist.org/packages/josaliba/paypal-ipn-bundle)[ RSS](/packages/josaliba-paypal-ipn-bundle/feed)WikiDiscussions master Synced 2mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

Symfony2 PayPal IPN Bundle
==========================

[](#symfony2-paypal-ipn-bundle)

Overview
--------

[](#overview)

[symfony2-paypal-ipn](https://github.com/orderly/symfony2-paypal-ipn) is a Symfony2 bundle for working with the PayPal IPN (Instant Payment Notification) service. The bundle acts as a listener for the PayPal IPN service and logs the incoming orders to your database using Doctrine. Sending order confirmation emails is easy too (see the \[sample Twig email controller\] [twigcontroller](/orderly/symfony2-paypal-ipn/blob/master/src/Orderly/PayPalIpnBundle/Controller/TwigNotificationEmailController.php) for details).

symfony2-paypal-ipn is available on [Packagist](http://packagist.org/packages/orderly/paypal-ipn-bundle) [packagist](http://packagist.org/packages/orderly/paypal-ipn-bundle) and [KnpBundles](http://knpbundles.com/orderly/symfony2-paypal-ipn) [knpbundles](http://knpbundles.com/orderly/symfony2-paypal-ipn) as well as on GitHub.

Description
-----------

[](#description)

symfony2-paypal-ipn is a direct port of \[codeigniter-paypal-ipn\] [codeigniterpaypalipn](https://github.com/orderly/codeigniter-paypal-ipn), an equivalent library for CodeIgniter users, also by Orderly Ltd.

This library ("bundle" in Symfony language) focuses on the "post-payment" workflow, i.e. the processing required once the payment has been made and PayPal has posted an Instant Payment Notification call to the IPN controller.

This library handles:

1. Validating the IPN call
2. Logging the IPN call
3. Extracting the order and line item information from the IPN call
4. Interpreting PayPal's payment status
5. Storing the order and line items in the database
6. Dispathing an event so that other bundles can do their stuff

All pre-payment functionality (e.g. posting the checkout information to PayPal) and custom post-payment workflow (e.g. sending emails) is left as an exercise for the reader. If you require a more general-purpose Symfony2 toolkit for working with PayPal, please see the \[JMSPaymentPaypalBundle\] [jmspaymentbundle](https://github.com/schmittjoh/JMSPaymentPaypalBundle).

This library also support getting the status from the Payment Data Transfer (PDT).

Dependencies
------------

[](#dependencies)

The Symfony PayPal IPN Bundle depends on [Symfony2](http://symfony.com/) [symfony2](http://symfony.com/), \[Doctrine 2.0\] [doctrine2.0](http://www.doctrine-project.org/), and curl.

An example order confirmation email which uses the [Twig](http://twig.sensiolabs.org/) [twig](http://twig.sensiolabs.org/) templating language is also provided.

Installation
------------

[](#installation)

### 1. Install from GitHub

[](#1-install-from-github)

We're going to install the PayPalIPNBundle directly into your Symfony `vendor` directory:

```
$ cd {{YOUR SYMFONY APP}}/vendor
$ git clone git://github.com/orderly/symfony2-paypal-ipn.git
...
$ mv symfony2-paypal-ipn orderly
```

Now the all-important `OrderlyPayPalIpnBundle.php` file should now be available here:

```
{{YOUR SYMFONY APP}}/vendor/orderly/src/Orderly/PaypalIpnBundle/OrderlyPayPalIpnBundle.php

```

### 2. Register the bundle

[](#2-register-the-bundle)

We now need to register the new bundle. Edit your `AppKernel.php` file:

```
{{YOUR SYMFONY APP}}/app/AppKernel.php

```

and add the following line to the end of the `$bundles` array in the `registerBundles()` method:

```
new Orderly\PayPalIpnBundle\OrderlyPayPalIpnBundle(),

```

Now edit your `autoload.php` file:

```
{{YOUR SYMFONY APP}}/app/autoload.php

```

and add the following line to the end of your `registerNamespaces()` invocation:

```
'Orderly'          => __DIR__.'/../vendor/orderly/src',

```

### 3. Deploy the database tables

[](#3-deploy-the-database-tables)

With the PayPalIPN Bundle you have the choice of storing your date in a rational database like MySQL or to use MongoDB. The next section provides information on how to use the two different systems.

#### 3.1 Deploy the database tables using ORM (MySQL)

[](#31--deploy-the-database-tables-using-orm-mysql)

If you're going to use a rational database system like MySQL you have to configure the driver to use a doctrine ORM. You can achive this by adding the following configuration to your bundles configuration:

```
orderly_pay_pal_ipn:
    # ... Rest of the configuration
    drivers:
        orm:
            object_manager: doctrine.orm.entity_manager
            classes: ~
```

The next step is to update/create the necessary database tables required by PayPalIpnBundle. There are two different ways of deploying the three database tables:

##### Using the Symfony console

[](#using-the-symfony-console)

You can install the tables with the following command in your project console:

```
$ php app/console doctrine:schema:update --force
```

Note that this method does **not** copy across the table field comments found in the SQL file.

##### Manually running the MySQL script

[](#manually-running-the-mysql-script)

Alternatively, you can run the `create_mysql_tables.sql` MySQL file against your database. You can find the file here:

```
Orderly/PayPalIpnBundle/Resources/config

```

If you choose this option, you may want to modify the `DEFAULT CHARSET` for each table (currently set to "utf8") before running.

#### 3.2 Deploy the database tables using ODM (MongoDB)

[](#32--deploy-the-database-tables-using-odm-mongodb)

To use MongoDB for your data store, make sure to install the [DoctrineMongoDBBundle](http://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html) before activating the ODM Driver in your section. More information on how to configure the bundle can be found on the [Symfony2 website](http://symfony.com/doc/current/bundles/DoctrineMongoDBBundle/index.html).

```
orderly_pay_pal_ipn:
    #....
    drivers:
        odm:
            object_manager: doctrine.odm.mongodb.document_manager
            classes: ~
```

**Note:** A fully configured example can be found under **4.1 Use MongoDB backend**

##### Create the database tables

[](#create-the-database-tables)

By running the following command your going to create/update the MonogoDB Collections:

```
$ php app/console doctrine:mongodb:update --force
```

### 4. Configure

[](#4-configure)

Now we need to configure the bundle. Add the below into your Symfony2 YAML configuration file `app/config/config.yml`:

```
# PaypalIpnBundle Configuration
orderly_pay_pal_ipn:

    # If set to false then service loads settings with "sandbox_" prefix
    islive:  false

    # Constants for the live environment (default settings in Configuration.php)
    email:    sales@CHANGEME.com
    url:      https://www.paypal.com/cgi-bin/webscr
    proxy:    ~
    debug:    %kernel.debug%
    pdttoken: pdt-token

    # Constants for the sandbox environment (default settings in Configuration.php)
    sandbox_email:       system_CHANGEME_biz@CHANGEME.com
    sandbox_url:         https://www.sandbox.paypal.com/cgi-bin/webscr
    sandbox_proxy:       ~
    sandbox_debug:       true
    sandbox_response:    VERIFIED
    sandbox_pdttoken:    pdt-token
    sandbox_pdtresponse:
        payment_status: Completed
        mc_gross: 123.00

    drivers:
        orm:
            object_manager: doctrine.orm.entity_manager
            classes: ~
```

Make sure to update the `email` and `sandbox_email` settings to your own PayPal account's.

When `islive` is set to false, the following configuration can be activated:

- `sandbox_response` allows you to mock IPN Paypal's response. If you don't set its value, your server will hit the Paypal server and most likely return INVALID.
- `sandbox_pdtresponse` allows you to mock PDT Paypal's response. If you don't set its value, your server will hit the Paypal server and most likely return FAIL. To mock the value, simply pass in a list of key value pair the server would return.

A note on the `debug` setting: if set to true, then PayPalIpnBundle will store the last IPN access which had IPN data (i.e. POST variables) into the database. Then when you access the IPN URL directly without data, it reloads the cached data. So it's effectively a "replay" mode which let's you directly inspect what the `validateIPN()` IPN handler is doing.

#### 4.1 Use MongoDB backend

[](#41-use-mongodb-backend)

To use the IPN listener with a MongoDB backend change the drivers section to **odm** and provide the name of your MongoDB object manager. Enclosed is a basic example configuration.

```
# PaypalIpnBundle Configuration
orderly_pay_pal_ipn:

    # If set to false then service loads settings with "sandbox_" prefix
    islive:  false

    # Constants for the live environment (default settings in Configuration.php)
    email:    sales@CHANGEME.com
    url:      https://www.paypal.com/cgi-bin/webscr
    proxy:    ~
    debug:    %kernel.debug%
    pdttoken: pdt-token

    # Constants for the sandbox environment (default settings in Configuration.php)
    sandbox_email:       system_CHANGEME_biz@CHANGEME.com
    sandbox_url:         https://www.sandbox.paypal.com/cgi-bin/webscr
    sandbox_proxy:       ~
    sandbox_debug:       true
    sandbox_response:    VERIFIED
    sandbox_pdttoken:    pdt-token
    sandbox_pdtresponse:
        payment_status: Completed
        mc_gross: 123.00

    drivers:
        odm:
            object_manager: doctrine.odm.mongodb.document_manager
            classes: ~
```

### 5. Setup routing (optional but recommended)

[](#5-setup-routing-optional-but-recommended)

To tell Symfony's routing system where to find one of our sample controllers, first open up the following file:

```
{{YOUR SYMFONY APP}}/app/config/routing.yml

```

#### To send order confirmations with Twig

[](#to-send-order-confirmations-with-twig)

Assuming you want to send order confirmation emails using [Twig](http://twig.sensiolabs.org/) [twig](http://twig.sensiolabs.org/), add in this controller:

```
OrderlyPayPalIpnBundleEmail:
    resource: "@OrderlyPayPalIpnBundle/Controller/TwigNotificationEmailController.php"
    type:     annotation
    prefix:   /ipn/
```

Your site will now be listening for incoming Instant Payment Notifications on the URL:

```
http://{{YOUR DOMAIN}}/ipn/ipn-twig-email-notification

```

Note that the sample email template provided depends on Twig's \[`number_format`\] [numberformat](https://github.com/fabpot/Twig/commit/0edcfdd) filter, which was added in December 2012 (you may need to update your Twig version to use this). Don't forget to tell PayPal about your new PayPal IPN URL.

#### To log orders but not send notifications

[](#to-log-orders-but-not-send-notifications)

Alternatively if you just want to log orders in the database (and not send out any notifications), then add in this controller:

```
OrderlyPayPalIpnBundleNoEmail:
    resource: "@OrderlyPayPalIpnBundle/Controller/NoNotificationController.php"
    type:     annotation
    prefix:   /ipn/
```

Your site will now be listening for incoming IPNs on:

```
http://{{YOUR DOMAIN}}/ipn/ipn-no-notification

```

Don't forget to tell PayPal about your new PayPal IPN URL.

**Disclaimer: the sample controllers provided are exactly that - samples. Please update one or other of these sample files with your own business logic before putting this bundle into production.**

#### To receive PDT variables

[](#to-receive-pdt-variables)

This is an example of what your PDT call would look like.

```
namespace Your\OwnBundle;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class YourPaypalController extends Controller {
    /**
     * Your return action from Paypal.
     */
    public function completeAction() {
        $tx = $this->getRequest()->get('tx');
        if (!$tx) {
            // Redirect to a non-found page
            return $this->redirect($this->generateUrl('notFound'));
        }

        $pdt = $this->get('orderly_pay_pal_pdt');
        $pdtArray = $pdt->getPdt($tx);

        $status = 'unknown';
        if (isset($pdtArray['payment_status'])) {
            $status = $pdtArray['payment_status'];
        }

        return $this->render('YourOwnBundle:YourPaypal:complete.html.twig',
            array('status' => $status)
        );
    }
}
```

### 6. Subscribing to events (if you need custom processing)

[](#6-subscribing-to-events-if-you-need-custom-processing)

After an IPN is received and if it is a valid one, an event with the incoming IPN will be dispatched. You can then subscribe a listener and perform whatever you need to do. Change your `config.yml` with something like this:

```
services:
    # ...

    paypal_im_received:
        class: Your\OwnBundle\Event\YourPayPalListener
        arguments: ["@doctrine.orm.entity_manager"]
        tags:
            - { name: kernel.event_listener, event: paypal.ipn.receive, method: onIPNReceive }

```

Now you just need to code your custom listener

```
namespace Your\OwnBundle\Event;

use Orderly\PayPalIpnBundle\Event\PayPalEvent;
use Doctrine\Common\Persistence\ObjectManager;

class YourPayPalListener {

    private $om;

    public function __construct(ObjectManager $om) {
        $this->om = $om;
    }

    public function onIPNReceive(PayPalEvent $event) {
        $ipn = $event->getIPN();
        // do your stuff
    }
}

```

### 7. Test and troubleshoot

[](#7-test-and-troubleshoot)

Now it's time to test. First, make sure that `islive` is set to false, and `sandbox_debug` is set to true.

Once debugging is switched on, this is how you test:

- Run through your checkout process as normal, making your PayPal sandbox payment etc
- PayPal will send the IPN POST data to your new PayPal IPN URL
- Check the PayPal IPN history for success or failure (e.g. HTTP status code 500)
- Check you received the order confirmation email (if you're sending one)
- Check the order and line items are stored in your database

If you have problems with any of your checks, then the next step is to manually invoke your IPN URL in a browser and see what happens (for example a PHP or Symfony error, or perhaps a database or Twig not found error). This works because of the debug "replay" functionality explained in step 3 above. Next:

- Fix the bug
- Repeat

### 8. Full configuration

[](#8-full-configuration)

```
# PaypalIpnBundle Configuration
orderly_pay_pal_ipn:

    # If set to false then service loads settings with "sandbox_" prefix
    islive:  false

    # Constants for the live environment (default settings in Configuration.php)
    email:    sales@CHANGEME.com
    url:      https://www.paypal.com/cgi-bin/webscr
    proxy:    ~
    debug:    %kernel.debug%
    pdttoken: pdt-token

    # Constants for the sandbox environment (default settings in Configuration.php)
    sandbox_email:       system_CHANGEME_biz@CHANGEME.com
    sandbox_url:         https://www.sandbox.paypal.com/cgi-bin/webscr
    sandbox_proxy:       ~
    sandbox_debug:       true
    sandbox_response:    VERIFIED
    sandbox_pdttoken:    pdt-token
    sandbox_pdtresponse:
        payment_status: Completed
        mc_gross: 123.00

    drivers: # Define one driver only.
        orm:
            object_manager: doctrine.orm.entity_manager
            classes:
                ipn_log: Orderly\PayPalIpnBundle\Entity\IpnLog
                ipn_order_items: Orderly\PayPalIpnBundle\Entity\IpnOrderItems
                ipn_orders: Orderly\PayPalIpnBundle\Entity\IpnOrders
        # OR for MongoDB support
        odm:
            object_manager: doctrine.odm.mongodb.document_manager
            classes:
                ipn_log: Orderly\PayPalIpnBundle\Document\IpnLog
                ipn_order_items: Orderly\PayPalIpnBundle\Document\IpnOrderItems
                ipn_orders: Orderly\PayPalIpnBundle\Document\IpnOrders
```

Support and bugs
----------------

[](#support-and-bugs)

For support requests, please email \[Orderly Ltd\] [orderlyemail](orderly-support@keplarllp.com). If you think there is a bug in the library, or a missing feature you would like to see added, please raise a \[new GitHub issue\] [newissue](https://github.com/orderly/symfony2-paypal-ipn/issues/new).

Credits
-------

[](#credits)

This library is a port of the \[Codeigniter PayPal IPN library\] [codeigniterpaypalipn](https://github.com/orderly/codeigniter-paypal-ipn), also released by Orderly Ltd.

Many thanks to all the contributors to symfony2-paypal-ipn:

- Author: [Kemor](https://github.com/kemor) [kemor](https://github.com/kemor)
- Contributor: [Strife](https://github.com/strife) [strife](https://github.com/strife)
- Contributor: \[Alex Dean\] [alexdean](https://github.com/alexanderdean)
- Contributor: \[Ivo Azirjans\] [ivoaz](https://github.com/ivoaz)
- Contributor: \[Alexander Pirsig\] [piscis](https://github.com/piscis)
- Contributor: \[Carles Climent\] [carlescliment](https://github.com/carlescliment)

Disclaimer and warning
----------------------

[](#disclaimer-and-warning)

Orderly Ltd does not accept any liability for any processing errors made by the Symfony2 PayPal IPN Bundle, or any financial losses incurred through its use.

In particular, this library does *not* fulfil the PayPal IPN requirement to:

> verify that the payment amount actually matches what you intend to charge. Although not technically an IPN issue, if you do not encrypt buttons, it is possible for someone to capture the original transmission and change the price. Without this check, you could accept a lesser payment than what you expected.

(This verification step is out of scope for this bundle because it would require integration with your product catalogue.)

Additionally this library does **not** properly handle refunds. Typically refunds are stored as a new order line in `ipn_orders` with a negative balance, but even this is not 100% predicatable.

Copyright
---------

[](#copyright)

symfony2-paypal-ipn is copyright (c) 2012 Orderly Ltd.

License
-------

[](#license)

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity12

Limited adoption so far

Community16

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 59.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/dc354dc753aeddb8f27083c03575bca58219c025a93f03a1dafa2a1ea54eacd1?d=identicon)[josaliba](/maintainers/josaliba)

---

Top Contributors

[![alexanderdean](https://avatars.githubusercontent.com/u/200511?v=4)](https://github.com/alexanderdean "alexanderdean (64 commits)")[![piscis](https://avatars.githubusercontent.com/u/326163?v=4)](https://github.com/piscis "piscis (20 commits)")[![carlescliment](https://avatars.githubusercontent.com/u/1255401?v=4)](https://github.com/carlescliment "carlescliment (5 commits)")[![jsgoupil](https://avatars.githubusercontent.com/u/808649?v=4)](https://github.com/jsgoupil "jsgoupil (5 commits)")[![freddyhaddad](https://avatars.githubusercontent.com/u/1421933?v=4)](https://github.com/freddyhaddad "freddyhaddad (3 commits)")[![micronax](https://avatars.githubusercontent.com/u/1337823?v=4)](https://github.com/micronax "micronax (2 commits)")[![ivoaz](https://avatars.githubusercontent.com/u/407855?v=4)](https://github.com/ivoaz "ivoaz (2 commits)")[![broncha](https://avatars.githubusercontent.com/u/46905?v=4)](https://github.com/broncha "broncha (2 commits)")[![josaliba](https://avatars.githubusercontent.com/u/1430362?v=4)](https://github.com/josaliba "josaliba (2 commits)")[![Schrank](https://avatars.githubusercontent.com/u/379680?v=4)](https://github.com/Schrank "Schrank (1 commits)")[![ivoaz-arcana](https://avatars.githubusercontent.com/u/6313617?v=4)](https://github.com/ivoaz-arcana "ivoaz-arcana (1 commits)")

### Embed Badge

![Health badge](/badges/josaliba-paypal-ipn-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/josaliba-paypal-ipn-bundle/health.svg)](https://phpackages.com/packages/josaliba-paypal-ipn-bundle)
```

###  Alternatives

[omnipay/paypal

PayPal gateway for Omnipay payment processing library

3156.8M53](/packages/omnipay-paypal)[eduardokum/laravel-boleto

Biblioteca com boletos para o laravel

626351.9k2](/packages/eduardokum-laravel-boleto)[tbbc/money-bundle

This is a Symfony bundle that integrates moneyphp/money library (Fowler pattern): https://github.com/moneyphp/money.

1961.9M](/packages/tbbc-money-bundle)[2checkout/2checkout-php

2Checkout PHP Library

83740.3k2](/packages/2checkout-2checkout-php)[smhg/sepa-qr-data

Generate QR code data for SEPA payments

61717.2k5](/packages/smhg-sepa-qr-data)[omnipay/dummy

Dummy driver for the Omnipay payment processing library

271.2M33](/packages/omnipay-dummy)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
