1 # Vend::Payment::TCLink - Interchange TrustCommerce TCLink support
3 # $Id: TCLink.pm,v 1.10 2009-03-16 19:34:01 jon Exp $
5 # Copyright (C) 2002-2007 Interchange Development Group
6 # Copyright (C) 2002 TrustCommerce <developer@trustcommerce.com>
8 # by Dan Helfman <dan@trustcommerce.com> with code reused and inspired by
9 # Mark Stosberg <mark@summersault.com>
11 # webmaster@nameastar.net
12 # Jeff Nappi <brage@cyberhighway.net>
13 # Paul Delys <paul@gi.alaska.edu>
15 # This program is free software; you can redistribute it and/or modify
16 # it under the terms of the GNU General Public License as published by
17 # the Free Software Foundation; either version 2 of the License, or
18 # (at your option) any later version.
20 # This program is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 # GNU General Public License for more details.
25 # You should have received a copy of the GNU General Public
26 # License along with this program; if not, write to the Free
27 # Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
30 package Vend::Payment::TCLink;
34 Vend::Payment::TCLink - Interchange TrustCommerce Support
42 [charge mode=trustcommerce param1=value1 param2=value2]
48 http://www.trustcommerce.com/tclink.html and CPAN both have this module,
49 which actually does the bulk of the work. All that Vend::Payment::TCLink
50 does is to massage the payment data between Interchange and Net::TCLink.
54 The Vend::Payment::TCLink module implements the trustcommerce() routine
55 for use with Interchange. It is compatible on a call level with the other
56 Interchange payment modules.
58 To enable this module, place this directive in C<interchange.cfg>:
60 Require module Vend::Payment::TCLink
62 This I<must> be in interchange.cfg or a file included from it.
64 Make sure CreditCardAuto is off (default in Interchange demos).
66 The mode can be named anything, but the C<gateway> parameter must be set
67 to C<trustcommerce>. To make it the default payment gateway for all credit
68 card transactions in a specific catalog, you can set in C<catalog.cfg>:
70 Variable MV_PAYMENT_MODE trustcommerce
72 It uses several of the standard settings from Interchange payment. Any time
73 we speak of a setting, it is obtained either first from the tag/call options,
74 then from an Interchange order Route named for the mode, then finally a
75 default global payment variable, For example, the C<id> parameter would
78 [charge mode=trustcommerce id=YourTrustCommerceID]
82 Route trustcommerce id YourTrustCommerceID
86 Variable TRUSTCOMMERCE_ID YourTrustCommerceID
88 The active settings are:
94 Your TrustCommerce customer ID, supplied by TrustCommerce when you sign up.
95 Global parameter is TRUSTCOMMERCE_ID.
99 Your TrustCommerce customer password, supplied by TrustCommerce when you
100 sign up. Global parameter is TRUSTCOMMERCE_SECRET.
104 The type of transaction to be run. Valid values are:
106 Interchange TrustCommerce
107 ---------------- -----------------
113 Global parameter is TRUSTCOMMERCE_ACTION.
117 Whether AVS (Address Verification System) is enabled. Valid values are "y"
118 for enabled and "n" for disabled. Global parameter is TRUSTCOMMERCE_AVS.
122 This remaps the form variable names to the ones needed by TrustCommerce. See
123 the C<Payment Settings> heading in the Interchange documentation for use.
127 Set this to C<TRUE> if you wish to operate in test mode, i.e. set the
128 TrustCommerce C<demo> query paramter to TRUE.
132 Route trustcommerce test TRUE
134 Variable TRUSTCOMMERCE_TEST TRUE
136 [charge mode=trustcommerce test=TRUE]
140 =head2 Troubleshooting
142 Try the instructions above, then enable test mode. A test order should complete.
144 Disable test mode, then test in various TrustCommerce error modes by
145 using the credit card number 4222 2222 2222 2222.
147 Then try a sale with the card number C<4111 1111 1111 1111>
148 and a valid expiration date. The sale should be denied, and the reason should
149 be in [data session payment_error].
157 Make sure you "Require"d the module in interchange.cfg:
159 Require module Vend::Payment::TrustCommerce
163 Make sure Net::TCLink is installed and working. You can test to see
164 whether your Perl thinks they are:
166 perl -MNet::TCLink -e 'print "It works.\n"'
168 If it "It works." and returns to the prompt you should be OK (presuming
169 they are in working order otherwise).
173 Check the error logs, both catalog and global.
177 Make sure you set your payment parameters properly.
181 Try an order, then put this code in a page:
185 my $string = $Tag->uneval( { ref => $Session->{payment_result} });
187 $string =~ s/,/,\n/g;
192 That should show what happened.
196 If all else fails, TrustCommerce consultants are available to help you out.
198 See http://www.trustcommerce.com/contact.html for more information, or email
199 developer@trustcommerce.com
205 There is actually nothing *in* Vend::Payment::TrustCommerce. It changes
206 packages to Vend::Payment and places things there.
210 Dan Helfman <dan@trustcommerce.com>, based on code by Mark Stosberg
211 <mark@summersault.com>, which was based on original code by Mike Heins.
215 webmaster@nameastar.net
216 Jeff Nappi <brage@cyberhighway.net>
217 Paul Delys <paul@gi.alaska.edu>
223 package Vend::Payment;
224 require Net::TCLink or die __PACKAGE__ . " requires Net::TCLink";
227 ::logGlobal("%s payment module initialized", __PACKAGE__)
228 unless $Vend::Quiet or ! $Global::VendRoot;
231 package Vend::Payment;
234 my ($user, $amount) = @_;
239 $user = $opt->{id} || $::Variable->{TRUSTCOMMERCE_ID} || undef;
240 $secret = $opt->{secret} || $::Variable->{TRUSTCOMMERCE_SECRET} || undef;
248 $actual = $opt->{actual};
251 my (%actual) = map_actual();
255 #::logGlobal("actual map result: " . ::uneval($actual));
257 $user = charge_param('id')
259 MStatus => 'failure-hard',
260 MErrMsg => errmsg('No customer id'),
264 $secret = charge_param('secret') if ! $secret;
266 my $precision = $opt->{precision} || 2;
268 my $referer = $opt->{referer}
269 || charge_param('referer');
271 $actual->{mv_credit_card_exp_month} =~ s/\D//g;
272 $actual->{mv_credit_card_exp_year} =~ s/\D//g;
273 $actual->{mv_credit_card_exp_year} =~ s/\d\d(\d\d)/$1/;
274 $actual->{mv_credit_card_number} =~ s/\D//g;
275 $actual->{b_zip} =~ s/\D//g;
277 my $exp = sprintf '%02d%02d', $actual->{mv_credit_card_exp_month},
278 $actual->{mv_credit_card_exp_year};
280 my $transtype = $opt->{transaction} || $::Variable->{TRUSTCOMMERCE_ACTION};
281 $transtype ||= 'sale';
285 authorize => 'preauth',
286 mauthcapture => 'sale',
287 mauthonly => 'preauth',
290 settle => 'postauth',
291 settle_prior => 'postauth',
294 if (defined $type_map{$transtype}) {
295 $transtype = $type_map{$transtype};
298 $amount = $opt->{total_cost} if $opt->{total_cost};
301 $amount = Vend::Interpolate::total_cost();
302 $amount = Vend::Util::round_to_frac_digits($amount,$precision);
306 $order_id = gen_order_id($opt);
308 $name = $actual->{b_fname} . ' ' . $actual->{b_lname};
310 $avs = $opt->{avs} || $::Variable->{TRUSTCOMMERCE_AVS} || 'n';
314 cc => $actual->{mv_credit_card_number},
316 demo => $opt->{test} || charge_param('test') || $::Variable->{TRUSTCOMMERCE_TEST},
318 address1 => $actual->{b_address},
319 city => $actual->{b_city},
320 state => $actual->{b_state},
321 zip => $actual->{b_zip},
322 country => $actual->{b_country},
323 action => $transtype,
324 transid => $actual->{order_id},
325 email => $actual->{email},
326 phone => $actual->{phone_day},
332 # delete query keys with undefined values
334 delete $query{$_} unless $query{$_};
336 delete $query{country} if $query{country} eq 'US';
338 #::logGlobal("trustcommerce query: " . ::uneval(\%query));
340 my %result = Net::TCLink::send(\%query);
342 # Interchange names are on the left, TCLink on the right
343 my %result_map = ( qw/
351 #::logGlobal("trustcommerce response: " . ::uneval(\%result));
353 for (keys %result_map) {
354 $result{$_} = $result{$result_map{$_}}
355 if defined $result{$result_map{$_}};
358 if ($result{status} eq 'approved') {
359 $result{MStatus} = 'success';
362 $result{MStatus} = 'failure';
363 delete $result{'order-id'};
365 # NOTE: A lot more AVS codes could be checked for here.
366 if ($result{avs} eq 'N') {
367 my $msg = q{You must enter the correct billing address of your credit card.};
368 $result{MErrMsg} = errmsg($msg);
371 my $msg = "TrustCommerce error: %s. Please call in your order or try again.";
372 $result{MErrMsg} = errmsg($msg);
376 #::logGlobal("result given to interchange " . ::uneval(\%result));
381 package Vend::Payment::TCLink;