line  
 stmt  
 bran  
 cond  
 sub  
 pod  
 time  
 code  
 
1 
 
  
 
   
 
 
 
 
 
 
 
 
 
 
 
 package Business::OnlinePayment::IPayment;  
 
2 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
3 
 
1
 
 
 
 
 
  
1
   
 
 
 
22787
 
 use 5.010001;  
 
  
 
1
 
 
 
 
 
 
 
 
 
5
 
    
 
4 
 
1
 
 
 
 
 
  
1
   
 
 
 
6
 
 use strict;  
 
  
 
1
 
 
 
 
 
 
 
 
 
2
 
    
 
  
 
1
 
 
 
 
 
 
 
 
 
23
 
    
 
5 
 
1
 
 
 
 
 
  
1
   
 
 
 
5
 
 use warnings;  
 
  
 
1
 
 
 
 
 
 
 
 
 
6
 
    
 
  
 
1
 
 
 
 
 
 
 
 
 
30
 
    
 
6 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
7 
 
 
 
 
 
 
 
 
 
 
 
 
 
 # preparation  
 
8 
 
1
 
 
 
 
 
  
1
   
 
 
 
980
 
 use XML::Compile::WSDL11;  
 
  
 
  
0
   
 
 
 
 
 
 
 
 
 
 
 
    
 
  
 
0
 
 
 
 
 
 
 
 
 
 
 
    
 
9 
 
 
 
 
 
 
 
 
 
 
 
 
 
 use XML::Compile::SOAP11;  
 
10 
 
 
 
 
 
 
 
 
 
 
 
 
 
 use XML::Compile::Transport::SOAPHTTP;  
 
11 
 
 
 
 
 
 
 
 
 
 
 
 
 
 use Business::OnlinePayment::IPayment::Response;  
 
12 
 
 
 
 
 
 
 
 
 
 
 
 
 
 use Business::OnlinePayment::IPayment::Transaction;  
 
13 
 
 
 
 
 
 
 
 
 
 
 
 
 
 use Business::OnlinePayment::IPayment::Return;  
 
14 
 
 
 
 
 
 
 
 
 
 
 
 
 
 use Digest::MD5 qw/md5_hex/;  
 
15 
 
 
 
 
 
 
 
 
 
 
 
 
 
 use URI;  
 
16 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
17 
 
 
 
 
 
 
 
 
 
 
 
 
 
 use Business::OnlinePayment 3;  
 
18 
 
 
 
 
 
 
 
 
 
 
 
 
 
 use Moo;  
 
19 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
20 
 
 
 
 
 
 
 
 
 
 
 
 
 
 use base 'Business::OnlinePayment';  
 
21 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
22 
 
 
 
 
 
 
 
 
 
 
 
 
 
 # use Log::Report mode => 'DEBUG';  
 
23 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
24 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 NAME  
 
25 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
26 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Business::OnlinePayment::IPayment - Checkout via Ipayment Silent Mode  
 
27 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
28 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 VERSION  
 
29 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
30 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Version 0.08  
 
31 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
32 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
33 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
34 
 
 
 
 
 
 
 
 
 
 
 
 
 
 our $VERSION = '0.08';  
 
35 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
36 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 DESCRIPTION  
 
37 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
38 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This module provides an interface for online payments via gateway, using the  
 
39 
 
 
 
 
 
 
 
 
 
 
 
 
 
 IPayment silent mode (L).   
 
40 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
41 
 
 
 
 
 
 
 
 
 
 
 
 
 
 It supports payments, capture and reverse operations, and vault-related  
 
42 
 
 
 
 
 
 
 
 
 
 
 
 
 
 functions.  
 
43 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
44 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 SYNOPSIS  
 
45 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
46 
 
 
 
 
 
 
 
 
 
 
 
 
 
   use Business::OnlinePayment::IPayment;  
 
47 
 
 
 
 
 
 
 
 
 
 
 
 
 
   my %account = (  
 
48 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  accountid => 99999,  
 
49 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  trxuserid => 99998,  
 
50 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  trxpassword => 0,  
 
51 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  adminactionpassword => '5cfgRT34xsdedtFLdfHxj7tfwx24fe',  
 
52 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  app_security_key => 'testtest',  
 
53 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  wsdl_file => $wsdl_file,  
 
54 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  success_url => 'http://example.net/checkout-payment',  
 
55 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  failure_url => 'http://example.net/checkout-success',  
 
56 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  hidden_trigger_rul => 'http://example.net/trigger',  
 
57 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 );  
 
58 
 
 
 
 
 
 
 
 
 
 
 
 
 
     
 
59 
 
 
 
 
 
 
 
 
 
 
 
 
 
     
 
60 
 
 
 
 
 
 
 
 
 
 
 
 
 
   my $secbopi = Business::OnlinePayment::IPayment->new(%account);  
 
61 
 
 
 
 
 
 
 
 
 
 
 
 
 
   $secbopi->transaction(transactionType => 'preauth',  
 
62 
 
 
 
 
 
 
 
 
 
 
 
 
 
                         trxAmount => 5000);  
 
63 
 
 
 
 
 
 
 
 
 
 
 
 
 
   # see Business::OnlinePayment::IPayment::Transaction for available options  
 
64 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
65 
 
 
 
 
 
 
 
 
 
 
 
 
 
   $response = $ua->post('https://ipayment.de/merchant/99999/processor/2.0/',  
 
66 
 
 
 
 
 
 
 
 
 
 
 
 
 
                         { ipayment_session_id => $secbopi->session_id,  
 
67 
 
 
 
 
 
 
 
 
 
 
 
 
 
                           addr_name => "Mario Pegula",  
 
68 
 
 
 
 
 
 
 
 
 
 
 
 
 
                           silent => 1,  
 
69 
 
 
 
 
 
 
 
 
 
 
 
 
 
                           cc_number => "4111111111111111",  
 
70 
 
 
 
 
 
 
 
 
 
 
 
 
 
                           cc_checkcode => "",  
 
71 
 
 
 
 
 
 
 
 
 
 
 
 
 
                           cc_expdate_month => "02",  
 
72 
 
 
 
 
 
 
 
 
 
 
 
 
 
                           trx_securityhash => $secbopi->trx_securityhash,  
 
73 
 
 
 
 
 
 
 
 
 
 
 
 
 
                           cc_expdate_year => "2014" });  
 
74 
 
 
 
 
 
 
 
 
 
 
 
 
 
     
 
75 
 
 
 
 
 
 
 
 
 
 
 
 
 
     
 
76 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 ACCESSORS  
 
77 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
78 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head3 Fixed values (accountData and processorUrls)  
 
