File Coverage

blib/lib/Net/Payjp.pm
Criterion Covered Total %
statement 170 170 100.0
branch 22 22 100.0
condition 27 29 93.1
subroutine 48 48 100.0
pod 1 18 5.5
total 268 287 93.3


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