1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
package Business::OnlinePayment::Exact;
use 5.006001;
use strict;
use warnings;
use SOAP::Lite;
use Business::OnlinePayment;
our @ISA = qw(Business::OnlinePayment);
our @EXPORT_OK = ();
our @EXPORT = qw();
our $VERSION = '0.01';
sub set_defaults {
my $self = shift;
$self->build_subs(qw(proxy on_action uri tns types process encodingstyle
order_number));
$self->proxy('https://secure2.e-xact.com/vpos/process/vpos.asmx');
$self->on_action('http://secure2.e-xact.com/vpos/process/Process');
$self->uri('http://secure2.e-xact.com/vpos/process/');
$self->tns('http://secure2.e-xact.com/vpos/process/');
$self->types('http://secure2.e-xact.com/vpos/process/encodedTypes');
$self->process('http://secure2.e-xact.com/vpos/process/Request');
$self->encodingstyle('http://schemas.xmlsoap.org/soap/encoding/');
}
sub map_fields {
my $self = shift;
my %content = $self->content();
my %actions = ('normal authorization' => '00',
'authorization only' => '01',
'credit' => '04',
'post authorization' => '02',
'void' => '13',
);
$content{'action'} = $actions{lc($content{'action'})};
$content{'name'} = $content{'first_name'}.' '.$content{'last_name'} ||
$content{'name'} if $content{'first_name'} and $content{'last_name'};
$content{'expiration'} =~ /(\d\d)\D*(\d\d)/ if $content{'expiration'};
$content{'expiration_month'} = $1 || $content{'expiration_month'};
$content{'expiration_year'} = $2 || $content{'expiration_year'};
$content{'expiration'} = $content{'expiration_month'}.
$content{'expiration_year'} || $content{'expiration'};
$self->content(%content);
}
sub remap_fields {
my($self,%map) = @_;
my %content = $self->content();
foreach(keys %map) {
$content{$map{$_}} = $content{$_};
}
$self->content(%content);
}
sub test_transaction {
my( $self, $enabled ) = @_;
die if $enabled;
}
sub submit {
my $self = shift;
$self->map_fields;
$self->remap_fields(
login => 'ExactID',
password => 'Password',
action => 'Transaction_Type',
amount => 'DollarAmount',
customer_ip => 'Client_IP',
order_number => 'Reference_No',
name => 'CardHoldersName',
address => 'VerificationStr1',
email => 'Client_Email',
card_number => 'Card_Number',
expiration => 'Expiry_Date',
referer => 'Customer_Ref',
);
my %content = $self->content();
#make data here
my @data;
foreach (keys %content) {
push @data, SOAP::Data->name($_ => $content{$_})->type('string');
}
my $data =
SOAP::Data->attr({'xsi:type' => 'types:Transaction'})
->name('Transaction')->value(\SOAP::Data->value(@data));
#figure out action
#make request
my $s = SOAP::Lite
->proxy($self->proxy)
->on_action(sub{return $self->on_action})
->uri($self->uri)
->readable(1);
$s->serializer->register_ns($self->tns => 'tns');
$s->serializer->register_ns($self->types => 'types');
my $m = SOAP::Data->name('q1:Process')
->attr({'xmlns:q1' => $self->process,
'soap:encodingStyle' => $self->encodingstyle});
my $result = $s->call($m => $data);
#get result
if ($result->fault) {
$self->is_success(0);
$self->error_message($result->faultstring);
}
else {
if ($result->valueof('//TransactionResult/Transaction_Approved')
eq '1' and $result->valueof('//TransactionResult/EXact_Resp_Code')
eq '00' and $result->valueof('//TransactionResult/Transaction_Error')
eq '0') {
$self->is_success(1);
$self->error_message(
$result->valueof('//TransactionResult/EXact_Message'));
$self->authorization(
$result->valueof('//TransactionResult/Authorization_Num'));
$self->order_number(
$result->valueof('//TransactionResult/SequenceNo'));
}
else {
$self->is_success(0);
$self->error_message(
$result->valueof('//TransactionResult/EXact_Message'));
}
}
}
1;
__END__
=head1 NAME
Business::OnlinePayment::Exact - Perl extension for doing credit card
processing through the E-xact v7 Web Services API payment gateway.
=head1 SYNOPSIS
use Business::OnlinePayment;
my $tx = new Business::OnlinePayment('Exact');
$tx->content(
amount => '19.00',
card_number => '4200000000000000',
expiration => '0110',
name => 'Some Guy',
action => 'authorization only',
login => 'A000XX-XX'
password => 'password'
);
$tx->submit;
if ($tx->is_success()) {
my $ordernum = $tx->order_number;
print "Got the cash";
}
else {
print $tx->error_message;
}
=head1 ABSTRACT
This is a Business::OnlinePayment module for E-xact loosely based on
Business::OnlinePayment::AuthorizeNet. I've only used it for normal
authorization so it may require some work to do pre auth, etc.
=head1 DESCRIPTION
See synopsis. It works like any other Business::OnlinePayment module.
The following content keys are usefull:
login
password
amount
card_number
expiration
name
referer
email
address
order_number
customer_ip
action
The following content keys are also available (but not really usefull):
'first_name' and 'last_name' will combine to override 'name'
'expiration_month' and 'expiration_year' will combine to override
'expiration'
The 'authorization' method will return the bank authorization code, and the
'order_number' method will contain the sequence number from E-xact.
The content key 'referer' can be used to store any string data (20 bytes)
and used to search for those transactions from the web interface.
=head2 EXPORT
None by default.
=head1 SEE ALSO
Business::OnlinePayment
SOAP::Lite
"Exact Payment WebService Plug-In Programming Reference Guide v7"
(which can be found on www.e-xact.com with enough digging)
=head1 AUTHOR
mock, E<lt>mock@obscurity.orgE<gt>
=head1 COPYRIGHT AND LICENSE
Copyright (C) 2005 by mock
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.8.1 or,
at your option, any later version of Perl 5 you may have available.
=cut
|