line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Business::OnlinePayment::Ogone; |
2
|
|
|
|
|
|
|
our $AUTHORITY = 'cpan:ESSELENS'; |
3
|
6
|
|
|
6
|
|
31900
|
use parent 'Business::OnlinePayment::HTTPS'; |
|
6
|
|
|
|
|
2302
|
|
|
6
|
|
|
|
|
37
|
|
4
|
6
|
|
|
6
|
|
163998
|
use strict; # keep Perl::Critic happy over common::sense; |
|
6
|
|
|
|
|
17
|
|
|
6
|
|
|
|
|
262
|
|
5
|
6
|
|
|
6
|
|
12502
|
use common::sense; |
|
6
|
|
|
|
|
80
|
|
|
6
|
|
|
|
|
52
|
|
6
|
6
|
|
|
6
|
|
483
|
use Carp; |
|
6
|
|
|
|
|
13
|
|
|
6
|
|
|
|
|
514
|
|
7
|
6
|
|
|
6
|
|
1612
|
use XML::Simple qw/:strict/; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
use Digest::SHA qw/sha1_hex sha256_hex sha512_hex/; |
9
|
|
|
|
|
|
|
use MIME::Base64; |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
# ABSTRACT: Online payment processing via Ogone |
12
|
|
|
|
|
|
|
our $VERSION = 0.2; |
13
|
|
|
|
|
|
|
our $API_VERSION = 4.9; |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# Ogone config defaults and info ###################################################################################### |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
our %defaults = ( |
18
|
|
|
|
|
|
|
server => 'secure.ogone.com', |
19
|
|
|
|
|
|
|
port => 443, |
20
|
|
|
|
|
|
|
); |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
our %info = ( |
23
|
|
|
|
|
|
|
'info_compat' => '0.01', # always 0.01 for now, |
24
|
|
|
|
|
|
|
'gateway_name' => 'Ogone', |
25
|
|
|
|
|
|
|
'gateway_url' => 'http://www.ogone.com/', |
26
|
|
|
|
|
|
|
'module_version' => $VERSION, |
27
|
|
|
|
|
|
|
'supported_types' => [ qw( CC ) ], |
28
|
|
|
|
|
|
|
'token_support' => 0, #card storage/tokenization support |
29
|
|
|
|
|
|
|
'test_transaction' => 1, #set true if ->test_transaction(1) works |
30
|
|
|
|
|
|
|
'supported_actions' => [ |
31
|
|
|
|
|
|
|
'Authorization Only', |
32
|
|
|
|
|
|
|
'Post Authorization', |
33
|
|
|
|
|
|
|
'Query', |
34
|
|
|
|
|
|
|
'Credit', |
35
|
|
|
|
|
|
|
] |
36
|
|
|
|
|
|
|
); |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
# Methods ############################################################################################################# |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
sub _info { |
41
|
|
|
|
|
|
|
return \%info; |
42
|
|
|
|
|
|
|
} |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
sub set_defaults { |
45
|
|
|
|
|
|
|
my $self = shift; |
46
|
|
|
|
|
|
|
my %data = @_; |
47
|
|
|
|
|
|
|
$self->{$_} = $defaults{$_} for keys %defaults; |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
$self->build_subs(qw/http_args result_xml/); |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
sub submit { |
54
|
|
|
|
|
|
|
my $self = shift; |
55
|
|
|
|
|
|
|
my %data = $self->content(); |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
# do not allow submitting same object twice |
58
|
|
|
|
|
|
|
croak 'submitting same object twice is not allowed' if $self->{_dirty}; $self->{_dirty} = 1; |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
# Turn the data into a format usable by the online processor |
61
|
|
|
|
|
|
|
croak 'no action parameter defined in content' unless exists $self->{_content}->{action}; |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# Default currency to Euro |
64
|
|
|
|
|
|
|
$self->{_content}->{currency} ||= 'EUR'; |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
# Table to translate from Business::OnlinePayment::Ogone args to Ogone API args |
67
|
|
|
|
|
|
|
# The values of this hash are also used as a list of allowed args for the HTTP POST request, thus preventing information leakage |
68
|
|
|
|
|
|
|
my %ogone_api_args = ( |
69
|
|
|
|
|
|
|
# credentials |
70
|
|
|
|
|
|
|
login => 'USERID', |
71
|
|
|
|
|
|
|
password => 'PSWD', |
72
|
|
|
|
|
|
|
PSPID => 'PSPID', |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
# primary identifier |
75
|
|
|
|
|
|
|
invoice_number => 'orderID', |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
# transaction identifiers (action = query) |
78
|
|
|
|
|
|
|
payid => 'PAYID', |
79
|
|
|
|
|
|
|
payidsub => 'PAYIDSUB', |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
# credit card data |
82
|
|
|
|
|
|
|
card_number => 'CARDNO', |
83
|
|
|
|
|
|
|
cvc => 'CVC', |
84
|
|
|
|
|
|
|
expiration => 'ED', |
85
|
|
|
|
|
|
|
alias => 'ALIAS', |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
# financial data |
88
|
|
|
|
|
|
|
currency => 'Currency', |
89
|
|
|
|
|
|
|
amount => 'amount', |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
# Ogone specific arguments |
92
|
|
|
|
|
|
|
operation => 'Operation', # REN, DEL, DES, SAL, SAS, RFD, RFS |
93
|
|
|
|
|
|
|
eci => 'ECI', # defaults 7: e-commerce with ssl (9: recurring e-commerce) |
94
|
|
|
|
|
|
|
accepturl => 'accepturl', |
95
|
|
|
|
|
|
|
declineurl => 'declineurl', |
96
|
|
|
|
|
|
|
exceptionurl => 'exceptionurl', |
97
|
|
|
|
|
|
|
paramplus => 'paramplus', |
98
|
|
|
|
|
|
|
complus => 'complus', |
99
|
|
|
|
|
|
|
language => 'LANGUAGE', |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# Business::OnlinePayment common |
102
|
|
|
|
|
|
|
description => 'COM', |
103
|
|
|
|
|
|
|
name => 'CN', |
104
|
|
|
|
|
|
|
email => 'EMAIL', |
105
|
|
|
|
|
|
|
address => 'Owneraddress', |
106
|
|
|
|
|
|
|
zip => 'OwnerZip', |
107
|
|
|
|
|
|
|
city => 'ownertown', |
108
|
|
|
|
|
|
|
country => 'ownercty', |
109
|
|
|
|
|
|
|
phone => 'ownertelno', |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
# client authentication (not used directly, only here as valid HTTP POST arg) |
112
|
|
|
|
|
|
|
SHASign => 'SHASign', # see sha_key, sha_type |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
# 3d secure arguments |
115
|
|
|
|
|
|
|
flag3d => 'FLAG3D', |
116
|
|
|
|
|
|
|
win3ds => 'win3ds', |
117
|
|
|
|
|
|
|
http_accept => 'HTTP_ACCEPT', |
118
|
|
|
|
|
|
|
http_user_agent => 'HTTP_USER_AGENT', |
119
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
# recurrent fields |
121
|
|
|
|
|
|
|
subscription_id => 'SUBSCRIPTION_ID', |
122
|
|
|
|
|
|
|
subscription_orderid => 'SUB_ORDERID', |
123
|
|
|
|
|
|
|
subscription_status => 'SUBSCRIPTION_STATUS', |
124
|
|
|
|
|
|
|
startdate => 'SUB_STARTDATE', |
125
|
|
|
|
|
|
|
enddate => 'SUB_ENDDATE', |
126
|
|
|
|
|
|
|
status => 'SUB_STATUS', |
127
|
|
|
|
|
|
|
period_unit => 'SUB_PERIOD_UNIT', # 'd', 'ww', 'm' (yes two 'w's) for resp daily weekly monthly |
128
|
|
|
|
|
|
|
period_moment => 'SUB_PERIOD_MOMENT', # Integer, the moment in time on which the payment is (0-7 when period_unit is ww, 1-31 for d, 1-12 for m?) |
129
|
|
|
|
|
|
|
period_number => 'SUB_PERIOD_NUMBER', |
130
|
|
|
|
|
|
|
); |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
# Only allow max of 2 digits after comma as we need to int ( $amount * 100 ) for Ogone |
133
|
|
|
|
|
|
|
croak 'max 2 digits after comma (or dot) allowed' if $self->{_content}->{amount} =~ m/[\,\.]\d{3}/; |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
# Ogone has multiple users per login, defaults to login |
136
|
|
|
|
|
|
|
$self->{_content}->{PSPID} ||= $self->{pspid} || $self->{PSPID} || $self->{login} || $self->{_content}->{login}; |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
# Login information, default to constructor values |
139
|
|
|
|
|
|
|
$self->{_content}->{login} ||= $self->{login}; |
140
|
|
|
|
|
|
|
$self->{_content}->{password} ||= $self->{password}; |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
# Default Operation request for authorization (RES) for authorization only, (capture full and close) SAS for post authorization |
143
|
|
|
|
|
|
|
$self->{_content}->{operation} ||= 'RES' if $self->{_content}->{action} =~ m/authorization only/; |
144
|
|
|
|
|
|
|
$self->{_content}->{operation} ||= 'SAL' if $self->{_content}->{action} =~ m/normal authorization/; |
145
|
|
|
|
|
|
|
$self->{_content}->{operation} ||= 'SAS' if $self->{_content}->{action} =~ m/post authorization/; |
146
|
|
|
|
|
|
|
|
147
|
|
|
|
|
|
|
# Default ECI is SSL e-commerce (7) or Recurring with e-commerce (9) if subscription_id exists |
148
|
|
|
|
|
|
|
$self->{_content}->{eci} ||= $self->{_content}->{subscription_id} ? 9 : 7; |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
# Remap the fields to their Ogone-API counterparts ie: cvc => CVC |
151
|
|
|
|
|
|
|
$self->remap_fields(%ogone_api_args); |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
croak "no sha_key provided" if $self->{_content}->{sha_type} && ! $self->{_content}->{sha_key}; |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
# These fields are required by Businiess::OnlinePayment::Ogone |
156
|
|
|
|
|
|
|
my @args_basic = (qw/login password PSPID action/); |
157
|
|
|
|
|
|
|
my @args_ccard = (qw/card_number expiration cvc/); |
158
|
|
|
|
|
|
|
my @args_alias = (qw/alias cvc/); |
159
|
|
|
|
|
|
|
my @args_recur = (@args_basic, qw/name subscription_id subscription_orderid invoice_number amount currency startdate enddate period_unit period_moment period_number/, $self->{_content}->{card_numer} ? @args_ccard : @args_alias ), |
160
|
|
|
|
|
|
|
my @args_new = (@args_basic, qw/invoice_number amount currency/, $self->{_content}->{card_number} ? @args_ccard : @args_alias); |
161
|
|
|
|
|
|
|
my @args_post = (@args_basic, qw/invoice_number/); |
162
|
|
|
|
|
|
|
my @query = (@args_basic, qw/invoice_number/); |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
# Poor man's given/when |
165
|
|
|
|
|
|
|
my %action_arguments = ( |
166
|
|
|
|
|
|
|
qr/normal authorization/i => \@args_new, |
167
|
|
|
|
|
|
|
qr/authorization only/i => \@args_new, |
168
|
|
|
|
|
|
|
qr/post authorization/i => \@args_post, |
169
|
|
|
|
|
|
|
qr/query/i => \@query, |
170
|
|
|
|
|
|
|
qr/recurrent authorization/i => \@args_recur |
171
|
|
|
|
|
|
|
); |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
# Compile a list of required arguments |
174
|
|
|
|
|
|
|
my @args = map { @{$action_arguments{$_}} } # lookup value using regex, return dereffed arrayref |
175
|
|
|
|
|
|
|
grep { $self->{_content}->{action} =~ $_ } # compare action input against regex key |
176
|
|
|
|
|
|
|
keys %action_arguments; # extract regular expressions |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
croak 'unable to determine HTTP POST @args, is the action parameter one of ( authorization only | normal authorization | post authorization | query | recurrent authorization )' unless @args; |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
# Enforce the field requirements by calling parent |
181
|
|
|
|
|
|
|
my @undefs = grep { ! defined $self->{_content}->{$_} } @args; |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
croak "missing required args: ". join(',',@undefs) if scalar @undefs; |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
# Your module should check to see if the require_avs() function returns true, and turn on AVS checking if it does. |
186
|
|
|
|
|
|
|
if ( $self->require_avs() ) { |
187
|
|
|
|
|
|
|
$self->{_content}->{CHECK_AAV} = 1; |
188
|
|
|
|
|
|
|
$self->{_content}->{CAVV_3D} = 1; |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
# Define all possible arguments for http request |
192
|
|
|
|
|
|
|
my @all_http_args = (values %ogone_api_args); |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
# Construct the HTTP POST parameters by selecting the ones which are defined from all_http_args |
195
|
|
|
|
|
|
|
my %http_req_args = map { $_ => $self->{_content}{$_} } |
196
|
|
|
|
|
|
|
grep { defined $self->{_content}{$_} } |
197
|
|
|
|
|
|
|
map { $ogone_api_args{$_} || $_ } @all_http_args; |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
# Ogone accepts the amount as 100 fold in integer form. |
200
|
|
|
|
|
|
|
# # Adding 0.5 to amount to prevent "rounding" errors, see http://stackoverflow.com/a/1274692 or perldoc -q round |
201
|
|
|
|
|
|
|
$http_req_args{amount} = int(100 * $http_req_args{amount} + 0.5) if exists $http_req_args{amount}; |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
# Map normal fields to their SUB_ counterparts when recurrent authorization is used |
204
|
|
|
|
|
|
|
if($self->{_content}->{action} =~ m/recurrent authorization/) { |
205
|
|
|
|
|
|
|
$http_req_args{SUB_COMMENT} = $http_req_args{COM} if exists $http_req_args{COM}; |
206
|
|
|
|
|
|
|
$http_req_args{SUB_AMOUNT} = $http_req_args{amount}; |
207
|
|
|
|
|
|
|
$http_req_args{SUB_ORDERID} = $http_req_args{orderID}; |
208
|
|
|
|
|
|
|
} |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
# PSPID might be entered in lowercase (as per old documentation) |
211
|
|
|
|
|
|
|
$http_req_args{PSPID} = $self->{_content}{pspid} if defined $self->{_content}{pspid}; |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
# Calculate sha1 by default, but has to be enabled in the Ogone backend to have any effect |
214
|
|
|
|
|
|
|
my ($sha_type) = ($self->{_content}->{sha_type} =~ m/^(1|256|512)$/); |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
# Create a reference to the correct sha${sha_type}_hex function, default to SHA-1 |
217
|
|
|
|
|
|
|
my $sha_hex = sub { my $type = shift; no strict; &{"sha".($type || 1)."_hex"}(@_); use strict; }; |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
# Algo: make a list of "KEY=value$passphrase" sort alphabetically |
220
|
|
|
|
|
|
|
my $signature = join('', |
221
|
|
|
|
|
|
|
sort map { uc($_) . "=" . $http_req_args{$_} . ($self->{_content}{sha_key} || '') } |
222
|
|
|
|
|
|
|
keys %http_req_args); |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
$http_req_args{SHASign} = $sha_hex->($sha_type,$signature); |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
# Construct the URL to query, taking into account the action and test_transaction values |
227
|
|
|
|
|
|
|
my %action_file = ( |
228
|
|
|
|
|
|
|
qr/normal authorization/i => 'orderdirect.asp', |
229
|
|
|
|
|
|
|
qr/authorization only/i => 'orderdirect.asp', |
230
|
|
|
|
|
|
|
qr/recurrent authorization/i => 'orderdirect.asp', |
231
|
|
|
|
|
|
|
qr/post authorization/i => 'maintenancedirect.asp', |
232
|
|
|
|
|
|
|
qr/query/i => 'querydirect.asp', |
233
|
|
|
|
|
|
|
); |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
my $uri_dir = $self->test_transaction() ? 'test' : 'prod'; |
236
|
|
|
|
|
|
|
my ($uri_file) = map { $action_file{$_} } |
237
|
|
|
|
|
|
|
grep { $self->{_content}->{action} =~ $_ } |
238
|
|
|
|
|
|
|
keys %action_file; |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
croak 'unable to determine URI path, is the action parameter one of ( authorization only | normal authorization | post authorization | query | recueent authorization)' unless $uri_file; |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
# Construct the path to be used in https_post |
243
|
|
|
|
|
|
|
$self->{path} = '/ncol/'.$uri_dir.'/'.$uri_file; |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
# Save the http args for later inspection |
246
|
|
|
|
|
|
|
$self->http_args(\%http_req_args); |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
# Submit the transaction to the processor and collect a response. |
249
|
|
|
|
|
|
|
my ($page, $response_code, %reply_headers) = $self->https_post(%http_req_args); |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
# Call server_response() with a copy of the entire unprocessed response |
252
|
|
|
|
|
|
|
$self->server_response([$response_code, \%reply_headers, $page]); |
253
|
|
|
|
|
|
|
|
254
|
|
|
|
|
|
|
my $xml = XMLin($page, ForceArray => [], KeyAttr => [] ); |
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
# Store the result xml for later inspection |
257
|
|
|
|
|
|
|
$self->result_xml($xml); |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
croak 'Ogone refused SHA digest' if $xml->{NCERRORPLUS} =~ m#^unknown order/1/s#; |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
# Call is_success() with either a true or false value, indicating if the transaction was successful or not. |
262
|
|
|
|
|
|
|
if ( $response_code =~ m/^200/ ) { |
263
|
|
|
|
|
|
|
$self->is_success(0); # defaults to fail |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
# croak 'incorrect credentials. WARNING: continuing with bad credentials will block your account s: '.$xml->{STATUS}.'{}'.$xml->{NCERROR} if $xml->{NCERROR} eq '50001119'; |
267
|
|
|
|
|
|
|
|
268
|
|
|
|
|
|
|
if ( $xml->{STATUS} == 46 ) { $self->is_success(1) } # identification required |
269
|
|
|
|
|
|
|
if ( $xml->{STATUS} == 5 ) { $self->is_success(1) } # authorization accepted |
270
|
|
|
|
|
|
|
if ( $xml->{STATUS} == 9 ) { $self->is_success(1) } # payment accepted |
271
|
|
|
|
|
|
|
if ( $xml->{STATUS} == 91 ) { $self->is_success(1) } # partial payment accepted |
272
|
|
|
|
|
|
|
if ( $xml->{STATUS} == 61 ) { $self->is_success(1) } # Author. deletion waiting |
273
|
|
|
|
|
|
|
if ( $xml->{STATUS} == 2 ) { $self->failure_status('refused') } # authorization refused |
274
|
|
|
|
|
|
|
if ( $xml->{STATUS} == 0 && $xml->{NCERROR} eq '50001134' ) { $self->failure_status('declined') } # 3d secure wrong identification |
275
|
|
|
|
|
|
|
if ( $xml->{STATUS} == 0 && $xml->{NCERRORPLUS} =~ m/status \(91\)/ ) { |
276
|
|
|
|
|
|
|
$self->failure_status('declined'); |
277
|
|
|
|
|
|
|
$self->error_message('Operation only allowed on fully completed transactions (status may not be 91)'); } |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
} else { |
280
|
|
|
|
|
|
|
warn "remote server did not respond with HTTP 200 status code"; |
281
|
|
|
|
|
|
|
$self->is_success(0) |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
# Extract the base64 encoded HTML part |
285
|
|
|
|
|
|
|
if ( $xml->{STATUS} == 46 ) { |
286
|
|
|
|
|
|
|
my $html = decode_base64($xml->{HTML_ANSWER}); |
287
|
|
|
|
|
|
|
# remove sillyness |
288
|
|
|
|
|
|
|
$html =~ s/ |
289
|
|
|
|
|
|
|
//g; |
290
|
|
|
|
|
|
|
$html =~ s/ //g; |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
# TODO: parse |
293
|
|
|
|
|
|
|
#open my $fh, '>', '/tmp/ogone_'.$self->{_content}->{win3ds}.'.html'; |
294
|
|
|
|
|
|
|
#print $fh $html; |
295
|
|
|
|
|
|
|
} |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
# Call result_code() with the servers result code |
298
|
|
|
|
|
|
|
$self->result_code($xml->{NCERROR}); |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
# If the transaction was successful, call authorization() with the authorization code the processor provided. |
301
|
|
|
|
|
|
|
if ( $self->is_success() ) { |
302
|
|
|
|
|
|
|
$self->authorization($xml->{PAYID}); |
303
|
|
|
|
|
|
|
} |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
# If the transaction was not successful, call error_message() with either the processor provided error message, or some error message to indicate why it failed. |
306
|
|
|
|
|
|
|
if ( not $self->is_success() and $xml->{NCERRORPLUS} ne '!' ) { # '!' == no errorplus |
307
|
|
|
|
|
|
|
$self->error_message($xml->{NCERRORPLUS}); |
308
|
|
|
|
|
|
|
} |
309
|
|
|
|
|
|
|
} |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
42; |
312
|
|
|
|
|
|
|
__END__ |