File Coverage

blib/lib/Business/Paybox.pm
Criterion Covered Total %
statement 12 71 16.9
branch 0 20 0.0
condition 0 29 0.0
subroutine 4 13 30.7
pod n/a
total 16 133 12.0


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             #
3             # OO wrapper in Perl for LocalhostListener.jar - PAYBOX.NET
4             # Copyright (C) 2000 Dirk Tostmann (tostmann@tosti.com)
5             #
6             # $rcs = ' $Id: Paybox.pm,v 1.2 2000/12/21 16:59:44 tostmann Exp $ ' ;
7             #
8             ################################################
9              
10             =head1 NAME
11              
12             Business::PayBox - OO wrapper for Paybox Java Localhost Listener (LHL)
13              
14             =head1 SYNOPSIS
15              
16             To create object:
17              
18             use Business::PayBox;
19              
20             $PB = Business::PayBox->new(MRID => '+490001234567');
21             or
22             $PB = Business::PayBox->new(MRID => '+490001234567', server => '192.168.1.1', port => 61);
23              
24             To do a payment:
25              
26             $result = $PB->do_test_payment(AMNT => 100, CURR => 'DEM', ORNM=>'TEST123', CPID => '+491773729269');
27             or
28             $result = $PB->dopayment(AMNT => 100, CURR => 'DEM', ORNM=>'TEST123', CPID => '+491773729269');
29              
30              
31             =head1 DESCRIPTION
32              
33             This is an OO wrapper for the PAYBOX - Integrated Solution. You must install Localhostlistener LHL (which comes as Java-Jar) to use this
34             module. After you succeed with this you can process payments as described above.
35              
36             =head1 CONSTRUCTOR
37              
38             =cut
39              
40             package Business::PayBox;
41              
42 1     1   961 use strict;
  1         4  
  1         56  
43 1     1   7 use vars qw/$DEBUG $VERSION/;
  1         2  
  1         94  
44 1     1   1250 use IO::Socket;
  1         37855  
  1         5  
45 1     1   1562 use POSIX qw/strftime/;
  1         9112  
  1         7  
