File Coverage

blib/lib/Net/Payjp.pm
Criterion Covered Total %
statement 150 150 100.0
branch 22 22 100.0
condition 27 29 93.1
subroutine 40 40 100.0
pod 1 14 7.1
total 240 255 94.1


line stmt bran cond sub pod time code
1             package Net::Payjp;
2              
3 11     11   804860 use strict;
  11         55  
  11         307  
4 11     11   76 use warnings;
  11         23  
  11         281  
5              
6 11     11   54 use LWP::UserAgent;
  11         21  
  11         266  
7 11     11   5452 use LWP::Protocol::https;
  11         1279839  
  11         489  
8 11     11   5339 use HTTP::Request::Common;
  11         25868  
  11         766  
9 11     11   6667 use JSON;
  11         111787  
  11         69  
10 11     11   1678 use List::Util qw/min/;
  11         22  
  11         1252  
11 11     11   90 use POSIX qw/floor/;
  11         27  
  11         97  
12              
13 11     11   4911 use Net::Payjp::Account;
  11         30  
  11         375  
14 11     11   3850 use Net::Payjp::Charge;
  11         39  
  11         312  
15 11     11   3923 use Net::Payjp::Customer;
  11         32  
  11         352  
16 11     11   4257 use Net::Payjp::Plan;
  11         29  
  11         369  
17 11     11   4061 use Net::Payjp::Subscription;
  11         37  
  11         349  
18 11     11   4100 use Net::Payjp::Token;
  11         31  
  11         418  
19 11     11   4072 use Net::Payjp::Transfer;
  11         31  
  11         367  
20 11     11   4053 use Net::Payjp::Event;
  11         26  
  11         378  
21 11     11   4152 use Net::Payjp::Tenant;
  11         38  
  11         423  
22 11     11   4054 use Net::Payjp::TenantTransfer;
  11         29  
  11         416  
23 11     11   4079 use Net::Payjp::Object;
  11         26  
  11         17123  
