File Coverage

blib/lib/Net/Stripe/Simple.pm
Criterion Covered Total %
statement 465 476 97.6
branch 122 146 83.5
condition 28 47 59.5
subroutine 123 124 99.1
pod 23 23 100.0
total 761 816 93.2


line stmt bran cond sub pod time code
1             package Net::Stripe::Simple;
2             $Net::Stripe::Simple::VERSION = '0.004';
3             # ABSTRACT: simple, non-Moose interface to the Stripe API
4              
5 3     3   246070 use v5.10;
  3         12  
6 3     3   18 use strict;
  3         5  
  3         83  
7 3     3   16 use warnings;
  3         4  
  3         116  
8              
9 3     3   16 use Exporter qw(import);
  3         5  
  3         108  
10 3     3   2460 use LWP::UserAgent;
  3         146122  
  3         123  
11 3     3   1597 use HTTP::Request::Common qw(GET POST DELETE);
  3         6595  
  3         262  
12 3     3   1651 use MIME::Base64 qw(encode_base64);
  3         2004  
  3         199  
13 3     3   20 use URI::Escape qw(uri_escape);
  3         4  
  3         173  
14 3     3   17 use Scalar::Util qw(reftype blessed);
  3         6  
  3         165  
15 3     3   2330 use JSON ();
  3         30771  
  3         97  
16 3     3   1492 use Devel::StackTrace;
  3         7828  
  3         77  
17              
18 3     3   1624 use Net::Stripe::Simple::Data;
  3         7  
  3         94  
19 3     3   1233 use Net::Stripe::Simple::Error;
  3         6  
  3         181  
20              
21             our @EXPORT_OK = qw(true false null data_object);
22             our %EXPORT_TAGS = ( const => [qw(true false null)], all => \@EXPORT_OK );
23              
24 3     3   13 use constant API_BASE => 'https://api.stripe.com/v1';
  3         3  
  3         16277  