46              
47             $DEBUG = 1;
48             $VERSION = '1.0';
49              
50             =head2 new($key => $value, ...)
51              
52             Call to initialize object. Valid Parameters are:
53              
54             Mandatory:
55             MRID => Merchant ID
56              
57             Others:
58             server => IP address or name of LHL server. (defaults to localhost)
59             port => Port of LHL server. (defaults to port 60)
60            
61             CMID => Customer ID (defaults to 0)
62             AUTT => Transaction Type
63             LANG => Language (defaults to DE)
64             PYMD => Zahlungsziel (defaults to 1)
65             LCMT => Localtime stamp (defaults to localtime)
66              
67             =cut
68              
69             sub new {
70 0     0     my $that = shift;
71 0   0       my $class = ref($that) || $that;
72 0           my %args = @_;
73 0           my $self = {};
74 0           foreach (keys %args) {
75 0           $self->{$_} = $args{$_};
76             }
77            
78 0           bless $self, $class;
79              
80 0   0       $self->{DATA}->{1} = {
      0        
      0        
      0        
      0        
      0        
81             MRID => $self->{MRID} || return,
82             CMID => $self->{CMID} || 0,
83             AUTT => $self->{AUTT} || 'T',
84             LANG => $self->{LANG} || 'DE',
85             PYMD => $self->{PYMD} || 1,
86             LCMT => $self->{LCMT} || strftime "%Y-%m-%d %H:%M:%S.000000000", localtime,
87             };
88              
89 0 0         return unless $self->connect2listener;
90              
91 0           $self;
92             }
93              
94             sub DESTROY {
95 0     0     my $self = shift;
96              
97 0 0         $self->{sock}->close if $self->{sock};
98             }
99              
100             sub connect2listener {
101 0     0     my $self = shift;
102 0   0       my $server = shift || $self->{server} || '127.0.0.1';
103 0   0       my $port = shift || $self->{port} || 60;
104              
105 0 0         $DEBUG && print STDERR "connecting to $server:$port ...\n";
106              
107 0           my $sock = IO::Socket::INET->new(
108             PeerAddr => $server,
109             PeerPort => $port,
110             Proto => 'tcp'
111             );
112              
113 0 0         return unless $sock;
114              
115 0           $self->{sock} = $sock;
116              
117 0           $sock;
118             }
119              
120             =head1 METHODS
121              
122             =head2 dopayment($key => $value, ...)
123              
124             Mandatory parameters are:
125              
126             AMNT => Amount (18.75 => 1875)
127             CURR => Currency (ISO ie: DEM/EUR)
128             ORNM => Order number/decr (max 40 char)
129             CPID => PayBoxNumber (must match /^\+\d{12}$/)
130              
131             This function will return undef on errors. In this case you can catch the error by accessing $PB->{ERROR} which will look like:
132              
133             $VAR1 = [
134             45,
135             'Undefinierter Fehler'
136             ];
137              
138             On success the return value will be a hash ref looking like:
139              
140             ...
141              
142             =cut
143              
144             sub dopayment {
145 0     0     my $self = shift;
146              
147 0           $self->{DATA}->{1}->{AUTT} = 'N',
148              
149             $self->do_test_payment(@_);
150             }
151              
152             =head2 do_test_payment($key => $value, ...)
153              
154             Acts the same as dopayment-call, only as a test call...
155              
156             =cut
157              
158             sub do_test_payment {
159 0     0     my $self = shift;
160              
161 0           delete $self->{ERROR};
162              
163 0           my %hash = @_;
164              
165 0           foreach (qw/AMNT CURR ORNM CPID/) {
166 0   0       $self->{DATA}->{1}->{$_} = $hash{$_} || return;
167             }
168              
169 0 0         return unless $self->{DATA}->{1}->{CPID} =~ /^\+\d{12}$/;
170              
171             #
172             # STEP 1
173             #
174              
175 0           my $data = $self->build_STEP1;
176 0   0       my $ans = $self->ask($data) || return;
177              
178             #
179             # STEP 2
180             #
181              
182 0 0         $self->parse_answer($ans) || return;
183 0 0         unless ($self->{DATA}->{2}->{STAT} eq 'AS') {
184 0           $self->{ERROR} = [$self->{DATA}->{2}->{ERRC},$self->{DATA}->{2}->{ERRM}];
185             }
186              
187             #
188             # STEP 3
189             #
190              
191 0           $data = $self->build_STEP3;
192 0 0         $self->{sock}->print("$data\n") || return;
193              
194 0 0         return $self->{ERROR} ? undef : $self->{DATA};
195             }
196              
197             sub build_STEP1 {
198 0     0     my $self = shift;
199              
200 0           my @VARS = ();
201 0           foreach (qw/MRID CMID CPID AMNT CURR LCMT ORNM AUTT LANG PYMD/) {
202 0           push @VARS, $self->{DATA}->{1}->{$_};
203             }
204              
205 0           sprintf ('MRID%s|CMID%04d|CPID%s|AMNT%d|CURR%3s|LCMT%s|ORNM%s|STEP1|AUTT%1s|LANG%2s|PYMD%d', @VARS);
206             }
207              
208             sub build_STEP3 {
209 0     0     my $self = shift;
210              
211 0           $self->{DATA}->{3}->{TANM} = $self->{DATA}->{2}->{ORNM};
212              
213 0           my @VARS = ();
214 0           foreach (qw/MRID CPID TANP ATCP PYMD ORNM TANM STAT/) {
215 0   0       $self->{DATA}->{3}->{$_} = $self->{DATA}->{3}->{$_} || $self->{DATA}->{2}->{$_} || $self->{DATA}->{1}->{$_};
216 0           push @VARS, $self->{DATA}->{3}->{$_};
217             }
218              
219 0           sprintf ('MRID%s|CPID%s|TANP%s|ATCP%s|STEP3|PYMD%d|ORNM%s|TANM%s|STAT%s', @VARS);
220             }
221              
222             sub parse_answer {
223 0     0     my $self = shift;
224 0   0       my $ans = shift || return;
225              
226 0           my @values = split(/\|/,$ans);
227            
228 0           foreach (@values) {
229 0 0         if (m/^([A-Z]{4})(.+)$/) {
230 0           $self->{DATA}->{2}->{$1} = $2;
231             }
232             }
233              
234 0           1;
235             }
236              
237             sub ask {
238 0     0     my $self = shift;
239 0           my $data = shift;
240              
241 0           $self->{sock}->print("$data\n");
242              
243 0           $self->{sock}->getline;
244             }
245              
246             =head1 EXAMPLE
247              
248             #!/usr/bin/perl
249              
250             use Business::PayBox;
251             use Data::Dumper;
252              
253             $PB = Business::PayBox->new(MRID=>'+490001234567') || die "connecting to listener failed";
254              
255             $result = $PB->do_test_payment(AMNT=>100,CURR=>DEM,ORNM=>'TEST123',CPID=>'+491773729269');
256              
257             print Dumper($result ? $result : $PB->{ERROR});
258              
259              
260             =head1 SEE ALSO
261              
262             http://www.paybox.net
263              
264             =head1 AUTHOR
265              
266             Dirk Tostmann (tostmann@tosti.com)
267              
268             =head1 COPYRIGHT
269              
270             Copyright (c) 2000 Dirk Tostmann. All rights reserved.
271             This program is free software; you can redistribute it
272             and/or modify it under the same terms as Perl itself.
273              
274             =cut