File Coverage

blib/lib/Net/Stripe/Simple.pm
Criterion Covered Total %
statement 464 475 97.6
branch 124 150 82.6
condition 30 50 60.0
subroutine 119 120 99.1
pod 21 22 95.4
total 758 817 92.7


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