File Coverage

blib/lib/Business/OnlinePayment/SurePay.pm
Criterion Covered Total %
statement 327 404 80.9
branch 104 188 55.3
condition 19 44 43.1
subroutine 44 57 77.1
pod 3 5 60.0
total 497 698 71.2


line stmt bran cond sub pod time code
1             package Business::OnlinePayment::SurePay;
2              
3 3     3   14055 use 5.006;
  3         11  
  3         137  
4 3     3   17 use strict;
  3         8  
  3         114  
5 3     3   1256 use Business::OnlinePayment;
  3         3869  
  3         109  
6 3     3   22 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK);
  3         7  
  3         252  
7 3     3   17 use warnings;
  3         6  
  3         3169  
8              
9             require Exporter;
10              
11             our @ISA = qw(Exporter Business::OnlinePayment);
12              
13             our @EXPORT_OK = qw();
14             our @EXPORT = qw();
15             our $VERSION = '0.01';
16              
17             local($SIG{ALRM}) = sub {die timeout()." sec timeout"};
18              
19             sub set_defaults {
20 2     2 0 144 my $self = shift;
21              
22 2         27 $self->build_subs(qw/order_number gateway_type debug_level debug_file timeout/);
23 2         661 $self->gateway_type('https');
24 2         92 $self->server('xml.surepay.com');
25 2         75 $self->port('443');
26 2         81 $self->path('/');
27 2         68 $self->debug_level('');
28 2         65 $self->debug_file('');
29 2         66 $self->timeout('120');
30            
31             }
32              
33             sub map_fields {
34 2     2 0 5 my($self) = @_;
35 2         3 my $i;
36 2         9 my %content = $self->content();
37              
38 2         53 for($i=1;$i<4;$i++) {
39 6         17 $content{"address$i"}='';
40 6 100       28 if ((20*($i-1)) < length($content{'address'})) {
41 2         13 $content{"address$i"} = substr($content{'address'}, 20*($i-1), 20);
42             }
43             }
44            
45 2 50       11 $content{'cvv2_status'}=$content{'cvv2'} ? '1':'9';
46            
47             # Checking test mode
48 2 50       61 if($self->test_transaction()) {
49 2         68 $self->server('xml.test.surepay.com');
50             }
51             else {
52 0         0 $self->server('xml.surepay.com');
53             }
54              
55             # stuff it back into %content
56 2         29 $self->content(%content);
57             }
58              
59             sub remap_fields {
60 2     2 1 17 my($self,%map) = @_;
61              
62 2         47 my %content = $self->content();
63 2         50 foreach(keys %map) {
64 20         43 $content{$map{$_}} = $content{$_};
65             }
66 2         21 $self->content(%content);
67             }
68              
69             sub get_fields {
70 12     12 1 37 my($self,@fields) = @_;
71              
72 12         47 my %content = $self->content();
73 12         337 my %new = ();
74 12         70 foreach( grep defined $content{$_}, @fields) { $new{$_} = $content{$_}; }
  62         130  
75 12         170 return %new;
76             }
77              
78             sub submit {
79 0     0 1   my($self) = @_;
80              
81 0           $self->map_fields();
82              
83 0           $self->remap_fields(
84             first_name => 'firstname',
85             last_name => 'lastname',
86             cvv2_status => 'cvv2status',
87             card_number => 'number',
88             order_number => 'ordernumber',
89             tax_amount => 'taxamount',
90             sku_number => 'sku',
91             tax_rate => 'taxrate',
92             amount => 'unitprice',
93             login => 'merchant'
94             );
95              
96 0           $self->required_fields(qw/first_name last_name address1 city state country zip
97             card_number expiration order_number description quantity sku_number
98             tax_rate amount login password /);
99              
100 0           my $Request_Manager = RequestManager->new(
101             'type' => $self->gateway_type(),
102             'host' => $self->server(),
103             'port' => $self->port(),
104             'path' => $self->path(),
105             'debuglevel' => $self->debug_level(),
106             'debugfile' => $self->debug_file()
107             );
108              
109 0           my $Request = Request->new($self->get_fields(qw/csp merchant password/));
110              
111 0           my $BillAddress = Address->new((type => 'billing'),
112             $self->get_fields(qw/firstname lastname address1 address2
113             address3 city state country zip phone eveningphone fax email/)
114             );
115              
116 0           my $ShipAddress = Address->new((type => 'shipping'),
117             $self->get_fields(qw/firstname lastname address1 address2
118             address3 city state country zip phone eveningphone fax email/)
119             );
120              
121 0           my $Payment_Instrument = CreditCard->new((address => $BillAddress),
122             $self->get_fields(qw/number expiration cvv2 cvv2status/)
123             );
124              
125 0           my $Auth_Reference = Auth->new((address => $ShipAddress, payInstrument => $Payment_Instrument),
126             $self->get_fields(qw/ecommerce eccommercecode ordernumber ponumber
127             ipaddress verbalauthcode verbalauthdate shippingcost taxamount trackingnumbers recurring
128             referringurl browsertype description/)
129             );
130              
131 0           $Auth_Reference->addLineItem(LineItem->new(
132             $self->get_fields(qw/sku description quantity taxrate unitprice /)
133             ));
134              
135 0           $Request->addAuth($Auth_Reference);
136              
137 0           alarm $self->timeout();
138 0           my $result = $Request_Manager->submit($Request);
139 0           alarm 0;
140              
141 0 0         if ($result->getFailure eq 'true') {
142 0           $self->is_success(0);
143 0           $self->error_message($result->getFailureMsg);
144             }
145             else{
146 0           $self->is_success(1);
147 0           $self->authorization($result->getAuthCode);
148             }
149             }
150              
151             1;
152              
153             package Address;
154              
155 3     3   28 use strict;
  3         6  
  3         6606  
