File Coverage

blib/lib/Business/GoCardless/Webhook.pm
Criterion Covered Total %
statement 32 33 96.9
branch 2 2 100.0
condition n/a
subroutine 10 10 100.0
pod 5 5 100.0
total 49 50 98.0


line stmt bran cond sub pod time code
1             package Business::GoCardless::Webhook;
2              
3             =head1 NAME
4              
5             Business::GoCardless::Webhook
6              
7             =head1 DESCRIPTION
8              
9             A class for gocardless webhooks, extends L.
10             For more details see the gocardless API documentation specific to webhooks:
11             https://developer.gocardless.com/#webhook-overview
12              
13             =cut
14              
15 19     19   2547 use strict;
  19         49  
  19         567  
16 19     19   151 use warnings;
  19         61  
  19         448  
17              
18 19     19   100 use Moo;
  19         66  
  19         102  
19             extends 'Business::GoCardless::Resource';
20             with 'Business::GoCardless::Utils';
21              
22 19     19   6827 use JSON ();
  19         54  
  19         472  
23 19     19   126 use Business::GoCardless::Exception;
  19         45  
  19         11261  
24              
25             =head1 ATTRIBUTES
26              
27             resource_type
28             action
29              
30             =cut
31              
32             has [ qw/
33             resource_type
34             action
35             _payload
36             / ] => (
37             is => 'rw',
38             clearer => 1,
39             );
40              
41             =head1 Operations on a webhook
42              
43             =head2 json
44              
45             Allows you to set the json data sent to you in the webhook:
46              
47             $Webhook->json( $json_data )
48              
49             Will throw a L exception if the json fails to
50             parse or if the signature does not match the payload data.
51              
52             =cut
53              
54             has json => (
55             is => 'rw',
56             required => 1,
57             trigger => sub {
58             my ( $self,$json ) = @_;
59              
60             # defensive decoding
61             my $params;
62             eval { $params = JSON->new->decode( $json ) };
63             $@ && do {
64             $self->_clear_payload;
65             $self->clear_resource_type;
66             $self->clear_action;
67              
68             Business::GoCardless::Exception->throw({
69             message => "Failed to parse json: $@",
70             });
71             };
72              
73             $self->resource_type( $params->{payload}{resource_type} );
74             $self->action( $params->{payload}{action} );
75             $self->_payload( $params->{payload} );
76              
77             if ( ! $self->signature_valid(
78             $params->{payload},$self->client->app_secret )
79             ) {
80             $self->_clear_payload;
81             $self->clear_resource_type;
82             $self->clear_action;
83              
84             Business::GoCardless::Exception->throw({
85             message => "Invalid signature for webhook",
86             });
87             }
88              
89             return $json;
90             }
91             );
92              
93             =head2 resources
94              
95             Returns an array of resource objects (Bill, Subscription, etc) that are present
96             in webhook allowing you to do things with them or update your own data:
97              
98             if ( $Webhook->is_bill ) {
99             foreach my $Bill ( $Webhook->resources ) {
100             ...
101             }
102             } elsif ( $Webhook->is_subscription ) {
103             ...
104              
105             =cut
106              
107             sub resources {
108 4     4 1 933 my ( $self ) = @_;
109              
110 4         8 my @resources;
111              
112 4 100       29 return if ! $self->resource_type;
113              
114             my $key = {
115             bill => 'bills',
116             pre_authorization => 'pre_authorizations',
117             subscription => 'subscriptions',
118 2         15 }->{ $self->resource_type };
119              
120 2         19 my $class_suffix = ucfirst( $self->resource_type );
121 2         6 $class_suffix =~ s/_([A-z])/uc($1)/ge;
  0         0  
122 2         356 my $class = "Business::GoCardless::$class_suffix";
123              
124 2         6 foreach my $hash ( @{ $self->_payload->{ $key } } ) {
  2         11  
125              
126             my $obj = $class->new(
127             client => $self->client,
128 4         14 %{ $hash },
  4         70  
129             );
130              
131 4         56 push( @resources,$obj );
132             }
133              
134 2         17 return @resources;
135             }
136              
137             =head2 is_bill
138              
139             =head2 is_pre_authorization
140              
141             =head2 is_subscription
142              
143             Shortcut methods to get the type of data in the webhook, and thus the type of
144             objects that will be returned by the call to ->resources
145              
146             =cut
147              
148 2     2 1 3544 sub is_bill { return shift->resource_type eq 'bill' }
149 2     2 1 17 sub is_pre_authorization { return shift->resource_type eq 'pre_authorization' }
150 2     2 1 23 sub is_subscription { return shift->resource_type eq 'subscription' }
151              
152             =head2 is_legacy
153              
154             See if the webhook is a legacy (Basic API) webhook
155              
156             if ( $Webhook->is_legacy ) {
157             ...
158             }
159              
160             =cut
161              
162 2     2 1 10 sub is_legacy { 1 }
163              
164             =head1 CONFIRMING WEBHOOKS
165              
166             According to the gocardless API docs you should respond once the signature of the
167             webhook has been checked. The response is a HTTP status 200 code:
168              
169             HTTP/1.1 200 OK
170              
171             You should handle this in your own code, the library will not do it for you. See
172             https://developer.gocardless.com/#response for more information
173              
174             =head1 AUTHOR
175              
176             Lee Johnson - C
177              
178             This library is free software; you can redistribute it and/or modify it under
179             the same terms as Perl itself. If you would like to contribute documentation,
180             features, bug fixes, or anything else then please raise an issue / pull request:
181              
182             https://github.com/Humanstate/business-gocardless
183              
184             =cut
185              
186             1;
187              
188             # vim: ts=4:sw=4:et