25              
26             # version of stripe's API to use
27             our $STRIPE_VERSION = '2014-06-17';
28              
29              
30             sub new {
31 1     1 1 1424 my ( $class, $api, $version ) = @_;
32 1   33     8 $class = ref($class) || $class;
33 1 50       3 die 'API key required' unless $api;
34 1   33     5 $version //= $STRIPE_VERSION;
35              
36 1   50     3 my $pkg_version = $Net::Stripe::Simple::VERSION // '0.01';
37              
38 1         8 my $ua = LWP::UserAgent->new;
39 1         2403 $ua->agent("$class/$pkg_version");
40 1         58 my $auth = 'Basic ' . encode_base64( $api . ':' );
41 1         9 bless { ua => $ua, auth => $auth, version => $version }, $class;
42             }
43              
44             # API
45              
46             # generic argument validation
47             sub _validate {
48 147     147   354 my $self = shift;
49 147         288 my $name = shift;
50 147         258 my $actions = shift;
51 147         320 my $action = shift;
52 147         435 ( my $err_name = $name ) =~ tr/_/ /;
53 147 100       1121 my $args = ref $_[0] eq 'HASH' ? $_[0] : { @_ == 1 ? ( id => $_[0] ) : @_ };
    100          
54 147 50       820 die "$err_name action required" unless $action;
55 147 50       666 die "unknown $err_name action: $action" unless exists $actions->{$action};
56 147   66     1274 my $method = $actions->{$action} //= $self->can("_${action}_$name");
57 147 50       513 die "logic error: $action $err_name action not implemented" unless $method;
58 147         498 return $args, $method;
59             }
60              
61             # removes private keys from args
62             sub _clean {
63 59     59   130 my $args = shift;
64 59         429 delete @$args{ grep /^_/, keys %$args };
65             }
66              
67             # generic implementations of these operations
68              
69             sub _retrieve {
70 23     23   56 my ( $self, $args ) = @_;
71 23         83 my ( $base, $id ) = @$args{qw(_base id)};
72 23 100       106 _invalid('No id provided.') unless defined $id;
73 12         97 return $self->_get( $base . '/' . uri_escape($id) );
74             }
75              
76             sub _update {
77 14     14   37 my ( $self, $args ) = @_;
78 14         59 my ( $base, $id ) = delete @$args{qw(_base id)};
79 14 100       101 _invalid('No id provided.') unless defined $id;
80 7         70 _clean($args);
81 7         61 return $self->_post( $base . '/' . uri_escape($id), $args );
82             }
83              
84             sub _create {
85 17     17   98 my ( $self, $args ) = @_;
86 17         56 my $base = delete $args->{_base};
87 17         57 _clean($args);
88 17         84 return $self->_post( $base, $args );
89             }
90              
91             sub _list {
92 11     11   31 my ( $self, $args ) = @_;
93 11         36 my $base = delete $args->{_base};
94 11         43 _clean($args);
95 11         66 return $self->_get( $base, $args );
96             }
97              
98             sub _del {
99 16     16   37 my ( $self, $args ) = @_;
100 16         58 my ( $base, $id ) = @$args{qw(_base id)};
101 16 100       92 _invalid('No id provided.') unless defined $id;
102 11         112 return $self->_delete( $base . '/' . uri_escape($id) );
103             }
104              
105             # create a common uri base; expects customer id and sub-base
106             sub _customer_base {
107 23     23   52 my $customer = shift;
108 23 100       93 _invalid('No customer id provided.') unless defined $customer;
109 19         131 return 'customers/' . uri_escape($customer) . '/' . shift;
110             }
111              
112              
113             sub charges {
114 9     9 1 2367 my $self = shift;
115             state $actions =
116 9         22 { map { $_ => undef } qw(create retrieve update refund capture list) };
  6         19  
117 9         49 my ( $args, $method ) = $self->_validate( 'charge', $actions, @_ );
118 9         35 $args->{_base} = 'charges';
119 9         44 return $self->$method($args);
120             }
121 1     1   6 sub _create_charge { goto &_create }
122 2     2   11 sub _retrieve_charge { goto &_retrieve }
123 2     2   11 sub _update_charge { goto &_update }
124              
125             sub _capture_charge {
126 2     2   8 my ( $self, $args ) = @_;
127 2         13 my ( $base, $id ) = delete @$args{qw(_base id)};
128 2 100       14 _invalid('No id provided.') unless defined $id;
129 1         8 _clean($args);
130 1         11 return $self->_post( $base . '/' . uri_escape($id) . '/capture', $args );
131             }
132 2     2   12 sub _list_charge { goto &_list }
133              
134             sub _refund_charge {
135 0     0   0 my ( $self, $args ) = @_;
136 0         0 my ( $base, $id ) = delete @$args{qw(_base id)};
137 0 0       0 _invalid('No id provided.') unless defined $id;
138 0         0 _clean($args);
139 0         0 return $self->_post( $base . '/' . uri_escape($id) . '/refund', $args );
140             }
141              
142              
143             sub refunds {
144 7     7 1 6533 my $self = shift;
145 7         17 state $actions = { map { $_ => undef } qw(create retrieve update list) };
  4         16  
146 7         34 my ( $args, $method ) = $self->_validate( 'refund', $actions, @_ );
147 7         23 $args->{_base} = 'charges';
148 7         24 return $self->$method($args);
149             }
150              
151             sub _create_refund {
152 2     2   5 my ( $self, $args ) = @_;
153 2         8 my ( $base, $id ) = delete @$args{qw(_base id)};
154 2 100       12 _invalid('No id provided.') unless defined $id;
155 1         5 _clean($args);
156 1         10 return $self->_post( $base . '/' . uri_escape($id) . '/refunds', $args );
157             }
158              
159             sub _retrieve_refund {
160 2     2   3 my ( $self, $args ) = @_;
161 2         7 my ( $base, $id, $charge ) = delete @$args{qw(_base id charge)};
162 2         3 my @errors;
163 2 100       17 push @errors, 'No id provided.' unless defined $id;
164 2 50       7 push @errors, 'No charge provided.' unless defined $charge;
165 2 100       9 _invalid( join ' ', @errors ) if @errors;
166 1         4 _clean($args);
167 1         8 return $self->_get(
168             $base . '/' . uri_escape($charge) . '/refunds/' . uri_escape($id),
169             $args );
170             }
171              
172             sub _update_refund {
173 2     2   6 my ( $self, $args ) = @_;
174 2         10 my ( $base, $id, $charge ) = delete @$args{qw(_base id charge)};
175 2         3 my @errors;
176 2 100       11 push @errors, 'No id provided.' unless defined $id;
177 2 50       7 push @errors, 'No charge provided.' unless defined $charge;
178 2 100       13 _invalid( join ' ', @errors ) if @errors;
179 1         4 _clean($args);
180 1         10 return $self->_post(
181             $base . '/' . uri_escape($charge) . '/refunds/' . uri_escape($id),
182             $args );
183             }
184              
185             sub _list_refund {
186 1     1   5 my ( $self, $args ) = @_;
187 1         8 my ( $base, $id ) = delete @$args{qw(_base id)};
188 1 50       6 _invalid('No id provided.') unless defined $id;
189 1         5 _clean($args);
190 1         19 return $self->_get( $base . '/' . uri_escape($id) . '/refunds', $args );
191             }
192              
193              
194             sub customers {
195 13     13 1 6339 my $self = shift;
196             state $actions =
197 13         34 { map { $_ => undef } qw(create retrieve update delete list) };
  5         11  
198 13         65 my ( $args, $method ) = $self->_validate( 'customer', $actions, @_ );
199 13         46 $args->{_base} = 'customers';
200 13         83 return $self->$method($args);
201             }
202 3     3   15 sub _create_customer { goto &_create }
203 3     3   13 sub _retrieve_customer { goto &_retrieve }
204 2     2   11 sub _update_customer { goto &_update }
205 4     4   26 sub _delete_customer { goto &_del }
206 1     1   7 sub _list_customer { goto &_list }
207              
208              
209             sub cards {
210 15     15 1 9233 my $self = shift;
211             state $actions =
212 15         34 { map { $_ => undef } qw(create retrieve update delete list) };
  5         61  
213 15         66 my ( $args, $method ) = $self->_validate( 'card', $actions, @_ );
214 15         41 $args->{_base} = 'cards';
215 15         49 return $self->$method($args);
216             }
217              
218             sub _create_card {
219 4     4   9 my ( $self, $args ) = @_;
220 4         18 my ( $base, $id, $customer ) = delete @$args{qw(_base id customer)};
221 4   66     30 $id //= $customer;
222 4         12 _clean($args);
223 4         15 return $self->_post( _customer_base( $id, $base ), $args );
224             }
225              
226             sub _retrieve_card {
227 3     3   5 my ( $self, $args ) = @_;
228 3         13 my ( $base, $id, $customer ) = @$args{qw(_base id customer)};
229 3         5 my @errors;
230 3 100       13 push @errors, 'No id provided.' unless defined $id;
231 3 100       11 push @errors, 'No customer id provided.' unless defined $customer;
232 3 100       18 _invalid( join ' ', @errors ) if @errors;
233 1         5 return $self->_get(
234             _customer_base( $customer, $base ) . '/' . uri_escape($id) );
235             }
236              
237             sub _update_card {
238 3     3   4 my ( $self, $args ) = @_;
239 3         8 my ( $base, $id, $customer ) = delete @$args{qw(_base id customer)};
240 3         4 my @errors;
241 3 100       7 push @errors, 'No id provided.' unless defined $id;
242 3 100       9 push @errors, 'No customer id provided.' unless defined $customer;
243 3 100       14 _invalid( join ' ', @errors ) if @errors;
244 1         3 _clean($args);
245 1         5 return $self->_post(
246             _customer_base( $customer, $base ) . '/' . uri_escape($id), $args );
247             }
248              
249             sub _delete_card {
250 3     3   7 my ( $self, $args ) = @_;
251 3         11 my ( $base, $id, $customer ) = @$args{qw(_base id customer)};
252 3         7 my @errors;
253 3 100       26 push @errors, 'No id provided.' unless defined $id;
254 3 100       29 push @errors, 'No customer id provided.' unless defined $customer;
255 3 100       24 _invalid( join ' ', @errors ) if @errors;
256 1         5 return $self->_delete(
257             _customer_base( $customer, $base ) . '/' . uri_escape($id) );
258             }
259              
260             sub _list_card {
261 2     2   4 my ( $self, $args ) = @_;
262 2         10 my ( $base, $id, $customer ) = delete @$args{qw(_base id customer)};
263 2   66     12 $id //= $customer;
264 2         7 _clean($args);
265 2         6 return $self->_get( _customer_base( $id, $base ), $args );
266             }
267              
268              
269             sub subscriptions {
270 17     17 1 5155 my $self = shift;
271             state $actions =
272 17         32 { map { $_ => undef } qw(create retrieve update cancel list) };
  5         10  
273 17         80 my ( $args, $method ) = $self->_validate( 'subscription', $actions, @_ );
274 17         46 $args->{_base} = 'subscriptions';
275 17         57 return $self->$method($args);
276             }
277              
278             sub _create_subscription {
279 4     4   7 my ( $self, $args ) = @_;
280 4         20 my ( $base, $id, $customer ) = delete @$args{qw(_base id customer)};
281 4   66     24 $id //= $customer;
282 4         10 _clean($args);
283 4         14 return $self->_post( _customer_base( $id, $base ), $args );
284             }
285              
286             sub _retrieve_subscription {
287 3     3   5 my ( $self, $args ) = @_;
288 3         9 my ( $base, $id, $customer ) = @$args{qw(_base id customer)};
289 3         4 my @errors;
290 3 100       12 push @errors, 'No id provided.' unless defined $id;
291 3 100       10 push @errors, 'No customer id provided.' unless defined $customer;
292 3 100       16 _invalid( join ' ', @errors ) if @errors;
293 1         6 return $self->_get(
294             _customer_base( $customer, $base ) . '/' . uri_escape($id) );
295             }
296              
297             sub _update_subscription {
298 4     4   6 my ( $self, $args ) = @_;
299 4         20 my ( $base, $id, $customer ) = delete @$args{qw(_base id customer)};
300 4         8 my @errors;
301 4 100       17 push @errors, 'No id provided.' unless defined $id;
302 4 100       14 push @errors, 'No customer id provided.' unless defined $customer;
303 4 100       25 _invalid( join ' ', @errors ) if @errors;
304 2         10 _clean($args);
305 2         10 return $self->_post(
306             _customer_base( $customer, $base ) . '/' . uri_escape($id), $args );
307             }
308              
309             sub _cancel_subscription {
310 5     5   11 my ( $self, $args ) = @_;
311 5         21 my ( $base, $id, $customer ) = @$args{qw(_base id customer)};
312 5         9 my @errors;
313 5 100       21 push @errors, 'No id provided.' unless defined $id;
314 5 100       19 push @errors, 'No customer id provided.' unless defined $customer;
315 5 100       28 _invalid( join ' ', @errors ) if @errors;
316 3         15 return $self->_delete(
317             _customer_base( $customer, $base ) . '/' . uri_escape($id) );
318             }
319              
320             sub _list_subscription {
321 1     1   4 my ( $self, $args ) = @_;
322 1         6 my ( $base, $id, $customer ) = delete @$args{qw(_base id customer)};
323 1   33     6 $id //= $customer;
324 1         5 _clean($args);
325 1         6 return $self->_get( _customer_base( $id, $base ), $args );
326             }
327              
328              
329             sub plans {
330 12     12 1 4046 my $self = shift;
331             state $actions =
332 12         27 { map { $_ => undef } qw(create retrieve update delete list) };
  5         11  
333 12         61 my ( $args, $method ) = $self->_validate( 'plan', $actions, @_ );
334 12         36 $args->{_base} = 'plans';
335 12         48 return $self->$method($args);
336             }
337 3     3   21 sub _create_plan { goto &_create }
338 2     2   6 sub _retrieve_plan { goto &_retrieve }
339 2     2   11 sub _update_plan { goto &_update }
340 4     4   19 sub _delete_plan { goto &_del }
341 1     1   5 sub _list_plan { goto &_list }
342              
343              
344             sub coupons {
345 8     8 1 5781 my $self = shift;
346 8         22 state $actions = { map { $_ => undef } qw(create retrieve delete list) };
  4         14  
347 8         48 my ( $args, $method ) = $self->_validate( 'coupon', $actions, @_ );
348 8         31 $args->{_base} = 'coupons';
349 8         37 return $self->$method($args);
350             }
351 2     2   14 sub _create_coupon { goto &_create }
352 2     2   11 sub _retrieve_coupon { goto &_retrieve }
353 3     3   21 sub _delete_coupon { goto &_del }
354 1     1   8 sub _list_coupon { goto &_list }
355              
356              
357             sub discounts {
358 5     5 1 1167 my $self = shift;
359 5         10 state $actions = { map { $_ => undef } qw(customer subscription) };
  2         8  
360 5         27 my ( $args, $method ) = $self->_validate( 'discount', $actions, @_ );
361 5         20 return $self->$method($args);
362             }
363              
364             sub _customer_discount {
365 2     2   5 my ( $self, $args ) = @_;
366 2         9 my ( $id, $customer ) = @$args{qw(id customer)};
367 2   66     40 $id //= $customer;
368 2         8 return $self->_delete( _customer_base( $id, 'discount' ) );
369             }
370              
371             sub _subscription_discount {
372 3     3   7 my ( $self, $args ) = @_;
373 3         9 my ( $id, $customer ) = @$args{qw(subscription customer)};
374 3         6 my @errors;
375 3 100       11 push @errors, 'No id provided.' unless defined $id;
376 3 100       12 push @errors, 'No customer id provided.' unless defined $customer;
377 3 100       17 _invalid( join ' ', @errors ) if @errors;
378 1         6 my $path =
379             _customer_base( $customer, 'subscriptions' ) . '/'
380             . uri_escape($id)
381             . '/discount';
382 1         6 return $self->_delete($path);
383             }
384              
385              
386             sub invoices {
387 13     13 1 11487 my $self = shift;
388             state $actions =
389 13         31 { map { $_ => undef }
  7         21  
390             qw(create retrieve lines update pay list upcoming) };
391 13         67 my ( $args, $method ) = $self->_validate( 'invoice', $actions, @_ );
392 13         43 $args->{_base} = 'invoices';
393 13         57 return $self->$method($args);
394             }
395 1     1   6 sub _create_invoice { goto &_create }
396 2     2   10 sub _retrieve_invoice { goto &_retrieve }
397              
398             sub _lines_invoice {
399 2     2   5 my ( $self, $args ) = @_;
400 2         6 my ( $base, $id ) = delete @$args{qw(_base id)};
401 2 100       9 _invalid('No id provided.') unless defined $id;
402 1         3 _clean($args);
403 1         7 return $self->_get( $base . '/' . uri_escape($id) . '/lines', $args );
404             }
405 2     2   11 sub _update_invoice { goto &_update }
406              
407             sub _pay_invoice {
408 2     2   6 my ( $self, $args ) = @_;
409 2         11 my ( $base, $id ) = @$args{qw(_base id)};
410 2 100       18 _invalid('No id provided.') unless defined $id;
411 1         8 return $self->_post( $base . '/' . uri_escape($id) . '/pay' );
412             }
413 1     1   6 sub _list_invoice { goto &_list }
414              
415             sub _upcoming_invoice {
416 3     3   7 my ( $self, $args ) = @_;
417 3         14 my ( $base, $id, $customer ) = @$args{qw(_base id customer)};
418 3   66     18 $id //= $customer;
419 3 100       14 _invalid('No id provided.') unless defined $id;
420 2         53 return $self->_get( $base . '/upcoming', { customer => $id } );
421             }
422              
423              
424             sub invoice_items {
425 8     8 1 905 my $self = shift;
426             state $actions =
427 8         23 { map { $_ => undef } qw(create retrieve update delete list) };
  5         17  
428 8         51 my ( $args, $method ) = $self->_validate( 'invoice_item', $actions, @_ );
429 8         33 $args->{_base} = 'invoiceitems';
430 8         38 return $self->$method($args);
431             }
432 1     1   7 sub _create_invoice_item { goto &_create }
433 2     2   22 sub _retrieve_invoice_item { goto &_retrieve }
434 2     2   10 sub _update_invoice_item { goto &_update }
435 2     2   16 sub _delete_invoice_item { goto &_del }
436 1     1   8 sub _list_invoice_item { goto &_list }
437              
438              
439             sub disputes {
440 4     4 1 3565 my $self = shift;
441 4         8 state $actions = { map { $_ => undef } qw(update close) };
  2         7  
442 4         15 my ( $args, $method ) = $self->_validate( 'dispute', $actions, @_ );
443 4         24 return $self->$method($args);
444             }
445              
446             sub _update_dispute {
447 2     2   4 my ( $self, $args ) = @_;
448 2         5 my $id = delete $args->{id};
449 2 100       7 _invalid('No id provided.') unless defined $id;
450 1         4 _clean($args);
451 1         8 my $path = 'charges/' . uri_escape($id) . '/dispute';
452 1         5 return $self->_post( $path, $args );
453             }
454              
455             sub _close_dispute {
456 2     2   4 my ( $self, $args ) = @_;
457 2         3 my $id = delete $args->{id};
458 2 100       10 _invalid('No id provided.') unless defined $id;
459 1         3 _clean($args);
460 1         5 my $path = 'charges/' . uri_escape($id) . '/dispute/close';
461 1         5 return $self->_post( $path, $args );
462             }
463              
464              
465             sub transfers {
466 8     8 1 4193 my $self = shift;
467             state $actions =
468 8         18 { map { $_ => undef } qw(create retrieve update cancel list) };
  5         13  
469 8         45 my ( $args, $method ) = $self->_validate( 'transfer', $actions, @_ );
470 8         24 $args->{_base} = 'transfers';
471 8         26 return $self->$method($args);
472             }
473 1     1   5 sub _create_transfer { goto &_create }
474 2     2   10 sub _retrieve_transfer { goto &_retrieve }
475 2     2   24 sub _update_transfer { goto &_update }
476              
477             sub _cancel_transfer {
478 2     2   4 my ( $self, $args ) = @_;
479 2         6 my ( $base, $id ) = @$args{qw(_base id)};
480 2 100       11 _invalid('No id provided.') unless defined $id;
481 1         8 my $path = $base . '/' . uri_escape($id) . '/cancel';
482 1         7 return $self->_post($path);
483             }
484 1     1   6 sub _list_transfer { goto &_list }
485              
486              
487             sub recipients {
488 10     10 1 4784 my $self = shift;
489             state $actions =
490 10         80 { map { $_ => undef } qw(create retrieve update delete list) };
  5         12  
491 10         55 my ( $args, $method ) = $self->_validate( 'recipient', $actions, @_ );
492 10         48 $args->{_base} = 'recipients';
493 10         38 return $self->$method($args);
494             }
495 2     2   11 sub _create_recipient { goto &_create }
496 2     2   10 sub _retrieve_recipient { goto &_retrieve }
497 2     2   10 sub _update_recipient { goto &_update }
498 3     3   18 sub _delete_recipient { goto &_del }
499 1     1   10 sub _list_recipient { goto &_list }
500              
501              
502             sub application_fees {
503 5     5 1 7417 my $self = shift;
504 5         11 state $actions = { map { $_ => undef } qw(retrieve refund list) };
  3         11  
505 5         24 my ( $args, $method ) = $self->_validate( 'application_fee', $actions, @_ );
506 5         15 $args->{_base} = 'application_fees';
507 5         19 return $self->$method($args);
508             }
509              
510 2     2   9 sub _retrieve_application_fee { goto &_retrieve }
511 1     1   7 sub _list_application_fee { goto &_list }
512              
513             sub _refund_application_fee {
514 2     2   3 my ( $self, $args ) = @_;
515 2         7 my ( $base, $id ) = delete @$args{qw(_base id)};
516 2 100       9 _invalid('No id provided.') unless defined $id;
517 1         4 _clean($args);
518 1         7 my $path = $base . '/' . uri_escape($id) . '/refund';
519 1         22 return $self->_post( $path, $args );
520             }
521              
522              
523             sub account {
524 1     1 1 3826 my $self = shift;
525 1 50       6 unshift @_, 'retrieve' unless @_;
526 1         2 state $actions = { map { $_ => undef } qw(retrieve) };
  1         5  
527 1         5 my ( $args, $method ) = $self->_validate( 'account', $actions, @_ );
528 1         3 $args->{_base} = 'account';
529 1         4 return $self->$method($args);
530             }
531              
532             sub _retrieve_account {
533 1     1   2 my ( $self, $args ) = @_;
534 1         2 my $base = $args->{_base};
535 1         3 return $self->_get($base);
536             }
537              
538              
539             sub balance {
540 4     4 1 7239 my $self = shift;
541 4         9 state $actions = { map { $_ => undef } qw(retrieve history transaction) };
  3         15  
542 4         21 my ( $args, $method ) = $self->_validate( 'balance', $actions, @_ );
543 4         13 $args->{_base} = 'balance';
544 4         17 return $self->$method($args);
545             }
546             sub _retrieve_balance {
547 1     1   4 my ( $self, $args ) = @_;
548 1         7 return $self->_get( $args->{_base} );
549             }
550              
551             sub _transaction_balance {
552 2     2   4 my ( $self, $args ) = @_;
553 2         6 my ( $base, $id ) = @$args{qw(_base id)};
554 2 100       10 _invalid('No id provided.') unless defined $id;
555 1         10 my $path = $base . '/history/' . uri_escape($id);
556 1         8 return $self->_get($path);
557             }
558              
559             sub _history_balance {
560 1     1   5 my ( $self, $args ) = @_;
561 1         4 my $base = delete $args->{_base};
562 1         5 _clean($args);
563 1         4 my $path = $base . '/history';
564 1         6 return $self->_get( $path, $args );
565             }
566              
567              
568             sub events {
569 3     3 1 6256 my $self = shift;
570 3         9 state $actions = { map { $_ => undef } qw(retrieve list) };
  2         7  
571 3         14 my ( $args, $method ) = $self->_validate( 'event', $actions, @_ );
572 3         13 $args->{_base} = 'events';
573 3         13 return $self->$method($args);
574             }
575 2     2   11 sub _retrieve_event { goto &_retrieve }
576 1     1   6 sub _list_event { goto &_list }
577              
578              
579             sub tokens {
580 5     5 1 4864 my $self = shift;
581 5         13 state $actions = { map { $_ => undef } qw(create retrieve bank) };
  3         11  
582 5         27 my ( $args, $method ) = $self->_validate( 'token', $actions, @_ );
583 5         16 $args->{_base} = 'tokens';
584 5         23 return $self->$method($args);
585             }
586 2     2   12 sub _create_token { goto &_create }
587 2     2   9 sub _retrieve_token { goto &_retrieve }
588 1     1   5 sub _bank_token { goto &_create }
589              
590             # Helper methods copied with modification from Net::Stripe
591              
592             sub _get {
593 36     36   388 my ( $self, $path, $args ) = @_;
594 36 100 100     313 $path .= '?' . _encode_params($args) if $args && %$args;
595 36         344 my $req = GET API_BASE . '/' . $path;
596 36         8154 return $self->_make_request($req);
597             }
598              
599             # implements PHP convention for encoding "dictionaries" (why don't they accept
600             # json bodies in posts?)
601             sub _encode_params {
602 47     47   121 my $args = shift;
603 47         107 my @components;
604 47         226 for my $key ( keys %$args ) {
605 71         1159 my $ek = uri_escape($key);
606 71         1121 my $value = $args->{$key};
607 71 50 100     567 if ( blessed $value
      66        
608             && $value->isa('Net::Stripe::Simple::Data')
609             && exists $value->{id} )
610             {
611 16         76 push @components, $ek . '=' . $value->{id};
612 16         49 next;
613             }
614              
615 55         116 my $ref = ref($value);
616 55 100       204 if ($ref eq 'HASH') {
    50          
617 22         107 for my $sk ( keys %$value ) {
618 38         348 my $sv = $value->{$sk};
619             next
620 38 50       125 if ref $sv; # don't think this PHP convention goes deeper
621 38         159 push @components,
622             $ek . '[' . uri_escape($sk) . ']=' . uri_escape($sv);
623             }
624             } elsif ($ref eq 'ARRAY') {
625 0         0 for my $sv (@$value) {
626 0 0       0 next if ref $sv; # again, I think we can't go deeper
627 0         0 push @components, $ek . '[]=' . uri_escape($sv);
628             }
629             } else {
630 33 50       129 $value = # JSON boolean stringification magic has been erased
    100          
631             ref $value eq 'JSON::PP::Boolean'
632             ? $value
633             ? 'true'
634             : 'false'
635             : uri_escape($value);
636 33         468 push @components, "$ek=$value"
637             }
638             }
639 47         892 return join( '&', @components );
640             }
641              
642             sub _delete {
643 17     17   173 my ( $self, $path, $args ) = @_;
644 17 50 33     150 $path .= '?' . _encode_params($args) if $args && %$args;
645 17         154 my $req = DELETE API_BASE . '/' . $path;
646 17         4473 return $self->_make_request($req);
647             }
648              
649             sub _post {
650 41     41   193 my ( $self, $path, $obj ) = @_;
651              
652 41 100       320 my $req = POST API_BASE . '/' . $path,
653             ( $obj ? ( Content => _encode_params($obj) ) : () );
654 41         23687 return $self->_make_request($req);
655             }
656              
657             sub _make_request {
658 94     94   260 my ( $self, $req ) = @_;
659 94         185 my ( $e, $resp, $ret );
660 94         202 state $json = do {
661 1         15 my $j = JSON->new;
662 1         8 $j->utf8(1);
663 1         1 $j;
664             };
665 94         288 eval {
666 94         1720 $req->header( Authorization => $self->{auth} );
667 94         6386 $req->header( Stripe_Version => $self->{version} );
668              
669 94         6848 $resp = $self->{ua}->request($req);
670 94 100       77216027 if ( $resp->code == 200 ) {
671 88         1842 my $hash = $json->decode( $resp->content );
672 88         29093 $ret = data_object($hash);
673             }
674             else {
675 6 50       92 if ( $resp->header('Content_Type') =~ m{text/html} ) {
676 0         0 $e = _hash_to_error(
677             code => $resp->code,
678             type => $resp->message,
679             message => $resp->message
680             );
681             }
682             else {
683 6         296 my $hash = $json->decode( $resp->content );
684 6   33     266 $e = _hash_to_error( $hash->{error} // $hash );
685             }
686             }
687             };
688 94 50       387 if ($@) {
689 0 0       0 $e = _hash_to_error(
690             {
691             type => "Could not decode HTTP response: $@",
692             $resp
693             ? ( message => $resp->status_line . " - " . $resp->content )
694             : (),
695             }
696             );
697             }
698 94 100       358 die $e if $e;
699 88 50       1384 return $ret if $ret;
700 0         0 die _hash_to_error();
701             }
702              
703             # generates validation error when parameters required to construct the URL
704             # have not been provided
705             sub _invalid {
706 53     53   114 my $message = shift;
707 53         238 my %params = ( type => 'Required parameter missing' );
708 53 50       278 $params{message} = $message if defined $message;
709 53         281 die _hash_to_error(%params);
710             }
711              
712              
713             sub data_object {
714 5625     5625 1 15048 my $ref = shift;
715 5625         8362 my $rr = ref $ref;
716 5625 100       16251 return unless $rr;
717 1353 50 66     9101 die "forbidden class: $rr" if blessed($ref) and $rr !~ /^JSON::/;
718 1353 100       5156 bless $ref, 'Net::Stripe::Simple::Data' if $rr eq 'HASH';
719              
720 1353 100       3520 if ($rr eq 'HASH') {
    100          
721 715         5165 data_object($_) for values %$ref
722             } elsif ($rr eq 'ARRAY') {
723 122         495 data_object($_) for @$ref
724             }
725              
726 1353         3432 return $ref;
727             }
728              
729             sub _hash_to_error {
730 63 100   63   1294 my %args = ( ref $_[0] ? %{ $_[0] } : @_ );
  7         52  
731 63         220 my $o = data_object( \%args );
732 63         966 my $trace = Devel::StackTrace->new( ignore_package => __PACKAGE__ );
733 63         68551 $o->{_trace} = $trace;
734 63         1011 bless $o, 'Net::Stripe::Simple::Error';
735             }
736              
737              
738 1     1 1 10 sub true() { JSON::true }
739 2     2 1 5356 sub false() { JSON::false }
740 1     1 1 825 sub null() { JSON::null }
741              
742             1;
743              
744             __END__
745              
746             =pod
747              
748             =encoding UTF-8
749              
750             =head1 NAME
751              
752             Net::Stripe::Simple - simple, non-Moose interface to the Stripe API
753              
754             =head1 VERSION
755              
756             version 0.004
757              
758             =head1 SYNOPSIS
759              
760             use Net::Stripe::Simple;
761              
762             my $stripe = Net::Stripe::Simple->new('sk_test_00000000000000000000000000');
763              
764             # when the only argument is an id, that's all you need
765             my $c1 = $stripe->customers( retrieve => 'cus_meFAKEfakeFAKE' );
766              
767             # you can provide arguments as a hash reference
768             my $c2 = $stripe->customers( retrieve => { id => 'cus_ImFAKEfakeFAKE' } );
769              
770             # or as key-value list
771             my $c3 = $stripe->customers( 'retrieve', id => 'cus_I2FAKEfakeFAKE', expand => 1 );
772              
773             =head1 DESCRIPTION
774              
775             A lightweight, limited-dependency client to the stripe.com API. This is just
776             a thin wrapper around stripe's RESTful API. It is "simple" in the sense that it
777             is simple to write and maintain and it maps simply onto Stripe's web
778             documentation, so it is simple to use. When you get a response back, it's just
779             the raw JSON blessed with some convenience methods: stringification to ids and
780             autoloaded attributes (L<Net::Stripe::Simple::Data>). If there is an error, the
781             error that is thrown is again just Stripe's JSON with a little blessing
782             (L<Net::Stripe::Simple::Error>).
783              
784             This simplicity comes at a cost: L<Net::Stripe::Simple> does not
785             validate your parameters aside from those required to construct the URL before
786             constructing a request and sending it off to Stripe. This means that if you've
787             done it wrong it takes a round trip to find out.
788              
789             For the full details of stripe's API, see L<https://stripe.com/docs/api>.
790              
791             =head2 Method Invocation
792              
793             Following the organization scheme of Stripe's API, actions are grouped by entity
794             type, each entity corresponding to a method. For a given method there are
795             generally a number of actions, which are treated as the primary key in a
796             parameter hash. Parameters for these actions are provided by a parameter hash
797             which is the value of the primary key. However, there is some flexibility.
798              
799             Methods that require only an id are flexible. All the following will work:
800              
801             $stripe->plans( retrieve => { id => $id } );
802             $stripe->plans( 'retrieve', id => $id );
803             $stripe->plans( retrieve => $id );
804              
805             Methods that require no arguments are also flexible:
806              
807             $stripe->plans( list => { } );
808             $stripe->plans('list');
809              
810             =head2 Export Tags
811              
812             L<Net::Stripe::Simple> exports nothing by default. It has four exportable
813             constants and one exportable function:
814              
815             =over 4
816              
817             =item true
818              
819             =item false
820              
821             =item null
822              
823             =item data_object
824              
825             =back
826              
827             To facilitate their export, it has two tags:
828              
829             =over 4
830              
831             =item :const
832              
833             The three constants.
834              
835             =item :all
836              
837             The three constants plus C<data_object>.
838              
839             =back
840              
841             =head1 NAME
842              
843             Net::Stripe::Simple - simple, non-Moose interface to the Stripe API
844              
845             =head1 METHODS
846              
847             =head2 new
848              
849             Net::Stripe::Simple->('sk_test_00000000000000000000000000', '2014-01-31')
850              
851             The class constructor method. The API key is required. The version date is
852             optional. If not supplied, the value of C<$Net::Stripe::Simple::STRIPE_VERSION>
853             will be supplied. L<Net::Stripe::Simple> was implemented or has been updated
854             for the following versions:
855              
856             =over 4
857              
858             =item 2014-01-31
859              
860             =item 2014-06-17
861              
862             =back
863              
864             The default version will always be the most recent version whose handling
865             required an update to L<Net::Stripe::Simple>.
866              
867             =head2 charges
868              
869             See L<https://stripe.com/docs/api#charges>.
870              
871             B<Available Actions>
872              
873             =over 4
874              
875             =item create
876              
877             $charge = $stripe->charges(
878             create => {
879             customer => $customer,
880             amount => 100,
881             currency => 'usd',
882             capture => 'false',
883             }
884             );
885              
886             =item retrieve
887              
888             $charge = $stripe->charges( retrieve => $id );
889              
890             =item update
891              
892             $charge = $stripe->charges(
893             update => {
894             id => $charge,
895             description => 'foo',
896             }
897             );
898              
899             =item refund
900              
901             Availability may depend on version of API.
902             $charge = $stripe->charges( refund => $id );
903              
904             =item capture
905              
906             $charge = $stripe->charges( capture => $id );
907              
908             =item list
909              
910             my $charges = $stripe->charges('list');
911              
912             =back
913              
914             =head2 refunds
915              
916             See L<https://stripe.com/docs/api#refunds>.
917              
918             B<Available Actions>
919              
920             =over 4
921              
922             =item create
923              
924             my $refund = $stripe->refunds(
925             create => {
926             id => $charge,
927             amount => 50
928             }
929             );
930              
931             =item retrieve
932              
933             $refund = $stripe->refunds(
934             retrieve => {
935             id => $refund,
936             charge => $charge
937             }
938             );
939              
940             =item update
941              
942             $refund = $stripe->refunds(
943             update => {
944             id => $refund,
945             charge => $charge,
946             metadata => { foo => 'bar' }
947             }
948             );
949              
950             =item list
951              
952             my $refunds = $stripe->refunds( list => $charge );
953              
954             =back
955              
956             =head2 customers
957              
958             See L<https://stripe.com/docs/api#customers>.
959              
960             B<Available Actions>
961              
962             =over 4
963              
964             =item create
965              
966             $customer = $stripe->customers(
967             create => {
968             metadata => { foo => 'bar' }
969             }
970             );
971              
972             =item retrieve
973              
974             $customer = $stripe->customers( retrieve => $id );
975              
976             =item update
977              
978             $customer = $stripe->customers(
979             update => {
980             id => $customer,
981             metadata => { foo => 'baz' }
982             }
983             );
984              
985             =item delete
986              
987             $customer = $stripe->customers( delete => $id );
988              
989             =item list
990              
991             my $customers = $stripe->customers(
992             list => {
993             created => { gte => $time - 100 }
994             }
995             );
996              
997             =back
998              
999             =head2 cards
1000              
1001             See L<https://stripe.com/docs/api#cards>.
1002              
1003             B<Available Actions>
1004              
1005             =over 4
1006              
1007             =item create
1008              
1009             $card = $stripe->cards(
1010             create => {
1011             customer => $customer,
1012             card => {
1013             number => '4242424242424242',
1014             exp_month => $expiry->month,
1015             exp_year => $expiry->year,
1016             cvc => 123
1017             }
1018             }
1019             );
1020              
1021             =item retrieve
1022              
1023             $card = $stripe->cards(
1024             retrieve => {
1025             customer => $customer,
1026             id => $id
1027             }
1028             );
1029              
1030             =item update
1031              
1032             $card = $stripe->cards(
1033             update => {
1034             customer => $customer,
1035             id => $card,
1036             name => 'foo',
1037             }
1038             );
1039              
1040             =item delete
1041              
1042             $card = $stripe->cards(
1043             delete => {
1044             customer => $customer,
1045             id => $id
1046             }
1047             );
1048              
1049             =item list
1050              
1051             my $cards = $stripe->cards( list => $customer );
1052              
1053             =back
1054              
1055             =head2 subscriptions
1056              
1057             See L<https://stripe.com/docs/api#subscriptions>.
1058              
1059             B<Available Actions>
1060              
1061             =over 4
1062              
1063             =item create
1064              
1065             $subscription = $stripe->subscriptions(
1066             create => {
1067             customer => $customer,
1068             plan => $plan,
1069             }
1070             );
1071              
1072             =item retrieve
1073              
1074             $subscription = $stripe->subscriptions(
1075             retrieve => {
1076             id => $id,
1077             customer => $customer,
1078             }
1079             );
1080              
1081             =item update
1082              
1083             $subscription = $stripe->subscriptions(
1084             update => {
1085             id => $id,
1086             customer => $customer,
1087             metadata => { foo => 'bar' }
1088             }
1089             );
1090              
1091             =item cancel
1092              
1093             $subscription = $stripe->subscriptions(
1094             cancel => {
1095             id => $id,
1096             customer => $customer,
1097             }
1098             );
1099              
1100             =item list
1101              
1102             my $subscriptions = $stripe->subscriptions( list => $customer );
1103              
1104             =back
1105              
1106             =head2 plans
1107              
1108             See L<https://stripe.com/docs/api#plans>.
1109              
1110             B<Available Actions>
1111              
1112             =over 4
1113              
1114             =item create
1115              
1116             $plan = $stripe->plans(
1117             create => {
1118             id => $id,
1119             amount => 100,
1120             currency => 'usd',
1121             interval => 'week',
1122             name => 'Foo',
1123             }
1124             );
1125              
1126             =item retrieve
1127              
1128             $plan = $stripe->plans( retrieve => $id );
1129              
1130             =item update
1131              
1132             $plan = $stripe->plans(
1133             update => {
1134             id => $id,
1135             metadata => { bar => 'baz' }
1136             }
1137             );
1138              
1139             =item delete
1140              
1141             $plan = $stripe->plans( delete => $id );
1142              
1143             =item list
1144              
1145             my $plans = $stripe->plans('list');
1146              
1147             =back
1148              
1149             =head2 coupons
1150              
1151             B<Available Actions>
1152              
1153             See L<https://stripe.com/docs/api#coupons>.
1154              
1155             =over 4
1156              
1157             =item create
1158              
1159             $coupon = $stripe->coupons(
1160             create => {
1161             percent_off => 1,
1162             duration => 'forever',
1163             }
1164             );
1165              
1166             =item retrieve
1167              
1168             $coupon = $stripe->coupons( retrieve => $id );
1169              
1170             =item delete
1171              
1172             $coupon = $stripe->coupons( delete => $coupon );
1173              
1174             =item list
1175              
1176             my $coupons = $stripe->coupons('list');
1177              
1178             =back
1179              
1180             =head2 discounts
1181              
1182             See L<https://stripe.com/docs/api#discounts>.
1183              
1184             B<Available Actions>
1185              
1186             =over 4
1187              
1188             =item customer
1189              
1190             my $deleted = $stripe->discounts( customer => $c );
1191              
1192             =item subscription
1193              
1194             $deleted = $stripe->discounts(
1195             subscription => {
1196             customer => $c,
1197             subscription => $s,
1198             }
1199             );
1200              
1201             =back
1202              
1203             =head2 invoices
1204              
1205             See L<https://stripe.com/docs/api#invoices>.
1206              
1207             B<Available Actions>
1208              
1209             =over 4
1210              
1211             =item create
1212              
1213             my $new_invoice = $stripe->invoices(
1214             create => {
1215             customer => $customer,
1216             }
1217             );
1218              
1219             =item retrieve
1220              
1221             $invoice = $stripe->invoices( retrieve => $id );
1222              
1223             =item lines
1224              
1225             my $lines = $stripe->invoices( lines => $invoice );
1226              
1227             =item update
1228              
1229             $stripe->subscriptions(
1230             update => {
1231             customer => $customer,
1232             id => $subscription,
1233             plan => $spare_plan,
1234             }
1235             );
1236              
1237             =item pay
1238              
1239             $new_invoice = $stripe->invoices( pay => $new_invoice );
1240              
1241             =item list
1242              
1243             my $invoices = $stripe->invoices( list => { customer => $customer } );
1244              
1245             =item upcoming
1246              
1247             $new_invoice = $stripe->invoices( upcoming => $customer );
1248              
1249             =back
1250              
1251             =head2 invoice_items
1252              
1253             See L<https://stripe.com/docs/api#invoiceitems>.
1254              
1255             B<Available Actions>
1256              
1257             =over 4
1258              
1259             =item create
1260              
1261             my $item = $stripe->invoice_items(
1262             create => {
1263             customer => $customer,
1264             amount => 100,
1265             currency => 'usd',
1266             metadata => { foo => 'bar' }
1267             }
1268             );
1269              
1270             =item retrieve
1271              
1272             $item = $stripe->invoice_items( retrieve => $id );
1273              
1274             =item update
1275              
1276             $item = $stripe->invoice_items(
1277             update => {
1278             id => $item,
1279             metadata => { foo => 'baz' }
1280             }
1281             );
1282              
1283             =item delete
1284              
1285             $item = $stripe->invoice_items( delete => $item );
1286              
1287             =item list
1288              
1289             my $items = $stripe->invoice_items( list => { customer => $customer } );
1290              
1291             =back
1292              
1293             =head2 disputes
1294              
1295             See L<https://stripe.com/docs/api#disputes>.
1296              
1297             B<Available Actions>
1298              
1299             =over 4
1300              
1301             =item update
1302              
1303             $stripe->disputes(
1304             update => {
1305             id => $charge,
1306             metadata => { foo => 'bar' }
1307             }
1308             );
1309              
1310             =item close
1311              
1312             $stripe->disputes( close => $charge );
1313              
1314             =back
1315              
1316             =head2 transfers
1317              
1318             See L<https://stripe.com/docs/api#transfers>.
1319              
1320             B<Available Actions>
1321              
1322             =over 4
1323              
1324             =item create
1325              
1326             my $transfer = $stripe->transfers(
1327             create => {
1328             amount => 1,
1329             currency => 'usd',
1330             recipient => $recipient,
1331             }
1332             );
1333              
1334             =item retrieve
1335              
1336             $transfer = $stripe->transfers( retrieve => $id );
1337              
1338             =item update
1339              
1340             $transfer = $stripe->transfers(
1341             update => {
1342             id => $transfer,
1343             metadata => { foo => 'bar' }
1344             }
1345             );
1346              
1347             =item cancel
1348              
1349             $transfer = $stripe->transfers( cancel => $transfer );
1350              
1351             =item list
1352              
1353             my $transfers = $stripe->transfers(
1354             list => {
1355             created => { gt => $time }
1356             }
1357             );
1358              
1359             =back
1360              
1361             =head2 recipients
1362              
1363             See L<https://stripe.com/docs/api#recipients>.
1364              
1365             B<Available Actions>
1366              
1367             =over 4
1368              
1369             =item create
1370              
1371             $recipient = $stripe->recipients(
1372             create => {
1373             name => 'I Am An Example',
1374             type => 'individual',
1375             }
1376             );
1377              
1378             =item retrieve
1379              
1380             $recipient = $stripe->recipients( retrieve => $id );
1381              
1382             =item update
1383              
1384             $recipient = $stripe->recipients(
1385             update => {
1386             id => $recipient,
1387             metadata => { foo => 'bar' },
1388             }
1389             );
1390              
1391             =item delete
1392              
1393             $recipient = $stripe->recipients( delete => $id );
1394              
1395             =item list
1396              
1397             my $recipients = $stripe->recipients('list');
1398              
1399             =back
1400              
1401             =head2 application_fees
1402              
1403             See L<https://stripe.com/docs/api#application_fees>.
1404              
1405             B<Available Actions>
1406              
1407             =over 4
1408              
1409             =item retrieve
1410              
1411             my $fee = $stripe->application_fees( retrieve => $id );
1412              
1413             =item refund
1414              
1415             my $fee = $stripe->application_fees( refund => $id );
1416              
1417             =item list
1418              
1419             my $fees = $stripe->application_fees('list');
1420              
1421             =back
1422              
1423             =head2 account
1424              
1425             See L<https://stripe.com/docs/api#account>.
1426              
1427             B<Available Actions>
1428              
1429             =over 4
1430              
1431             =item retrieve
1432              
1433             my $account = $stripe->account('retrieve'); # or
1434             $account = $stripe->account;
1435              
1436             =back
1437              
1438             =head2 balance
1439              
1440             See L<https://stripe.com/docs/api#balance>.
1441              
1442             B<Available Actions>
1443              
1444             =over 4
1445              
1446             =item retrieve
1447              
1448             my $balance = $stripe->balance('retrieve');
1449              
1450             =item history
1451              
1452             my $history = $stripe->balance('history');
1453              
1454             =item transaction
1455              
1456             $balance = $stripe->balance( transaction => $charge );
1457              
1458             =back
1459              
1460             =head2 events
1461              
1462             See L<https://stripe.com/docs/api#events>.
1463              
1464             B<Available Actions>
1465              
1466             =over 4
1467              
1468             =item retrieve
1469              
1470             $event = $stripe->events( retrieve => $id );
1471              
1472             =item list
1473              
1474             my $events = $stripe->events( list => { created => { gt => $time } } );
1475              
1476             =back
1477              
1478             =head2 tokens
1479              
1480             See L<https://stripe.com/docs/api#tokens>.
1481              
1482             B<Available Actions>
1483              
1484             =over 4
1485              
1486             =item create
1487              
1488             $token = $stripe->tokens(
1489             create => {
1490             card => {
1491             number => '4242424242424242',
1492             exp_month => $expiry->month,
1493             exp_year => $expiry->year,
1494             cvc => 123
1495             }
1496             }
1497             );
1498             $token = $stripe->tokens(
1499             create => {
1500             bank_account => {
1501             country => 'US',
1502             routing_number => '110000000',
1503             account_number => '000123456789',
1504             }
1505             }
1506             );
1507              
1508             =item retrieve
1509              
1510             $token = $stripe->tokens( retrieve => $id );
1511              
1512             =item bank
1513              
1514             To preserve the parallel with the Stripe's API documentation, there is a
1515             special "bank" action, but it is simply a synonym for the code above.
1516             $token = $stripe->tokens(
1517             bank => {
1518             bank_account => {
1519             country => 'US',
1520             routing_number => '110000000',
1521             account_number => '000123456789',
1522             }
1523             }
1524             );
1525              
1526             =back
1527              
1528             =head1 FUNCTIONS
1529              
1530             =head2 data_object($hash_ref)
1531              
1532             This function recursively converts a hash ref into a data object. This is just
1533             L<Net::Stripe::Simple::Data>, whose only function is to autoload accessors for
1534             all the keys in the hash. It is made for adding magic to JSON objects. If you
1535             try to give it something that contains blessed references whose class is
1536             outside the JSON namespace it will die.
1537              
1538             =head1 SEE ALSO
1539              
1540             L<Net::Stripe>, L<Business::Stripe>
1541              
1542             =head1 EXPORTED CONSTANTS
1543              
1544             These are just the corresponding L<JSON> constants. They are exported by
1545             L<Net::Stripe::Simple> for convenience.
1546              
1547             use Net::Stripe::Simple qw(:const);
1548             ...
1549             my $subscription = $stripe->subscriptions(
1550             update => {
1551             id => $id,
1552             customer => $customer_id,
1553             plan => $plan_id,
1554             prorate => true,
1555             }
1556             );
1557              
1558             You can import the constants individually or all together with C<:const>.
1559              
1560             =over 4
1561              
1562             =item true
1563              
1564             =item false
1565              
1566             =item null
1567              
1568             =back
1569              
1570             =head1 AUTHORS
1571              
1572             =over 4
1573              
1574             =item *
1575              
1576             Grant Street Group <developers@grantstreet.com>
1577              
1578             =item *
1579              
1580             David F. Houghton <dfhoughton@gmail.com>
1581              
1582             =back
1583              
1584             =head1 COPYRIGHT AND LICENSE
1585              
1586             This software is copyright (c) 2014 by Grant Street Group.
1587              
1588             This is free software; you can redistribute it and/or modify it under
1589             the same terms as the Perl 5 programming language system itself.
1590              
1591             =head1 AUTHORS
1592              
1593             =over 4
1594              
1595             =item *
1596              
1597             Grant Street Group <developers@grantstreet.com>
1598              
1599             =item *
1600              
1601             David F. Houghton <dfhoughton@gmail.com>
1602              
1603             =back
1604              
1605             =head1 COPYRIGHT AND LICENSE
1606              
1607             This software is copyright (c) 2014 by Grant Street Group.
1608              
1609             This is free software; you can redistribute it and/or modify it under
1610             the same terms as the Perl 5 programming language system itself.
1611              
1612             =cut