File Coverage

blib/lib/Business/OnlinePayment/IPayment/Return.pm
Criterion Covered Total %
statement 69 75 92.0
branch 30 36 83.3
condition 18 30 60.0
subroutine 19 21 90.4
pod 17 17 100.0
total 153 179 85.4


line stmt bran cond sub pod time code
1             package Business::OnlinePayment::IPayment::Return;
2 7     7   44 use strict;
  7         27  
  7         224  
3 7     7   32 use warnings;
  7         15  
  7         144  
4 7     7   29 use utf8;
  7         13  
  7         31  
5 7     7   118 use Moo;
  7         19  
  7         31  
6              
7             =encoding utf8
8              
9             =head1 NAME
10              
11             Business::OnlinePayment::IPayment::Return - Helper class for Ipayment SOAP ipaymentReturn
12              
13             =head1 SYNOPSIS
14              
15             my $bopi = Business::OnlinePayment::IPayment->new(....)
16             # do the preauth transaction and post
17             my $response = $ua->post($secbopi->ipayment_cgi_location, { ... });
18             # get the parameters
19             my $ipayres = $bopi->get_response_obj($response->header('location'));
20              
21             # here we have our Business::OnlinePayment::IPayment::Return object
22             my $return = $bopi->capture($ipayres->ret_trx_number);
23             if ($return->is_success) {
24             print $return->address_info, "\n", $return->ret_transdate, "\n",
25             $return->ret_transtime, "\n", $return->trx_paymentmethod, "\n",
26             $return->ret_trx_number, "\n", $return->ret_authcode, "\n",
27             $return->trx_paymentdata_country, "\n"
28             }
29             elsif($return->is_error) {
30             print $return->status, $return->error_info
31             }
32            
33             =cut
34              
35             # please note that the interface is very similar to the
36             # IPayment::Respone, but the parsing is done differently. In fact,
37             # with a response we have the paramaters flattened, while with a SOAP
38             # response we get nested structures.
39              
40             =head2 ACCESSORS
41              
42             We get this from the response hashref from the SOAP server
43              
44             =over 4
45              
46             =item errorDetails
47              
48             Hashref with the error details
49              
50             {
51             'retAdditionalMsg' => 'Not enough funds left (28184) for this capture.',
52             'retFatalerror' => 0,
53             'retErrorMsg' => 'Capture nicht m',
54             'retErrorcode' => 10031
55             }
56              
57              
58             =cut
59              
60             has errorDetails => (is => 'ro');
61              
62             =item status
63              
64             =item ret_status
65              
66             Status string (ERROR or SUCCESS)
67              
68             =cut
69              
70             has status => (is => 'ro',
71             default => sub { return "" });
72              
73             sub ret_status {
74 1     1 1 439 return shift->status;
75             }
76              
77              
78             =item successDetails
79              
80             Hashref with the success details
81              
82             {
83             'retTransDate' => '17.04.13',
84             'retTrxNumber' => '1-84664243',
85             'retTransTime' => '10:34:10',
86             'retAuthCode' => '',
87             'retStorageId' => '18895061', # if storage is used
88             'trxPayauthStatus' => 'I', # 3D detail
89             'trxIssuerAvsResponse' => 'A', # avs detail
90             } }
91              
92             =cut
93              
94             has successDetails => (is => 'ro');
95              
96              
97             =item trx_paymentmethod
98              
99             =item paymentMethod
100              
101             In this parameter the name of the medium used, payment will be
102             returned. the For example, a credit card type (such as Visa or
103             MasterCard) or ELV.
104              
105             =cut
106              
107             has paymentMethod => (is => 'ro',
108             default => sub { return "" });
109              
110             sub trx_paymentmethod {
111 3     3 1 2413 return shift->paymentMethod;
112             }
113              
114             =item trx_remoteip_country
115              
116             =item trxRemoteIpCountry
117              
118             Iso code of the IP which does the transaction.
119              
120             =cut
121              
122             has trxRemoteIpCountry => (is => 'ro',
123             default => sub { return "" });
124              
125             sub trx_remoteip_country {
126 6     6 1 467 return shift->trxRemoteIpCountry;
127             }
128              
129              
130             =item trx_paymentdata_country
131              
132             =item trxPaymentDataCountry
133              
134             In this parameter, if possible, the ISO code of the country returned
135             to the the payment data belongs. The field contains, for example, for
136             credit card payments, the country the card-issuing bank and ELV
137             payments the bank country.
138              
139             =cut
140              
141             has trxPaymentDataCountry => (is => 'ro',
142             default => sub { return "" });
143              
144              
145             sub trx_paymentdata_country {
146 6     6 1 859 return shift->trxPaymentDataCountry;
147             }
148              
149             =item addressData
150              
151             Hashref with the details of the cardholder's address
152              
153             =cut
154              
155             has addressData => (is => 'ro');
156              
157              
158             =item is_success
159              
160             Return true if the transaction was successful, false otherwise
161              
162             =cut
163              
164             sub is_success {
165 22     22 1 19874 my $self = shift;
166 22 100 66     226 if ((uc($self->status) eq 'SUCCESS') and
167             $self->successDetails) {
168 16         115 return 1
169             } else {
170             return undef
171 6         29 }
172             }
173              
174             =item is_error
175              
176             Return true if there is an error and the SOAP service says so.
177              
178             =cut
179              
180             sub is_error {
181 17     17 1 1506 my $self = shift;
182 17 100 100     244 if ((uc($self->status) eq 'ERROR') or (!$self->is_success)) {
183 16         102 return 1
184             } else {
185             return undef
186 1         5 }
187             }
188              
189             =item address_info
190              
191             The various AddressData fields combined in a single string. It could
192             return just an empty string.
193              
194             =cut
195              
196              
197             sub address_info {
198 4     4 1 20201 my $self = shift;
199 4         17 my $data = $self->addressData;
200 4 100       22 return "" unless $data;
201 2         5 my @details;
202 2         6 foreach my $k (qw/addrName addrStreet addrStreet2 addrZip addrCity
203             addrState addrCountry addrEmail addrTelefon
204             addrTelefax/) {
205 20 100       48 if (my $f = $data->{$k}) {
206 12         22 push @details, $f;
207             }
208             }
209 2         15 return join(" ", @details);
210             }
211              
212             =item error_info
213              
214             Given that if you need to access the individual fields of the error,
215             the method C is available, you may want to use this for
216             a stringified message, which basically combine all the 4 fields.
217              
218             =cut
219              
220              
221             sub error_info {
222 8     8 1 2094 my $self = shift;
223 8 50       29 return "" unless $self->is_error;
224 8         31 my $error_details = $self->errorDetails;
225 8 100       28 unless ($error_details) {
226 1         15 warn "An error without an error string?\n";
227 1         8 return ""
228             }
229 7         14 my @errors;
230 7 100       25 if ($error_details->{retFatalerror}) {
231 1         2 push @errors, "FATAL:";
232             }
233 7         21 foreach my $k (qw/retErrorMsg retAdditionalMsg retErrorcode/) {
234 21 100       63 push @errors, $error_details->{$k} if $error_details->{$k}
235             }
236 7         86 return join(" ", @errors);
237             }
238              
239             =item ret_transdate
240              
241             =item ret_transtime
242              
243             =item trx_timestamp
244              
245             Date of the transaction, time of the transaction, and the two combined.
246              
247             =cut
248              
249             sub ret_transdate {
250 24     24 1 530 my $self = shift;
251             return "" unless ($self->successDetails and
252 24 100 100     141 defined $self->successDetails->{retTransDate});
253 18         80 return $self->successDetails->{retTransDate};
254             }
255              
256             sub ret_transtime {
257 18     18 1 454 my $self = shift;
258             return "" unless ($self->successDetails and
259 18 100 100     101 defined $self->successDetails->{retTransTime});
260 12         88 return $self->successDetails->{retTransTime};
261             }
262              
263             sub trx_timestamp {
264 9     9 1 434 my $self = shift;
265 9 100 66     22 if ($self->ret_transdate or $self->ret_transtime) {
266 6         16 return $self->ret_transdate . " " . $self->ret_transtime;
267             } else {
268 3         11 return "";
269             }
270             }
271              
272             =item ret_trx_number
273              
274             Transaction number, as returned by the IPayment server
275              
276             =cut
277              
278             sub ret_trx_number {
279 21     21 1 1062 my $self = shift;
280             return "" unless ($self->successDetails and
281 21 100 66     138 defined($self->successDetails->{retTrxNumber}));
282 20         114 return $self->successDetails->{retTrxNumber};
283             }
284              
285              
286             =item ret_authcode
287              
288             Auth code, as returned by the IPayment server
289              
290             =cut
291              
292             sub ret_authcode {
293 3     3 1 418 my $self = shift;
294             return "" unless ($self->successDetails and
295 3 100 66     20 defined($self->successDetails->{retAuthCode}));
296 2         10 return $self->successDetails->{retAuthCode};
297             }
298              
299             =item storage_id
300              
301             The storage id (if used).
302              
303             =cut
304              
305             sub storage_id {
306 2     2 1 5 my $self = shift;
307             return "" unless ($self->successDetails and
308 2 50 33     21 defined($self->successDetails->{retStorageId}));
309 2         14 return $self->successDetails->{retStorageId};
310             }
311              
312             =item trx_issuer_avs_response
313              
314             AVS related response.p. 62 of the doc
315              
316             =cut
317              
318             sub trx_issuer_avs_response {
319 0     0 1 0 my $self = shift;
320             return "" unless ($self->successDetails and
321 0 0 0     0 defined($self->successDetails->{trxIssuerAvsResponse}));
322 0         0 return $self->successDetails->{trxIssuerAvsResponse};
323             }
324              
325             =item trx_payauth_status
326              
327             3D-related response, p. 62 of the doc
328              
329             =cut
330              
331             sub trx_payauth_status {
332 0     0 1 0 my $self = shift;
333             return "" unless ($self->successDetails and
334 0 0 0     0 defined($self->successDetails->{trxPayauthStatus}));
335 0         0 return $self->successDetails->{trxPayauthStatus};
336             }
337              
338              
339             =item ret_errorcode
340              
341             The error code. 0 in case of success
342              
343             =cut
344              
345             sub ret_errorcode {
346 4     4 1 516 my $self = shift;
347 4 100       15 unless ($self->errorDetails) {
348 2 100       12 if (lc($self->status) eq 'success') {
349 1         4 return 0;
350             } else {
351 1         4 return "";
352             }
353             }
354 2         8 return $self->errorDetails->{retErrorcode};
355             }
356              
357              
358             =back
359              
360             =cut
361              
362             1;