156              
157             our (%_Valid_Type,%_Valid_Field);
158             foreach (qw( billing shipping )) {
159             $_Valid_Type{$_}++;
160             }
161              
162             foreach (qw( firstname lastname address1 address2 address3 city state zip
163             country phone eveningphone fax email type )) {
164             $_Valid_Field{$_}++;
165             }
166              
167             our %_Max_Length = (
168             'firstname' => 20,
169             'lastname' => 20,
170             'address1' => 20,
171             'address2' => 20,
172             'address3' => 20,
173             'city' => 20,
174             'state' => 2,
175             'zip' => 9,
176             'country' => 2,
177             'phone' => 20,
178             'eveningphone' => 20,
179             'fax' => 20,
180             'email' => 40,
181             );
182              
183             sub new {
184 4     4   19 my ($class,%fields) = @_;
185 4         10 my $self = bless( {}, $class);
186 4         6 my ($label,$value);
187 4         15 while ( ($label,$value) = each %fields ) {
188 40         87 $self->_Add_Field($label,$value);
189             }
190 4         18 return $self;
191             }
192              
193             sub _Add_Field {
194 40     40   58 my ($self,$label,$value) = @_;
195 40         74 $value = Common->clean($value);
196 40 100       123 $value =~ s/\D//g if $label =~ /^(phone|eveningphone|fax|zip)$/;
197 40 100       98 $value = uc $value if $label =~ /^(country|state)$/;
198 40 100       119 return undef unless $value =~ /\S/;
199              
200 32 100       72 if ($label =~ /^type$/) {
201 4 50       13 die "Invalid Address Type: ($value)" unless $_Valid_Type{$value};
202             }
203              
204 32 100 66     168 $value = substr($value,0,$_Max_Length{$label}) if ($_Max_Length{$label}) && ($_Max_Length{$label} > 0);
205              
206 32 50       67 die "Invalid Address Field Name: ($label)" unless $_Valid_Field{$label};
207 32 50 33     118 die "Invalid Email Address: ($value)" if $label eq 'email' && $value !~ /\w+\@\w+/;
208 32 50 33     67 die "Invalid Phone Number: ($value)" if $label eq 'phone' && length($value) < 10;
209 32 50 33     69 die "Invalid Phone Number: ($value)" if $label eq 'eveningphone' && length($value) < 10;
210 32         69 $self->{$label} = $value;
211 32         102 return undef;
212             }
213              
214             sub getType {
215 4     4   8 my $self = shift; return $self->{'type'};
  4         11  
216             }
217              
218             sub make_XML {
219 4     4   8 my $self = shift;
220 4         6 my $label;
221 4         6 my $xml = qq(
222 4         31 foreach $label ( keys %_Valid_Field ) {
223 56 100       148 $xml .= qq($label="$self->{$label}" ) if defined $self->{$label};
224             }
225 4         11 $xml .= qq(/>);
226 4         13 return $xml;
227             }
228              
229             1;
230              
231             package Auth;
232              
233 3     3   30 use strict;
  3         11  
  3         3932  
234              
235             our %_Valid_Field_Name;
236             foreach (qw/ ecommerce ecommercecode ordernumber ponumber ipaddress verbalauthcode verbalauthdate
237             shippingcost taxamount trackingnumbers recurring referringurl browsertype description /) {
238             $_Valid_Field_Name{$_}++;
239             }
240              
241             our %_Max_Length = (
242             'ordernumber' => 10,
243             'ponumber' => 25,
244             'ipaddress' => 15,
245             'verbalauthcode' => 6,
246             'verbalauthdate' => 17,
247             'trackingnumbers' => 100,
248             );
249              
250             sub new {
251 2     2   11 my ($class,%fields) = @_;
252 2         6 my $self = bless( {}, $class);
253 2         3 my ($label, $value);
254 2         17 while ( ($label, $value) = each %fields ) { $self->_Add_Field($label, $value); }
  10         26  
255 2         8 return $self;
256             }
257              
258             sub _Add_Field {
259 10     10   14 my ($self,$label,$value) = @_;
260 10         12 my $backup;
261              
262 10 100       32 if ($label =~ /^address$/) {
263 2         5 my $pref = ref $value;
264 2 50       8 die "Invalid Address Reference: ($pref)" unless $pref eq 'Address';
265 2         6 my $type = $value->getType;
266 2 50       15 die "Invalid Address Type: ($type)" unless $type eq 'shipping';
267 2         8 $self->{$label} = $value;
268 2         9 return undef;
269             }
270 8 100       22 if ($label =~ /^payInstrument$/) {
271 2         6 my $pref = ref $value;
272 2 50 33     10 die "Invalid Payment Instrument: ($pref)" unless $pref eq 'CreditCard' || $pref eq 'TeleCheck';
273 2         9 $self->{$label} = $value;
274 2         10 return undef;
275             }
276              
277 6 100       27 $value = Common->clean($value) if ($label =~ /^(ponumber|verbalauthcode|ipaddress|refurl|browser|verbalauthdate)$/);
278              
279 6 100       20 if ($label =~ /^ordernumber$/) {
280 2         4 $backup = $value;
281 2 50 33     20 die "Invalid order number: ($backup)" unless $value =~ /^\d+$/ && length($value) <= 10;
282             }
283              
284 6 100       16 if ($label =~ /^verbalauthdate$/) {
285 1         1 $backup = $value;
286 1 50 33     19 die "Invalid Authorization Date: ($backup)" unless $value =~ /^\d+$/ && length($value) <= 17;
287             }
288              
289 6 50       18 if ($label =~ /^(shippingcost|taxamount)$/) {
290 0         0 $value=~ s/[^\d\.]//g;
291 0         0 $value = sprintf("%.2f",$value);
292             }
293            
294 6 100 66     49 $value = substr($value,0,$_Max_Length{$label}) if (($_Max_Length{$label}) && ($_Max_Length{$label} > 0));
295            
296 6 50       22 die "Invalid Auth Field Name ($label)" unless $_Valid_Field_Name{$label};
297 6 50       21 return undef unless $value =~ /\S/;
298 6         14 $self->{$label} = $value;
299 6         25 return undef;
300             }
301              
302             sub addLineItem {
303 2     2   4 my ($self,$item) = @_;
304 2         4 my $pref = ref $item;
305 2 50       16 die "invalid line item reference ($pref)" unless $pref eq 'LineItem';
306 2         5 push(@{$self->{'items'}},$item);
  2         6  
307 2         16 return undef;
308             }
309              
310             sub make_XML {
311 2     2   4 my $self = shift;
312 2         2 my $label;
313 2 50       19 die "The ordernumber field is requered" unless $self->{'ordernumber'};
314 2 50       4 die "No Line Items in Auth" unless scalar @{$self->{'items'}} > 0;
  2         9  
315              
316 2 50       9 $self->{'shippingcost'} = $self->{'shippingcost'}.'USD' if $self->{'shippingcost'};
317 2 50       6 $self->{'taxamount'} = $self->{'taxamount'}.'USD' if $self->{'taxamount'};
318 2 50       11 $self->{'ecommercecode'} = $self->{'ecommercecode'} ? $self->{'ecommercecode'} : '07';
319 2         5 my $xml = qq(
320 2         29 foreach $label ( keys %_Valid_Field_Name ) {
321 28 100       59 next if $label =~ /^description$/;
322 26 100       67 $xml .= qq($label="$self->{$label}" ) if defined $self->{$label};
323             };
324 2         5 $xml .= ">";
325 2         10 $xml .= $self->{'payInstrument'}->make_XML;
326 2         8 $xml .= $self->{'address'}->make_XML;
327 2         5 foreach (@{$self->{'items'}}) { $xml .= $_->make_XML; }
  2         6  
  2         9  
328 2 50       17 $xml .= Text->new('description',$self->{'description'})->make_XML if $self->{'description'};
329 2         18 $xml .= qq();
330 2         10 return $xml;
331             }
332              
333             1;
334              
335             package AuthResponse;
336              
337 3     3   23 use strict;
  3         7  
  3         2456  
338              
339             sub new {
340 0     0   0 my ($class,$xml) = @_;
341 0         0 $xml =~ s/[\n\cM]//g;
342 0 0       0 die $xml unless ( $xml =~ m/.*<\/pp\.response>/);
343 0         0 my $self = bless ({}, $class);
344              
345 0         0 ($xml) = $xml =~ m/(|\/>])/g;
346 0         0 $xml =~ s/(authstatus="[^ ]+) /$1" /g;
347 0 0       0 $self->{'authcode'} = $1 if $xml =~ /authcode="([^\"]*)"/;
348 0 0       0 $self->{'authstatus'} = $1 if $xml =~ /authstatus="([^\"]*)"/;
349 0 0       0 $self->{'avs'} = $1 if $xml =~ /avs="([^\"]*)"/;
350 0 0       0 $self->{'cvv2result'} = $1 if $xml =~ /cvv2result="([^\"]*)"/;
351 0 0       0 $self->{'csp'} = $1 if $xml =~ /csp="([^\"]*)"/;
352 0 0       0 $self->{'merchant'} = $1 if $xml =~ /merchant="([^\"]*)"/;
353 0 0       0 $self->{'failure'} = $1 if $xml =~ /failure="([^\"]*)"/;
354 0 0       0 $self->{'ordernumber'} = $1 if $xml =~ /ordernumber="([^\"]*)"/;
355 0 0       0 $self->{'transactionid'} = $1 if $xml =~ /transactionid="([^\"]*)"/;
356 0 0       0 $self->{'message'} = $1 if $xml =~ />([^<]*)
357 0 0 0     0 $self->{'failure'} = 'false'
358             unless (defined $self->{'failure'}) && ($self->{'failure'} =~ /^true$/);
359              
360 0         0 return $self;
361             }
362              
363 0     0   0 sub getAuthCode { my $self = shift; return $self->{'authcode'}; }
  0         0  
364 0     0   0 sub getAuthStatus { my $self = shift; return $self->{'authstatus'}; }
  0         0  
365 0     0   0 sub getAVS { my $self = shift; return $self->{'avs'}; }
  0         0  
366 0     0   0 sub getcvv2result { my $self = shift; return $self->{'cvv2result'}; }
  0         0  
367 0     0   0 sub getCSP { my $self = shift; return $self->{'csp'}; }
  0         0  
368 0     0   0 sub getMerchant { my $self = shift; return $self->{'merchant'}; }
  0         0  
369 0     0   0 sub getFailure { my $self = shift; return $self->{'failure'}; }
  0         0  
370 0     0   0 sub getOrderNumber { my $self = shift; return $self->{'ordernumber'}; }
  0         0  
371 0     0   0 sub getTransactionID { my $self = shift; return $self->{'transactionid'}; }
  0         0  
372 0     0   0 sub getFailureMsg { my $self = shift; return $self->{'message'}; }
  0         0  
373              
374             1;
375              
376             package CreditCard;
377              
378 3     3   21 use strict;
  3         14  
  3         7170  
379              
380             our %_Valid_Field_Name;
381             foreach (qw/ number expiration cvv2 cvv2status address /) { $_Valid_Field_Name{$_}++; }
382              
383             our %_Max_Length = (
384             'cardnumber' => 19,
385             'expiration' => 5,
386             'cvv2' => 4,
387             'cvv2status' => 1,
388             );
389              
390             sub new {
391 2     2   10 my ($class,%fields) = @_;
392 2         6 my $self = bless( {}, $class);
393 2         4 my ($l,$v);
394 2         16 while ( ($l,$v) = each %fields ) { $self->addField($l,$v); }
  8         26  
395 2         8 return $self;
396             }
397              
398             sub addField {
399 8     8   11 my ($self,$label,$value) = @_;
400 8         9 my $backup;
401              
402 8 100       25 if ($label =~ /^address$/) {
403 2         4 my $pref = ref $value;
404 2 50       47 die "Invalid Address Reference ($pref)" unless $pref eq 'Address';
405 2         8 my $type = $value->getType;
406 2 50       9 die "Invalid Address Type ($type)" unless $type eq 'billing';
407 2         3 $self->{$label} = $value;
408 2         10 return undef;
409             }
410              
411 6         15 $value = Common->clean($value);
412              
413 6 100       18 if ($label =~ /^number$/) {
414 2         5 $backup=$value;
415 2         8 $value = $self->_CreditCardNumberCheck($value);
416 2 50       8 die "Invalid Credit Ccard Number: $backup\n" unless $value;
417             }
418              
419 6 100       22 if ($label =~ /^expiration$/) {
420 2         4 $backup=$value;
421 2         11 my ($month,$year) = $value =~ m#^(\d\d)/(\d\d)$#;
422 2 50 33     19 die "Invalid Credit Card Expiration: $backup\n" unless $month =~ /\d\d/ && $year =~ /\d\d/;
423 2         8 $value = "$month/$year";
424             }
425              
426 6 100 66     33 $value = substr($value,0,$_Max_Length{$label}) if (($_Max_Length{$label}) && ($_Max_Length{$label} > 0));
427            
428 6 50       22 die "Invalid Credit Card Field Name ($label)" unless $_Valid_Field_Name{$label};
429 6 50       54 return undef unless $value =~ /\S/;
430 6         25 $self->{$label} = $value;
431 6         24 return undef;
432             }
433              
434             sub make_XML {
435 2     2   5 my $self = shift;
436 2         4 my $label;
437 2         4 my $xml = qq(
438 2         7 foreach $label ( keys %_Valid_Field_Name ) {
439 10 100       26 next if $label =~ /^address$/;
440 8 100       50 $xml .= qq($label="$self->{$label}" ) if defined $self->{$label};
441             };
442 2         5 $xml .= ">";
443 2         9 $xml .= $self->{'address'}->make_XML;
444 2         5 $xml .= qq();
445 2         6 return $xml;
446             }
447              
448             sub _CreditCardNumberCheck {
449 2     2   4 my ($self,$cardNumber) = @_;
450 2         4 my ($i, $sum, $weight);
451 2 50       10 return undef if ($cardNumber =~ /^\s*$/); # invalid if empty
452 2         5 $cardNumber =~ s/\D//g;
453 2         11 for ($i = 0; $i < length($cardNumber) - 1; $i++) {
454 30         52 $weight = substr($cardNumber, -1 * ($i + 2), 1) * (2 - ($i % 2));
455 30 50       78 $sum += (($weight < 10) ? $weight : ($weight - 9));
456             }
457 2 50       13 return $cardNumber if substr($cardNumber, -1) == (10 - $sum % 10) % 10;
458 0         0 return undef;
459             }
460              
461             1;
462              
463             package LineItem;
464              
465 3     3   48 use strict;
  3         7  
  3         2128  
466              
467             our %_Valid_Field_Name;
468             foreach (qw/ description quantity sku taxrate unitprice /) {
469             $_Valid_Field_Name{$_}++;
470             }
471              
472             our %_Max_Length = (
473             'description' => 200,
474             );
475              
476             sub new {
477 2     2   7 my ($class,%fields) = @_;
478 2         6 my $self = bless( {}, $class);
479 2         4 my ($label, $value);
480 2         10 while ( ($label, $value) = each %fields ) { $self->_Add_Field($label, $value); }
  10         36  
481 2         12 return $self;
482             }
483              
484             sub _Add_Field {
485 10     10   22 my ($self,$label,$value) = @_;
486 10         10 my $backup;
487              
488 10 100       48 $value = Common->clean($value) if ($label =~ /^(sku|description)$/);
489              
490 10 100       27 if ($label =~ /^quantity$/) {
491 2         5 $value =~ s/\D//g;
492 2   50     7 $value ||= 0;
493             }
494 10 100       26 if ($label =~ /^taxrate$/) {
495 2         4 $value =~ s/[^\d\.]//g;
496 2   50     13 $value ||= 0;
497             }
498 10 100       25 if ($label =~ /^unitprice$/) {
499 2         5 $value =~ s/[^\d\.\-]//g;
500 2         36 $value = sprintf("%.2f",$value);
501             }
502              
503 10 100 66     37 $value = substr($value,0,$_Max_Length{$label}) if (($_Max_Length{$label}) && ($_Max_Length{$label} > 0));
504            
505 10 50       24 die "Invalid Line Item Field Name ($label)" unless $_Valid_Field_Name{$label};
506 10 50       33 return undef unless $value =~ /\S/;
507 10         25 $self->{$label} = $value;
508 10         33 return undef;
509             }
510              
511             sub make_XML {
512 2     2   5 my $self = shift;
513 2         3 my $label;
514 2 50       13 $self->{'unitprice'} = $self->{'unitprice'}.'USD' if ($self->{'unitprice'});
515 2         11 my $xml = qq(
516 2         8 foreach $label ( keys %_Valid_Field_Name ) {
517 10 50       38 $xml .= qq($label="$self->{$label}" ) if defined $self->{$label};
518             };
519 2         6 $xml .= qq(>);
520 2         17 return $xml;
521             }
522              
523             1;
524              
525             package Common;
526              
527 3     3   19 use strict;
  3         14  
  3         121  
528 3     3   3992 use Net::SSLeay;
  3         74456  
  3         1944  
529              
530             sub doctype {
531 0     0   0 my $self = shift;
532 0         0 return qq();
533             }
534              
535             sub clean {
536 56     56   79 my ($self,$value) = @_;
537 56         85 $value =~ s/[^\w !\@#\$\%^&\*\)\)\[\]{}_\-\+=|\\~`:;"'<>,\.\?\/]//g;
538 56         68 $value =~ s/&/&/g;
539 56         56 $value =~ s/
540 56         58 $value =~ s/>/>/g;
541 56         58 $value =~ s/\"/"/g;
542 56         58 $value =~ s/\n+/\n/g;
543 56         123 return $value;
544             }
545              
546             sub https_post {
547 2     2   7 my ($self,$host,$port,$path,$slowly,$type,$request) = @_;
548 2         4 my ($form,$page);
549 2 50       7 $Net::SSLeay::slowly = $slowly if $slowly > 0;
550 2         22 $request =~ s/([^a-zA-Z0-9_.-])/uc sprintf("%%%02x",ord($1))/eg;
  334         1251  
551 2         10 $request =~ s/ /+/g;
552 2         24 $form = "$type=$request";
553             eval
554 2         5 {
555 2         22 ($page) = Net::SSLeay::post_https($host,$port,$path,'',$form);
556             };
557 2         18383 $@ =~ s/ at .*//;
558 2 50 50     41 return $page? ('',$page) : ($@ || 'null response');
559             }
560              
561             1;
562              
563             package Request;
564              
565 3     3   44 use strict;
  3         8  
  3         2008  
566              
567             our %_Valid_Field_Name;
568             foreach (qw/ csp merchant password /) {
569             $_Valid_Field_Name{$_}++;
570             }
571              
572             sub new {
573 2     2   7 my ($class,%fields) = @_;
574 2         4 my $self = bless( {}, $class);
575 2         4 my ($label, $value);
576 2         12 while ( ($label, $value) = each %fields ) { $self->_Add_Field($label, $value); }
  4         12  
577 2         7 return $self;
578             }
579              
580             sub _Add_Field {
581 4     4   7 my ($self,$label,$value) = @_;
582              
583 4 50       34 $value = Common->clean($value) if ($label =~ /^(merchant|password|csp)$/);
584              
585 4 50       13 die "Invalid Auth Field Name ($label)" unless $_Valid_Field_Name{$label};
586 4 50       20 return undef unless $value =~ /\S/;
587 4         16 $self->{$label} = $value;
588 4         15 return undef;
589             }
590              
591             sub addAuth {
592 2     2   5 my ($self,$obj) = @_;
593 2         4 my $pref = ref $obj;
594 2 50       8 die "Invalid Auth Reference: ($pref)" unless $pref eq 'Auth';
595 2 50       16 $self->{'auths'} = [] unless $self->{'auths'};
596 2         4 push(@{$self->{'auths'}},$obj);
  2         6  
597 2         4 return undef;
598             }
599              
600             sub make_XML {
601 2     2   6 my $self = shift;
602 2 50       4 die "No Auth Field In Request" unless ((scalar @{$self->{'auths'}}) > 0);
  2         16  
603 2         4 my $label;
604 2         3 my $xml = qq(
605 2         8 foreach $label ( keys %_Valid_Field_Name ) {
606 6 100       27 $xml .= qq($label="$self->{$label}" ) if defined $self->{$label};
607             };
608 2         11 $xml .= qq(>);
609 2         4 foreach (@{$self->{'auths'}}){ $xml .= $_->make_XML; }
  2         11  
  2         9  
610 2         6 $xml .= qq();
611 2         12 return $xml;
612             }
613              
614             1;
615              
616             package RequestManager;
617              
618 3     3   19 use strict;
  3         6  
  3         1360  
619              
620             sub new {
621 2     2   305 my ($class, %param) = @_;
622 2 50       20 die "Host must be defined" unless $param{'host'};
623 2 50       8 die "Port must be defined" unless $param{'port'};
624 2 50       8 die "Path must be defined" unless $param{'path'};
625 2         4 $param{'host'} =~ s/^https:\/\///;
626 2   50     30 $param{'debuglevel'} ||= 0;
627 2         8 return bless (\%param, $class);
628             }
629              
630             sub submit {
631 2     2   5 my ($self,$req) = @_;
632 2         3 my ($res);
633 2         6 local (*DBG);
634 2 50       11 die "Unrecognized Request Object Reference" unless (ref $req eq 'Request');
635 2         11 my $smsg = $req->make_XML;
636 2         12 my $debugfile = $self->{'debugfile'};
637 2 50       15 if ($self->{'debuglevel'} > 0) {
638 0 0       0 if ($debugfile) {
639 0         0 open (DBG,">>$debugfile");
640 0         0 print DBG "smsg: $smsg\n";
641 0         0 close DBG;
642             }
643             else {
644 0         0 print "smsg: $smsg\n";
645             }
646             }
647 2         4 my $slowly = 0;
648 2         4 my $label = 'xml';
649 2         18 my ($msg,$output) = Common->https_post(
650             $self->{'host'},
651             $self->{'port'},
652             $self->{'path'},
653             $slowly,
654             $label,
655             $smsg
656             );
657 2 50       13 if ($msg) {
658 2         0 die "https error: $msg";
659             }
660 0 0       0 if ($self->{'debuglevel'} > 0) {
661 0 0       0 if ($debugfile) {
662 0         0 open (DBG,">>$debugfile");
663 0         0 print DBG "rmsg: $output\n";
664 0         0 close DBG;
665             }
666             else {
667 0         0 print "rmsg: $output\n";
668             }
669             }
670 0 0       0 die "No Response From SurePay Gateway" unless $output;
671 0         0 return AuthResponse->new($output);
672             }
673              
674             1;
675              
676             package Text;
677              
678 3     3   18 use strict;
  3         5  
  3         1178  
679              
680             sub new
681             {
682 2     2   7 my ($class,$type,$text) = @_;
683 2 50       22 die "Invalid Auth Text Type ($type)" unless $type =~ /^description$/;
684 2         21 return bless { 'type' => $type, 'text' => $text }, $class;
685             }
686              
687             sub make_XML {
688 2     2   4 my $self = shift;
689 2         12 my $type = $self->{'type'};
690 2         6 my $text = $self->{'text'};
691 2         5 $text =~ s/[^\w !\@#\$\%^&\*\)\)\[\]{}_\-\+=|\\~`:;"'<>,\.\?\/\n\t]//g;
692 2         5 $text =~ s/\n+$/\n/;
693 2         4 $text =~ s/]]>//g;
694 2         3 $text =~ s/"/\"/g;
695 2         3 $text =~ s/&/&/g;
696 2         7 $text = qq();
697 2         9 return qq($text);
698             }
699              
700             1;
701              
702             __END__