Payum making inroads into PHP Ecommerce – Notifications: Series I

My friend Maksim is making great inroads in an ecommerce component for abstracting payment processing. The library is called Payum and it is being integrated into popular Ecommerce frameworks such as Vespolina and Sylius. We have successfully integrated it with Sylius and soon will be in Vespolina.

Here is his write up on how to handle notifications with Payum:

Untitled (1)

Managing notifications.

The notification is a callback. A payment can send it back to us to let us know about changes.
It could be Paypal Instant Payment Notification (IPN) or Payex Transaction Callback for example.
Here in this chapter we show you how to store it somewhere and process it later (with a cron script for example).


First we have to create a model where we would store all the info:

class Notification extends \ArrayObject
    protected $id;
    public function getId()
        return $this->id;

Then we have to do our notification action which would actually do all the job:

use Payum\Action\ActionInterface;
use Payum\Request\SecuredNotifyRequest;
class StoreNotificationAction implements ActionInterface
    protected $notificationStorage;
    public function __constructor(StorageInterface $notificationStorage)
        $this->notificationStorage = $notificationStorage;
    public function execute($request)
        $notification = $this->notificationStorage->createModel();
        foreach ($request->getNotification() as $name => $value) {
            $paymentNotification[$name] => $value;
    public function supports($request)
        return $request instanceof SecuredNotifyRequest;

In the code above we created payum custom action.
The main purpose of the action to store notification that with a request.
To do so it requires a storage.
Now we can update `config.php` described in the documentation.

use Payum\Extension\StorageExtension;
use Payum\Storage\FilesystemStorage;
$storeNotificationAction = new StoreNotificationAction(
    new FilesystemStorage('/path/to/storage', 'Notification', 'id')

Now we have to implement `notify.php` script which must be accessible from the internet.

use Payum\Request\SecuredNotifyRequest;
include 'config.php';
$token = $requestVerifier->verify();
$payment = $registry->getPayment($token->getPaymentName());
$payment->execute(new SecuredNotifyRequest($_REQUEST, $token));

Setup Paypal IPN.

The code above could be reused by any payment.
Now I want to show changes need to enable Paypal IPN. To do so we have to modify `prepare.php` a bit:

$notifyToken = $tokenStorage->createModel();
$paymentDetails['NOTIFYURL'] = $notifyToken->getTargetUrl();

Here we created one more token: `notify` and tell paypal to use its target url for notifications.

You can find more on and the official site here.

It is comming to you soon in too!

Thanks to Maksim’s fine abstractions!

DDD Kata Primes Video with PHPSpec

I created a video for the primes kata from my understanding of DDD approach. Here is the repo

Plese keep in mind I worked already seen the other solution, however under similar principles but with different flow of work and focus. Also I did the work with lots of interruption and and mobilizing on a taxi twice and from remote with bad and 0 wifi access. I used the previous solution a bit as the domain expert and tried to focus on intent.

The vide is taking a long time so when it is up on vimeo I will post a note update on this blog post.


Medusa + Satis: Effective Mobile Work On Symfony2 Components Projects

There was a time when one could wait for composer to finish downloading dependencies.

There was a time when one could do other things while waiting for composer install to finish.

There was a time when one needed to give a demo talk and had to entertain people while downloading on the background.

No more!

Introducing Medusa + Satis!

step 1: First of all, clone composer/satis and instaclick/medusa into folders under your say main folder Sites. Then run on each one of them composer (composer install). Do this for both of the repos satis and medusa. This will create medusa/bin/medusa and satis/bin/satis scripts to be run later.

step 2: Clone medusa/skeleton parallel to the satis and medusa folders above.

git clone
cd medusa-skeleton
cp satis.json.dist satis.json
pico medusa.json // add more packages should need be

step 3: Use the scripts.

I have created some scripts on the skeleton ``, etc.

So easily do:




step 4: Ensure composer uses satis.

And make your global ~/.composer/config.json look like:

~ cat ~/.composer/config.json                                                  Luiss-MacBook-Pro-2 [17:14:27]
    "config": {
        "github-oauth": {
            "": "XYZ"
    "repositories": [
            "type": "composer",
            "url": "http://satis.l"

Since you have said http://satis.l is a local served folder, then add your vhost and entry on /etc/hosts accordingly to serve files on web folder under medusa-skeleton folder. Don’t forget to restart apache ;).

Check the index.html file created:

Screen Shot 2013-09-16 at 1.14.57 PM

step 5: Use it.

Your personal packagist thanks to satis. And also now test your medusa by disconnecting your wifi and continue developing with composer. In my case I have added the phpspec/phpspec repository so that it will not go online for this but rather fetch it from my server. So if you create a new folder, add a composer.json for a new project with just this dependency then you can freely run composer install:

    "name": "cordoval/x",
    "autoload": {
        "psr-0": {
            "": "src/"
    "require": {
        "php": ">=5.3.3",
        "phpspec/phpspec": "2.0.*@dev"
    "config": {
        "bin-dir": "bin"
    "minimum-stability": "dev"

With the above composer.json:

composer install
Loading composer repositories with package information
The "" file could not be downloaded: php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known
failed to open stream: php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known could not be fully loaded, package information was loaded from the local cache and may be out of date
Installing dependencies (including require-dev)
  - Installing symfony/yaml (dev-master 6286e95)
    Cloning 6286e95889e326311ff90ae4f96ddc15d6db2c39
  - Installing symfony/finder (dev-master ad276bc)
    Cloning ad276bcd7378de41257550c42c4bc0c059783ef3
  - Installing symfony/event-dispatcher (dev-master f86ac04)
    Cloning f86ac04039d0f529ef5ad572b9014453975bc3ad
  - Installing symfony/console (dev-master 8b3d262)
    Cloning 8b3d2627cc923f07bac5bb9fdc0622363ce1369b
  - Installing phpspec/prophecy (dev-master 00741ed)
    Cloning 00741edfbb26f588a1ea679e71da91263aca7240
  - Installing phpspec/php-diff (v1.0.1)
    Cloning 8d82ac415225fac373a4073ba14b1fe286aa2312
  - Installing phpspec/phpspec (dev-master 79f9127)
    Cloning 79f91276fc8c853596b8180103d93762072e457a
symfony/event-dispatcher suggests installing symfony/dependency-injection ()
symfony/event-dispatcher suggests installing symfony/http-kernel ()
phpspec/phpspec suggests installing whatthejeff/nyancat-scoreboard (~1.1 – Enables the Nyan Cat formatter)
Writing lock file
Generating autoload files

All of this while disconnected from the internets. From now on you can:

  • Create your own component repos and composer install them like you do but within your local dev lappy.
  • Create your own private component repos and composer install them like you do but within your local dev lappy.
  • Cache public repos and have no care for network delays and whenever you do a talk do demos with no care of whether network is down or saturated or if it takes x time.

I hope you enjoy this and is useful on your projects. Please support me by buying my Symfony2 Ecommerce book.

Thanks for reading!

Libro de Un Año con Symfony (Symfony2) en Español

Gracias a Matthias Noback por dejarme traducir su libro “Un Año con Symfony”. Este será lanzado el 4 de Octubre. Yo estaré en Argentina en el el mismo dia danto una charla. Luego de mucho trabajo traduciendo y leyendo por segunda vez el libro he quedado impresionado de todo lo que he podido aprender de Matthias. Si eres un desarrollador que le gusta leer las cosas en su propio idioma este libro de buen nivel te va a encantar.

Screen Shot 2013-09-14 at 3.25.45 AM

Recuerda si te anotas antes del 4 de Octubre obtendrás un descuento. Con mucho esfuerzo para la comunidad!