1 package Business::OnlinePayment::PaymentsGateway;
5 use Business::OnlinePayment;
6 use Net::SSLeay qw(sslcat);
7 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $DEBUG);
11 @ISA = qw( Exporter AutoLoader Business::OnlinePayment);
18 my %pg_response_code = (
19 'A01' => 'Transaction approved/completed',
20 'U01' => 'Merchant not allowed to access customer account',
21 'U02' => 'Customer account is in the ACH Direct "known bad" list',
22 'U03' => 'Merchant daily limit exceeded',
23 'U04' => 'Merchant monthly limit exceeded',
24 'U05' => 'AVS state/zipcode check failed',
25 'U06' => 'AVS state/area code check failed',
26 'U07' => 'AVS anonymous email check failed',
27 'U08' => 'Account has more transactions than the merchant\'s daily velocity'.
29 'U09' => 'Account has more transactions than the merchant\'s velocity'.
31 'U10' => 'Transaction has the same attributes as another transaction'.
32 ' within the time set by the merchant',
33 'U11' => '(RECUR TRANS NOT FOUND) Transaction types 40-42 only',
34 'U12' => 'Original transaction not voidable or capture-able',
35 'U13' => 'Transaction to be voided or captured was not found',
36 'U14' => 'void/capture and original transaction types do not agree (CC/EFT)',
37 'U18' => 'Void or Capture failed',
38 #'U19' => 'Account ABA number if invalid',
39 'U19' => 'Account ABA number is invalid',
40 'U20' => 'Credit card number is invalid',
41 'U21' => 'Date is malformed',
42 'U22' => 'Swipe data is malformed',
43 'U23' => 'Malformed expiration date',
44 'U51' => 'Merchant is not "live"',
45 'U52' => 'Merchant not approved for transaction type (CC or EFT)',
46 'U53' => 'Transaction amount exceeds merchant\'s per transaction limit',
47 'U54' => 'Merchant\'s configuration requires updating - call customer'.
49 'U80' => 'Transaction was declined due to preauthorization (ATM Verify)'.
51 'U84' => 'Preauthorizer not responding',
52 'U85' => 'Preauthorizer error',
53 'U83' => 'Transaction was declined due to authorizer declination',
54 'U84' => 'Authorizer not responding',
55 'U85' => 'Authorizer error',
56 'U86' => 'Authorizer AVS check failed',
57 'F01' => 'Required field is missing',
58 'F03' => 'Name is not recognized',
59 'F04' => 'Value is not allowed',
60 'F05' => 'Field is repeated in message',
61 'F07' => 'Fields cannot both be present',
62 #'E10' => 'Merchant id or password in incorrect',
63 'E10' => 'Merchant id or password is incorrect',
64 'E20' => 'Transaction message not received (I/O flush required?)',
65 'E90' => 'Originating IP not on merchant\'s approved IP list',
66 'E99' => 'An unspecified error has occurred',
71 $self->server('paymentsgateway.net');
77 my %content = $self->content();
81 'normal authorization' => 0,
82 'authorization only' => 1,
83 'post authorization' => 2,
90 'american express' => 10,
96 #pg_type/action = action + type
98 $self->transaction_type( $actions{ lc($content{'action'}) }
99 + $types{ lc($content{'type' }) } );
101 #$self->content(%content);
105 my($self, %map) = @_;
106 my %content = $self->content();
108 $content{$_} = ref($map{$_})
110 : $content{$map{$_}};
112 $self->content(%content);
119 #my %content = $self->content();
121 $self->revmap_fields(
122 'PG_MERCHANT_ID' => 'login',
123 'pg_password' => 'password',
124 'pg_transaction_type' => \($self->transaction_type()),
125 #'pg_merchant_data_1'
127 #'pg_merchant_data_9'
128 'pg_total_amount' => 'amount',
129 #'pg_sales_tax_amount'
130 'pg_consumer_id' => 'customer_id',
131 'ecom_consumerorderid' => 'invoice_number', #???
133 'pg_billto_postal_name_company' => 'company', #????
134 'ecom_billto_postal_name_first' => 'first_name', #????
135 'ecom_billto_postal_name_last' => 'last_name', # ????
136 'ecom_billto_postal_street_line1' => 'address',
137 #'ecom_billto_postal_street_line2'
138 'ecom_billto_postal_city' => 'city',
139 'ecom_billto_postal_stateprov' => 'state',
140 'ecom_billto_postal_postalcode' => 'zip',
141 'ecom_billto_postal_countrycode' => 'country',
142 'ecom_billto_telecom_phone_number' => 'phone',
143 'ecom_billto_online_email' => 'email',
145 #'pg_billto_dl_number'
146 #'pg_billto_dl_state'
147 'ecom_payment_check_trn' => 'routing_code',
148 'ecom_payment_check_account' => 'account_number',
149 'ecom_payment_check_account_type' => \'C', #checking
150 #'ecom_payment_check_checkno' =>
152 my %content = $self->content();
154 # name (first_name & last_name ) ?
157 # card_number exp_date
159 #account_number routing_code bank_name
162 qw( PG_MERCHANT_ID pg_password pg_transaction_type ),
163 ( map { "pg_merchant_$_" } ( 1 .. 9 ) ),
164 qw( pg_total_amount pg_sales_tax_amount pg_consumer_id
165 ecom_consumerorderid ecom_walletid
166 pg_billto_postal_name_company
167 ecom_billto_postal_name_first ecom_billto_postal_name_last
168 ecom_billto_postal_street_line1
169 ecom_billto_postal_street_line2
170 ecom_billto_postal_city ecom_billto_postal_stateprov
171 ecom_billto_postal_postalcode ecom_billto_postal_countrycode
172 ecom_billto_telecom_phone_number ecom_billto_online_email
173 pg_billto_ssn pg_billto_dl_number pg_billto_dl_state
177 if ( $content{'type'} =~ /^check$/i ) {
178 push @fields, qw( ecom_payment_check_trn
179 ecom_payment_check_account
180 ecom_payment_check_account_type );
182 croak $content{'type'}. ' not (yet) supported';
185 my $request = join("\n", map { "$_=". $content{$_} }
186 grep { defined($content{$_}) && $content{$_} ne '' }
190 warn $request if $DEBUG;
192 warn "TEST: ". $self->test_transaction(). "\n" if $DEBUG;
194 $self->port( $self->port() + 1000 ) if $self->test_transaction();
196 warn "SERVER ". $self->server(). "\n" if $DEBUG;
197 warn "PORT ". $self->port(). "\n" if $DEBUG;
199 my $reply = sslcat( $self->server(), $self->port(), $request );
200 die "no reply from server" unless $reply;
202 warn "reply from server: $reply\n" if $DEBUG;
204 my %response = map { /^(\w+)=(.*)$/ or /^(endofdata)()$/
205 or warn "can't parse response line: $_";
207 } split(/\n/, $reply);
209 if ( $response{'pg_response_type'} eq 'A' ) {
210 $self->is_success(1);
211 $self->result_code($response{'pg_response_code'});
212 $self->authorization($response{'pg_authorization_code'});
214 $self->is_success(0);
215 $self->result_code($response{'pg_response_code'});
216 $self->error_message( $pg_response_code{$response{'pg_response_code'}}.
217 ': '. $response{'pg_response_description'} );
227 Business::OnlinePayment::PaymentsGateway - PaymentsGateway.Net backend for Business::OnlinePayment
231 use Business::OnlinePayment;
233 my $tx = new Business::OnlinePayment("PaymentsGateway");
238 action => 'Normal Authorization',
239 description => 'Business::OnlinePayment test',
241 invoice_number => '100100',
242 name => 'Tofu Beast',
243 account_number => '12345',
244 routing_code => '123456789',
245 bank_name => 'First National Test Bank',
249 if($tx->is_success()) {
250 print "Card processed successfully: ".$tx->authorization."\n";
252 print "Card was rejected: ".$tx->error_message."\n";
257 For detailed information see L<Business::OnlinePayment>.
261 This module only implements 'CHECK' (ACH) transactions at this time. Credit
262 card transactions are not (yet) supported.
266 This module implements the interface documented in the
267 "PaymentsGateway.net Integration Guide, Version 2.1, September 2002"
271 Ivan Kohler <ivan-paymentsgateway@420.am>
275 perl(1). L<Business::OnlinePayment>