1 package Business::OnlinePayment::PPIPayMover;
4 use vars qw($VERSION @ISA $DEBUG);
6 use Business::OnlinePayment::PPIPayMover::constants;
7 use Business::OnlinePayment::PPIPayMover::TransactionClient;
8 use Business::OnlinePayment::PPIPayMover::CreditCardRequest;
9 use Business::OnlinePayment::PPIPayMover::CountryCodes;
10 use Business::OnlinePayment::PPIPayMover::CreditCardResponse;
13 @ISA = qw(Business::OnlinePayment);
16 my $tranclient = new Business::OnlinePayment::PPIPayMover::TransactionClient;
17 #my $ccreq = new Business::OnlinePayment::PPIPayMover::CreditCardRequest;
22 #$self->server('secure.linkpt.net');
25 $self->build_subs(qw(order_number avs_code));
32 my %content = $self->content();
35 # target types: SALE, ADJUSTMENT, AUTH, CAPTURE, CREDIT, FORCE_AUTH,
36 # FORCE_SALE, QUERY_CREDIT, QUERY_PAYMENT or VOID
38 'normal authorization' => 'SALE',
39 'authorization only' => 'AUTH',
41 'post authorization' => 'CAPTURE',
44 $content{'action'} = $actions{lc($content{'action'})} || $content{'action'};
50 'american express' => 'CC',
55 $content{'type'} = $types{lc($content{'type'})} || $content{'type'};
56 $self->transaction_type($content{'type'});
58 # stuff it back into %content
59 $self->content(%content);
87 #get from new() args instead# payee =>
90 #recurring_billing => 'cnp_recurring',
94 my %content = $self->content;
97 unless ( $content{action} eq 'CAPTURE'
98 || ( $content{'action'} =~ /^(CREDIT|VOID)$/
99 && exists $content{'order_number'} )
102 if ( $self->transaction_type() =~
103 /^(cc|visa|mastercard|american express|discover)$/i
106 Carp::croak("PPIPayMover can't handle transaction type: ".
107 $self->transaction_type());
110 $content{'expiration'} =~ /^(\d+)\D+\d*(\d{2})$/
111 or croak "unparsable expiration $content{expiration}";
113 ( $month, $year ) = ( $1, "20$2" );
114 $month = '0'. $month if $month =~ /^\d$/;
117 my $ccreq = new Business::OnlinePayment::PPIPayMover::CreditCardRequest;
119 $self->revmap_fields( $ccreq,
121 'ChargeTotal' => 'amount',
122 'ChargeType' => 'action',
123 'CreditCardNumber' => 'card_number',
124 'CreditCardVerificationNumber' => 'cvv2',
125 'ExpireMonth' => \$month,
126 'ExpireYear' => \$year,
128 'BillAddressOne' => 'address',
129 #'BillAddressTwo' => '',
130 'BillCity' => 'city',
131 'BillCompany' => 'company',
132 'BillCountryCode' => 'country',
133 #'BillCustomerTitle' => '',
134 'BillEmail', => 'email',
136 'BillFirstName' => 'first_name',
137 'BillLastName' => 'last_name',
138 #'BillMiddleName' => '',
140 'BillPhone' => 'phone',
141 'BillPostalCode' => 'zip',
142 'BillStateOrProvince' => 'state',
144 'ShipAddressOne' => 'ship_address',
145 #'ShipAddressTwo' => '',
146 'ShipCity' => 'ship_city',
147 'ShipCompany' => 'ship_company',
148 'ShipCountryCode' => 'ship_country',
149 #'ShipCustomerTitle' => '',
150 'ShipEmail', => 'ship_email',
151 'ShipFax' => 'ship_fax',
152 'ShipFirstName' => 'ship_first_name',
153 'ShipLastName' => 'ship_last_name',
154 #'ShipMiddleName' => '',
156 'ShipPhone' => 'ship_phone',
157 'ShipPostalCode' => 'ship_zip',
158 'ShipStateOrProvince' => 'ship_state',
160 #'OrderId' => 'order_number',
161 'OrderId' => (int (rand 999999998) + 1 ), # XXX This can result in duplicate order ids. You should use your own sequence instead.
162 'BuyerCode' => '83487235',
163 'CustomerIPAddress' => 'customer_ip',
164 'OrderCustomerId' => 'customer_id',
165 'OrderDescription' => 'description',
166 #'OrderUserId' => '',
167 #'PurchaseOrderNumber' => '',
168 'TransactionConditionCode' => \( TCC_CARDHOLDER_NOT_PRESENT_SECURE_ECOMMERCE ),
169 #'ShippingCharge' => '',
174 'InvoiceNumber' => 'invoice_number',
175 'Industry' => \( RETAIL ),
176 #'FolioNumber' => '',
178 #'ChargeTotalIncludesRestaurant'
179 #'ChargeTotalIncludesGiftshop'
180 #'ChargeTotalIncludesMinibar'
181 #'ChargeTotalIncludesPhone'
182 #'ChargeTotalIncludesLaundry'
183 #'ChargeTotalIncludesOther'
196 #'ReferenceId' => '', # XXX Use reference ID for follow-on transactions (CAPTURE, VOID)
205 # Send the transaction! (test token)
207 my $token = $content{'login'};
208 $token = "TEST$token" if $self->test_transaction();
210 my $ccresponse = $tranclient->doTransaction(
211 "", # transaction key (?)
216 die $tranclient->GetErrorString unless defined $ccresponse;
218 $self->result_code($ccresponse->GetResponseCode);
219 $self->avs_code($ccresponse->GetAVSCode);
220 $self->order_number($ccresponse->GetOrderId);
222 if ( $self->result_code == 1 ) { # eq '1' ?
223 $self->is_success(1);
224 #$self->authorization($ccresponse->GetBankApprovalCode);
225 $self->authorization($ccresponse->GetReferenceId); #"Identifier for follow-on transactions"
227 $self->is_success(0);
228 $self->error_message($ccresponse->GetResponseCodeText);
233 ## print "ResponseCode : ", $ccresponse->GetResponseCode, "\n";
234 ## print "ResponseCodeText : ", $ccresponse->GetResponseCodeText, "\n";
235 # print "Timestamp : ", $datetime, "\n";
236 # print "IsoCode : ", $ccresponse->GetIsoCode, "\n";
237 ## print "OrderId : ", $ccresponse->GetOrderId, "\n";
238 ## print "BankApprovalCode : ", $ccresponse->GetBankApprovalCode, "\n";
239 # print "State : ", $ccresponse->GetState, "\n";
240 # print "AuthorizedAmount : ", $ccresponse->GetAuthorizedAmount, "\n";
241 # print "OriginalAuthorizedAmount: ", $ccresponse->GetOriginalAuthorizedAmount,
243 # print "CapturedAmount : ", $ccresponse->GetCapturedAmount, "\n";
244 # print "CreditedAmount : ", $ccresponse->GetCreditedAmount, "\n";
245 # print "TimeStampCreated : ", $ccresponse->GetTimeStampCreated, "\n";
246 ## print "ReferenceId : ", $ccresponse->GetReferenceId, "\n";
247 # print "BankTransactionId : ", $ccresponse->GetBankTransactionId, "\n";
248 # print "BatchId : ", $ccresponse->GetBatchId, "\n";
249 # #print "AVS Code : ", $ccresponse->GetAVSCode, "\n";
251 #this is different from a "normal" B:OP revmap, it sets things in $ccreq
253 my($self, $ccreq, %map) = @_;
254 my %content = $self->content();
256 my $method = "Set$_";
257 my $content = ref($map{$_}) ? ${ $map{$_} } : $content{$map{$_}};
258 $ccreq->$method($content);
268 Business::OnlinePayment::PPIPayMover - PPI PayMover backend for Business::OnlinePayment
272 use Business::OnlinePayment;
274 my $tx = new Business::OnlinePayment( 'PPIPayMover' );
277 login => '195325FCC230184964CAB3A8D93EEB31888C42C714E39CBBB2E541884485D04B', #token
279 action => 'Normal Authorization',
280 description => 'Business::OnlinePayment test',
282 invoice_number => '100100',
283 customer_id => 'jsk',
284 name => 'Grub Tetris',
285 address => '123 Anystreet',
289 email => 'ivan-ppipaymover@420.am',
290 card_number => '4007000000027',
291 expiration => '09/12',
295 if($tx->is_success()) {
296 print "Card processed successfully: ".$tx->authorization."\n";
298 print "Card was rejected: ".$tx->error_message."\n";
301 =head1 SUPPORTED TRANSACTION TYPES
303 =head2 Visa, MasterCard, American Express, JCB, Discover/Novus, Carte blanche/Di
308 For detailed information see L<Business::OnlinePayment>.
314 Ivan Kohler <ivan-ppipaymover@420.am>
316 =head1 COPYRIGHT AND LICENSE
318 Based on API components from PPI PayMover provided without clear licensing, so,
319 probably not freely licensable at the moment... assuming that can be resolved:
321 Business::OnlinePayment conversion copyright (c) 2006 Ivan Kohler
322 All rights reserved. This program is free software; you can redistribute it
323 and/or modify it under the same terms as Perl itself.
327 perl(1), L<Business::OnlinePayment>.