79 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
80 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The following attributes should and can be set only in the  
 
81 
 
 
 
 
 
 
 
 
 
 
 
 
 
 constructor, as they are pretty much fixed values.  
 
82 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
83 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =over 4  
 
84 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
85 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item wsdl_file  
 
86 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
87 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The name of th WSDL file. It should be a local file.  
 
88 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
89 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
90 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
91 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has wsdl_file => (is => 'rw');  
 
92 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
93 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item accountid  
 
94 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
95 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The Ipayment account id (the one put into the CGI url). Integer.  
 
96 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
97 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
98 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
99 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has accountid => (is => 'rw',  
 
100 
 
 
 
 
 
 
 
 
 
 
 
 
 
                   isa => sub {  
 
101 
 
 
 
 
 
 
 
 
 
 
 
 
 
                       die "Not an integer" unless $_[0] =~ m/^[0-9]+$/s  
 
102 
 
 
 
 
 
 
 
 
 
 
 
 
 
                   });  
 
103 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
104 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item trxuserid  
 
105 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
106 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The application ID, you can in your ipayment configuration menu read  
 
107 
 
 
 
 
 
 
 
 
 
 
 
 
 
 using  Anwendung > Details. Integer  
 
108 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
109 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
110 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
111 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has trxuserid => (is => 'rw',  
 
112 
 
 
 
 
 
 
 
 
 
 
 
 
 
                   isa => sub {  
 
113 
 
 
 
 
 
 
 
 
 
 
 
 
 
                       die "Not an integer" unless $_[0] =~ m/^[0-9]+$/s  
 
114 
 
 
 
 
 
 
 
 
 
 
 
 
 
                   });  
 
115 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
116 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item trxpassword  
 
117 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
118 
 
 
 
 
 
 
 
 
 
 
 
 
 
 For each application, there is an application password which  
 
119 
 
 
 
 
 
 
 
 
 
 
 
 
 
 automatically ipayment System is presented. The password consists of  
 
120 
 
 
 
 
 
 
 
 
 
 
 
 
 
 numbers. You will find the application password in your ipayment  
 
121 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Anwendungen > Details  
 
122 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
123 
 
 
 
 
 
 
 
 
 
 
 
 
 
 B   
 
124 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
125 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
126 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
127 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has trxpassword => (is => 'rw');  
 
128 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
129 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item adminactionpassword  
 
130 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
131 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The admin password.  
 
132 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
133 
 
 
 
 
 
 
 
 
 
 
 
 
 
 B   
 
134 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
135 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut   
 
136 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
137 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has adminactionpassword => (is => 'rw');  
 
138 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
139 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
140 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item app_security_key  
 
141 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
142 
 
 
 
 
 
 
 
 
 
 
 
 
 
 If this attribute is set, we will (and shall) send a checksum for the  
 
143 
 
 
 
 
 
 
 
 
 
 
 
 
 
 parameters.  
 
144 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
145 
 
 
 
 
 
 
 
 
 
 
 
 
 
 B   
 
146 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
147 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
148 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
149 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has app_security_key => (is => 'rw');  
 
150 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
151 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
152 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item accountData  
 
153 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
154 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Accessor to retrieve the hash with the account data details. The  
 
155 
 
 
 
 
 
 
 
 
 
 
 
 
 
 output will look like this:  
 
156 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
157 
 
 
 
 
 
 
 
 
 
 
 
 
 
  accountData => {  
 
158 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  accountid => 99999,  
 
159 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  trxuserid => 99999,  
 
160 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  trxpassword =>0,  
 
161 
 
 
 
 
 
 
 
 
 
 
 
 
 
                  adminactionpassword => '5cfgRT34xsdedtFLdfHxj7tfwx24fe'}  
 
