File Coverage

blib/lib/Business/PAYONE.pm
Criterion Covered Total %
statement 32 63 50.7
branch 0 16 0.0
condition n/a
subroutine 11 15 73.3
pod 0 3 0.0
total 43 97 44.3


line stmt bran cond sub pod time code
1             package Business::PAYONE {
2 1     1   159989 use Mojo::UserAgent;
  1         652148  
  1         8  
3 1     1   57 use Digest::SHA qw/hmac_sha256 hmac_sha256_hex hmac_sha256_base64/;
  1         2  
  1         54  
4 1     1   486 use Crypt::Mac::HMAC qw( hmac_b64 );
  1         1242  
  1         50  
5 1     1   1104 use DateTime;
  1         521347  
  1         46  
6 1     1   616 use DateTime::Format::HTTP;
  1         4026  
  1         72  
7 1     1   823 use Data::Dump qw/dump/;
  1         8295  
  1         111  
8 1     1   1050 use Moo;
  1         6216  
  1         6  
9 1     1   1454 use Carp qw/confess croak/;
  1         2  
  1         54  
10 1     1   19 use namespace::clean;
  1         2  
  1         11  
11 1     1   406 use version;
  1         3  
  1         13  
12 1     1   111 use v5.36;
  1         9  
13              
14             our $VERSION = qv("v0.4.0");
15              
16             has ua => (
17             is => 'ro',
18             default => sub { Mojo::UserAgent->new() },
19             );
20              
21             has endpoint_host => (
22             is => 'ro',
23             );
24              
25             has PSPID => (
26             is => 'ro',
27             );
28              
29             has api_key => (
30             is => 'ro',
31             );
32              
33             has api_secret => (
34             is => 'ro',
35             );
36              
37             has tid => ( is => 'ro' );
38             has kSig => ( is => 'ro' );
39              
40             sub BUILD {
41 0     0 0   my ($self, $args) = @_;
42             }
43              
44             sub CreateHostedCheckout {
45 0     0 0   my ($self, $args) = @_;
46              
47 0           my $auth = $self->_create_autorization({
48             method => 'POST',
49             endpoint => 'hostedcheckouts',
50             });
51              
52 0           my $amount = sprintf("%.0f", int ($args->{amount} * 100));
53 0 0         confess 'Invalid-amount' if $amount !~ m/^\d+$/;
54 0 0         confess 'Invalid-currencyCode' if !$args->{currencyCode};
55 0 0         confess 'Invalid-merchantReference' if !$args->{merchantReference};
56              
57             my $reqargs = {
58             order => {
59             references => {
60             merchantReference => $args->{merchantReference},
61             },
62             amountOfMoney => {
63             amount => $amount,
64             currencyCode => $args->{currencyCode},
65             },
66             },
67             hostedCheckoutSpecificInput => {
68             showResultPage => \1,
69             returnUrl => ''.$args->{returnUrl},
70             },
71             cardPaymentMethodSpecificInput => {
72             authorizationMode => 'SALE', # Capture
73             },
74             redirectPaymentMethodSpecificInput => {
75             requiresApproval => \0,
76             redirectionData => {
77             returnUrl => ''.$args->{returnUrl},
78             },
79             }
80 0           };
81              
82             # use Data::Dump qw/dump/; die dump($reqargs);
83              
84             my $res = $self->ua->post(
85             $auth->{endpoint_uri},
86             # 'http://redbaron.italpro.net:3000',
87             {
88             'Content-type' => $auth->{h_content_type},
89             'Date' => $auth->{h_date},
90             'Authorization' => $auth->{authorization},
91             } =>
92 0           json => $reqargs
93             )->result;
94 0 0         confess $res->message .': ' . dump($res->json) if !$res->is_success;
95              
96             # confess Data::Dump::dump($res->json);
97              
98 0           return $res->json;
99             }
100              
101             sub GetHostedCheckoutStatus {
102 0     0 0   my ($self, $args) = @_;
103              
104 0 0         confess 'Invalid-checkoutId' if !$args->{checkoutId};
105              
106             my $auth = $self->_create_autorization({
107             method => 'GET',
108             endpoint => 'hostedcheckouts',
109             url_extra => '/'.$args->{checkoutId},
110 0           });
111              
112             # die $auth->{endpoint_uri};
113              
114             my $res = $self->ua->get(
115             $auth->{endpoint_uri},
116             {
117             'Content-type' => $auth->{h_content_type},
118             'Date' => $auth->{h_date},
119             'Authorization' => $auth->{authorization},
120             }
121 0           )->result;
122 0 0         confess $res->message .': ' . dump($res->json) if !$res->is_success;
123              
124             # confess Data::Dump::dump($res->json);
125              
126 0           return $res->json;
127             }
128              
129 0     0     sub _create_autorization($self, $args) {
  0            
  0            
  0            
130 0           my $now = DateTime->now(time_zone => 'UTC');
131              
132 0           my $request_method = $args->{method};
133 0 0         confess 'Invalid-method' if $args->{method} !~ m/^(POST|GET)$/xs;
134              
135 0           my $endpoint_path = '/v2/'.$self->PSPID.'/hostedcheckouts'.$args->{url_extra};
136 0 0         my $h_content_type = $request_method eq 'POST' ? 'application/json; charset=utf-8' : '';
137 0           my $h_date = DateTime::Format::HTTP->format_datetime($now);
138 0           my $string_to_hash = $request_method . "\n" . $h_content_type . "\n" . $h_date . "\n" . $endpoint_path . "\n";
139 0           my $signature = hmac_b64('SHA256', $self->api_secret, $string_to_hash);
140 0           my $authorization = "GCS v1HMAC:" . $self->api_key . ":" . $signature;
141              
142             return {
143 0           h_date => $h_date,
144             h_content_type => $h_content_type,
145             authorization => $authorization,
146             endpoint_uri => $self->endpoint_host . $endpoint_path,
147             };
148             }
149             }
150              
151             1;
152              
153             =head1 NAME
154              
155             Business::PAYONE - Perl library for PAYONE online payment system
156              
157             =head1 SYNOPSIS
158              
159             user Business::PAYONE;
160             my $po = Business::PAYONE->new({
161             endpoint_host => 'https://payment.preprod.payone.com',
162             PSPID => 'MyPSPID',
163             api_key => 'xxxxxxxxxxxxxxxxxx',
164             api_secret => 'yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy',
165             });
166              
167             # Create hosted checkout
168             my $pores = $po->CreateHostedCheckout({
169             amount => 290.40,
170             currencyCode => 'EUR',
171             merchantReference => 'XD542SS',
172             returnUrl => 'https://my_site_postpay_page/',
173             });
174              
175             # Store the checkoutid we need later to retrieve transaction result
176             my $payone_checkoutid = $pores->{hostedCheckoutId};
177              
178             # Get the URL and then redirect user to it for payment
179             my $redirect_url = $pores->{redirectUrl};
180             # Do redirection...
181              
182             # Then when user comes back to returnURL...
183              
184             # Verifiy transaction
185             my $pores = $po->GetHostedCheckoutStatus({
186             checkoutId => $payone_checkoutid,
187             });
188             my $status = $pores->{status};
189              
190             if ( $status eq 'PAYMENT_CREATED' && $pores->{createdPaymentOutput}->{payment}->{status} eq 'CAPTURED' ) {
191             # Success
192             }
193              
194             =head1 DESCRIPTION
195              
196             This is HIGHLY EXPERIMENTAL and in the works, do not use for now. It currently only support I<HostedCheckout> (partially).
197              
198             I plan to work on this module if there is interest.
199              
200             =head1 REPOSITORY
201              
202             GitHub repository: L<https://github.com/mc7244/Business-PAYONE>
203              
204             =head1 AUTHOR
205              
206             Michele Beltrame, C<mb@blendgroup.it>
207              
208             =head1 LICENSE
209              
210             This library is free software under the Artistic License 2.0.
211              
212             =cut