Testing Stripe Webhooks in PHP applications

Responsible web developers should practice test driven development, but let's be honest, many of us skip testing once in a while to speed up feature development or at least that's what we say to ourselves in order to sleep better. Even if you are not really responsible, you should at least test the most crucial part of your application and what's more crucial than handling payment.

Stripe is a major payment processing service, it is safe to say that 99% of developers prefer working with Stripe than any other payment gateway due to it's clear and well documented API and the fact that many other developer have already created beautiful packages which make working with Stripe a breeze.

The simple package we've created might be the one you were missing and I'll tell you why in a second.

In case you are building a remotely complicated application which handles Stripe payments you'll probably have to process so called web hooks or events which happen on the Stripe's side and which are actually regular HTTP requests. Stripe can notify you for example when a charge is captured or a charge failed and this is something your application should know about and handle.

Let's see how we could capture events in a simple Laravel route. By the way this is just an example, the same principles apply to other frameworks and the package is framework agnostic so you can plug it in any php application.

The simplest way to capture Stripe web hook events is to create a route like this:

Route::post('stripe/webhooks', function () {
    /* Get web hook event type */
    $eventType = Input::json('type');

    /* Fire an event */
    $response = Event::fire($eventType, Input::json());

    /* you should test the response right? read on... */

});

This is a simple route which will capture web hooks from Stripe, and then it will fire an event named by Stripe's convention which can be handled in an Event class, similar to this:

class StripeEventHandler {

    /**
     * Handle charge captured event
     */
    public function onChargeCaptured($event)
    {

    }

    /**
     * Register the listeners for the subscriber.
     *
     * @param  Illuminate\Events\Dispatcher  $events
     * @return array
     */
    public function subscribe($events)
    {
        $events->listen('charge.captured', 'StripeEventHandler@onChargeCaptured');
    }

}

This setup seems simple and it's probably something many of you have created in this or similar fashion. But what should you do in order to test the functionality of your event handler? You want to automate the testing and the only way to test Stripe web hooks is to log into Stripe's interface and click a simulated web hook event, not really automatic testing is it?

The PHP Stripe Webhook Tester package allows you to easily test (simulate) all of Stripe's web hook events and it's really easy in your test suite to trigger an event you want to test like this:

$tester = new TeamTNT\Stripe\WebhookTester();
$tester->setVersion('2014-09-08');
$tester->setEndpoint('http://local.dev/stripe/webhooks');

$response = $tester->triggerEvent('charge.succeeded');

Since Stripe has different versions of the API you can specify which version (by date) you want to simulate with the setVersion() method or you can skip to use the default.

You can also chain methods in order to have shorter code, like this:

$tester = new TeamTNT\Stripe\WebhookTester('http://local.dev/stripe/webhooks);
$response = $tester->setVersion('2014-09-08')->triggerEvent('charge.succeeded');

For the ones of you who are lazy, here is a simple unit test example on how to test the charge.succeded event

<?php 

use TeamTNT\Stripe;

class WebhookControllerTest extends TestCase {

    public function testChargeSucceded()
    {
        $tester = new WebhookTester('http://localhost/stripe/webhooks');
        $response = $tester->triggerEvent('charge.succeeded');
        $this->assertEquals(200, $response->getStatusCode());
    }
}

Now, you can assert the response to your liking and you'll be safe that your application is doing what it's meant to do. You can grab the package from Github - Php Stripe Webhook Tester.

Happy coding and feel free to leave comments.



comments powered by Disqus