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 |