retro spiller

technokracy

Testing Stripe Webhooks and CakePHP

In my previous post, Stripe Webhooks and CakePHP, I included a sample controller method that received a webhook from Stripe and turned it into a PHP object, then retrieved the event from Stripe (based on the webhook event id) and took action based on what type the event was.

As the Stripe API library uses static methods, we can easily simulate these in a controller test. The two classes we’ll build for testing are Stripe and Stripe_Event, and only need a single method each.

At the top of our ControllerTest.php file after App::uses('UsersController', 'Controller');, the Stripe class containing a mocked setApiKey method:

1
2
3
4
5
6
7
8
<?php
class Stripe {

  public static function setApiKey($key) {
      return true;
  }

}

Next, the Stripe_Event class extending the Stripe class will also have a single method retrieve, which will return simulated results based on the event_id given:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
<?php
class Stripe_Event extends Stripe {

  public static function retrieve($event_id) {
      $json = array(
          'evt_00000000000001' => '{
             "id": "evt_00000000000001",
             "type": "invoice.payment_succeeded",
             "data": {
                 "object": {
                     "date": 1380720202,
                     "id": "in_2gBzT1cqSAkJkx",
                     "period_start": 1380720202,
                     "period_end": 1380720202,
                     "subtotal": 6000,
                     "total": 6000,
                     "customer": "cus_2f60z3nrkGskCg",
                     "paid": true,
                     "amount_due": 6000,
                     "charge": "ch_2gBzl5UsuosW2R",
                 }
             }
         }',
          'evt_00000000000002' => '{
             "id": "evt_00000000000003",
             "type": "invoice.payment_failed",
             "data": {
                 "object": {
                     "date": 1380720202,
                     "id": "in_2gBzT1cqSAkJkA",
                     "period_start": 1380720202,
                     "period_end": 1380720202,
                     "subtotal": 0,
                     "total": 0,
                     "customer": "cus_2f62nI7WxHsL33"
                 }
             }
         }',
          'evt_00000000000003' => '{
             "id": "evt_00000000000004",
             "type": "customer.subscription.deleted",
             "data": {
                 "object": {
                     "date": 1380720202,
                     "id": "in_2gBzT1cqSAkJkA",
                     "period_start": 1380720202,
                     "period_end": 1380720202,
                     "subtotal": 0,
                     "total": 0,
                     "customer": "cus_2f60z3nrkGskCg"
                 }
             }
         }',
      );
      return json_decode($json[$event_id]);
  }
}

I’ve trimmed the JSON data down to what is relevant to my app, but it’s easy to get test JSON from Stripe via the Events & Webhooks section of the dashboard. Just find the event you would like to test and copy and paste the event data into the mocked retrieve method.

In the actual test, set the event_id to retrieve the desired event. For example, to retrieve the first “invoice.payment_succeeded” event:

1
2
3
4
5
6
7
8
<?php
$json_request = '{
 "id": "evt_00000000000001"
}';
$result = $this->testAction('/users/process_webhook', array(
  'data' => $json_request,
  'method' => 'post'
));

Happy testing!