162 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
163 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
164 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
165 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
166 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub accountData {  
 
167 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $self = shift;  
 
168 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my %account_data = (  # mandatory  
 
169 
 
 
 
 
 
 
 
 
 
 
 
 
 
                         accountId => $self->accountid,  
 
170 
 
 
 
 
 
 
 
 
 
 
 
 
 
                         trxuserId => $self->trxuserid,  
 
171 
 
 
 
 
 
 
 
 
 
 
 
 
 
                         trxpassword => $self->trxpassword  
 
172 
 
 
 
 
 
 
 
 
 
 
 
 
 
                         );  
 
173 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $adminpass = $self->adminactionpassword;  
 
174 
 
 
 
 
 
 
 
 
 
 
 
 
 
     if (defined $adminpass) {  
 
175 
 
 
 
 
 
 
 
 
 
 
 
 
 
         $account_data{adminactionpassword} = $adminpass;  
 
176 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
177 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return \%account_data;  
 
178 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
179 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
180 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item success_url   
 
181 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
182 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Mandatory (for us) field, where to redirect the user in case of success.  
 
183 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
184 
 
 
 
 
 
 
 
 
 
 
 
 
 
 CGI-Name: C   
 
185 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
186 
 
 
 
 
 
 
 
 
 
 
 
 
 
 I
   
187 
 
 
 
 
 
 
 
 
 
 
 
 
 
 script.> (no need to C)   
 
188 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
189 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
190 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
191 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has success_url => (is => 'rw',  
 
192 
 
 
 
 
 
 
 
 
 
 
 
 
 
                     isa => sub { die "Missing success url" unless $_[0] },  
 
193 
 
 
 
 
 
 
 
 
 
 
 
 
 
                     default => sub { die "Missing success url" },  
 
194 
 
 
 
 
 
 
 
 
 
 
 
 
 
                    );  
 
195 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
196 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item failure_url  
 
197 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
198 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Mandatory (for us) field, where to redirect the user in case of failure.  
 
199 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
200 
 
 
 
 
 
 
 
 
 
 
 
 
 
 CGI Name: C   
 
201 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Data type: String  
 
202 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
203 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This URL is more in case of failure of ipayment system with the error information and parameters B. This URL must point to a CGI script that can handle the paramaters.   
 
204 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
205 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
206 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
207 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has failure_url => (is => 'rw',  
 
208 
 
 
 
 
 
 
 
 
 
 
 
 
 
                     isa => sub { die "Missing failure url" unless $_[0] },  
 
209 
 
 
 
 
 
 
 
 
 
 
 
 
 
                     default => sub { die "Missing success url" },  
 
210 
 
 
 
 
 
 
 
 
 
 
 
 
 
                    );  
 
211 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
212 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
213 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item hidden_trigger_url  
 
214 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
215 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Optional url for the hidden trigger.  
 
216 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
217 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
218 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
219 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has hidden_trigger_url => (is => 'rw');  
 
220 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
221 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
222 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item processorUrls  
 
223 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
224 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Return the hashref with the defined urls  
 
225 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
226 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =back  
 
227 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
228 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
229 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
230 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub processorUrls {  
 
231 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $self = shift;  
 
232 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return {  
 
233 
 
 
 
 
 
 
 
 
 
 
 
 
 
             redirectUrl => $self->success_url,  
 
234 
 
 
 
 
 
 
 
 
 
 
 
 
 
             silentErrorUrl => $self->failure_url,  
 
235 
 
 
 
 
 
 
 
 
 
 
 
 
 
             hiddenTriggerUrl => $self->hidden_trigger_url  
 
236 
 
 
 
 
 
 
 
 
 
 
 
 
 
            };  
 
237 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
238 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
239 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
240 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
241 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
242 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
243 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head3 error  
 
244 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
245 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This accessors point to a XML::Compile::SOAP backtrace. The object is  
 
246 
 
 
 
 
 
 
 
 
 
 
 
 
 
 quite large and deeply nested, but it's there just in case we need it.  
 
247 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
248 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
249 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
250 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has error => (is => 'rwp');  
 
251 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
252 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head3 debug  
 
253 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
254 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Every call to session id stores the trace into this attribute.  
 
255 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
256 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
257 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
258 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has debug => (is => 'rwp');  
 
259 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
260 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head3 trx_obj  
 
261 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
262 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Attribute to hold a L object   
 
263 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
264 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
265 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
266 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has trx_obj => (is => 'rwp');  
 
267 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
268 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head3 transaction  
 
269 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
270 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Constructor for the object above. All the argument are passed verbatim  
 
271 
 
 
 
 
 
 
 
 
 
 
 
 
 
 to the L constructor,   
 
272 
 
 
 
 
 
 
 
 
 
 
 
 
 
 then the object is stored.  
 
273 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
274 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
275 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
276 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub transaction {  
 
277 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $self = shift;  
 
278 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my %trx = @_;  
 
279 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $trxdata = Business::OnlinePayment::IPayment::Transaction->new(%trx);  
 
280 
 
 
 
 
 
 
 
 
 
 
 
 
 
     $self->_set_trx_obj($trxdata);  
 
281 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
282 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
283 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
284 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 METHODS  
 
285 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
286 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =over 4  
 
287 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
288 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item session_id  
 
289 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
290 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This is the main method to call. The session is not stored in the object, because it can used only B. So calling session_id will send the data to the SOAP service and retrieve the session key.   
 
291 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
292 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
293 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
294 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub session_id {  
 
295 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $self = shift;  
 
296 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # clean eventually stale data  
 
297 
 
 
 
 
 
 
 
 
 
 
 
 
 
     $self->_set_error(undef);  
 
298 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
299 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my %args = (  
 
300 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 # fixed values  
 
301 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 accountData => $self->accountData,  
 
302 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 processorUrls => $self->processorUrls,  
 
303 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 # then the transaction  
 
304 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 transactionType => $self->trx_obj->transactionType,  
 
305 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 paymentType => $self->trx_obj->paymentType,  
 
306 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 transactionData => $self->trx_obj->transactionData,  
 
307 
 
 
 
 
 
 
 
 
 
 
 
 
 
                );  
 
308 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # and the options, if needed  
 
309 
 
 
 
 
 
 
 
 
 
 
 
 
 
     if ($self->trx_obj->options) {  
 
310 
 
 
 
 
 
 
 
 
 
 
 
 
 
         $args{options} = $self->trx_obj->options;  
 
311 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
312 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
313 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # do the request passing the accountData  
 
314 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my ($res, $trace) = $self->_get_soap_object('createSession')->(%args);  
 
315 
 
 
 
 
 
 
 
 
 
 
 
 
 
     $self->_set_debug($trace);  
 
316 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
317 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # check if we got something valuable  
 
318 
 
 
 
 
 
 
 
 
 
 
 
 
 
     unless ($res and  
 
319 
 
 
 
 
 
 
 
 
 
 
 
 
 
             ref($res) eq 'HASH' and   
 
320 
 
 
 
 
 
 
 
 
 
 
 
 
 
             exists $res->{createSessionResponse}->{sessionId}) {  
 
321 
 
 
 
 
 
 
 
 
 
 
 
 
 
         # ok, we got an error. Save the trace to the error and return  
 
322 
 
 
 
 
 
 
 
 
 
 
 
 
 
         $self->_set_error($trace);  
 
323 
 
 
 
 
 
 
 
 
 
 
 
 
 
         return undef;  
 
324 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
325 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
326 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return $res->{createSessionResponse}->{sessionId};  
 
327 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # please note that we don't store the sessionId. It's a fire and forget.  
 
328 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
329 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
330 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
331 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item raw_response_hash  
 
332 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
333 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Debug for the arguments passed to IPayment::Return;  
 
334 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
335 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
336 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
337 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has raw_response_hash => (is => 'rwp');  
 
338 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
339 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
340 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
341 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item capture($ret_trx_number, $amount, $currency, $opts)  
 
342 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
343 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Charge an amount previously preauth'ed. C<$amount> and C<$currency>  
 
344 
 
 
 
 
 
 
 
 
 
 
 
 
 
 are optional and may be used to charge partial amounts. C<$amount> and  
 
345 
 
 
 
 
 
 
 
 
 
 
 
 
 
 C<$currency> follow the same rules of C and C    
 
346 
 
 
 
 
 
 
 
 
 
 
 
 
 
 of L (no decimal,   
 
347 
 
 
 
 
 
 
 
 
 
 
 
 
 
 usually multiply by 100).  
 
348 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
349 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The last optional argument should be a hashref with additional  
 
350 
 
 
 
 
 
 
 
 
 
 
 
 
 
 parameters to pass to transactionData (notably shopperId).  
 
351 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
352 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
353 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
354 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _do_post_payment_op {  
 
355 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my ($self, $op, $number, $amount, $currency, $trxdetails) = @_;  
 
356 
 
 
 
 
 
 
 
 
 
 
 
 
 
     unless (defined $number) {  
 
357 
 
 
 
 
 
 
 
 
 
 
 
 
 
         $self->_set_error("Missing transaction number");  
 
358 
 
 
 
 
 
 
 
 
 
 
 
 
 
         return undef;  
 
359 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
360 
 
 
 
 
 
 
 
 
 
 
 
 
 
     die "Wrong usage, missing operation" unless $op;  
 
361 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my %args = (  
 
362 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 accountData => $self->accountData,  
 
363 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 origTrxNumber => $number,  
 
364 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 );  
 
365 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # amount is always mandatory for transactionData  
 
366 
 
 
 
 
 
 
 
 
 
 
 
 
 
     if ($amount) {  
 
367 
 
 
 
 
 
 
 
 
 
 
 
 
 
         my %trxdata;  
 
368 
 
 
 
 
 
 
 
 
 
 
 
 
 
         die "Wrong amount $amount!\n" unless ($amount =~ m/^[1-9][0-9]*$/s);  
 
369 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
370 
 
 
 
 
 
 
 
 
 
 
 
 
 
         unless ($currency) {  
 
371 
 
 
 
 
 
 
 
 
 
 
 
 
 
             $currency = 'EUR'  
 
372 
 
 
 
 
 
 
 
 
 
 
 
 
 
         }  
 
373 
 
 
 
 
 
 
 
 
 
 
 
 
 
         unless ($currency =~ m/^[A-Z]{3}$/s) {  
 
374 
 
 
 
 
 
 
 
 
 
 
 
 
 
             die "Wrong currency name!\n";  
 
375 
 
 
 
 
 
 
 
 
 
 
 
 
 
         }  
 
376 
 
 
 
 
 
 
 
 
 
 
 
 
 
           
 
377 
 
 
 
 
 
 
 
 
 
 
 
 
 
         %trxdata = (  
 
378 
 
 
 
 
 
 
 
 
 
 
 
 
 
                     trxAmount => $amount,  
 
379 
 
 
 
 
 
 
 
 
 
 
 
 
 
                     trxCurrency => $currency,  
 
380 
 
 
 
 
 
 
 
 
 
 
 
 
 
                     );  
 
381 
 
 
 
 
 
 
 
 
 
 
 
 
 
         if ($trxdetails and  
 
382 
 
 
 
 
 
 
 
 
 
 
 
 
 
             (ref($trxdetails) eq 'HASH')  
 
383 
 
 
 
 
 
 
 
 
 
 
 
 
 
             and %$trxdetails) {  
 
384 
 
 
 
 
 
 
 
 
 
 
 
 
 
             foreach my $k (keys %$trxdetails) {  
 
385 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 unless ($trxdata{$k}) {  
 
386 
 
 
 
 
 
 
 
 
 
 
 
 
 
                     $trxdata{$k} = $trxdetails->{$k}  
 
387 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 }  
 
388 
 
 
 
 
 
 
 
 
 
 
 
 
 
             }  
 
389 
 
 
 
 
 
 
 
 
 
 
 
 
 
         }  
 
390 
 
 
 
 
 
 
 
 
 
 
 
 
 
         $args{transactionData} = \%trxdata;  
 
391 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
392 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
393 
 
 
 
 
 
 
 
 
 
 
 
 
 
     die "Wrong operation" unless ($op eq 'capture' or  
 
394 
 
 
 
 
 
 
 
 
 
 
 
 
 
                                   $op eq 'refund' or  
 
395 
 
 
 
 
 
 
 
 
 
 
 
 
 
                                   $op eq 'reverse');  
 
396 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
397 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my ($res, $trace) = $self->_get_soap_object($op)->(%args);  
 
398 
 
 
 
 
 
 
 
 
 
 
 
 
 
     $self->_set_debug($trace);  
 
399 
 
 
 
 
 
 
 
 
 
 
 
 
 
     $self->_set_raw_response_hash($res);  
 
400 
 
 
 
 
 
 
 
 
 
 
 
 
 
     if ($res and ref($res) eq 'HASH' and  
 
401 
 
 
 
 
 
 
 
 
 
 
 
 
 
         exists $res->{"${op}Response"}->{ipaymentReturn}) {  
 
402 
 
 
 
 
 
 
 
 
 
 
 
 
 
         return Business::OnlinePayment::IPayment::Return  
 
403 
 
 
 
 
 
 
 
 
 
 
 
 
 
           ->new($res->{"${op}Response"}->{ipaymentReturn});  
 
404 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
405 
 
 
 
 
 
 
 
 
 
 
 
 
 
     else {  
 
406 
 
 
 
 
 
 
 
 
 
 
 
 
 
         $self->_set_error($trace);  
 
407 
 
 
 
 
 
 
 
 
 
 
 
 
 
         return undef;  
 
408 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
409 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
410 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
411 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item datastorage_op($datastorage_id)  
 
412 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
413 
 
 
 
 
 
 
 
 
 
 
 
 
 
 After calling C, if you have a valid datastorage id, you   
 
414 
 
 
 
 
 
 
 
 
 
 
 
 
 
 may want to use that instead of creating a session and use the form.  
 
415 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
416 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This method will do a SOAP request to the Ipayment server, using the  
 
417 
 
 
 
 
 
 
 
 
 
 
 
 
 
 transaction details provided in the call to C, and do the   
 
418 
 
 
 
 
 
 
 
 
 
 
 
 
 
 requested operation. So far it's supported preauth and auth. The  
 
419 
 
 
 
 
 
 
 
 
 
 
 
 
 
 capture and other operations should be done via its own method (which  
 
420 
 
 
 
 
 
 
 
 
 
 
 
 
 
 don't require the datastorage, but simply the previous transaction's  
 
421 
 
 
 
 
 
 
 
 
 
 
 
 
 
 id).  
 
422 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
423 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
424 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
425 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub datastorage_op {  
 
426 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my ($self, $id) = @_;  
 
427 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return unless $id;  
 
428 
 
 
 
 
 
 
 
 
 
 
 
 
 
       
 
429 
 
 
 
 
 
 
 
 
 
 
 
 
 
     $self->_set_error(undef);  
 
430 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # this should be fully populated by now  
 
431 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my %args = (  
 
432 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 accountData => $self->accountData,  
 
433 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 paymentData => {  
 
434 
 
 
 
 
 
 
 
 
 
 
 
 
 
                                 storageData => {  
 
435 
 
 
 
 
 
 
 
 
 
 
 
 
 
                                                 fromDatastorageId => $id,  
 
436 
 
 
 
 
 
 
 
 
 
 
 
 
 
                                                },  
 
437 
 
 
 
 
 
 
 
 
 
 
 
 
 
                                },  
 
438 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 transactionData => $self->trx_obj->transactionData,  
 
439 
 
 
 
 
 
 
 
 
 
 
 
 
 
                );  
 
440 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $operation = $self->trx_obj->transactionType;  
 
441 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # append the options if needed  
 
442 
 
 
 
 
 
 
 
 
 
 
 
 
 
     if ($self->trx_obj->options) {  
 
443 
 
 
 
 
 
 
 
 
 
 
 
 
 
         $args{options} = $self->trx_obj->options;  
 
444 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
445 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my ($res, $trace) = $self->_get_soap_object($operation)->(%args);  
 
446 
 
 
 
 
 
 
 
 
 
 
 
 
 
     $self->_set_debug($trace);  
 
447 
 
 
 
 
 
 
 
 
 
 
 
 
 
     $self->_set_raw_response_hash($res);  
 
448 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
449 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # in the trasaction object the call is defined as in CGI, but we  
 
450 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # need the SOAP one  
 
451 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $op = $self->_translate_to_soap_call($operation);  
 
452 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
453 
 
 
 
 
 
 
 
 
 
 
 
 
 
     if ($res and ref($res) eq 'HASH' and  
 
454 
 
 
 
 
 
 
 
 
 
 
 
 
 
         exists $res->{"${op}Response"}->{ipaymentReturn}) {  
 
455 
 
 
 
 
 
 
 
 
 
 
 
 
 
         return Business::OnlinePayment::IPayment::Return  
 
456 
 
 
 
 
 
 
 
 
 
 
 
 
 
           ->new($res->{"${op}Response"}->{ipaymentReturn});  
 
457 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
458 
 
 
 
 
 
 
 
 
 
 
 
 
 
     else {  
 
459 
 
 
 
 
 
 
 
 
 
 
 
 
 
         $self->_set_error($trace);  
 
460 
 
 
 
 
 
 
 
 
 
 
 
 
 
         return undef;  
 
461 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
462 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
463 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
464 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item expire_datastorage($id)  
 
465 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
466 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Given the storage id passed as argument, expire it. Keep in mind that  
 
467 
 
 
 
 
 
 
 
 
 
 
 
 
 
 expiring it multiple times returns always true, so the return code is  
 
468 
 
 
 
 
 
 
 
 
 
 
 
 
 
 not really interesting.  
 
469 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
470 
 
 
 
 
 
 
 
 
 
 
 
 
 
 It returns 0 if the storage didn't exist.  
 
471 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
472 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
473 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
474 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub expire_datastorage {  
 
475 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my ($self, $id) = @_;  
 
476 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return unless $id;  
 
477 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $op = 'expireDatastorage';  
 
478 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my %args = (  
 
479 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 accountData => $self->accountData,  
 
480 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 datastorageId => $id,  
 
481 
 
 
 
 
 
 
 
 
 
 
 
 
 
                );  
 
482 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my ($res, $trace) = $self->_get_soap_object($op)->(%args);  
 
483 
 
 
 
 
 
 
 
 
 
 
 
 
 
     $self->_set_debug($trace);  
 
484 
 
 
 
 
 
 
 
 
 
 
 
 
 
     $self->_set_raw_response_hash($res);  
 
485 
 
 
 
 
 
 
 
 
 
 
 
 
 
     if ($res and ref($res) eq 'HASH' and  
 
486 
 
 
 
 
 
 
 
 
 
 
 
 
 
         exists $res->{"${op}Response"}->{expireDatastorageReturn}) {  
 
487 
 
 
 
 
 
 
 
 
 
 
 
 
 
         return $res->{"${op}Response"}->{expireDatastorageReturn};  
 
488 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
489 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return;  
 
490 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
491 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
492 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
493 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub capture {  
 
494 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my ($self, $number, $amount, $currency, $opts) = @_;  
 
495 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # init the soap, if not already  
 
496 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return $self->_do_post_payment_op(capture => $number,  
 
497 
 
 
 
 
 
 
 
 
 
 
 
 
 
                                       $amount, $currency, $opts);  
 
498 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
499 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
500 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item reverse($ret_trx_number)  
 
501 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
502 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Release the amount previously preauth'ed, passing the original  
 
503 
 
 
 
 
 
 
 
 
 
 
 
 
 
 transaction number. No partial amount can be released, and will  
 
504 
 
 
 
 
 
 
 
 
 
 
 
 
 
 succeed only if no charging has been done.  
 
505 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
506 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
507 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
508 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
509 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub reverse {  
 
510 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my ($self, $number) = @_;  
 
511 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # we don't pass $amount and $currency  
 
512 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return $self->_do_post_payment_op(reverse => $number);  
 
513 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
514 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
515 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item refund($ret_trx_number, $amount, $currency, $opts)  
 
516 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
517 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Refund the given amount. Please note that we have to pass the  
 
518 
 
 
 
 
 
 
 
 
 
 
 
 
 
 transaction number B, not the C one.    
 
519 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
520 
 
 
 
 
 
 
 
 
 
 
 
 
 
 The last optional argument should be a hashref with additional  
 
521 
 
 
 
 
 
 
 
 
 
 
 
 
 
 parameters to pass to transactionData (notably shopperId).  
 
522 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
523 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
524 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
525 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub refund {  
 
526 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my ($self, $number, $amount, $currency, $opts) = @_;  
 
527 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return $self->_do_post_payment_op(refund => $number,  
 
528 
 
 
 
 
 
 
 
 
 
 
 
 
 
                                       $amount, $currency, $opts);  
 
529 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
530 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
531 
 
 
 
 
 
 
 
 
 
 
 
 
 
 # accessors to soap objects  
 
532 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
533 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has _soap_createSession => (is => 'rw');  
 
534 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has _soap_capture => (is => 'rw');  
 
535 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has _soap_reverse => (is => 'rw');  
 
536 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has _soap_refund => (is => 'rw');  
 
537 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has _soap_preAuthorize => (is => 'rw');  
 
538 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has _soap_authorize => (is => 'rw');  
 
539 
 
 
 
 
 
 
 
 
 
 
 
 
 
 has _soap_expireDatastorage => (is => 'rw');  
 
540 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
541 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _get_soap_object {  
 
542 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my ($self, $op) = @_;  
 
543 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $call = $self->_translate_to_soap_call($op);  
 
544 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $accessor = "_soap_" . $call;  
 
545 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $obj = $self->$accessor;  
 
546 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return $obj if $obj;  
 
547 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $wsdl = XML::Compile::WSDL11->new($self->wsdl_file);  
 
548 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $client = $wsdl->compileClient($call);  
 
549 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # set the object  
 
550 
 
 
 
 
 
 
 
 
 
 
 
 
 
     $self->$accessor($client);  
 
551 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return $self->$accessor;  
 
552 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
553 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
554 
 
 
 
 
 
 
 
 
 
 
 
 
 
 # this method may be used for to do a sanity check, as it will die on  
 
555 
 
 
 
 
 
 
 
 
 
 
 
 
 
 # undef/wrong values.  
 
556 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
557 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub _translate_to_soap_call {  
 
558 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my ($self, $op) = @_;  
 
559 
 
 
 
 
 
 
 
 
 
 
 
 
 
     die "No operation provided!" unless $op;  
 
560 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my %hash = (capture => 'capture',  
 
561 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 reverse =>  'reverse',  
 
562 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 refund =>  'refund',  
 
563 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 preauth => 'preAuthorize',  
 
564 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 auth => 'authorize',  
 
565 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 authorize =>  'authorize',  
 
566 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 preAuthorize => 'preAuthorize',  
 
567 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 createSession => 'createSession',  
 
568 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 expireDatastorage => 'expireDatastorage',  
 
569 
 
 
 
 
 
 
 
 
 
 
 
 
 
                );  
 
570 
 
 
 
 
 
 
 
 
 
 
 
 
 
     die "Wrong call $op!" unless $hash{$op};  
 
571 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return $hash{$op};  
 
572 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
573 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
574 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =back  
 
575 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
576 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 SOAP specification  
 
577 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
578 
 
 
 
 
 
 
 
 
 
 
 
 
 
   Name: createSession  
 
579 
 
 
 
 
 
 
 
 
 
 
 
 
 
   Binding: ipaymentBinding  
 
580 
 
 
 
 
 
 
 
 
 
 
 
 
 
   Endpoint: https://ipayment.de/service/3.0/  
 
581 
 
 
 
 
 
 
 
 
 
 
 
 
 
   SoapAction: createSession  
 
582 
 
 
 
 
 
 
 
 
 
 
 
 
 
   Input:  
 
583 
 
 
 
 
 
 
 
 
 
 
 
 
 
     use: literal  
 
584 
 
 
 
 
 
 
 
 
 
 
 
 
 
     namespace: https://ipayment.de/service_v3/binding  
 
585 
 
 
 
 
 
 
 
 
 
 
 
 
 
     message: createSessionRequest  
 
586 
 
 
 
 
 
 
 
 
 
 
 
 
 
     parts:  
 
587 
 
 
 
 
 
 
 
 
 
 
 
 
 
       accountData: https://ipayment.de/service_v3/extern:AccountData  
 
588 
 
 
 
 
 
 
 
 
 
 
 
 
 
       transactionData: https://ipayment.de/service_v3/extern:TransactionData  
 
589 
 
 
 
 
 
 
 
 
 
 
 
 
 
       transactionType: https://ipayment.de/service_v3/extern:TransactionType  
 
590 
 
 
 
 
 
 
 
 
 
 
 
 
 
       paymentType: https://ipayment.de/service_v3/extern:PaymentType  
 
591 
 
 
 
 
 
 
 
 
 
 
 
 
 
       options: https://ipayment.de/service_v3/extern:OptionData  
 
592 
 
 
 
 
 
 
 
 
 
 
 
 
 
       processorUrls: https://ipayment.de/service_v3/extern:ProcessorUrlData  
 
593 
 
 
 
 
 
 
 
 
 
 
 
 
 
   Output:  
 
594 
 
 
 
 
 
 
 
 
 
 
 
 
 
     use: literal  
 
595 
 
 
 
 
 
 
 
 
 
 
 
 
 
     namespace: https://ipayment.de/service_v3/binding  
 
596 
 
 
 
 
 
 
 
 
 
 
 
 
 
     message: createSessionResponse  
 
597 
 
 
 
 
 
 
 
 
 
 
 
 
 
     parts:  
 
598 
 
 
 
 
 
 
 
 
 
 
 
 
 
       sessionId: http://www.w3.org/2001/XMLSchema:string  
 
599 
 
 
 
 
 
 
 
 
 
 
 
 
 
   Style: rpc  
 
600 
 
 
 
 
 
 
 
 
 
 
 
 
 
   Transport: http://schemas.xmlsoap.org/soap/http  
 
601 
 
 
 
 
 
 
 
 
 
 
 
 
 
     
 
602 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
603 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 SECURITY  
 
604 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
605 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =over 4  
 
606 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
607 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item trx_securityhash  
 
608 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
609 
 
 
 
 
 
 
 
 
 
 
 
 
 
 If we have a security key, we trigger the hash generation, so we can  
 
610 
 
 
 
 
 
 
 
 
 
 
 
 
 
 double check the result.  
 
611 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
612 
 
 
 
 
 
 
 
 
 
 
 
 
 
 CGI Name: C   
 
613 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Data type: string, maximum 32 characters  
 
614 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
615 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Security hash of CGI command concatenating Id, amount, currency,  
 
616 
 
 
 
 
 
 
 
 
 
 
 
 
 
 password, Transaction Security Key (should be set in the configuration  
 
617 
 
 
 
 
 
 
 
 
 
 
 
 
 
 menu using ipayment). The hash is C, C,    
 
618 
 
 
 
 
 
 
 
 
 
 
 
 
 
 C, C and the I.     
 
619 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
620 
 
 
 
 
 
 
 
 
 
 
 
 
 
   md5_hex($trxuser_id . $trx_amount . $trx_currency . $trxpassword . $sec_key);   
 
621 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
622 
 
 
 
 
 
 
 
 
 
 
 
 
 
   perl -e 'use Digest::MD5 qw/md5_hex/;  
 
623 
 
 
 
 
 
 
 
 
 
 
 
 
 
                 print  md5_hex("99998" . 5000 . "EUR" . 0 .  "testtest"), "\n";'  
 
624 
 
 
 
 
 
 
 
 
 
 
 
 
 
   # => then in the form  
 
625 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
  
626 
 
 
 
 
 
 
 
 
 
 
 
 
 
          value="db4812171baef817dec0cd56c0f5c8cd">  
 
627 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
628 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
629 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
630 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub trx_securityhash {  
 
631 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $self = shift;  
 
632 
 
 
 
 
 
 
 
 
 
 
 
 
 
     unless ($self->app_security_key) {  
 
633 
 
 
 
 
 
 
 
 
 
 
 
 
 
         warn "hash requested, but app_security_key wasn't provided!\n";  
 
634 
 
 
 
 
 
 
 
 
 
 
 
 
 
         return;  
 
635 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
636 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return md5_hex($self->trxuserid .  
 
637 
 
 
 
 
 
 
 
 
 
 
 
 
 
                    $self->trx_obj->trxAmount .  
 
638 
 
 
 
 
 
 
 
 
 
 
 
 
 
                    $self->trx_obj->trxCurrency .  
 
639 
 
 
 
 
 
 
 
 
 
 
 
 
 
                    $self->trxpassword .  
 
640 
 
 
 
 
 
 
 
 
 
 
 
 
 
                    $self->app_security_key);  
 
641 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
642 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
643 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =back  
 
644 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
645 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 UTILITIES  
 
646 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
647 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head3 get_response_obj($rawuri) or get_response_obj(%params)  
 
648 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
649 
 
 
 
 
 
 
 
 
 
 
 
 
 
 To be sure the transaction happened as aspected, we have to check this back.  
 
650 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Expected hash:  
 
651 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
652 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Success:  
 
653 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
654 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'ret_transtime' => '08:42:05',       'ret_transtime' => '08:42:03',  
 
655 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'ret_errorcode' => '0',              'ret_errorcode' => '0',  
 
656 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'redirect_needed' => '0',            'redirect_needed' => '0',  
 
657 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'ret_transdate' => '14.03.13',       'ret_transdate' => '14.03.13',  
 
658 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'addr_name' => 'Mario Pegula',       'addr_name' => 'Mario Rossi',  
 
659 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'trx_paymentmethod' => 'VisaCard',   'trx_paymentmethod' => 'AmexCard',  
 
660 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'ret_authcode' => '',                'ret_authcode' => '',  
 
661 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'trx_currency' => 'EUR',             'trx_currency' => 'EUR',  
 
662 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'ret_url_checksum' => 'md5sum',  
 
663 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'ret_param_checksum' => 'md5sum',  
 
664 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'ret_ip' => '88.198.37.147',         'ret_ip' => '88.198.37.147',  
 
665 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'trx_typ' => 'preauth',              'trx_typ' => 'preauth',  
 
666 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'ret_trx_number' => '1-83443831',    'ret_trx_number' => '1-83443830',  
 
667 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'ret_status' => 'SUCCESS',           'ret_status' => 'SUCCESS',  
 
668 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'trx_paymenttyp' => 'cc',            'trx_paymenttyp' => 'cc',  
 
669 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'trx_paymentdata_country' => 'US',  
 
670 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'trx_amount' => '5000',              'trx_amount' => '1000',  
 
671 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'ret_booknr' => '1-83443831',        'ret_booknr' => '1-83443830',  
 
672 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'trxuser_id' => '99998',             'trxuser_id' => '99999',  
 
673 
 
 
 
 
 
 
 
 
 
 
 
 
 
   'trx_remoteip_country' => 'DE'       'trx_remoteip_country' => 'DE'  
 
674 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
675 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Returns a L object, so you   
 
676 
 
 
 
 
 
 
 
 
 
 
 
 
 
 can call ->is_success on it.  
 
677 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
678 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This is just a shortcut for  
 
679 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
680 
 
 
 
 
 
 
 
 
 
 
 
 
 
   Business::OnlinePayment::IPayment::Response->new(%params);  
 
681 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
682 
 
 
 
 
 
 
 
 
 
 
 
 
 
 with C and C inherited from the fixed    
 
683 
 
 
 
 
 
 
 
 
 
 
 
 
 
 values of this class.  
 
684 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
685 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
686 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
687 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub get_response_obj {  
 
688 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my ($self, @args) = @_;  
 
689 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my %details;  
 
690 
 
 
 
 
 
 
 
 
 
 
 
 
 
     # only one argument: we have an URI  
 
691 
 
 
 
 
 
 
 
 
 
 
 
 
 
     if (@args == 1) {  
 
692 
 
 
 
 
 
 
 
 
 
 
 
 
 
         my $raw_url = shift(@args);  
 
693 
 
 
 
 
 
 
 
 
 
 
 
 
 
         my $uri = URI->new($raw_url);  
 
694 
 
 
 
 
 
 
 
 
 
 
 
 
 
         %details = $uri->query_form;  
 
695 
 
 
 
 
 
 
 
 
 
 
 
 
 
         $details{raw_url} = $raw_url;  
 
696 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
697 
 
 
 
 
 
 
 
 
 
 
 
 
 
     elsif ((@args % 2) == 0) {  
 
698 
 
 
 
 
 
 
 
 
 
 
 
 
 
         %details = @args;  
 
699 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
700 
 
 
 
 
 
 
 
 
 
 
 
 
 
     else {  
 
701 
 
 
 
 
 
 
 
 
 
 
 
 
 
         die "Arguments to validate the response not provided "  
 
702 
 
 
 
 
 
 
 
 
 
 
 
 
 
           . "(paramaters or raw url";  
 
703 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
704 
 
 
 
 
 
 
 
 
 
 
 
 
 
     unless (exists $details{my_security_key}) {  
 
705 
 
 
 
 
 
 
 
 
 
 
 
 
 
         $details{my_security_key} = $self->app_security_key;  
 
706 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
707 
 
 
 
 
 
 
 
 
 
 
 
 
 
     unless (exists $details{my_userid}) {  
 
708 
 
 
 
 
 
 
 
 
 
 
 
 
 
         $details{my_userid}       = $self->trxuserid;  
 
709 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
710 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return Business::OnlinePayment::IPayment::Response->new(%details);  
 
711 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
712 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
713 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head3 ipayment_cgi_location  
 
714 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
715 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Returns the correct url where the customer posts the CC data, which is simply:  
 
716 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L/processor/2.0/>   
 
717 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
718 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
719 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
720 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub ipayment_cgi_location {  
 
721 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $self = shift;  
 
722 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return 'https://ipayment.de/merchant/' . $self->accountid  
 
723 
 
 
 
 
 
 
 
 
 
 
 
 
 
       . '/processor/2.0/';  
 
724 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
725 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
726 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
727 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head2 Additional information  
 
728 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
729 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head3 country  
 
730 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
731 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Country code of the cardholder of the current  
 
732 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L object   
 
733 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
734 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Being these information transaction specific, if a transaction has not  
 
735 
 
 
 
 
 
 
 
 
 
 
 
 
 
 been initiated, the method will not do anything nor will return  
 
736 
 
 
 
 
 
 
 
 
 
 
 
 
 
 anything.  
 
737 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
738 
 
 
 
 
 
 
 
 
 
 
 
 
 
 UK will be translated to GB, and EI to IE.  
 
739 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
740 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
741 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
742 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
743 
 
 
 
 
 
 
 
 
 
 
 
 
 
 sub country {  
 
744 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $self = shift;  
 
745 
 
 
 
 
 
 
 
 
 
 
 
 
 
     #   
 
746 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return unless $self->trx_obj;  
 
747 
 
 
 
 
 
 
 
 
 
 
 
 
 
     if (@_ == 1) {  
 
748 
 
 
 
 
 
 
 
 
 
 
 
 
 
         $self->trx_obj->addr_info->{country} = shift;  
 
749 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
750 
 
 
 
 
 
 
 
 
 
 
 
 
 
     my $country = uc($self->trx_obj->addr_info->{country});  
 
751 
 
 
 
 
 
 
 
 
 
 
 
 
 
     return unless $country =~ m/^[A-Z]{2,3}$/s;  
 
752 
 
 
 
 
 
 
 
 
 
 
 
 
 
     if ($country eq 'UK') {  
 
753 
 
 
 
 
 
 
 
 
 
 
 
 
 
         return 'GB';  
 
754 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
755 
 
 
 
 
 
 
 
 
 
 
 
 
 
     elsif ($country eq 'EI') {  
 
756 
 
 
 
 
 
 
 
 
 
 
 
 
 
         return 'IE';  
 
757 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
758 
 
 
 
 
 
 
 
 
 
 
 
 
 
     else {  
 
759 
 
 
 
 
 
 
 
 
 
 
 
 
 
         return $country;  
 
760 
 
 
 
 
 
 
 
 
 
 
 
 
 
     }  
 
761 
 
 
 
 
 
 
 
 
 
 
 
 
 
 }  
 
762 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
763 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 TESTING  
 
764 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
765 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Test credit card numbers can be found here: L.   
 
766 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
767 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 AUTHOR  
 
768 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
769 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Marco Pessotto, C<<  >>   
 
770 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
771 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 BUGS  
 
772 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
773 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Please report any bugs or feature requests to C, or through   
 
774 
 
 
 
 
 
 
 
 
 
 
 
 
 
 the web interface at L.  I will be notified, and then you'll   
 
775 
 
 
 
 
 
 
 
 
 
 
 
 
 
 automatically be notified of progress on your bug as I make changes.  
 
776 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
777 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
778 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
779 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
780 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 SUPPORT  
 
781 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
782 
 
 
 
 
 
 
 
 
 
 
 
 
 
 You can find documentation for this module with the perldoc command.  
 
783 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
784 
 
 
 
 
 
 
 
 
 
 
 
 
 
     perldoc Business::OnlinePayment::IPayment  
 
785 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
786 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
787 
 
 
 
 
 
 
 
 
 
 
 
 
 
 You can also look for information at:  
 
788 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
789 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =over 4  
 
790 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
791 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * RT: CPAN's request tracker (report bugs here)  
 
792 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
793 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L   
 
794 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
795 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * AnnoCPAN: Annotated CPAN documentation  
 
796 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
797 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L   
 
798 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
799 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * CPAN Ratings  
 
800 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
801 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L   
 
802 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
803 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =item * Search CPAN  
 
804 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
805 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L   
 
806 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
807 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =back  
 
808 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
809 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
810 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 ACKNOWLEDGEMENTS  
 
811 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
812 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Thanks to Stefan Hornburg (Racke) C for the initial   
 
813 
 
 
 
 
 
 
 
 
 
 
 
 
 
 code, ideas and support.  
 
814 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
815 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =head1 LICENSE AND COPYRIGHT  
 
816 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
817 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Copyright 2013-2014 Marco Pessotto.  
 
818 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
819 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This program is free software; you can redistribute it and/or modify it  
 
820 
 
 
 
 
 
 
 
 
 
 
 
 
 
 under the terms of the the Artistic License (2.0). You may obtain a  
 
821 
 
 
 
 
 
 
 
 
 
 
 
 
 
 copy of the full license at:  
 
822 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
823 
 
 
 
 
 
 
 
 
 
 
 
 
 
 L   
 
824 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
825 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Any use, modification, and distribution of the Standard or Modified  
 
826 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Versions is governed by this Artistic License. By using, modifying or  
 
827 
 
 
 
 
 
 
 
 
 
 
 
 
 
 distributing the Package, you accept this license. Do not use, modify,  
 
828 
 
 
 
 
 
 
 
 
 
 
 
 
 
 or distribute the Package, if you do not accept this license.  
 
829 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
830 
 
 
 
 
 
 
 
 
 
 
 
 
 
 If your Modified Version has been derived from a Modified Version made  
 
831 
 
 
 
 
 
 
 
 
 
 
 
 
 
 by someone other than you, you are nevertheless required to ensure that  
 
832 
 
 
 
 
 
 
 
 
 
 
 
 
 
 your Modified Version complies with the requirements of this license.  
 
833 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
834 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This license does not grant you the right to use any trademark, service  
 
835 
 
 
 
 
 
 
 
 
 
 
 
 
 
 mark, tradename, or logo of the Copyright Holder.  
 
836 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
837 
 
 
 
 
 
 
 
 
 
 
 
 
 
 This license includes the non-exclusive, worldwide, free-of-charge  
 
838 
 
 
 
 
 
 
 
 
 
 
 
 
 
 patent license to make, have made, use, offer to sell, sell, import and  
 
839 
 
 
 
 
 
 
 
 
 
 
 
 
 
 otherwise transfer the Package with respect to any patent claims  
 
840 
 
 
 
 
 
 
 
 
 
 
 
 
 
 licensable by the Copyright Holder that are necessarily infringed by the  
 
841 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Package. If you institute patent litigation (including a cross-claim or  
 
842 
 
 
 
 
 
 
 
 
 
 
 
 
 
 counterclaim) against any party alleging that the Package constitutes  
 
843 
 
 
 
 
 
 
 
 
 
 
 
 
 
 direct or contributory patent infringement, then this Artistic License  
 
844 
 
 
 
 
 
 
 
 
 
 
 
 
 
 to you shall terminate on the date that such litigation is filed.  
 
845 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
846 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER  
 
847 
 
 
 
 
 
 
 
 
 
 
 
 
 
 AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.  
 
848 
 
 
 
 
 
 
 
 
 
 
 
 
 
 THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR  
 
849 
 
 
 
 
 
 
 
 
 
 
 
 
 
 PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY  
 
850 
 
 
 
 
 
 
 
 
 
 
 
 
 
 YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR  
 
851 
 
 
 
 
 
 
 
 
 
 
 
 
 
 CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR  
 
852 
 
 
 
 
 
 
 
 
 
 
 
 
 
 CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,  
 
853 
 
 
 
 
 
 
 
 
 
 
 
 
 
 EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 
854 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
855 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
856 
 
 
 
 
 
 
 
 
 
 
 
 
 
 =cut  
 
857 
 
 
 
 
 
 
 
 
 
 
 
 
 
    
 
858 
 
 
 
 
 
 
 
 
 
 
 
 
 
 1; # End of Business::OnlinePayment::IPayment