From e4ba988a963aa70a0d0f7ac370b45c3b1d16a853 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 1 Apr 2004 14:30:22 +0000 Subject: [PATCH 1/1] initial import --- BusinessOnlinePayment.pm | 302 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 302 insertions(+) create mode 100644 BusinessOnlinePayment.pm diff --git a/BusinessOnlinePayment.pm b/BusinessOnlinePayment.pm new file mode 100644 index 0000000..63e8c96 --- /dev/null +++ b/BusinessOnlinePayment.pm @@ -0,0 +1,302 @@ +# Vend::Payment::BusinessOnlinePayment - Interchange wrapper for +# Business::OnlinePayment modules +# +# Copyright (C) 2004 Ivan Kohler. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify it +# under the same terms as Perl itself. +# +# Ivan Kohler + +package Vend::Payment::BusinessOnlinePayment; + +=head1 NAME + +Vend::Payment::BusinessOnlinePayment - Interchange wrapper for Business::OnlinePayment + +=head1 SYNOPSIS + + &charge=onlinepayment + + or + + [charge mode=onlinepayment param1=value1 param2=value2] + +=head1 PREREQUISITES + + Business::OnlinePayment + Business::OnlinePayment:: gateway module + + See L or + L + +=head1 DESCRIPTION + +This is a wrapper around Business::OnlinePayment for Interchange. + +The Vend::Payment::BusinessOnlinePayment module implements the onlinepayment() +routine for use with Interchange. It is compatible on a call level with the +other Interchange payment modules. In theory (and even usually in practice) +you could switch from another gateway to a Business::OnlinePayment supported +gateway (or between different Business::OnlinePayment gateways) with a few +configuration file changes. + +Business::OnlinePayment is a set of related Perl modules for processing online +payments (credit cards, electronic checks, and other payment systems). It +provides a consistant interface for processing online payments, regardless of +the gateway backend being used, in the same way that DBI provides an consistant +interface to different databases. + +See L for more information and +supported gateways. + +It is hoped that a future version of Interchange will do all credit card +processing through Business::OnlinePayment, but this is my no means +guaranteed and the timeframe is unknown. Think ALSA somewhere around +Linux 2.2 and you've got the general idea. + +Currently this module is recommended for people with gateway processors +unsupported by a native Interchange Vend::Payment:: module and for the +adventurous. + +=head1 USAGE + +To enable this module, place this directive in C: + + Require module Vend::Payment::BusinessOnlinePayment + +This I be in interchange.cfg or a file included from it. + +The mode can be named anything, but the C parameter must be set +to C. To make it the default payment gateway for all credit +card transactions in a specific catalog, you can set in C: + + Variable MV_PAYMENT_MODE onlinepayment + +It uses several of the standard settings from Interchange payment. Any time +we speak of a setting, it is obtained either first from the tag/call options, +then from an Interchange order Route named for the mode, then finally a +default global payment variable, For example, the C parameter would +be specified by: + + [charge mode=onlinepayment setting=value] + +or + + Route onlinepayment setting value + +or + + Variable MV_PAYMENT_SETTING value + +The following settings are available: + +=over 4 + +=item processor + +Your Business::OnlinePayment processor. + +=item id + +Your Business::OnlinePayment login. + +=item secret + +Your Busienss::OnlinePayment password. + +=item transaction + +The type of transaction to be run. Valid values are: + + Interchange Business::OnlinePayment + ---------------- ----------------------- + auth Authorization Only + return Credit + reverse + sale Normal Authorization + settle Post Authorization + void Void + +=item test + +Set this true if you wish to operate in test mode. Make sure to verify +that your specific Business::OnlinePayment:: gateway module supports a +test mode. + +=back + +In addition, any other processor options are passed to your gateway. See +the documentation for your specific Business::OnlinePayment:: gateway module +for details on what options are required, if any. + +=head1 AUTHOR + +Ivan Kohler + +=cut + +package Vend::Payment; +use strict; +use vars qw( $VERSION ); +use Business::OnlinePayment; + +$VERSION = '0.01'; + +my $default_avs = q{You must enter the correct billing address of your credit }. + q{card. The bank returned the following error: %s}; + +my $default_declined = "error: %s. Please call in your order or try again."; + +sub onlinepayment { + my ($user, $amount) = @_; + + my $opt = {}; + my $secret; + + if ( ref($user) ) { + $opt = $user; + $user = $opt->{id}; + $secret = $opt->{secret}; + } + + my $actual = $opt->{actual} || { map_actual() }; + + $user ||= charge_param('id') + or return ( MStatus => 'failure-hard', + MErrMsg => errmsg('No account id'), + ); + + $secret ||= charge_param('secret'); + + my $precision = $opt->{precision} || 2; + + my $referer = $opt->{referer} || charge_param('referer'); + + $actual->{$_} = $opt->{$_} + foreach grep defined($opt->{$_}), qw( + order_id + auth_code + mv_credit_card_exp_month + mv_credit_card_exp_year + mv_credit_card_number + ); + + $actual->{mv_credit_card_exp_month} =~ s/\D//g; + $actual->{mv_credit_card_exp_year} =~ s/\D//g; + $actual->{mv_credit_card_exp_year} =~ s/\d\d(\d\d)/$1/; + $actual->{mv_credit_card_number} =~ s/\D//g; + + my $exp = sprintf '%02d/%02d', $actual->{mv_credit_card_exp_month}, + $actual->{mv_credit_card_exp_year}; + + my %ic2bop = ( + 'auth' => 'Authorization Only', + 'return' => 'Credit', + #'reverse' => + 'sale' => 'Normal Authorization', + 'settle' => 'Post Authorization', + 'void' => 'Void', + ); + + my $action = $ic2bop{$opt->{transaction} || 'sale'}; + + $amount = $opt->{total_cost} if $opt->{total_cost}; + + if ( ! $amount ) { + $amount = Vend::Interpolate::total_cost(); + $amount = Vend::Util::round_to_frac_digits($amount, $precision); + } + + my $order_id = gen_order_id($opt); + + my $processor = charge_param('processor'); + + #processor options! + my %ignore = map { $_=>1 } qw(gateway processor id secret transaction ); + my %options = map { $_=>1 } + grep { !$ignore{$_} } ( + keys(%$opt), + map { s/^MV_PAYMENT_//; lc($_); } + grep { /^MV_PAYMENT_/ } + keys %$main::Variable + ); + + my $transaction = + new Business::OnlinePayment ( $processor, %options ); + + $transaction->test_transaction($opt->{test} || charge_param('test')); + + $actual->{$_} =~ s/[\n\r]//g foreach keys %$actual; + + $transaction->content( + 'type' => 'CC', + 'login' => $user, + 'password' => $secret, + 'action' => $action, + #'description' + 'amount' => $amount, + 'card_number' => $actual->{mv_credit_card_number}, + 'expiration' => $exp, + 'cvv2' => $actual->{cvv2}, + 'order_number' => $actual->{order_id}, + 'auth_code' => $actual->{auth_code}, + #'recurring_billing' + 'invoice_number' => $actual->{mv_order_number}, + #'customer_id' + 'last_name' => $actual->{b_lname}, + 'first_name' => $actual->{b_fname}, + 'name' => $actual->{b_fname}. ' '. $actual->{b_lname}, + 'company' => $actual->{b_company}, + 'address' => $actual->{b_address}, + 'city' => $actual->{b_city}, + 'state' => $actual->{b_state}, + 'zip' => $actual->{b_zip}, + 'country' => $actual->{b_country}, + 'ship_last_name' => $actual->{lname}, + 'ship_first_name' => $actual->{fname}, + 'ship_name' => $actual->{fname}. ' '. $actual->{lname}, + 'ship_company' => $actual->{company}, + 'ship_address' => $actual->{address}, + 'ship_city' => $actual->{city}, + 'ship_state' => $actual->{state}, + 'ship_zip' => $actual->{zip}, + 'ship_country' => $actual->{country}, + 'referer' => $referer, + 'email' => $actual->{email}, + 'phone' => $actual->{phone_day}, + ); + + $transaction->submit(); + + my %result; + if ( $transaction->is_success() ) { + + $result{MStatus} = 'success'; + $result{'order-id'} = $transaction->order_number || $opt->{'order_id'}; + + } else { + + $result{MStatus} = 'failure'; + delete $result{'order-id'}; + + if ( 0 ) { #need a standard Business::OnlinePayment way to ask about AVS + $result{MErrMsg} = errmsg( + $opt->{'message_avs'} || $default_avs, + $transaction->error_message + ) + } else { + $result{MErrMsg} = errmsg( + $opt->{'message_declined'} || "$processor $default_declined", + $transaction->error_message + ); + } + + } + + return %result; + +} + +1; + -- 2.11.0