24              
25             # ABSTRACT: API client for pay.jp
26              
27             =head1 SYNOPSIS
28              
29             # Create charge
30             my $payjp = Net::Payjp->new(api_key => $API_KEY);
31             my $res = $payjp->charge->create(
32             card => 'token_id_by_Checkout_or_payjp.js',
33             amount => 3500,
34             currency => 'jpy',
35             );
36             if(my $e = $res->error){
37             print "Error;
38             print $e->{message}."\n";
39             }
40             # Id of charge.
41             print $res->id;
42              
43             # Retrieve a charge
44             $payjp->id($res->id); # Set id of charge
45             $res = $payjp->charge->retrieve; # or $payjp->charge->retrieve($res->id);
46              
47             =head1 DESCRIPTION
48              
49             This module is a wrapper around the Pay.jp HTTP API.Methods are generally named after the object name and the acquisition method.
50              
51             This method returns json objects for responses from the API.
52              
53             =head1 new Method
54              
55             This creates a new Payjp api object. The following parameters are accepted:
56              
57             =over
58              
59             =item api_key
60              
61             This is required. You get this from your Payjp Account settings.
62              
63             =back
64              
65             =cut
66              
67             our $VERSION = '0.2.1';
68             our $API_BASE = 'https://api.pay.jp';
69             our $INITIAL_DELAY_SEC = 2;
70             our $MAX_DELAY_SEC = 32;
71              
72             sub new{
73 113     113 0 2030 my $self = shift;
74 113         327 bless{__PACKAGE__->_init(@_)},$self;
75             }
76              
77             sub _init{
78 113     113   162 my $self = shift;
79 113         363 my %p = @_;
80             return(
81             api_key => $p{api_key},
82             id => $p{id},
83             api_base => $API_BASE,
84             max_retry => $p{max_retry} || 0,
85             initial_delay => $p{initial_delay} || $INITIAL_DELAY_SEC,
86 113   100     1747 max_delay => $p{max_delay} || $MAX_DELAY_SEC,
      66        
      66        
87             );
88             }
89              
90             sub api_key{
91 70     70 1 3167 my $self = shift;
92 70 100       192 $self->{api_key} = shift if @_;
93 70         549 return $self->{api_key};
94             }
95              
96             sub api_base{
97 59     59 0 107 my $self = shift;
98 59 100       203 $self->{api_base} = shift if @_;
99 59         437 return $self->{api_base};
100             }
101              
102             sub id{
103 106     106 0 3565 my $self = shift;
104 106 100       289 $self->{id} = shift if @_;
105 106         366 return $self->{id};
106             }
107              
108             =head1 Charge Methods
109              
110             =head2 create
111              
112             Create a new charge
113              
114             L
115              
116             $payjp->charge->create(
117             card => 'tok_76e202b409f3da51a0706605ac81',
118             amount => 3500,
119             currency => 'jpy',
120             description => 'yakiimo',
121             );
122              
123             =head2 retrieve
124              
125             Retrieve a charge
126              
127             L
128              
129             $payjp->charge->retrieve('ch_fa990a4c10672a93053a774730b0a');
130              
131             =head2 save
132              
133             Update a charge
134              
135             L
136              
137             $payjp->id('ch_fa990a4c10672a93053a774730b0a');
138             $payjp->charge->save(description => 'update description.');
139              
140             =head2 refund
141              
142             Refund a charge
143              
144             L
145              
146             $payjp->id('ch_fa990a4c10672a93053a774730b0a');
147             $payjp->charge->refund(amount => 1000, refund_reason => 'test.');
148              
149             =head2 capture
150              
151             Capture a charge
152              
153             L
154              
155             $payjp->id('ch_fa990a4c10672a93053a774730b0a');
156             $payjp->charge->capture(amount => 2000);
157              
158             =head2 all
159              
160             Returns the charge list
161              
162             L
163              
164             $payjp->charge->all("limit" => 2, "offset" => 1);
165              
166             =head1 Customer Methods
167              
168             =head2 create
169              
170             Create a cumtomer
171              
172             L
173              
174             $payjp->customer->create(
175             "description" => "test",
176             );
177              
178             =head2 retrieve
179              
180             Retrieve a customer
181              
182             L
183              
184             $payjp->customer->retrieve('cus_121673955bd7aa144de5a8f6c262');
185              
186             =head2 save
187              
188             Update a customer
189              
190             L
191              
192             $payjp->id('cus_121673955bd7aa144de5a8f6c262');
193             $payjp->customer->save(email => 'test@test.jp');
194              
195             =head2 delete
196              
197             Delete a customer
198              
199             L
200              
201             $payjp->id('cus_121673955bd7aa144de5a8f6c262');
202             $payjp->customer->delete;
203              
204             =head2 all
205              
206             Returns the customer list
207              
208             L
209              
210             $res = $payjp->customer->all(limit => 2, offset => 1);
211              
212             =cut
213              
214             sub charge{
215 13     13 0 30 my $self = shift;
216 13         80 return Net::Payjp::Charge->new(%$self);
217             }
218              
219             =head1 Cutomer card Methods
220              
221             Returns a customer's card object
222              
223             my $card = $payjp->customer->card('cus_4df4b5ed720933f4fb9e28857517');
224              
225             =head2 create
226              
227             Create a customer's card
228              
229             L
230              
231             $card->create(
232             card => 'tok_76e202b409f3da51a0706605ac81'
233             );
234              
235             =head2 retrieve
236              
237             Retrieve a customer's card
238              
239             L
240              
241             $card->retrieve('car_f7d9fa98594dc7c2e42bfcd641ff');
242              
243             =head2 save
244              
245             Update a customer's card
246              
247             L
248              
249             $card->id('car_f7d9fa98594dc7c2e42bfcd641ff');
250             $card->save(exp_year => "2026", exp_month => "05", name => 'test');
251              
252             =head2 delete
253              
254             Delete a customer's card
255              
256             L
257              
258             $card->id('car_f7d9fa98594dc7c2e42bfcd641ff');
259             $card->delete;
260              
261             =head2 all
262              
263             Returns the customer's card list
264              
265             L
266              
267             $card->all(limit => 2, offset => 0);
268              
269             =head1 Customer subscription Methods
270              
271             Returns a customer's subscription object
272              
273             my $subscription = $payjp->customer->subscription('sub_567a1e44562932ec1a7682d746e0');
274              
275             =head2 retrieve
276              
277             Retrieve a customer's subscription
278              
279             L
280              
281             $subscription->retrieve('sub_567a1e44562932ec1a7682d746e0');
282              
283             =head2 all
284              
285             Returns the customer's subscription list
286              
287             L
288              
289             $subscription->all(limit => 1, offset => 0);
290              
291             =cut
292              
293             sub customer{
294 12     12 0 33 my $self = shift;
295 12         64 return Net::Payjp::Customer->new(%$self);
296             }
297              
298             =head1 Plan Methods
299              
300             =head2 create
301              
302             Create a plan
303              
304             L
305              
306             $payjp->plan->create(
307             amount => 500,
308             currency => "jpy",
309             interval => "month",
310             trial_days => 30,
311             name => 'test_plan'
312             );
313              
314             =head2 retrieve
315              
316             Retrieve a plan
317              
318             L
319              
320             $payjp->plan->retrieve('pln_45dd3268a18b2837d52861716260');
321              
322             =head2 save
323              
324             Update a plan
325              
326             L
327              
328             $payjp->id('pln_45dd3268a18b2837d52861716260');
329             $payjp->plan->save(name => 'NewPlan');
330              
331             =head2 delete
332              
333             Delete a plan
334              
335             L
336              
337             $payjp->id('pln_45dd3268a18b2837d52861716260');
338             $payjp->plan->delete;
339              
340             =head2 all
341              
342             Returns the plan list
343              
344             L
345              
346             $payjp->plan->all("limit" => 5, "offset" => 0);
347              
348             =cut
349              
350             sub plan{
351 5     5 0 14 my $self = shift;
352 5         35 return Net::Payjp::Plan->new(%$self);
353             }
354              
355             =head1 Subscription Methods
356              
357             =head2 create
358              
359             Create a subscription
360              
361             L
362              
363             $payjp->subscription->create(
364             customer => 'cus_4df4b5ed720933f4fb9e28857517',
365             plan => 'pln_9589006d14aad86aafeceac06b60'
366             );
367              
368             =head2 retrieve
369              
370             Retrieve a subscription
371              
372             L
373              
374             $payjp->subscription->retrieve('sub_567a1e44562932ec1a7682d746e0');
375              
376             =head2 save
377              
378             Update a subscription
379              
380             L
381              
382             $payjp->id('sub_567a1e44562932ec1a7682d746e0');
383             $payjp->subscription->save(trial_end => 1473911903);
384              
385             =head2 pause
386              
387             Pause a subscription
388              
389             L
390              
391             $payjp->id('sub_567a1e44562932ec1a7682d746e0');
392             $payjp->subscription->pause;
393              
394             =head2 resume
395              
396             Resume a subscription
397              
398             L
399              
400             $payjp->id('sub_567a1e44562932ec1a7682d746e0');
401             $payjp->subscription->resume;
402              
403             =head2 cancel
404              
405             Cancel a subscription
406              
407             L
408              
409             $payjp->id('sub_567a1e44562932ec1a7682d746e0');
410             $payjp->subscription->cancel;
411              
412             =head2 delete
413              
414             Delete a subscription
415              
416             L
417              
418             $payjp->id('sub_567a1e44562932ec1a7682d746e0');
419             $payjp->subscription->delete;
420              
421             =head2 all
422              
423             Returns the subscription list
424              
425             L
426              
427             $payjp->subscription->all(limit => 3, offset => 0);
428              
429             =cut
430              
431             sub subscription{
432 9     9 0 25 my $self = shift;
433 9         55 return Net::Payjp::Subscription->new(%$self);
434             }
435              
436             =head1 Token Methods
437              
438             =head2 retrieve
439              
440             Retrieve a token
441              
442             L
443              
444             $payjp->token->retrieve('tok_eff34b780cbebd61e87f09ecc9c6');
445              
446             =cut
447              
448             sub token{
449 10     10 0 23 my $self = shift;
450 10         54 return Net::Payjp::Token->new(%$self);
451             }
452              
453             =head1 Transfer Methods
454              
455             =head2 retrieve
456              
457             Retrieve a transfer
458              
459             L
460              
461             $payjp->transfer->retrieve('tr_8f0c0fe2c9f8a47f9d18f03959ba1');
462              
463             =head2 all
464              
465             Returns the transfer list
466              
467             L
468              
469             $payjp->transfer->all("limit" => 3, offset => 0);
470              
471             =head2 charges
472              
473             Returns the charge list
474              
475             L
476              
477             $payjp->transfer->charges(
478             limit => 3,
479             offset => 0
480             );
481              
482             =cut
483              
484             sub transfer{
485 16     16 0 35 my $self = shift;
486 16         76 return Net::Payjp::Transfer->new(%$self);
487             }
488              
489             =head1 Event Methods
490              
491             =head2 retrieve
492              
493             Retrieve a event
494              
495             L
496              
497             $res = $payjp->event->retrieve('evnt_2f7436fe0017098bc8d22221d1e');
498              
499             =head2 all
500              
501             Returns the event list
502              
503             L
504              
505             $payjp->event->all(limit => 10, offset => 0);
506              
507             =cut
508              
509             sub event{
510 12     12 0 1212 my $self = shift;
511 12         65 return Net::Payjp::Event->new(%$self);
512             }
513              
514             =head1 Account Methods
515              
516             =head2 retrieve
517              
518             Retrieve a account
519              
520             L
521              
522             $payjp->account->retrieve;
523              
524             =cut
525              
526             sub account{
527 9     9 0 27 my $self = shift;
528 9         50 return Net::Payjp::Account->new(%$self);
529             }
530              
531             sub tenant{
532 5     5 0 14 my $self = shift;
533 5         28 return Net::Payjp::Tenant->new(%$self);
534             }
535              
536             sub tenant_transfer{
537 8     8 0 22 my $self = shift;
538 8         35 return Net::Payjp::TenantTransfer->new(%$self);
539             }
540              
541             sub _request{
542 66     66   139 my $self = shift;
543 66         266 my %p = @_;
544              
545 66         132 my $url = $p{url};
546 66   100     188 my $method = $p{method} || 'GET';
547 66   100     267 my $retry = $p{retry} || 0;
548              
549 66         135 my $req;
550             my $with_param;
551 66 100 100     249 if(ref $p{param} eq 'HASH' and keys %{$p{param}} > 0) {
  35         191  
552 23         52 $with_param = 1;
553             }
554 66 100 100     214 if($with_param and ($method eq 'GET' or $method eq 'DELETE')){
      100        
555 14         29 my @param;
556 14         23 foreach my $k(keys %{$p{param}}){
  14         64  
557 14         61 push(@param, "$k=".$p{param}->{$k});
558             }
559 14         72 $url .= '?'.join("&", @param);
560             }
561 66 100 100     255 if($method eq 'POST' and $with_param){
562 9         50 $req = POST($url, $self->_api_param(param => $p{param}));
563             } else {
564 57         264 $req = new HTTP::Request $method => $url;
565             }
566              
567 66         53529 $req->authorization_basic($self->api_key, '');
568 66         21754 my $ua = LWP::UserAgent->new();
569 66         512 $ua->timeout(30);
570 66         11587 my $client = {
571             'bindings_version' => $VERSION,
572             'lang' => 'perl',
573             'lang_version' => $],
574             'publisher' => 'payjp',
575             'uname' => $^O
576             };
577 66         1115 $ua->default_header(
578             'User-Agent' => 'Payjp/v1 PerlBindings/'.$VERSION,
579             'X-Payjp-Client-User-Agent' => JSON->new->encode($client),
580             );
581              
582 66         48202 my $res = $ua->request($req);
583 66         4237 my $code = $res->code;
584 66 100 100     3923 if($code == 200){
    100          
    100          
585 59         379 my $obj = $self->_to_object(JSON->new->decode($res->content));
586 59 100       454 $self->id($obj->id) if $obj->id;
587 59         334 return $obj;
588             } elsif($code == 429 and $retry < $self->{max_retry}){
589             sleep($self->_get_delay_sec(
590             retry => $retry,
591             init_sec => $self->{initial_delay},
592             max_sec => $self->{max_delay}
593 3         35 ));
594 3         186 return $self->_request(method => $method, url =>$url, param => $p{param}, retry => $retry + 1);
595             } elsif($code =~ /^4/){
596 3         30 return $self->_to_object(JSON->new->decode($res->content));
597             }
598 1         10 return $self->_to_object(
599             {
600             error => {
601             message => $res->message,
602             status_code => $code,
603             }
604             }
605             );
606             }
607              
608             sub _get_delay_sec {
609 6     6   1118 my $self = shift;
610 6         26 my %p = @_;
611 6         18 my $retry = $p{retry}; # number
612 6         14 my $init_sec = $p{init_sec}; # number
613 6         13 my $max_sec = $p{max_sec}; # number
614              
615 6         5000698 return min($init_sec * 2 ** $retry, $max_sec) / 2 * (1 + rand(1));
616             }
617              
618             sub _to_object{
619 64     64   3842 my $self = shift;
620 64         104 my $hash = shift;
621              
622 64         304 return Net::Payjp::Object->new(%$hash);
623             }
624              
625             sub _api_param{
626 11     11   36 my $self = shift;
627 11         29 my %p = @_;
628 11         21 my $param = $p{param};
629              
630 11         18 my $req_param;
631 11         17 foreach my $k(keys(%{$param})){
  11         38  
632 13 100       69 if(ref($param->{$k}) eq 'HASH'){
633 2         3 foreach(keys(%{$param->{$k}})){
  2         8  
634 2         11 $req_param->{$k.'['.$_.']'} = $param->{$k}->{$_};
635             }
636             }
637             else{
638 11         31 $req_param->{$k} = $param->{$k};
639             }
640             }
641 11         61 return $req_param;
642             }
643              
644             sub _instance_url{
645 33     33   64 my $self = shift;
646 33   100     101 return $self->_class_url.'/'.($self->id or '');
647             }
648              
649             sub _class_url{
650 47     47   83 my $self = shift;
651 47         445 my ($class) = lc(ref($self)) =~ /([^:]*$)/;
652 47         151 return $self->api_base.'/v1/'.$class.'s';
653             }
654              
655             1;