File Coverage

blib/lib/Business/OnlinePayment/PaymentsGateway.pm
Criterion Covered Total %
statement 29 59 49.1
branch 2 24 8.3
condition 0 3 0.0
subroutine 8 9 88.8
pod 1 4 25.0
total 40 99 40.4


line stmt bran cond sub pod time code
1             package Business::OnlinePayment::PaymentsGateway;
2              
3 2     2   1562 use strict;
  2         2  
  2         71  
4 2     2   10 use Carp;
  2         2  
  2         155  
5 2     2   879 use Business::OnlinePayment;
  2         3493  
  2         51  
6 2     2   2886 use Net::SSLeay qw(sslcat);
  2         39915  
  2         1205  
7 2     2   24 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $DEBUG);
  2         4  
  2         2815  
8              
9             @ISA = qw( Business::OnlinePayment );
10             $VERSION = '0.02';
11              
12             $DEBUG = 0;
13              
14             my %pg_response_code = (
15             'A01' => 'Transaction approved/completed',
16             'U01' => 'Merchant not allowed to access customer account',
17             'U02' => 'Customer account is in the ACH Direct "known bad" list',
18             'U03' => 'Merchant daily limit exceeded',
19             'U04' => 'Merchant monthly limit exceeded',
20             'U05' => 'AVS state/zipcode check failed',
21             'U06' => 'AVS state/area code check failed',
22             'U07' => 'AVS anonymous email check failed',
23             'U08' => 'Account has more transactions than the merchant\'s daily velocity'.
24             ' limit allows for',
25             'U09' => 'Account has more transactions than the merchant\'s velocity'.
26             ' window allows for',
27             'U10' => 'Transaction has the same attributes as another transaction'.
28             ' within the time set by the merchant',
29             'U11' => '(RECUR TRANS NOT FOUND) Transaction types 40-42 only',
30             'U12' => 'Original transaction not voidable or capture-able',
31             'U13' => 'Transaction to be voided or captured was not found',
32             'U14' => 'void/capture and original transaction types do not agree (CC/EFT)',
33             'U18' => 'Void or Capture failed',
34             #'U19' => 'Account ABA number if invalid',
35             'U19' => 'Account ABA number is invalid',
36             'U20' => 'Credit card number is invalid',
37             'U21' => 'Date is malformed',
38             'U22' => 'Swipe data is malformed',
39             'U23' => 'Malformed expiration date',
40             'U51' => 'Merchant is not "live"',
41             'U52' => 'Merchant not approved for transaction type (CC or EFT)',
42             'U53' => 'Transaction amount exceeds merchant\'s per transaction limit',
43             'U54' => 'Merchant\'s configuration requires updating - call customer'.
44             ' support',
45             'U80' => 'Transaction was declined due to preauthorization (ATM Verify)'.
46             ' result',
47             'U84' => 'Preauthorizer not responding',
48             'U85' => 'Preauthorizer error',
49             'U83' => 'Transaction was declined due to authorizer declination',
50             'U84' => 'Authorizer not responding',
51             'U85' => 'Authorizer error',
52             'U86' => 'Authorizer AVS check failed',
53             'F01' => 'Required field is missing',
54             'F03' => 'Name is not recognized',
55             'F04' => 'Value is not allowed',
56             'F05' => 'Field is repeated in message',
57             'F07' => 'Fields cannot both be present',
58             #'E10' => 'Merchant id or password in incorrect',
59             'E10' => 'Merchant id or password is incorrect',
60             'E20' => 'Transaction message not received (I/O flush required?)',
61             'E90' => 'Originating IP not on merchant\'s approved IP list',
62             'E99' => 'An unspecified error has occurred',
63             );
64              
65             sub set_defaults {
66 1     1 0 45 my $self = shift;
67 1         33 $self->server('paymentsgateway.net');
68 1         47 $self->port( 5050 );
69             }
70              
71             sub map_fields {
72 1     1 0 3 my $self = shift;
73 1         3 my %content = $self->content();
74              
75             #ACTION MAP
76 1         20 my %actions = (
77             'normal authorization' => 0,
78             'authorization only' => 1,
79             'post authorization' => 2,
80             'credit' => 3,
81             );
82              
83 1         6 my %types = (
84             'visa' => 10,
85             'mastercard' => 10,
86             'american express' => 10,
87             'discover' => 10,
88             'cc' => 10,
89             'check' => 20,
90             'echeck' => 20,
91             );
92              
93             #pg_type/action = action + type
94              
95 1         29 $self->transaction_type( $actions{ lc($content{'action'}) }
96             + $types{ lc($content{'type' }) } );
97              
98             #$self->content(%content);
99             }
100              
101             sub revmap_fields {
102 1     1 0 23 my($self, %map) = @_;
103 1         4 my %content = $self->content();
104 1         19 foreach(keys %map) {
105 2         5 $content{$_} = ref($map{$_})
106 19 100       47 ? ${ $map{$_} }
107             : $content{$map{$_}};
108             }
109 1         9 $self->content(%content);
110             }
111              
112             sub submit {
113 0     0 1   my $self = shift;
114 0           $self->map_fields();
115              
116             #my %content = $self->content();
117              
118 0           $self->revmap_fields(
119             'PG_MERCHANT_ID' => 'login',
120             'pg_password' => 'password',
121             'pg_transaction_type' => \($self->transaction_type()),
122             #'pg_merchant_data_1'
123             #...
124             #'pg_merchant_data_9'
125             'pg_total_amount' => 'amount',
126             #'pg_sales_tax_amount'
127             'pg_consumer_id' => 'customer_id',
128             'ecom_consumerorderid' => 'invoice_number', #???
129             #'ecom_walletid' =>
130             'pg_billto_postal_name_company' => 'company', #????
131             'ecom_billto_postal_name_first' => 'first_name', #????
132             'ecom_billto_postal_name_last' => 'last_name', # ????
133             'ecom_billto_postal_street_line1' => 'address',
134             #'ecom_billto_postal_street_line2'
135             'ecom_billto_postal_city' => 'city',
136             'ecom_billto_postal_stateprov' => 'state',
137             'ecom_billto_postal_postalcode' => 'zip',
138             'ecom_billto_postal_countrycode' => 'country',
139             'ecom_billto_telecom_phone_number' => 'phone',
140             'ecom_billto_online_email' => 'email',
141             #'pg_billto_ssn'
142             #'pg_billto_dl_number'
143             #'pg_billto_dl_state'
144             'ecom_payment_check_trn' => 'routing_code',
145             'ecom_payment_check_account' => 'account_number',
146             'ecom_payment_check_account_type' => \'C', #checking
147             #'ecom_payment_check_checkno' =>
148             );
149 0           my %content = $self->content();
150              
151             # name (first_name & last_name ) ?
152             # fax
153              
154             # card_number exp_date
155              
156             #account_number routing_code bank_name
157              
158 0           my @fields = (
159             qw( PG_MERCHANT_ID pg_password pg_transaction_type ),
160 0           ( map { "pg_merchant_$_" } ( 1 .. 9 ) ),
161             qw( pg_total_amount pg_sales_tax_amount pg_consumer_id
162             ecom_consumerorderid ecom_walletid
163             pg_billto_postal_name_company
164             ecom_billto_postal_name_first ecom_billto_postal_name_last
165             ecom_billto_postal_street_line1
166             ecom_billto_postal_street_line2
167             ecom_billto_postal_city ecom_billto_postal_stateprov
168             ecom_billto_postal_postalcode ecom_billto_postal_countrycode
169             ecom_billto_telecom_phone_number ecom_billto_online_email
170             pg_billto_ssn pg_billto_dl_number pg_billto_dl_state
171             )
172             );
173              
174 0 0         if ( $content{'type'} =~ /^e?check$/i ) {
175 0           push @fields, qw( ecom_payment_check_trn
176             ecom_payment_check_account
177             ecom_payment_check_account_type );
178             } else {
179 0           croak $content{'type'}. ' not (yet) supported';
180             }
181              
182 0 0         my $request = join("\n", map { "$_=". $content{$_} }
  0            
183 0           grep { defined($content{$_}) && $content{$_} ne '' }
184             @fields ).
185             "\nendofdata\n";
186              
187 0 0         warn $request if $DEBUG;
188              
189 0 0         warn "TEST: ". $self->test_transaction(). "\n" if $DEBUG;
190              
191 0 0         $self->port( $self->port() + 1000 ) if $self->test_transaction();
192              
193 0 0         warn "SERVER ". $self->server(). "\n" if $DEBUG;
194 0 0         warn "PORT ". $self->port(). "\n" if $DEBUG;
195              
196 0           my $reply = sslcat( $self->server(), $self->port(), $request );
197 0 0         die "no reply from server" unless $reply;
198              
199 0 0         warn "reply from server: $reply\n" if $DEBUG;
200              
201 0 0 0       my %response = map { /^(\w+)=(.*)$/ or /^(endofdata)()$/
  0            
202             or warn "can't parse response line: $_";
203 0           ($1, $2);
204             } split(/\n/, $reply);
205              
206 0 0         if ( $response{'pg_response_type'} eq 'A' ) {
207 0           $self->is_success(1);
208 0           $self->result_code($response{'pg_response_code'});
209 0           $self->authorization($response{'pg_authorization_code'});
210             } else {
211 0           $self->is_success(0);
212 0           $self->result_code($response{'pg_response_code'});
213 0           $self->error_message( $pg_response_code{$response{'pg_response_code'}}.
214             ': '. $response{'pg_response_description'} );
215             }
216             }
217              
218             1;
219              
220             __END__