| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
##### TODO: expand grammar map |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
package ICS::Simple; |
|
4
|
|
|
|
|
|
|
|
|
5
|
1
|
|
|
1
|
|
22265
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
51
|
|
|
6
|
1
|
|
|
1
|
|
6
|
no strict "refs"; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
1967
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
eval "use ICS"; |
|
9
|
|
|
|
|
|
|
die qq{ICS::Simple requires the CyberSource ICS module.\nSee http://www.cybersource.com/support_center/implementation/downloads/scmp_api/.\n} if $@; |
|
10
|
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 NAME |
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
ICS::Simple - Simple interface to CyberSource ICS2 |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 VERSION |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
Version 0.06 |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=cut |
|
20
|
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
our $VERSION = '0.06'; |
|
22
|
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
=head1 SYNOPSIS |
|
24
|
|
|
|
|
|
|
|
|
25
|
|
|
|
|
|
|
Here is some basic code. Hopefully I'll come back through soon to document it properly. |
|
26
|
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
use ICS::Simple; |
|
28
|
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
my $ics = ICS::Simple->new( |
|
30
|
|
|
|
|
|
|
ICSPath => '/opt/ics', |
|
31
|
|
|
|
|
|
|
MerchantId => 'v0123456789', # CyberSource supplies this number to you |
|
32
|
|
|
|
|
|
|
Mode => 'test', |
|
33
|
|
|
|
|
|
|
Currency => 'USD', |
|
34
|
|
|
|
|
|
|
Grammar => 'UpperCamel', # defaults to raw ICS responses, so you might want to set this |
|
35
|
|
|
|
|
|
|
#ErrorsTo => 'all-errors@some.fun.place.com', |
|
36
|
|
|
|
|
|
|
CriticalErrorsTo => 'only-critical-errors@some.fun.place.com', |
|
37
|
|
|
|
|
|
|
); |
|
38
|
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
my $request = { |
|
40
|
|
|
|
|
|
|
OrderId => 'order19857219', |
|
41
|
|
|
|
|
|
|
FirstName => 'Fred', |
|
42
|
|
|
|
|
|
|
LastName => 'Smith', |
|
43
|
|
|
|
|
|
|
Email => 'fred.smith@buyer-of-stuff.com', |
|
44
|
|
|
|
|
|
|
CardNumber => '4111111111111111', |
|
45
|
|
|
|
|
|
|
CardCVV => '123', |
|
46
|
|
|
|
|
|
|
CardExpYear => '2008', |
|
47
|
|
|
|
|
|
|
CardExpMonth => '12', |
|
48
|
|
|
|
|
|
|
BillingAddress => '123 Main St', |
|
49
|
|
|
|
|
|
|
BillingCity => 'Olympia', |
|
50
|
|
|
|
|
|
|
BillingRegion => 'WA', |
|
51
|
|
|
|
|
|
|
BillingPostalCode => '98501', |
|
52
|
|
|
|
|
|
|
BillingCountryCode => 'US', |
|
53
|
|
|
|
|
|
|
ShippingAddress1 => '6789 Industrial Pl', |
|
54
|
|
|
|
|
|
|
ShippingAddress2 => 'Floor 83, Room 11415', |
|
55
|
|
|
|
|
|
|
ShippingCity => 'Olympia', |
|
56
|
|
|
|
|
|
|
ShippingRegion => 'WA', |
|
57
|
|
|
|
|
|
|
ShippingPostalCode => '98506', |
|
58
|
|
|
|
|
|
|
ShippingCountryCode => 'US', |
|
59
|
|
|
|
|
|
|
ShippingFee => '25.05', |
|
60
|
|
|
|
|
|
|
HandlingFee => '5.00', |
|
61
|
|
|
|
|
|
|
Items => [ |
|
62
|
|
|
|
|
|
|
{ Description => 'Mega Lizard Monster RC', |
|
63
|
|
|
|
|
|
|
Price => '25.00', |
|
64
|
|
|
|
|
|
|
SKU => 'prod15185' }, |
|
65
|
|
|
|
|
|
|
{ Description => 'Super Racer Parts Kit', |
|
66
|
|
|
|
|
|
|
Price => '15.30', |
|
67
|
|
|
|
|
|
|
SKU => 'prod23523' }, |
|
68
|
|
|
|
|
|
|
{ Description => 'Uber Space Jacket', |
|
69
|
|
|
|
|
|
|
Price => '72.24', |
|
70
|
|
|
|
|
|
|
SKU => 'prod18718' }, |
|
71
|
|
|
|
|
|
|
], |
|
72
|
|
|
|
|
|
|
}; |
|
73
|
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
my $response = $ics->requestBill($request); |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
if ($response->{success}) { |
|
77
|
|
|
|
|
|
|
print "Woo! Success!\n"; |
|
78
|
|
|
|
|
|
|
$response = $response->{response}; |
|
79
|
|
|
|
|
|
|
print "Thanks for your payment of \$$response->{BillAmount}.\n"; |
|
80
|
|
|
|
|
|
|
} |
|
81
|
|
|
|
|
|
|
else { |
|
82
|
|
|
|
|
|
|
print "Boo! Failure!\n"; |
|
83
|
|
|
|
|
|
|
print "Error: $response->{error}->{description}\n"; |
|
84
|
|
|
|
|
|
|
} |
|
85
|
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
=head1 FUNCTIONS |
|
87
|
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head2 new |
|
89
|
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
=cut |
|
91
|
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
sub new { |
|
93
|
0
|
|
|
0
|
|
|
my $class = shift; |
|
94
|
0
|
|
|
|
|
|
my %args = @_; |
|
95
|
0
|
|
|
|
|
|
my $self = {}; |
|
96
|
0
|
|
|
|
|
|
bless($self, $class); |
|
97
|
0
|
|
|
|
|
|
foreach my $arg (keys(%args)) { |
|
98
|
0
|
|
|
|
|
|
$self->set($arg, $args{$arg}, $self); |
|
99
|
|
|
|
|
|
|
} |
|
100
|
0
|
|
0
|
|
|
|
$self->{server_mode} ||= 'test'; # default to test mode |
|
101
|
0
|
|
0
|
|
|
|
$self->{icspath} ||= '/opt/ics'; |
|
102
|
0
|
|
0
|
|
|
|
$self->{cvv_accepted} ||= $ICS::Simple::cvvAcceptedDefault; |
|
103
|
0
|
|
|
|
|
|
return $self; |
|
104
|
|
|
|
|
|
|
} |
|
105
|
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
=head2 set |
|
107
|
|
|
|
|
|
|
|
|
108
|
|
|
|
|
|
|
=cut |
|
109
|
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
sub set { |
|
111
|
0
|
|
|
0
|
|
|
my ($self, $key, $val, $namespace, $mapRequired) = @_; |
|
112
|
0
|
|
|
|
|
|
my $lookupKey = lc($key); |
|
113
|
0
|
|
|
|
|
|
$lookupKey =~ s|_||g; |
|
114
|
0
|
0
|
0
|
|
|
|
return undef if ($mapRequired && !$ICS::Simple::fieldMap->{$lookupKey}); # if we require that the name is mapped but it isn't, fail |
|
115
|
0
|
|
0
|
|
|
|
$key = $ICS::Simple::fieldMap->{$lookupKey} || $key; # if it has a mapped name, use it instead |
|
116
|
0
|
|
|
|
|
|
$namespace->{$key} = $val; |
|
117
|
0
|
|
|
|
|
|
return $key; |
|
118
|
|
|
|
|
|
|
} |
|
119
|
|
|
|
|
|
|
|
|
120
|
|
|
|
|
|
|
=head2 requestIcs |
|
121
|
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
=cut |
|
123
|
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
sub requestIcs { |
|
125
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
126
|
0
|
|
|
|
|
|
my $request = shift; |
|
127
|
0
|
|
0
|
|
|
|
$request->{server_mode} ||= $self->{server_mode}; |
|
128
|
0
|
|
0
|
|
|
|
$request->{server_host} ||= $self->{server_host}; |
|
129
|
0
|
0
|
|
|
|
|
unless ($request->{server_host}) { |
|
130
|
0
|
0
|
|
|
|
|
if ($request->{server_mode} =~ m|^\s*prod|i) { |
|
131
|
0
|
|
|
|
|
|
$request->{server_host} = 'ics2.ic3.com'; |
|
132
|
0
|
|
|
|
|
|
$request->{server_port} = '80'; |
|
133
|
|
|
|
|
|
|
} else { |
|
134
|
0
|
|
|
|
|
|
$request->{server_host} = 'ics2test.ic3.com'; |
|
135
|
0
|
|
|
|
|
|
$request->{server_port} = '80'; |
|
136
|
|
|
|
|
|
|
} |
|
137
|
|
|
|
|
|
|
} |
|
138
|
0
|
|
0
|
|
|
|
$request->{currency} ||= 'USD'; |
|
139
|
0
|
|
0
|
|
|
|
$request->{merchant_id} ||= $self->{merchant_id}; |
|
140
|
0
|
|
0
|
|
|
|
$request->{decline_avs_flags} ||= $self->{decline_avs_flags} || $ICS::Simple::avsRejectedDefault; |
|
|
|
|
0
|
|
|
|
|
|
141
|
|
|
|
|
|
|
|
|
142
|
0
|
|
|
|
|
|
my $response = {}; |
|
143
|
0
|
|
|
|
|
|
%{$response} = ICS::ics_send(%{$request}); |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
|
|
145
|
0
|
|
0
|
|
|
|
$ICS::Simple::response->{rmsg} = $response->{auth_rmsg} || $response->{ics_rmsg}; |
|
146
|
0
|
0
|
|
|
|
|
$response->{success} = ($response->{ics_rcode} == 1 ? 1 : 0); |
|
147
|
0
|
0
|
|
|
|
|
if (!$response->{success}) { |
|
148
|
0
|
|
0
|
|
|
|
$response->{rmsg} = $ICS::Simple::vitalErrorMap->{$response->{ics_rcode}} || $response->{rmsg}; |
|
149
|
0
|
|
0
|
|
|
|
$response->{auth_auth_error} = $ICS::Simple::vitalErrorMap->{$response->{auth_auth_response}} || $ICS::Simple::vitalErrorMap->{0}; |
|
150
|
|
|
|
|
|
|
} |
|
151
|
|
|
|
|
|
|
|
|
152
|
0
|
|
|
|
|
|
my $error = {}; |
|
153
|
0
|
0
|
|
|
|
|
if ($response->{ics_rcode} != 1) { # error |
|
154
|
0
|
|
|
|
|
|
$error = $self->_handleError($request, $response); |
|
155
|
|
|
|
|
|
|
} |
|
156
|
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
return { |
|
158
|
0
|
|
|
|
|
|
success => $response->{success}, |
|
159
|
|
|
|
|
|
|
request => $request, |
|
160
|
|
|
|
|
|
|
response => $self->_translateResponse($response), |
|
161
|
|
|
|
|
|
|
error => $error |
|
162
|
|
|
|
|
|
|
}; |
|
163
|
|
|
|
|
|
|
} |
|
164
|
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
=head2 _translateResponse |
|
166
|
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=cut |
|
168
|
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
sub _translateResponse { |
|
170
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
171
|
0
|
|
|
|
|
|
my $response = shift; |
|
172
|
0
|
|
0
|
|
|
|
my $grammar = shift || $self->{x_grammar}; |
|
173
|
0
|
0
|
0
|
|
|
|
my $gMap = (ref($grammar) eq 'HASH' ? $grammar : ($ICS::Simple::grammarMap->{lc($grammar)} || $ICS::Simple::grammarMap->{stock} || {})); |
|
174
|
0
|
0
|
|
|
|
|
my $mapRequired = ($gMap->{_mapRequired} ? 1 : 0); |
|
175
|
0
|
|
|
|
|
|
foreach my $key (keys(%{$response})) { |
|
|
0
|
|
|
|
|
|
|
|
176
|
0
|
|
|
|
|
|
my $val = $response->{$key}; |
|
177
|
0
|
|
|
|
|
|
delete($response->{$key}); # remove old key |
|
178
|
0
|
0
|
0
|
|
|
|
return undef if ($mapRequired && !$gMap->{$key}); # if we require that the name is mapped but it isn't, fail |
|
179
|
0
|
|
0
|
|
|
|
$key = $gMap->{$key} || $key; # if it has a mapped name, use it instead |
|
180
|
0
|
|
|
|
|
|
$response->{$key} = $val; # insert new key |
|
181
|
|
|
|
|
|
|
} |
|
182
|
0
|
|
|
|
|
|
return $response; |
|
183
|
|
|
|
|
|
|
} |
|
184
|
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
=head2 _resolveApp |
|
186
|
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
=cut |
|
188
|
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
sub _resolveApp { |
|
190
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
191
|
0
|
|
|
|
|
|
my $appVal = shift; |
|
192
|
0
|
0
|
|
|
|
|
my @apps = (ref($appVal) eq 'ARRAY' ? @{$appVal} : split(/\s*[,;]+\s*/, $appVal)); # turn it into an array if it isn't one already |
|
|
0
|
|
|
|
|
|
|
|
193
|
0
|
|
|
|
|
|
my @appsResolved; |
|
194
|
0
|
|
|
|
|
|
foreach my $app (@apps) { |
|
195
|
0
|
0
|
|
|
|
|
next unless $app; # in case we grabbed an empty one (two delimiters seperated by spaces would cause this) |
|
196
|
0
|
|
|
|
|
|
my $lookupKey = lc($app); |
|
197
|
0
|
|
|
|
|
|
$lookupKey =~ s|_||g; |
|
198
|
0
|
|
0
|
|
|
|
$app = $ICS::Simple::appMap->{$lookupKey} || $app; # if it has a mapped name, use it instead |
|
199
|
0
|
|
|
|
|
|
push(@appsResolved, $app); |
|
200
|
|
|
|
|
|
|
} |
|
201
|
0
|
|
|
|
|
|
return join(',', @appsResolved); |
|
202
|
|
|
|
|
|
|
} |
|
203
|
|
|
|
|
|
|
|
|
204
|
|
|
|
|
|
|
=head2 _constructOffers |
|
205
|
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
=cut |
|
207
|
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
sub _constructOffers { |
|
209
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
210
|
0
|
|
|
|
|
|
my $itemsKey = shift; |
|
211
|
0
|
|
|
|
|
|
my $namespace = shift; |
|
212
|
0
|
|
|
|
|
|
my $items = $namespace->{$itemsKey}; |
|
213
|
0
|
0
|
|
|
|
|
my @items = (ref($items) eq 'ARRAY' ? @{$items} : [$items]); |
|
|
0
|
|
|
|
|
|
|
|
214
|
0
|
|
|
|
|
|
my @offers; |
|
215
|
0
|
|
|
|
|
|
my $i = 0; |
|
216
|
0
|
|
|
|
|
|
foreach my $item (@items) { |
|
217
|
0
|
|
|
|
|
|
my @offerAttrs; |
|
218
|
0
|
|
|
|
|
|
foreach my $attr (keys(%{$item})) { |
|
|
0
|
|
|
|
|
|
|
|
219
|
0
|
|
|
|
|
|
my $val = $item->{$attr}; |
|
220
|
0
|
|
|
|
|
|
my $lookupKey = lc($attr); |
|
221
|
0
|
|
|
|
|
|
$lookupKey =~ s|_||g; |
|
222
|
0
|
|
0
|
|
|
|
$attr = $ICS::Simple::offerAttrMap->{$lookupKey} || $attr; # if it has a mapped name, use it instead |
|
223
|
0
|
|
|
|
|
|
push(@offerAttrs, $attr.':'.$val); |
|
224
|
|
|
|
|
|
|
} |
|
225
|
0
|
|
|
|
|
|
my $offer = join('^', 'offerid:'.$i, @offerAttrs); |
|
226
|
0
|
|
|
|
|
|
$namespace->{'offer'.$i} = $offer; |
|
227
|
0
|
|
|
|
|
|
$i++; |
|
228
|
|
|
|
|
|
|
} |
|
229
|
0
|
|
|
|
|
|
delete($namespace->{$itemsKey}); |
|
230
|
|
|
|
|
|
|
} |
|
231
|
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
=head2 request |
|
233
|
|
|
|
|
|
|
|
|
234
|
|
|
|
|
|
|
=cut |
|
235
|
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
sub request { # convert the request into ICS format and then send it to requestIcs |
|
237
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
238
|
0
|
|
|
|
|
|
my $request = shift; |
|
239
|
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
# combine input namespaces into one |
|
241
|
0
|
|
|
|
|
|
my $item = {}; |
|
242
|
0
|
|
|
|
|
|
for my $key (keys(%{$self})) { |
|
|
0
|
|
|
|
|
|
|
|
243
|
0
|
|
|
|
|
|
$self->set($key, $self->{$key}, $item, 1); |
|
244
|
|
|
|
|
|
|
} |
|
245
|
0
|
|
|
|
|
|
for my $key (keys(%{$request})) { |
|
|
0
|
|
|
|
|
|
|
|
246
|
0
|
|
|
|
|
|
$self->set($key, $request->{$key}, $item, 1); |
|
247
|
|
|
|
|
|
|
} |
|
248
|
|
|
|
|
|
|
|
|
249
|
0
|
0
|
|
|
|
|
@{$item->{x_items}} = (ref($item->{x_items}) eq 'ARRAY' ? @{$item->{x_items}} : [$item->{x_items}]); |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
250
|
|
|
|
|
|
|
|
|
251
|
0
|
0
|
|
|
|
|
if ($item->{x_shipping_handling_fee}) { |
|
252
|
0
|
|
|
|
|
|
my $offer = { |
|
253
|
|
|
|
|
|
|
Amount => $item->{x_shipping_handling_fee}, |
|
254
|
|
|
|
|
|
|
ProductCode => 'shipping_and_handling', |
|
255
|
|
|
|
|
|
|
ProductName => 'Shipping & Handling', |
|
256
|
|
|
|
|
|
|
}; |
|
257
|
0
|
|
|
|
|
|
delete($item->{x_shipping_handling_fee}); |
|
258
|
0
|
|
|
|
|
|
unshift(@{$item->{x_items}}, $offer); |
|
|
0
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
} |
|
260
|
|
|
|
|
|
|
|
|
261
|
0
|
0
|
|
|
|
|
if ($item->{x_shipping_fee}) { |
|
262
|
0
|
|
|
|
|
|
my $offer = { |
|
263
|
|
|
|
|
|
|
Amount => $item->{x_shipping_fee}, |
|
264
|
|
|
|
|
|
|
ProductCode => 'shipping_only', |
|
265
|
|
|
|
|
|
|
ProductName => 'Shipping', |
|
266
|
|
|
|
|
|
|
}; |
|
267
|
0
|
|
|
|
|
|
delete($item->{x_shipping_fee}); |
|
268
|
0
|
|
|
|
|
|
unshift(@{$item->{x_items}}, $offer); |
|
|
0
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
} |
|
270
|
|
|
|
|
|
|
|
|
271
|
0
|
0
|
|
|
|
|
if ($item->{x_handling_fee}) { |
|
272
|
0
|
|
|
|
|
|
my $offer = { |
|
273
|
|
|
|
|
|
|
Amount => $item->{x_handling_fee}, |
|
274
|
|
|
|
|
|
|
ProductCode => 'handling_only', |
|
275
|
|
|
|
|
|
|
ProductName => 'Handling', |
|
276
|
|
|
|
|
|
|
}; |
|
277
|
0
|
|
|
|
|
|
delete($item->{x_handling_fee}); |
|
278
|
0
|
|
|
|
|
|
unshift(@{$item->{x_items}}, $offer); |
|
|
0
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
} |
|
280
|
|
|
|
|
|
|
|
|
281
|
0
|
|
|
|
|
|
$self->_constructOffers('x_items', $item); |
|
282
|
|
|
|
|
|
|
|
|
283
|
0
|
|
|
|
|
|
$item->{ics_applications} = $self->_resolveApp($item->{ics_applications}); |
|
284
|
0
|
|
0
|
|
|
|
$item->{decline_avs_flags} = $item->{decline_avs_flags} || $self->{decline_avs_flags} || $ICS::Simple::avsRejectedDefault; |
|
285
|
|
|
|
|
|
|
|
|
286
|
0
|
|
|
|
|
|
return $self->requestIcs($item); |
|
287
|
|
|
|
|
|
|
} |
|
288
|
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
=head2 requestBill |
|
290
|
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
=cut |
|
292
|
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
sub requestBill { |
|
294
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
295
|
0
|
|
|
|
|
|
my $request = shift; |
|
296
|
0
|
|
|
|
|
|
$request->{action} = ['auth', 'bill']; |
|
297
|
0
|
|
|
|
|
|
return $self->request($request); |
|
298
|
|
|
|
|
|
|
} |
|
299
|
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
=head2 requestAuth |
|
301
|
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
=cut |
|
303
|
|
|
|
|
|
|
|
|
304
|
|
|
|
|
|
|
sub requestAuth { |
|
305
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
306
|
0
|
|
|
|
|
|
my $request = shift; |
|
307
|
0
|
|
|
|
|
|
$request->{action} = ['auth']; |
|
308
|
0
|
|
|
|
|
|
return $self->request($request); |
|
309
|
|
|
|
|
|
|
} |
|
310
|
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
=head2 requestAuthReversal |
|
312
|
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
=cut |
|
314
|
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
sub requestAuthReversal { |
|
316
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
317
|
0
|
|
|
|
|
|
my $request = shift; |
|
318
|
0
|
|
|
|
|
|
$request->{action} = ['authreversal']; |
|
319
|
0
|
|
|
|
|
|
return $self->request($request); |
|
320
|
|
|
|
|
|
|
} |
|
321
|
|
|
|
|
|
|
|
|
322
|
|
|
|
|
|
|
=head2 requestSettle |
|
323
|
|
|
|
|
|
|
|
|
324
|
|
|
|
|
|
|
=cut |
|
325
|
|
|
|
|
|
|
|
|
326
|
|
|
|
|
|
|
sub requestSettle { |
|
327
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
328
|
0
|
|
|
|
|
|
my $request = shift; |
|
329
|
0
|
|
|
|
|
|
$request->{action} = ['bill']; |
|
330
|
0
|
|
|
|
|
|
return $self->request($request); |
|
331
|
|
|
|
|
|
|
} |
|
332
|
|
|
|
|
|
|
|
|
333
|
|
|
|
|
|
|
=head2 requestCredit |
|
334
|
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
=cut |
|
336
|
|
|
|
|
|
|
|
|
337
|
|
|
|
|
|
|
sub requestCredit { |
|
338
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
339
|
0
|
|
|
|
|
|
my $request = shift; |
|
340
|
0
|
|
|
|
|
|
$request->{action} = ['credit']; |
|
341
|
0
|
|
|
|
|
|
return $self->request($request); |
|
342
|
|
|
|
|
|
|
} |
|
343
|
|
|
|
|
|
|
|
|
344
|
|
|
|
|
|
|
=head2 _handleError |
|
345
|
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
=cut |
|
347
|
|
|
|
|
|
|
|
|
348
|
|
|
|
|
|
|
sub _handleError { # it failed, but in a normal kind of way |
|
349
|
0
|
|
|
0
|
|
|
my $self = shift; |
|
350
|
0
|
|
|
|
|
|
my $request = shift; # just so we can pass it through to _handleCriticalError |
|
351
|
0
|
|
|
|
|
|
my $response = shift; |
|
352
|
|
|
|
|
|
|
|
|
353
|
0
|
|
|
|
|
|
my $statusCode = lc($response->{ics_rflag}); |
|
354
|
0
|
|
|
|
|
|
$statusCode =~ s|^\s+||; |
|
355
|
0
|
|
|
|
|
|
$statusCode =~ s|\s+$||; |
|
356
|
|
|
|
|
|
|
|
|
357
|
0
|
|
0
|
|
|
|
my $error = $ICS::Simple::errorMap->{$statusCode} || $ICS::Simple::errorMap->{default}; |
|
358
|
0
|
|
|
|
|
|
$error->{statuscode} = $statusCode; |
|
359
|
0
|
|
|
|
|
|
$error->{data} = $response->{ics_rmsg}; |
|
360
|
|
|
|
|
|
|
|
|
361
|
|
|
|
|
|
|
# mail the error, if we can |
|
362
|
0
|
|
|
|
|
|
my $sendErrorsTo = $self->{x_errors_to}; |
|
363
|
0
|
0
|
0
|
|
|
|
if ($error->{critical} || $response->{ics_rcode} < 0) { # critical! |
|
364
|
0
|
|
0
|
|
|
|
$sendErrorsTo = $self->{x_critical_errors_to} || $sendErrorsTo; |
|
365
|
|
|
|
|
|
|
} |
|
366
|
0
|
|
0
|
|
|
|
$self->_sendError('CyberSource Error: '.($error->{name} || $statusCode), $sendErrorsTo, $request, $response, $error); |
|
367
|
|
|
|
|
|
|
|
|
368
|
0
|
|
|
|
|
|
return $error; |
|
369
|
|
|
|
|
|
|
} |
|
370
|
|
|
|
|
|
|
|
|
371
|
|
|
|
|
|
|
=head2 _sendError |
|
372
|
|
|
|
|
|
|
|
|
373
|
|
|
|
|
|
|
=cut |
|
374
|
|
|
|
|
|
|
|
|
375
|
|
|
|
|
|
|
sub _sendError { |
|
376
|
|
|
|
|
|
|
my $self = shift; |
|
377
|
|
|
|
|
|
|
my $subject = shift || 'ICS::Simple Error Mail'; |
|
378
|
|
|
|
|
|
|
my $sendTo = shift or return undef; |
|
379
|
|
|
|
|
|
|
my $request = shift; |
|
380
|
|
|
|
|
|
|
my $response = shift; |
|
381
|
|
|
|
|
|
|
my $error = shift; |
|
382
|
|
|
|
|
|
|
|
|
383
|
1
|
|
|
1
|
|
6701
|
use Data::Dumper; |
|
|
1
|
|
|
|
|
10667
|
|
|
|
1
|
|
|
|
|
79
|
|
|
384
|
1
|
|
|
1
|
|
353
|
use Mail::Send; |
|
|
0
|
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
|
385
|
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
my @mailTo = (ref($sendTo) eq 'ARRAY' ? @{$sendTo} : split(/\s*[,;]+\s*/, $sendTo)); |
|
387
|
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
my $msg = Mail::Send->new; |
|
389
|
|
|
|
|
|
|
$msg->to(@mailTo); |
|
390
|
|
|
|
|
|
|
$msg->subject($subject); |
|
391
|
|
|
|
|
|
|
$msg->add('X-Site', $self->{x_site}); |
|
392
|
|
|
|
|
|
|
$msg->add('X-IP', $ENV{REMOTE_ADDR}); |
|
393
|
|
|
|
|
|
|
|
|
394
|
|
|
|
|
|
|
my $body = $msg->open; |
|
395
|
|
|
|
|
|
|
my $bodyContent = join("\n", |
|
396
|
|
|
|
|
|
|
'['.gmtime().' UTC]', |
|
397
|
|
|
|
|
|
|
'ERROR:', Dumper($error), |
|
398
|
|
|
|
|
|
|
'RESPONSE:', Dumper($response), |
|
399
|
|
|
|
|
|
|
'REQUEST:', Dumper($request), |
|
400
|
|
|
|
|
|
|
'ENV:', Dumper(\%ENV), |
|
401
|
|
|
|
|
|
|
'ICS::Simple:', Dumper($self), |
|
402
|
|
|
|
|
|
|
); |
|
403
|
|
|
|
|
|
|
|
|
404
|
|
|
|
|
|
|
# filter things before we send it out |
|
405
|
|
|
|
|
|
|
$bodyContent =~ s|(customer_cc_number'.*?'[^']{4})([^']+?)([^']{4}')|$1.('x' x length($2)).$3|ge; # keep the first/last 4 characters, replace all else |
|
406
|
|
|
|
|
|
|
$bodyContent =~ s|(customer_cc_cv_number'.*?')([^']+?)(')|$1.('x' x length($2)).$3|ge; # replace all the characters |
|
407
|
|
|
|
|
|
|
|
|
408
|
|
|
|
|
|
|
print $body $bodyContent; |
|
409
|
|
|
|
|
|
|
$body->close; |
|
410
|
|
|
|
|
|
|
|
|
411
|
|
|
|
|
|
|
return $error; |
|
412
|
|
|
|
|
|
|
} |
|
413
|
|
|
|
|
|
|
|
|
414
|
|
|
|
|
|
|
=head1 AUTHOR |
|
415
|
|
|
|
|
|
|
|
|
416
|
|
|
|
|
|
|
Dusty Wilson, C<< >> |
|
417
|
|
|
|
|
|
|
|
|
418
|
|
|
|
|
|
|
=head1 BUGS |
|
419
|
|
|
|
|
|
|
|
|
420
|
|
|
|
|
|
|
The documentation needs to be finished. Or started. Sorry about that. |
|
421
|
|
|
|
|
|
|
|
|
422
|
|
|
|
|
|
|
Please report any bugs or feature requests to |
|
423
|
|
|
|
|
|
|
C, or through the web interface at |
|
424
|
|
|
|
|
|
|
L. |
|
425
|
|
|
|
|
|
|
I will be notified, and then you'll automatically be notified of progress on |
|
426
|
|
|
|
|
|
|
your bug as I make changes. |
|
427
|
|
|
|
|
|
|
|
|
428
|
|
|
|
|
|
|
=head1 SUPPORT |
|
429
|
|
|
|
|
|
|
|
|
430
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
|
431
|
|
|
|
|
|
|
|
|
432
|
|
|
|
|
|
|
perldoc ICS::Simple |
|
433
|
|
|
|
|
|
|
|
|
434
|
|
|
|
|
|
|
You can also look for information at: |
|
435
|
|
|
|
|
|
|
|
|
436
|
|
|
|
|
|
|
=over 4 |
|
437
|
|
|
|
|
|
|
|
|
438
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
|
439
|
|
|
|
|
|
|
|
|
440
|
|
|
|
|
|
|
L |
|
441
|
|
|
|
|
|
|
|
|
442
|
|
|
|
|
|
|
=item * CPAN Ratings |
|
443
|
|
|
|
|
|
|
|
|
444
|
|
|
|
|
|
|
L |
|
445
|
|
|
|
|
|
|
|
|
446
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
|
447
|
|
|
|
|
|
|
|
|
448
|
|
|
|
|
|
|
L |
|
449
|
|
|
|
|
|
|
|
|
450
|
|
|
|
|
|
|
=item * Search CPAN |
|
451
|
|
|
|
|
|
|
|
|
452
|
|
|
|
|
|
|
L |
|
453
|
|
|
|
|
|
|
|
|
454
|
|
|
|
|
|
|
=back |
|
455
|
|
|
|
|
|
|
|
|
456
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
|
457
|
|
|
|
|
|
|
|
|
458
|
|
|
|
|
|
|
=head1 COPYRIGHT & LICENSE |
|
459
|
|
|
|
|
|
|
|
|
460
|
|
|
|
|
|
|
Copyright 2006 Dusty Wilson, all rights reserved. |
|
461
|
|
|
|
|
|
|
|
|
462
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
|
463
|
|
|
|
|
|
|
under the same terms as Perl itself. |
|
464
|
|
|
|
|
|
|
|
|
465
|
|
|
|
|
|
|
=cut |
|
466
|
|
|
|
|
|
|
|
|
467
|
|
|
|
|
|
|
$ICS::Simple::fieldMap = { # not case-sens on the key-side |
|
468
|
|
|
|
|
|
|
# forced lowercase |
|
469
|
|
|
|
|
|
|
# stripped underscores |
|
470
|
|
|
|
|
|
|
host => 'server_host', |
|
471
|
|
|
|
|
|
|
serverhost => 'server_host', |
|
472
|
|
|
|
|
|
|
port => 'server_port', |
|
473
|
|
|
|
|
|
|
serverport => 'server_port', |
|
474
|
|
|
|
|
|
|
mode => 'server_mode', |
|
475
|
|
|
|
|
|
|
servermode => 'server_mode', |
|
476
|
|
|
|
|
|
|
icspath => 'icspath', |
|
477
|
|
|
|
|
|
|
hostid => 'host_id', |
|
478
|
|
|
|
|
|
|
merchantid => 'merchant_id', |
|
479
|
|
|
|
|
|
|
orderid => 'merchant_ref_number', |
|
480
|
|
|
|
|
|
|
merchantorderid => 'merchant_ref_number', |
|
481
|
|
|
|
|
|
|
ordernumber => 'merchant_ref_number', |
|
482
|
|
|
|
|
|
|
merchantordernumber => 'merchant_ref_number', |
|
483
|
|
|
|
|
|
|
orderrefnumber => 'merchant_ref_number', |
|
484
|
|
|
|
|
|
|
merchantorderrefnumber => 'merchant_ref_number', |
|
485
|
|
|
|
|
|
|
refnumber => 'merchant_ref_number', |
|
486
|
|
|
|
|
|
|
merchantrefnumber => 'merchant_ref_number', |
|
487
|
|
|
|
|
|
|
merchantdescriptor => 'merchant_descriptor', |
|
488
|
|
|
|
|
|
|
merchantdesc => 'merchant_descriptor', |
|
489
|
|
|
|
|
|
|
merchantdescriptorcontact => 'merchant_descriptor_contact', |
|
490
|
|
|
|
|
|
|
merchantdesccontact => 'merchant_descriptor_contact', |
|
491
|
|
|
|
|
|
|
currency => 'currency', |
|
492
|
|
|
|
|
|
|
action => 'ics_applications', |
|
493
|
|
|
|
|
|
|
actions => 'ics_applications', |
|
494
|
|
|
|
|
|
|
icsapplications => 'ics_applications', |
|
495
|
|
|
|
|
|
|
declineavs => 'decline_avs_flags', |
|
496
|
|
|
|
|
|
|
cvvaccepted => 'cvv_accepted', |
|
497
|
|
|
|
|
|
|
firstname => 'customer_firstname', |
|
498
|
|
|
|
|
|
|
givenname => 'customer_firstname', |
|
499
|
|
|
|
|
|
|
customergivenname => 'customer_firstname', |
|
500
|
|
|
|
|
|
|
customerfirstname => 'customer_firstname', |
|
501
|
|
|
|
|
|
|
lastname => 'customer_lastname', |
|
502
|
|
|
|
|
|
|
familyname => 'customer_lastname', |
|
503
|
|
|
|
|
|
|
customerfamilyname => 'customer_lastname', |
|
504
|
|
|
|
|
|
|
customerlastname => 'customer_lastname', |
|
505
|
|
|
|
|
|
|
email => 'customer_email', |
|
506
|
|
|
|
|
|
|
customeremail => 'customer_email', |
|
507
|
|
|
|
|
|
|
billingaddress => 'bill_address1', |
|
508
|
|
|
|
|
|
|
billingaddress1 => 'bill_address1', |
|
509
|
|
|
|
|
|
|
billingaddress2 => 'bill_address2', |
|
510
|
|
|
|
|
|
|
billaddress => 'bill_address1', |
|
511
|
|
|
|
|
|
|
billaddress1 => 'bill_address1', |
|
512
|
|
|
|
|
|
|
billaddress2 => 'bill_address2', |
|
513
|
|
|
|
|
|
|
billingcity => 'bill_city', |
|
514
|
|
|
|
|
|
|
billcity => 'bill_city', |
|
515
|
|
|
|
|
|
|
billingregion => 'bill_state', |
|
516
|
|
|
|
|
|
|
billregion => 'bill_state', |
|
517
|
|
|
|
|
|
|
billingstateprov => 'bill_state', |
|
518
|
|
|
|
|
|
|
billstateprov => 'bill_state', |
|
519
|
|
|
|
|
|
|
billingprov => 'bill_state', |
|
520
|
|
|
|
|
|
|
billprov => 'bill_state', |
|
521
|
|
|
|
|
|
|
billingprovince => 'bill_state', |
|
522
|
|
|
|
|
|
|
billprovince => 'bill_state', |
|
523
|
|
|
|
|
|
|
billingstate => 'bill_state', |
|
524
|
|
|
|
|
|
|
billstate => 'bill_state', |
|
525
|
|
|
|
|
|
|
billingpostalcode => 'bill_zip', |
|
526
|
|
|
|
|
|
|
billingpostal => 'bill_zip', |
|
527
|
|
|
|
|
|
|
billpostalcode => 'bill_zip', |
|
528
|
|
|
|
|
|
|
billpostal => 'bill_zip', |
|
529
|
|
|
|
|
|
|
billingcountrycode => 'bill_country', |
|
530
|
|
|
|
|
|
|
billingcountry => 'bill_country', |
|
531
|
|
|
|
|
|
|
billcountrycode => 'bill_country', |
|
532
|
|
|
|
|
|
|
billcountry => 'bill_country', |
|
533
|
|
|
|
|
|
|
shippingaddress => 'ship_to_address1', |
|
534
|
|
|
|
|
|
|
shippingaddress1 => 'ship_to_address1', |
|
535
|
|
|
|
|
|
|
shippingaddress2 => 'ship_to_address2', |
|
536
|
|
|
|
|
|
|
shipaddress => 'ship_to_address1', |
|
537
|
|
|
|
|
|
|
shipaddress1 => 'ship_to_address1', |
|
538
|
|
|
|
|
|
|
shipaddress2 => 'ship_to_address2', |
|
539
|
|
|
|
|
|
|
shiptoaddress => 'ship_to_address1', |
|
540
|
|
|
|
|
|
|
shiptoaddress1 => 'ship_to_address1', |
|
541
|
|
|
|
|
|
|
shiptoaddress2 => 'ship_to_address2', |
|
542
|
|
|
|
|
|
|
shippingcity => 'ship_to_city', |
|
543
|
|
|
|
|
|
|
shipcity => 'ship_to_city', |
|
544
|
|
|
|
|
|
|
shiptocity => 'ship_to_city', |
|
545
|
|
|
|
|
|
|
shippingregion => 'ship_to_state', |
|
546
|
|
|
|
|
|
|
shipregion => 'ship_to_state', |
|
547
|
|
|
|
|
|
|
shiptoregion => 'ship_to_state', |
|
548
|
|
|
|
|
|
|
shippingstateprov => 'ship_to_state', |
|
549
|
|
|
|
|
|
|
shipstateprov => 'ship_to_state', |
|
550
|
|
|
|
|
|
|
shiptostateprov => 'ship_to_state', |
|
551
|
|
|
|
|
|
|
shippingprov => 'ship_to_state', |
|
552
|
|
|
|
|
|
|
shipprov => 'ship_to_state', |
|
553
|
|
|
|
|
|
|
shiptoprov => 'ship_to_state', |
|
554
|
|
|
|
|
|
|
shippingprovince => 'ship_to_state', |
|
555
|
|
|
|
|
|
|
shipprovince => 'ship_to_state', |
|
556
|
|
|
|
|
|
|
shiptoprovince => 'ship_to_state', |
|
557
|
|
|
|
|
|
|
shippingstate => 'ship_to_state', |
|
558
|
|
|
|
|
|
|
shipstate => 'ship_to_state', |
|
559
|
|
|
|
|
|
|
shiptostate => 'ship_to_state', |
|
560
|
|
|
|
|
|
|
shippingpostalcode => 'ship_to_zip', |
|
561
|
|
|
|
|
|
|
shippingpostal => 'ship_to_zip', |
|
562
|
|
|
|
|
|
|
shippostalcode => 'ship_to_zip', |
|
563
|
|
|
|
|
|
|
shippostal => 'ship_to_zip', |
|
564
|
|
|
|
|
|
|
shiptopostalcode => 'ship_to_zip', |
|
565
|
|
|
|
|
|
|
shiptopostal => 'ship_to_zip', |
|
566
|
|
|
|
|
|
|
shippingcountrycode => 'ship_to_country', |
|
567
|
|
|
|
|
|
|
shippingcountry => 'ship_to_country', |
|
568
|
|
|
|
|
|
|
shipcountrycode => 'ship_to_country', |
|
569
|
|
|
|
|
|
|
shipcountry => 'ship_to_country', |
|
570
|
|
|
|
|
|
|
shiptocountrycode => 'ship_to_country', |
|
571
|
|
|
|
|
|
|
shiptocountry => 'ship_to_country', |
|
572
|
|
|
|
|
|
|
cardexpmonth => 'customer_cc_expmo', |
|
573
|
|
|
|
|
|
|
ccexpmo => 'customer_cc_expmo', |
|
574
|
|
|
|
|
|
|
customerccexpmo => 'customer_cc_expmo', |
|
575
|
|
|
|
|
|
|
cardexpyear => 'customer_cc_expyr', |
|
576
|
|
|
|
|
|
|
ccexpyr => 'customer_cc_expyr', |
|
577
|
|
|
|
|
|
|
customerccexpyr => 'customer_cc_expyr', |
|
578
|
|
|
|
|
|
|
cardnumber => 'customer_cc_number', |
|
579
|
|
|
|
|
|
|
ccnumber => 'customer_cc_number', |
|
580
|
|
|
|
|
|
|
customerccnumber => 'customer_cc_number', |
|
581
|
|
|
|
|
|
|
cardcvnumber => 'customer_cc_cv_number', |
|
582
|
|
|
|
|
|
|
cardcv => 'customer_cc_cv_number', |
|
583
|
|
|
|
|
|
|
cardcvvnumber => 'customer_cc_cv_number', |
|
584
|
|
|
|
|
|
|
cardcvv => 'customer_cc_cv_number', |
|
585
|
|
|
|
|
|
|
cardcvv2 => 'customer_cc_cv_number', |
|
586
|
|
|
|
|
|
|
cardcvnnumber => 'customer_cc_cv_number', |
|
587
|
|
|
|
|
|
|
cardcvn => 'customer_cc_cv_number', |
|
588
|
|
|
|
|
|
|
cccvnnumber => 'customer_cc_cv_number', |
|
589
|
|
|
|
|
|
|
cccv => 'customer_cc_cv_number', |
|
590
|
|
|
|
|
|
|
cccvv => 'customer_cc_cv_number', |
|
591
|
|
|
|
|
|
|
cccvn => 'customer_cc_cv_number', |
|
592
|
|
|
|
|
|
|
customercccvnnumber => 'customer_cc_cv_number', |
|
593
|
|
|
|
|
|
|
customercccvvnumber => 'customer_cc_cv_number', |
|
594
|
|
|
|
|
|
|
customercccvv2number => 'customer_cc_cv_number', |
|
595
|
|
|
|
|
|
|
customercccvnumber => 'customer_cc_cv_number', |
|
596
|
|
|
|
|
|
|
ignoreavs => 'ignore_avs', |
|
597
|
|
|
|
|
|
|
ignorebadcv => 'ignore_bad_cv', |
|
598
|
|
|
|
|
|
|
timeout => 'timeout', |
|
599
|
|
|
|
|
|
|
# x_* items are custom (not ICS) fields that are processed before sending |
|
600
|
|
|
|
|
|
|
appname => 'x_site', |
|
601
|
|
|
|
|
|
|
app => 'x_site', |
|
602
|
|
|
|
|
|
|
sitename => 'x_site', |
|
603
|
|
|
|
|
|
|
site => 'x_site', |
|
604
|
|
|
|
|
|
|
xsite => 'x_site', |
|
605
|
|
|
|
|
|
|
errto => 'x_errors_to', |
|
606
|
|
|
|
|
|
|
errorto => 'x_errors_to', |
|
607
|
|
|
|
|
|
|
errorsto => 'x_errors_to', |
|
608
|
|
|
|
|
|
|
xerrorsto => 'x_errors_to', |
|
609
|
|
|
|
|
|
|
criterrto => 'x_critical_errors_to', |
|
610
|
|
|
|
|
|
|
criterrorto => 'x_critical_errors_to', |
|
611
|
|
|
|
|
|
|
criterrorsto => 'x_critical_errors_to', |
|
612
|
|
|
|
|
|
|
criticalerrto => 'x_critical_errors_to', |
|
613
|
|
|
|
|
|
|
criticalerrorto => 'x_critical_errors_to', |
|
614
|
|
|
|
|
|
|
criticalerrorsto => 'x_critical_errors_to', |
|
615
|
|
|
|
|
|
|
xcriticalerrorsto => 'x_critical_errors_to', |
|
616
|
|
|
|
|
|
|
grammar => 'x_grammar', |
|
617
|
|
|
|
|
|
|
shippingfee => 'x_shipping_fee', |
|
618
|
|
|
|
|
|
|
xshippingfee => 'x_shipping_fee', |
|
619
|
|
|
|
|
|
|
handlingfee => 'x_handling_fee', |
|
620
|
|
|
|
|
|
|
xhandlingfee => 'x_handling_fee', |
|
621
|
|
|
|
|
|
|
shippinghandlingfee => 'x_shipping_handling_fee', |
|
622
|
|
|
|
|
|
|
xshippinghandlingfee => 'x_shipping_handling_fee', |
|
623
|
|
|
|
|
|
|
merch => 'x_items', |
|
624
|
|
|
|
|
|
|
offer => 'x_items', |
|
625
|
|
|
|
|
|
|
offers => 'x_items', |
|
626
|
|
|
|
|
|
|
item => 'x_items', |
|
627
|
|
|
|
|
|
|
items => 'x_items', |
|
628
|
|
|
|
|
|
|
xitem => 'x_items', |
|
629
|
|
|
|
|
|
|
xitems => 'x_items', |
|
630
|
|
|
|
|
|
|
}; |
|
631
|
|
|
|
|
|
|
|
|
632
|
|
|
|
|
|
|
$ICS::Simple::appMap = { # not case-sens on the key-side |
|
633
|
|
|
|
|
|
|
# forced lowercase |
|
634
|
|
|
|
|
|
|
# stripped underscores |
|
635
|
|
|
|
|
|
|
auth => 'ics_auth', |
|
636
|
|
|
|
|
|
|
icsauth => 'ics_auth', |
|
637
|
|
|
|
|
|
|
bill => 'ics_bill', |
|
638
|
|
|
|
|
|
|
icsbill => 'ics_bill', |
|
639
|
|
|
|
|
|
|
credit => 'ics_credit', |
|
640
|
|
|
|
|
|
|
icscredit => 'ics_credit', |
|
641
|
|
|
|
|
|
|
authreversal => 'ics_auth_reversal', |
|
642
|
|
|
|
|
|
|
icsauthreversal => 'ics_auth_reversal', |
|
643
|
|
|
|
|
|
|
authrev => 'ics_auth_reversal', |
|
644
|
|
|
|
|
|
|
icsauthrev => 'ics_auth_reversal', |
|
645
|
|
|
|
|
|
|
revauth => 'ics_auth_reversal', |
|
646
|
|
|
|
|
|
|
icsrevauth => 'ics_auth_reversal', |
|
647
|
|
|
|
|
|
|
reverseauth => 'ics_auth_reversal', |
|
648
|
|
|
|
|
|
|
icsreverseauth => 'ics_auth_reversal', |
|
649
|
|
|
|
|
|
|
score => 'ics_score', |
|
650
|
|
|
|
|
|
|
icsscore => 'ics_score', |
|
651
|
|
|
|
|
|
|
export => 'ics_export', |
|
652
|
|
|
|
|
|
|
icsexport => 'ics_export', |
|
653
|
|
|
|
|
|
|
dav => 'ics_dav', |
|
654
|
|
|
|
|
|
|
icsdav => 'ics_dav', |
|
655
|
|
|
|
|
|
|
}; |
|
656
|
|
|
|
|
|
|
|
|
657
|
|
|
|
|
|
|
$ICS::Simple::offerAttrMap = { # not case-sens on the key-side |
|
658
|
|
|
|
|
|
|
# forced lowercase |
|
659
|
|
|
|
|
|
|
# stripped underscores |
|
660
|
|
|
|
|
|
|
description => 'product_name', |
|
661
|
|
|
|
|
|
|
productname => 'product_name', |
|
662
|
|
|
|
|
|
|
sku => 'merchant_product_sku', |
|
663
|
|
|
|
|
|
|
itemsku => 'merchant_product_sku', |
|
664
|
|
|
|
|
|
|
productid => 'merchant_product_sku', |
|
665
|
|
|
|
|
|
|
itemid => 'merchant_product_sku', |
|
666
|
|
|
|
|
|
|
merchantproductsku => 'merchant_product_sku', |
|
667
|
|
|
|
|
|
|
type => 'product_code', |
|
668
|
|
|
|
|
|
|
producttype => 'product_code', |
|
669
|
|
|
|
|
|
|
code => 'product_code', |
|
670
|
|
|
|
|
|
|
productcode => 'product_code', |
|
671
|
|
|
|
|
|
|
each => 'amount', |
|
672
|
|
|
|
|
|
|
price => 'amount', |
|
673
|
|
|
|
|
|
|
amount => 'amount', |
|
674
|
|
|
|
|
|
|
count => 'quantity', |
|
675
|
|
|
|
|
|
|
qty => 'quantity', |
|
676
|
|
|
|
|
|
|
quantity => 'quantity', |
|
677
|
|
|
|
|
|
|
tax => 'tax_amount', |
|
678
|
|
|
|
|
|
|
taxamount => 'tax_amount', |
|
679
|
|
|
|
|
|
|
}; |
|
680
|
|
|
|
|
|
|
|
|
681
|
|
|
|
|
|
|
$ICS::Simple::grammarMap = { |
|
682
|
|
|
|
|
|
|
stock => {}, # no change -- raw response |
|
683
|
|
|
|
|
|
|
lowercamel => { |
|
684
|
|
|
|
|
|
|
success => 'success', |
|
685
|
|
|
|
|
|
|
request_token => 'requestToken', |
|
686
|
|
|
|
|
|
|
request_id => 'requestId', |
|
687
|
|
|
|
|
|
|
merchant_ref_number => 'orderNumber', |
|
688
|
|
|
|
|
|
|
rmsg => 'responseMessage', |
|
689
|
|
|
|
|
|
|
ics_rflag => 'icsResponseFlag', |
|
690
|
|
|
|
|
|
|
ics_rcode => 'icsResponseCode', |
|
691
|
|
|
|
|
|
|
ics_rmsg => 'icsResponseMessage', |
|
692
|
|
|
|
|
|
|
auth_auth_time => 'authTime', |
|
693
|
|
|
|
|
|
|
auth_rflag => 'authResponseFlag', |
|
694
|
|
|
|
|
|
|
auth_rcode => 'authResponseCode', |
|
695
|
|
|
|
|
|
|
auth_rmsg => 'authResponseMessage', |
|
696
|
|
|
|
|
|
|
auth_auth_response => 'authResponse', |
|
697
|
|
|
|
|
|
|
auth_auth_error => 'authError', |
|
698
|
|
|
|
|
|
|
auth_auth_amount => 'authAmount', |
|
699
|
|
|
|
|
|
|
auth_auth_code => 'authCode', |
|
700
|
|
|
|
|
|
|
auth_cv_result => 'authCvResult', |
|
701
|
|
|
|
|
|
|
auth_cv_result_raw => 'authCvRaw', |
|
702
|
|
|
|
|
|
|
auth_auth_avs => 'authAvsResult', |
|
703
|
|
|
|
|
|
|
auth_avs_raw => 'authAvsRaw', |
|
704
|
|
|
|
|
|
|
auth_factor_code => 'authFactorCode', |
|
705
|
|
|
|
|
|
|
auth_vital_error => 'authVitalError', |
|
706
|
|
|
|
|
|
|
bill_bill_request_time => 'billRequestTime', |
|
707
|
|
|
|
|
|
|
bill_rflag => 'billResponseFlag', |
|
708
|
|
|
|
|
|
|
bill_rcode => 'billResponseCode', |
|
709
|
|
|
|
|
|
|
bill_rmsg => 'billResponseMessage', |
|
710
|
|
|
|
|
|
|
bill_trans_ref_no => 'billTransactionNumber', |
|
711
|
|
|
|
|
|
|
bill_bill_amount => 'billAmount', |
|
712
|
|
|
|
|
|
|
currency => 'currency', |
|
713
|
|
|
|
|
|
|
}, |
|
714
|
|
|
|
|
|
|
uppercamel => { |
|
715
|
|
|
|
|
|
|
success => 'Success', |
|
716
|
|
|
|
|
|
|
request_token => 'RequestToken', |
|
717
|
|
|
|
|
|
|
request_id => 'RequestId', |
|
718
|
|
|
|
|
|
|
merchant_ref_number => 'OrderNumber', |
|
719
|
|
|
|
|
|
|
rmsg => 'ResponseMessage', |
|
720
|
|
|
|
|
|
|
ics_rflag => 'IcsResponseFlag', |
|
721
|
|
|
|
|
|
|
ics_rcode => 'IcsResponseCode', |
|
722
|
|
|
|
|
|
|
ics_rmsg => 'IcsResponseMessage', |
|
723
|
|
|
|
|
|
|
auth_auth_time => 'AuthTime', |
|
724
|
|
|
|
|
|
|
auth_rflag => 'AuthResponseFlag', |
|
725
|
|
|
|
|
|
|
auth_rcode => 'AuthResponseCode', |
|
726
|
|
|
|
|
|
|
auth_rmsg => 'AuthResponseMessage', |
|
727
|
|
|
|
|
|
|
auth_auth_response => 'AuthResponse', |
|
728
|
|
|
|
|
|
|
auth_auth_error => 'AuthError', |
|
729
|
|
|
|
|
|
|
auth_auth_amount => 'AuthAmount', |
|
730
|
|
|
|
|
|
|
auth_auth_code => 'AuthCode', |
|
731
|
|
|
|
|
|
|
auth_cv_result => 'AuthCvResult', |
|
732
|
|
|
|
|
|
|
auth_cv_result_raw => 'AuthCvRaw', |
|
733
|
|
|
|
|
|
|
auth_auth_avs => 'AuthAvsResult', |
|
734
|
|
|
|
|
|
|
auth_avs_raw => 'AuthAvsRaw', |
|
735
|
|
|
|
|
|
|
auth_factor_code => 'AuthFactorCode', |
|
736
|
|
|
|
|
|
|
bill_bill_request_time => 'BillRequestTime', |
|
737
|
|
|
|
|
|
|
bill_rflag => 'BillResponseFlag', |
|
738
|
|
|
|
|
|
|
bill_rcode => 'BillResponseCode', |
|
739
|
|
|
|
|
|
|
bill_rmsg => 'BillResponseMessage', |
|
740
|
|
|
|
|
|
|
bill_trans_ref_no => 'BillTransactionNumber', |
|
741
|
|
|
|
|
|
|
bill_bill_amount => 'BillAmount', |
|
742
|
|
|
|
|
|
|
currency => 'Currency', |
|
743
|
|
|
|
|
|
|
}, |
|
744
|
|
|
|
|
|
|
}; |
|
745
|
|
|
|
|
|
|
|
|
746
|
|
|
|
|
|
|
$ICS::Simple::errorMap = { |
|
747
|
|
|
|
|
|
|
default => { |
|
748
|
|
|
|
|
|
|
name => 'UNKNOWN', |
|
749
|
|
|
|
|
|
|
description => 'Unable to process order.', |
|
750
|
|
|
|
|
|
|
}, |
|
751
|
|
|
|
|
|
|
esystem => { |
|
752
|
|
|
|
|
|
|
name => 'SYSTEM', |
|
753
|
|
|
|
|
|
|
description => 'System error.', |
|
754
|
|
|
|
|
|
|
critical => 1, |
|
755
|
|
|
|
|
|
|
}, |
|
756
|
|
|
|
|
|
|
etimeout => { |
|
757
|
|
|
|
|
|
|
name => 'TIMEOUT', |
|
758
|
|
|
|
|
|
|
description => 'Communications timeout. Please wait a few moments, then try again.', |
|
759
|
|
|
|
|
|
|
}, |
|
760
|
|
|
|
|
|
|
dduplicate => { |
|
761
|
|
|
|
|
|
|
name => 'DUPLICATE', |
|
762
|
|
|
|
|
|
|
description => 'Duplicate transaction refused.', |
|
763
|
|
|
|
|
|
|
}, |
|
764
|
|
|
|
|
|
|
dinvalid => { |
|
765
|
|
|
|
|
|
|
name => 'INVALIDDATA', |
|
766
|
|
|
|
|
|
|
description => 'The provided credit card was declined. Check your billing address, credit card number, and CVV and try again or use a different card.', |
|
767
|
|
|
|
|
|
|
}, |
|
768
|
|
|
|
|
|
|
dinvaliddata => { |
|
769
|
|
|
|
|
|
|
name => 'INVALIDDATA', |
|
770
|
|
|
|
|
|
|
description => 'The provided credit card was declined. Check your billing address, credit card number, and CVV and try again or use a different card.', |
|
771
|
|
|
|
|
|
|
}, |
|
772
|
|
|
|
|
|
|
dinvalidcard => { |
|
773
|
|
|
|
|
|
|
name => 'INVALIDCARD', |
|
774
|
|
|
|
|
|
|
description => 'The provided credit card was declined. Check your billing address, credit card number, and CVV and try again or use a different card.', |
|
775
|
|
|
|
|
|
|
}, |
|
776
|
|
|
|
|
|
|
dinvalidaddress => { |
|
777
|
|
|
|
|
|
|
name => 'INVALIDADDRESS', |
|
778
|
|
|
|
|
|
|
description => 'Invalid address data provided. Please reenter the necessary data and try again.', |
|
779
|
|
|
|
|
|
|
}, |
|
780
|
|
|
|
|
|
|
dmissingfield => { |
|
781
|
|
|
|
|
|
|
name => 'MISSINGFIELD', |
|
782
|
|
|
|
|
|
|
description => 'Required field data missing. Please reenter the necessary data and try again.', |
|
783
|
|
|
|
|
|
|
}, |
|
784
|
|
|
|
|
|
|
drestricted => { |
|
785
|
|
|
|
|
|
|
name => 'RESTRICTED', |
|
786
|
|
|
|
|
|
|
description => 'Unable to process order.', |
|
787
|
|
|
|
|
|
|
}, |
|
788
|
|
|
|
|
|
|
dcardrefused => { |
|
789
|
|
|
|
|
|
|
name => 'CARDREFUSED', |
|
790
|
|
|
|
|
|
|
description => 'The provided credit card was declined. Check your billing address, credit card number, and CVV and try again or use a different card.', |
|
791
|
|
|
|
|
|
|
}, |
|
792
|
|
|
|
|
|
|
dcall => { |
|
793
|
|
|
|
|
|
|
name => 'CALL', |
|
794
|
|
|
|
|
|
|
description => 'Unable to process order.', |
|
795
|
|
|
|
|
|
|
}, |
|
796
|
|
|
|
|
|
|
dcardexpired => { |
|
797
|
|
|
|
|
|
|
name => 'CARDEXPIRED', |
|
798
|
|
|
|
|
|
|
description => 'The provided credit card is expired. Please use another card and try again.', |
|
799
|
|
|
|
|
|
|
}, |
|
800
|
|
|
|
|
|
|
davsno => { |
|
801
|
|
|
|
|
|
|
name => 'AVSFAILED', |
|
802
|
|
|
|
|
|
|
description => 'The provided credit card was declined. Check your billing address, credit card number, and CVV and try again or use a different card.', |
|
803
|
|
|
|
|
|
|
}, |
|
804
|
|
|
|
|
|
|
dcv => { |
|
805
|
|
|
|
|
|
|
name => 'CV', |
|
806
|
|
|
|
|
|
|
description => 'The provided credit card was declined. Check your billing address, credit card number, and CVV and try again or use a different card.', |
|
807
|
|
|
|
|
|
|
}, |
|
808
|
|
|
|
|
|
|
dnoauth => { |
|
809
|
|
|
|
|
|
|
name => 'NOAUTH', |
|
810
|
|
|
|
|
|
|
description => 'The requested transaction does not match a valid, existing authorization transaction.', |
|
811
|
|
|
|
|
|
|
}, |
|
812
|
|
|
|
|
|
|
dscore => { |
|
813
|
|
|
|
|
|
|
name => 'SCORE', |
|
814
|
|
|
|
|
|
|
description => 'Score exceeds limit.', |
|
815
|
|
|
|
|
|
|
}, |
|
816
|
|
|
|
|
|
|
dsettings => { |
|
817
|
|
|
|
|
|
|
name => 'SETTINGS', |
|
818
|
|
|
|
|
|
|
description => 'The provided credit card was declined. Check your billing address, credit card number, and CVV and try again or use a different card.', |
|
819
|
|
|
|
|
|
|
}, |
|
820
|
|
|
|
|
|
|
}; |
|
821
|
|
|
|
|
|
|
|
|
822
|
|
|
|
|
|
|
$ICS::Simple::cvvAcceptedDefault = 'M,P,U,X,1'; |
|
823
|
|
|
|
|
|
|
|
|
824
|
|
|
|
|
|
|
$ICS::Simple::cvvMap = { |
|
825
|
|
|
|
|
|
|
I => { |
|
826
|
|
|
|
|
|
|
note => 'Card verification number failed processor\'s data validation check.', |
|
827
|
|
|
|
|
|
|
}, |
|
828
|
|
|
|
|
|
|
M => { |
|
829
|
|
|
|
|
|
|
note => 'Card verification number matched.', |
|
830
|
|
|
|
|
|
|
}, |
|
831
|
|
|
|
|
|
|
N => { |
|
832
|
|
|
|
|
|
|
note => 'Card verification number not matched.', |
|
833
|
|
|
|
|
|
|
}, |
|
834
|
|
|
|
|
|
|
P => { |
|
835
|
|
|
|
|
|
|
note => 'Card verification number not processed.', |
|
836
|
|
|
|
|
|
|
}, |
|
837
|
|
|
|
|
|
|
S => { |
|
838
|
|
|
|
|
|
|
note => 'Card verification number is on the card but was not included in the request.', |
|
839
|
|
|
|
|
|
|
}, |
|
840
|
|
|
|
|
|
|
U => { |
|
841
|
|
|
|
|
|
|
note => 'Card verification is not supported by the issuing bank.', |
|
842
|
|
|
|
|
|
|
}, |
|
843
|
|
|
|
|
|
|
X => { |
|
844
|
|
|
|
|
|
|
note => 'Card verification is not supported by the card association.', |
|
845
|
|
|
|
|
|
|
}, |
|
846
|
|
|
|
|
|
|
1 => { |
|
847
|
|
|
|
|
|
|
note => 'CyberSource does not support card verification for this processor or card type.', |
|
848
|
|
|
|
|
|
|
}, |
|
849
|
|
|
|
|
|
|
2 => { |
|
850
|
|
|
|
|
|
|
note => 'The processor returned an unrecognized value for the card verification response.', |
|
851
|
|
|
|
|
|
|
}, |
|
852
|
|
|
|
|
|
|
3 => { |
|
853
|
|
|
|
|
|
|
note => 'The processor did not return a card verification result code.', |
|
854
|
|
|
|
|
|
|
}, |
|
855
|
|
|
|
|
|
|
}; |
|
856
|
|
|
|
|
|
|
|
|
857
|
|
|
|
|
|
|
$ICS::Simple::avsRejectedDefault = 'A,C,E,I,N,R,S,U,W,1,2'; |
|
858
|
|
|
|
|
|
|
|
|
859
|
|
|
|
|
|
|
$ICS::Simple::avsMap = { |
|
860
|
|
|
|
|
|
|
A => { |
|
861
|
|
|
|
|
|
|
note => 'Street address matches, but both 5-digit ZIP code and 9-digit ZIP code do not match.', |
|
862
|
|
|
|
|
|
|
}, |
|
863
|
|
|
|
|
|
|
B => { |
|
864
|
|
|
|
|
|
|
note => 'Street address matches, but postal code not verified. Returned only for non-U.S.-issued Visa cards.', |
|
865
|
|
|
|
|
|
|
}, |
|
866
|
|
|
|
|
|
|
C => { |
|
867
|
|
|
|
|
|
|
note => 'Street address and postal code do not match. Returned only for non U.S.-issued Visa cards.', |
|
868
|
|
|
|
|
|
|
}, |
|
869
|
|
|
|
|
|
|
D => { |
|
870
|
|
|
|
|
|
|
note => 'Street address and postal code both match. Returned only for non-U.S.-issued Visa cards.', |
|
871
|
|
|
|
|
|
|
}, |
|
872
|
|
|
|
|
|
|
E => { |
|
873
|
|
|
|
|
|
|
note => 'AVS data is invalid.', |
|
874
|
|
|
|
|
|
|
}, |
|
875
|
|
|
|
|
|
|
G => { |
|
876
|
|
|
|
|
|
|
note => 'Non-U.S. issuing bank does not support AVS.', |
|
877
|
|
|
|
|
|
|
}, |
|
878
|
|
|
|
|
|
|
I => { |
|
879
|
|
|
|
|
|
|
note => 'Address information not verified. Returned only for non-U.S.-issued Visa cards.', |
|
880
|
|
|
|
|
|
|
}, |
|
881
|
|
|
|
|
|
|
J => { |
|
882
|
|
|
|
|
|
|
note => 'Card member name, billing address, and postal code all match. Ship-to information verified and chargeback protection guaranteed through the Fraud Protection Program. This code is returned only if you are signed up to use AAV+ with the American Express Phoenix processor.', |
|
883
|
|
|
|
|
|
|
}, |
|
884
|
|
|
|
|
|
|
K => { |
|
885
|
|
|
|
|
|
|
note => 'Card member\'s name matches. Both billing address and billing postal code do not match. This code is returned only if you are signed up to use Enhanced AVS or AAV+ with the American Express Phoenix processor.', |
|
886
|
|
|
|
|
|
|
}, |
|
887
|
|
|
|
|
|
|
L => { |
|
888
|
|
|
|
|
|
|
note => 'Card member\'s name matches. Billing postal code matches, but billing address does not match. This code is returned only if you are signed up to use Enhanced AVS or AAV+ with the American Express Phoenix processor.', |
|
889
|
|
|
|
|
|
|
}, |
|
890
|
|
|
|
|
|
|
M => { |
|
891
|
|
|
|
|
|
|
note => 'Street address and postal code both match. Returned only for non-U.S.-issued Visa cards.', |
|
892
|
|
|
|
|
|
|
}, |
|
893
|
|
|
|
|
|
|
N => { |
|
894
|
|
|
|
|
|
|
note => 'Street address and postal code do not match. Returned only for U.S.-issued Visa cards.', |
|
895
|
|
|
|
|
|
|
}, |
|
896
|
|
|
|
|
|
|
O => { |
|
897
|
|
|
|
|
|
|
note => 'Card member name matches. Billing address matches, but billing postal code does not match. This code is returned only if you are signed up to use Enhanced AVS or AAV+ with the American Express Phoenix processor.', |
|
898
|
|
|
|
|
|
|
}, |
|
899
|
|
|
|
|
|
|
P => { |
|
900
|
|
|
|
|
|
|
note => 'Postal code matches, but street address not verified. Returned only for non-U.S.-issued Visa cards.', |
|
901
|
|
|
|
|
|
|
}, |
|
902
|
|
|
|
|
|
|
Q => { |
|
903
|
|
|
|
|
|
|
note => 'Card member name, billing address, and postal code all match. Ship-to information verified but chargeback protection not guaranteed (Standard program). This code is returned only if you are signed up to use AAV+ with the American Express Phoenix processor.', |
|
904
|
|
|
|
|
|
|
}, |
|
905
|
|
|
|
|
|
|
R => { |
|
906
|
|
|
|
|
|
|
note => 'System unavailable.', |
|
907
|
|
|
|
|
|
|
}, |
|
908
|
|
|
|
|
|
|
S => { |
|
909
|
|
|
|
|
|
|
note => 'U.S. issuing bank does not support AVS.', |
|
910
|
|
|
|
|
|
|
}, |
|
911
|
|
|
|
|
|
|
U => { |
|
912
|
|
|
|
|
|
|
note => 'Address information unavailable. Returned if non-U.S. AVS is not available or if the AVS in a U.S. bank is not functioning properly.', |
|
913
|
|
|
|
|
|
|
}, |
|
914
|
|
|
|
|
|
|
V => { |
|
915
|
|
|
|
|
|
|
note => 'Card member name matches. Both billing address and billing postal code match. This code is returned only if you are signed up to use Enhanced AVS or AAV+ with the American Express Phoenix processor.', |
|
916
|
|
|
|
|
|
|
}, |
|
917
|
|
|
|
|
|
|
W => { |
|
918
|
|
|
|
|
|
|
note => 'Street address does not match, but 9-digit ZIP code matches.', |
|
919
|
|
|
|
|
|
|
}, |
|
920
|
|
|
|
|
|
|
X => { |
|
921
|
|
|
|
|
|
|
note => 'Exact match. Street address and 9-digit ZIP code both match.', |
|
922
|
|
|
|
|
|
|
}, |
|
923
|
|
|
|
|
|
|
Y => { |
|
924
|
|
|
|
|
|
|
note => 'Street address and 5-digit ZIP code both match.', |
|
925
|
|
|
|
|
|
|
}, |
|
926
|
|
|
|
|
|
|
Z => { |
|
927
|
|
|
|
|
|
|
note => 'Street address does not match, but 5-digit ZIP code matches.', |
|
928
|
|
|
|
|
|
|
}, |
|
929
|
|
|
|
|
|
|
1 => { |
|
930
|
|
|
|
|
|
|
note => 'CyberSource AVS code. AVS is not supported for this processor or card type.', |
|
931
|
|
|
|
|
|
|
}, |
|
932
|
|
|
|
|
|
|
2 => { |
|
933
|
|
|
|
|
|
|
note => 'CyberSource AVS code. The processor returned an unrecognized value for the AVS response.', |
|
934
|
|
|
|
|
|
|
}, |
|
935
|
|
|
|
|
|
|
}; |
|
936
|
|
|
|
|
|
|
|
|
937
|
|
|
|
|
|
|
$ICS::Simple::vitalErrorMap = { |
|
938
|
|
|
|
|
|
|
'01' => { |
|
939
|
|
|
|
|
|
|
action => 'decline', |
|
940
|
|
|
|
|
|
|
note => 'Refer to Issuer', |
|
941
|
|
|
|
|
|
|
description => 'Please call your card issuer.', |
|
942
|
|
|
|
|
|
|
}, |
|
943
|
|
|
|
|
|
|
'02' => { |
|
944
|
|
|
|
|
|
|
action => 'decline', |
|
945
|
|
|
|
|
|
|
note => 'Refer to Issuer - Special Condition', |
|
946
|
|
|
|
|
|
|
description => 'Please call your card issuer.', |
|
947
|
|
|
|
|
|
|
}, |
|
948
|
|
|
|
|
|
|
'03' => { |
|
949
|
|
|
|
|
|
|
action => 'error', |
|
950
|
|
|
|
|
|
|
note => 'Invalid Merchant ID', |
|
951
|
|
|
|
|
|
|
description => 'Please call customer service to complete order.', |
|
952
|
|
|
|
|
|
|
}, |
|
953
|
|
|
|
|
|
|
'04' => { |
|
954
|
|
|
|
|
|
|
action => 'decline', |
|
955
|
|
|
|
|
|
|
note => 'Pick up card', |
|
956
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
957
|
|
|
|
|
|
|
}, |
|
958
|
|
|
|
|
|
|
'05' => { |
|
959
|
|
|
|
|
|
|
action => 'decline', |
|
960
|
|
|
|
|
|
|
note => 'Do Not Honor', |
|
961
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
962
|
|
|
|
|
|
|
}, |
|
963
|
|
|
|
|
|
|
'06' => { |
|
964
|
|
|
|
|
|
|
action => 'error', |
|
965
|
|
|
|
|
|
|
note => 'General Error', |
|
966
|
|
|
|
|
|
|
description => 'Please call customer service to complete order.', |
|
967
|
|
|
|
|
|
|
}, |
|
968
|
|
|
|
|
|
|
'07' => { |
|
969
|
|
|
|
|
|
|
action => 'decline', |
|
970
|
|
|
|
|
|
|
note => 'Pick up card - Special Condition', |
|
971
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
972
|
|
|
|
|
|
|
}, |
|
973
|
|
|
|
|
|
|
'12' => { |
|
974
|
|
|
|
|
|
|
action => 'error', |
|
975
|
|
|
|
|
|
|
note => 'Unknown system error', |
|
976
|
|
|
|
|
|
|
description => 'Please call customer service to complete order.', |
|
977
|
|
|
|
|
|
|
}, |
|
978
|
|
|
|
|
|
|
'13' => { |
|
979
|
|
|
|
|
|
|
action => 'error', |
|
980
|
|
|
|
|
|
|
note => 'Invalid Amount', |
|
981
|
|
|
|
|
|
|
description => 'Invalid amount.', |
|
982
|
|
|
|
|
|
|
}, |
|
983
|
|
|
|
|
|
|
'14' => { |
|
984
|
|
|
|
|
|
|
action => 'error', |
|
985
|
|
|
|
|
|
|
note => 'Invalid Card Number', |
|
986
|
|
|
|
|
|
|
description => 'Invalid card number.', |
|
987
|
|
|
|
|
|
|
}, |
|
988
|
|
|
|
|
|
|
'15' => { |
|
989
|
|
|
|
|
|
|
action => 'error', |
|
990
|
|
|
|
|
|
|
note => 'No such issuer', |
|
991
|
|
|
|
|
|
|
description => 'Invalid card number.', |
|
992
|
|
|
|
|
|
|
}, |
|
993
|
|
|
|
|
|
|
'19' => { |
|
994
|
|
|
|
|
|
|
action => 'decline', |
|
995
|
|
|
|
|
|
|
note => 'Unknown Decline Error', |
|
996
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
997
|
|
|
|
|
|
|
}, |
|
998
|
|
|
|
|
|
|
'28' => { |
|
999
|
|
|
|
|
|
|
action => 'error', |
|
1000
|
|
|
|
|
|
|
note => 'File is temporarily unavailable', |
|
1001
|
|
|
|
|
|
|
description => 'Please call customer service to complete order.', |
|
1002
|
|
|
|
|
|
|
}, |
|
1003
|
|
|
|
|
|
|
'39' => { |
|
1004
|
|
|
|
|
|
|
action => 'error', |
|
1005
|
|
|
|
|
|
|
note => 'Invalid Card Number', |
|
1006
|
|
|
|
|
|
|
description => 'Invalid card number.', |
|
1007
|
|
|
|
|
|
|
}, |
|
1008
|
|
|
|
|
|
|
'41' => { |
|
1009
|
|
|
|
|
|
|
action => 'decline', |
|
1010
|
|
|
|
|
|
|
note => 'Pick up card - Lost', |
|
1011
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
1012
|
|
|
|
|
|
|
}, |
|
1013
|
|
|
|
|
|
|
'43' => { |
|
1014
|
|
|
|
|
|
|
action => 'decline', |
|
1015
|
|
|
|
|
|
|
note => 'Pick up card - Stolen', |
|
1016
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
1017
|
|
|
|
|
|
|
}, |
|
1018
|
|
|
|
|
|
|
'51' => { |
|
1019
|
|
|
|
|
|
|
action => 'decline', |
|
1020
|
|
|
|
|
|
|
note => 'Insufficient Funds', |
|
1021
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
1022
|
|
|
|
|
|
|
}, |
|
1023
|
|
|
|
|
|
|
'52' => { |
|
1024
|
|
|
|
|
|
|
action => 'error', |
|
1025
|
|
|
|
|
|
|
note => 'Unknown Card Number Error', |
|
1026
|
|
|
|
|
|
|
description => 'Invalid Card Number', |
|
1027
|
|
|
|
|
|
|
}, |
|
1028
|
|
|
|
|
|
|
'53' => { |
|
1029
|
|
|
|
|
|
|
action => 'error', |
|
1030
|
|
|
|
|
|
|
note => 'Unknown Card Number Error', |
|
1031
|
|
|
|
|
|
|
description => 'Invalid Card Number', |
|
1032
|
|
|
|
|
|
|
}, |
|
1033
|
|
|
|
|
|
|
'54' => { |
|
1034
|
|
|
|
|
|
|
action => 'expired', |
|
1035
|
|
|
|
|
|
|
note => 'Expired Card', |
|
1036
|
|
|
|
|
|
|
description => 'Expired card.', |
|
1037
|
|
|
|
|
|
|
}, |
|
1038
|
|
|
|
|
|
|
'55' => { |
|
1039
|
|
|
|
|
|
|
action => 'error', |
|
1040
|
|
|
|
|
|
|
note => 'Incorrect PIN', |
|
1041
|
|
|
|
|
|
|
description => 'Incorrect Card/PIN combination.', # is it safe to let them know the PIN is wrong? |
|
1042
|
|
|
|
|
|
|
}, |
|
1043
|
|
|
|
|
|
|
'57' => { |
|
1044
|
|
|
|
|
|
|
action => 'decline', |
|
1045
|
|
|
|
|
|
|
note => 'Transaction Disallowed - Card', |
|
1046
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
1047
|
|
|
|
|
|
|
}, |
|
1048
|
|
|
|
|
|
|
'58' => { |
|
1049
|
|
|
|
|
|
|
action => 'decline', |
|
1050
|
|
|
|
|
|
|
note => 'Transaction Disallowed - Term', |
|
1051
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
1052
|
|
|
|
|
|
|
}, |
|
1053
|
|
|
|
|
|
|
'61' => { |
|
1054
|
|
|
|
|
|
|
action => 'decline', |
|
1055
|
|
|
|
|
|
|
note => 'Withdrawal Limit Exceeded', |
|
1056
|
|
|
|
|
|
|
description => 'Withdrawal limit exceeded.', |
|
1057
|
|
|
|
|
|
|
}, |
|
1058
|
|
|
|
|
|
|
'62' => { |
|
1059
|
|
|
|
|
|
|
action => 'decline', |
|
1060
|
|
|
|
|
|
|
note => 'Invalid Service Code, Restricted', |
|
1061
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
1062
|
|
|
|
|
|
|
}, |
|
1063
|
|
|
|
|
|
|
'63' => { |
|
1064
|
|
|
|
|
|
|
action => 'decline', |
|
1065
|
|
|
|
|
|
|
note => 'Unknown Decline Error', |
|
1066
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
1067
|
|
|
|
|
|
|
}, |
|
1068
|
|
|
|
|
|
|
'65' => { |
|
1069
|
|
|
|
|
|
|
action => 'decline', |
|
1070
|
|
|
|
|
|
|
note => 'Activity Limit Exceeded', |
|
1071
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
1072
|
|
|
|
|
|
|
}, |
|
1073
|
|
|
|
|
|
|
'75' => { |
|
1074
|
|
|
|
|
|
|
action => 'decline', |
|
1075
|
|
|
|
|
|
|
note => 'PIN Attempts Exceeded', |
|
1076
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
1077
|
|
|
|
|
|
|
}, |
|
1078
|
|
|
|
|
|
|
'78' => { |
|
1079
|
|
|
|
|
|
|
action => 'error', |
|
1080
|
|
|
|
|
|
|
note => 'Unknown Invalid Card Number Error', |
|
1081
|
|
|
|
|
|
|
description => 'Invalid Card Number', |
|
1082
|
|
|
|
|
|
|
}, |
|
1083
|
|
|
|
|
|
|
'79' => { |
|
1084
|
|
|
|
|
|
|
action => 'call', |
|
1085
|
|
|
|
|
|
|
note => 'Unknown Error', |
|
1086
|
|
|
|
|
|
|
description => 'Please call customer service to complete order.', |
|
1087
|
|
|
|
|
|
|
}, |
|
1088
|
|
|
|
|
|
|
'80' => { |
|
1089
|
|
|
|
|
|
|
action => 'error', |
|
1090
|
|
|
|
|
|
|
note => 'Invalid Expiration Date', |
|
1091
|
|
|
|
|
|
|
description => 'Invalid expiration date.', |
|
1092
|
|
|
|
|
|
|
}, |
|
1093
|
|
|
|
|
|
|
'82' => { |
|
1094
|
|
|
|
|
|
|
action => 'decline', |
|
1095
|
|
|
|
|
|
|
note => 'Cashback Limit Exceeded', |
|
1096
|
|
|
|
|
|
|
description => 'Cashback limit exceeded.', |
|
1097
|
|
|
|
|
|
|
}, |
|
1098
|
|
|
|
|
|
|
'83' => { |
|
1099
|
|
|
|
|
|
|
action => 'decline', |
|
1100
|
|
|
|
|
|
|
note => 'Unknown PIN Verification Error', |
|
1101
|
|
|
|
|
|
|
description => 'Can not verify PIN.', |
|
1102
|
|
|
|
|
|
|
}, |
|
1103
|
|
|
|
|
|
|
'86' => { |
|
1104
|
|
|
|
|
|
|
action => 'decline', |
|
1105
|
|
|
|
|
|
|
note => 'Unknown PIN Verification Error', |
|
1106
|
|
|
|
|
|
|
description => 'Can not verify PIN.', |
|
1107
|
|
|
|
|
|
|
}, |
|
1108
|
|
|
|
|
|
|
'91' => { |
|
1109
|
|
|
|
|
|
|
action => 'unavailable', |
|
1110
|
|
|
|
|
|
|
note => 'Issuer or switch is unavailable', |
|
1111
|
|
|
|
|
|
|
description => 'Please call customer service to complete order.', |
|
1112
|
|
|
|
|
|
|
}, |
|
1113
|
|
|
|
|
|
|
'92' => { |
|
1114
|
|
|
|
|
|
|
action => 'call', |
|
1115
|
|
|
|
|
|
|
note => 'Unknown Error', |
|
1116
|
|
|
|
|
|
|
description => 'Please call customer service to complete order.', |
|
1117
|
|
|
|
|
|
|
}, |
|
1118
|
|
|
|
|
|
|
'93' => { |
|
1119
|
|
|
|
|
|
|
action => 'decline', |
|
1120
|
|
|
|
|
|
|
note => 'Violation, Cannot Complete', |
|
1121
|
|
|
|
|
|
|
description => 'Authorization has been declined.', |
|
1122
|
|
|
|
|
|
|
}, |
|
1123
|
|
|
|
|
|
|
'96' => { |
|
1124
|
|
|
|
|
|
|
action => 'error', |
|
1125
|
|
|
|
|
|
|
note => 'System Malfunction', |
|
1126
|
|
|
|
|
|
|
description => 'Please call customer service to complete order.', |
|
1127
|
|
|
|
|
|
|
}, |
|
1128
|
|
|
|
|
|
|
'EA' => { |
|
1129
|
|
|
|
|
|
|
action => 'error', |
|
1130
|
|
|
|
|
|
|
note => 'Verification Error', |
|
1131
|
|
|
|
|
|
|
description => 'Please call customer service to complete order.', |
|
1132
|
|
|
|
|
|
|
}, |
|
1133
|
|
|
|
|
|
|
'EB' => { |
|
1134
|
|
|
|
|
|
|
action => 'call', |
|
1135
|
|
|
|
|
|
|
note => 'Unknown Error', |
|
1136
|
|
|
|
|
|
|
description => 'Please call customer service to complete order.', |
|
1137
|
|
|
|
|
|
|
}, |
|
1138
|
|
|
|
|
|
|
'EC' => { |
|
1139
|
|
|
|
|
|
|
action => 'error', |
|
1140
|
|
|
|
|
|
|
note => 'Verification Error', |
|
1141
|
|
|
|
|
|
|
description => 'Please call customer service to complete order.', |
|
1142
|
|
|
|
|
|
|
}, |
|
1143
|
|
|
|
|
|
|
'N3' => { |
|
1144
|
|
|
|
|
|
|
action => 'error', |
|
1145
|
|
|
|
|
|
|
note => 'Cashback Service Not Available', |
|
1146
|
|
|
|
|
|
|
description => 'Cashback service is not available.', |
|
1147
|
|
|
|
|
|
|
}, |
|
1148
|
|
|
|
|
|
|
'N4' => { |
|
1149
|
|
|
|
|
|
|
action => 'decline', |
|
1150
|
|
|
|
|
|
|
note => 'Issuer Withdrawal Limit Exceeded', |
|
1151
|
|
|
|
|
|
|
description => 'Amount exceeds issuer withdrawal limit.', |
|
1152
|
|
|
|
|
|
|
}, |
|
1153
|
|
|
|
|
|
|
'N7' => { |
|
1154
|
|
|
|
|
|
|
action => 'error', |
|
1155
|
|
|
|
|
|
|
note => 'Invalid CVV2 Data Supplied', |
|
1156
|
|
|
|
|
|
|
description => 'Invalid card security code.', # should we let the enduser know this? |
|
1157
|
|
|
|
|
|
|
}, |
|
1158
|
|
|
|
|
|
|
}; |
|
1159
|
|
|
|
|
|
|
|
|
1160
|
|
|
|
|
|
|
1; # End of ICS::Simple |