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   799935 use strict;
  11         56  
  11         312  
4 11     11   64 use warnings;
  11         24  
  11         249  
5              
6 11     11   55 use LWP::UserAgent;
  11         20  
  11         275  
7 11     11   4950 use LWP::Protocol::https;
  11         1273130  
  11         489  
8 11     11   5461 use HTTP::Request::Common;
  11         25885  
  11         798  
9 11     11   6802 use JSON;
  11         111841  
  11         77  
10 11     11   1682 use List::Util qw/min/;
  11         25  
  11         1240  
11 11     11   85 use POSIX qw/floor/;
  11         25  
  11         103  
12              
13 11     11   5329 use Net::Payjp::Account;
  11         44  
  11         308  
14 11     11   3866 use Net::Payjp::Charge;
  11         30  
  11         315  
15 11     11   3993 use Net::Payjp::Customer;
  11         33  
  11         359  
16 11     11   4956 use Net::Payjp::Plan;
  11         37  
  11         356  
17 11     11   4178 use Net::Payjp::Subscription;
  11         31  
  11         379  
18 11     11   4409 use Net::Payjp::Token;
  11         26  
  11         366  
19 11     11   4121 use Net::Payjp::Transfer;
  11         26  
  11         374  
20 11     11   4050 use Net::Payjp::Event;
  11         34  
  11         380  
21 11     11   4133 use Net::Payjp::Tenant;
  11         30  
  11         389  
22 11     11   4123 use Net::Payjp::TenantTransfer;
  11         26  
  11         420  
23 11     11   4165 use Net::Payjp::Object;
  11         27  
  11         17067  
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.2';
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 2538 my $self = shift;
74 113         302 bless{__PACKAGE__->_init(@_)},$self;
75             }
76              
77             sub _init{
78 113     113   179 my $self = shift;
79 113         373 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     1678 max_delay => $p{max_delay} || $MAX_DELAY_SEC,
      66        
      66        
87             );
88             }
89              
90             sub api_key{
91 70     70 1 3882 my $self = shift;
92 70 100       176 $self->{api_key} = shift if @_;
93 70         516 return $self->{api_key};
94             }
95              
96             sub api_base{
97 59     59 0 100 my $self = shift;
98 59 100       163 $self->{api_base} = shift if @_;
99 59         405 return $self->{api_base};
100             }
101              
102             sub id{
103 106     106 0 3923 my $self = shift;
104 106 100       288 $self->{id} = shift if @_;
105 106         413 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 34 my $self = shift;
216 13         77 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 30 my $self = shift;
295 12         68 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 15 my $self = shift;
352 5         30 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 29 my $self = shift;
433 9         61 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 24 my $self = shift;
450 10         57 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 40 my $self = shift;
486 16         75 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 1405 my $self = shift;
511 12         69 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 21 my $self = shift;
528 9         55 return Net::Payjp::Account->new(%$self);
529             }
530              
531             sub tenant{
532 5     5 0 14 my $self = shift;
533 5         31 return Net::Payjp::Tenant->new(%$self);
534             }
535              
536             sub tenant_transfer{
537 8     8 0 20 my $self = shift;
538 8         43 return Net::Payjp::TenantTransfer->new(%$self);
539             }
540              
541             sub _request{
542 66     66   136 my $self = shift;
543 66         226 my %p = @_;
544              
545 66         137 my $url = $p{url};
546 66   100     225 my $method = $p{method} || 'GET';
547 66   100     246 my $retry = $p{retry} || 0;
548              
549 66         130 my $req;
550             my $with_param;
551 66 100 100     249 if(ref $p{param} eq 'HASH' and keys %{$p{param}} > 0) {
  35         177  
552 23         46 $with_param = 1;
553             }
554 66 100 100     220 if($with_param and ($method eq 'GET' or $method eq 'DELETE')){
      100        
555 14         27 my @param;
556 14         25 foreach my $k(keys %{$p{param}}){
  14         47  
557 14         65 push(@param, "$k=".$p{param}->{$k});
558             }
559 14         69 $url .= '?'.join("&", @param);
560             }
561 66 100 100     275 if($method eq 'POST' and $with_param){
562 9         57 $req = POST($url, $self->_api_param(param => $p{param}));
563             } else {
564 57         301 $req = new HTTP::Request $method => $url;
565             }
566              
567 66         54586 $req->authorization_basic($self->api_key, '');
568 66         23597 my $ua = LWP::UserAgent->new();
569 66         479 $ua->timeout(30);
570 66         12428 my $client = {
571             'bindings_version' => $VERSION,
572             'lang' => 'perl',
573             'lang_version' => $],
574             'publisher' => 'payjp',
575             'uname' => $^O
576             };
577 66         1120 $ua->default_header(
578             'User-Agent' => 'Payjp/v1 PerlBindings/'.$VERSION,
579             'X-Payjp-Client-User-Agent' => JSON->new->encode($client),
580             );
581              
582 66         53868 my $res = $ua->request($req);
583 66         4207 my $code = $res->code;
584 66 100 100     3865 if($code == 200){
    100          
    100          
585 59         363 my $obj = $self->_to_object(JSON->new->decode($res->content));
586 59 100       443 $self->id($obj->id) if $obj->id;
587 59         338 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         32 ));
594 3         73 return $self->_request(method => $method, url =>$url, param => $p{param}, retry => $retry + 1);
595             } elsif($code =~ /^4/){
596 3         25 return $self->_to_object(JSON->new->decode($res->content));
597             }
598 1         11 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   1549 my $self = shift;
610 6         23 my %p = @_;
611 6         14 my $retry = $p{retry}; # number
612 6         16 my $init_sec = $p{init_sec}; # number
613 6         8 my $max_sec = $p{max_sec}; # number
614              
615 6         6000446 return min($init_sec * 2 ** $retry, $max_sec) / 2 * (1 + rand(1));
616             }
617              
618             sub _to_object{
619 64     64   3829 my $self = shift;
620 64         98 my $hash = shift;
621              
622 64         324 return Net::Payjp::Object->new(%$hash);
623             }
624              
625             sub _api_param{
626 11     11   26 my $self = shift;
627 11         27 my %p = @_;
628 11         29 my $param = $p{param};
629              
630 11         20 my $req_param;
631 11         22 foreach my $k(keys(%{$param})){
  11         36  
632 13 100       40 if(ref($param->{$k}) eq 'HASH'){
633 2         4 foreach(keys(%{$param->{$k}})){
  2         8  
634 2         12 $req_param->{$k.'['.$_.']'} = $param->{$k}->{$_};
635             }
636             }
637             else{
638 11         33 $req_param->{$k} = $param->{$k};
639             }
640             }
641 11         85 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   86 my $self = shift;
651 47         450 my ($class) = lc(ref($self)) =~ /([^:]*$)/;
652 47         170 return $self->api_base.'/v1/'.$class.'s';
653             }
654              
655             1;