discourse-legacysite-perl/site/slowtwitch.com/cgi-bin/articles/admin/Links/Payment/Direct/Moneris.pm
2024-06-17 21:49:12 +10:00

153 lines
5.5 KiB
Perl

# ==================================================================
# Gossamer Links - enhanced directory management system
#
# Website : http://gossamer-threads.com/
# Support : http://gossamer-threads.com/scripts/support/
# CVS Info : 087,071,086,086,085
# Revision : $Id: Moneris.pm,v 1.2 2005/03/05 01:29:09 brewt Exp $
#
# Copyright (c) 2003 Gossamer Threads Inc. All Rights Reserved.
# Redistribution in part or in whole strictly prohibited. Please
# see LICENSE file for full details.
# ==================================================================
#
# Glue between Gossamer Links and Moneris payment interface
package Links::Payment::Direct::Moneris;
use strict;
# Make sure the payment module is available
use GT::Payment::Direct::Moneris 1.007; # CVS Versions < 1.7 were for the old, defunct Moneris payment system
use Links qw/$IN $CFG $DB/;
use vars qw/%INVALID %EMPTY/;
my @FIELDS = (
keys %GT::Payment::Direct::Moneris::NAME_MAP,
qw/ credit_card_number credit_card_expiry_month credit_card_expiry_year
billing_country billing_email charge_total/
);
sub required {
# -----------------------------------------------------------------------------
# Returns a list of required field names. Each field name will be looked for
# in the language file, prefixed with 'PAYMENT_DIRECT_Moneris_', for the title
# of the field, and 'PAYMENT_DIRECT_DESC_Moneris_' for a description of the
# field's contents.
# Note that these are just required SETUP fields, so things like credit card
# number, billing name, etc. are NOT included.
return
account_token => { type => 'TEXT', valid => '^\w+$' },
account_token2 => { type => 'TEXT', valid => '^\w+$' };
}
sub optional {
return
test_mode => { type => 'YESNO' }
}
sub payment_info {
# -----------------------------------------------------------------------------
# Returns a hash of various parameters used to figure out how to display the
# payment form for this payment method.
return {
fields => [
grep ! /^(?:account|capture|currency|test)/, @FIELDS
],
no_cc_brand => 1
};
}
sub verify {
# -----------------------------------------------------------------------------
# Checks that $IN, combined with the saved admin settings, makes up all of the
# required information. Returns 1 on success, or an array ref of invalid and
# empty keys array references (i.e. [\@invalid, \@empty]) on failure.
_collect_data();
if (keys %INVALID or keys %EMPTY) {
my ($i, %order);
for (@{$GT::Payment::Direct::Moneris::REQUIRED{AUTHORIZE}}) { $order{$_} = $i++ }
return [ # Error
[sort { ($order{$a} || 0x7fff_ffff) <=> ($order{$b} || 0x7fff_ffff) } keys %INVALID],
[sort { ($order{$a} || 0x7fff_ffff) <=> ($order{$b} || 0x7fff_ffff) } keys %EMPTY]
];
}
else {
return 1; # Success
}
}
sub complete {
# -----------------------------------------------------------------------------
# Checks that $IN, combined with the saved admin settings, makes up all of the
# required information. Returns (1, $message) on success, (0, $reason) on
# declined, or (-1, $errormsg) on error.
my $pay = _collect_data() or return;
# Set the admin-specified fields
while (my ($k, $v) = each %{$CFG->{payment}->{direct}->{used}->{Moneris}}) {
$pay->$k($v) or return (-1, "Payment configuration error (Invalid $k)");
}
$pay->check('sale') or return (-1, $pay->error);
my $ret = $pay->sale;
if (not defined $ret) { # An error occured in the module
return (-1, $pay->error);
}
else { # The request at least got through to Moneris
if ($ret == 1) { # Approved!
my $resp_text;
my @receipt = $pay->receipt();
my $receipt = "Transaction approved\n\n";
while (@receipt) {
my ($k, $v) = splice @receipt, 0, 2;
$receipt .= "$k: $v\n";
$resp_text = $v if $k eq 'Status';
}
return (1, $resp_text, $receipt);
}
elsif ($ret == 0) { # Declined
return (0, $pay->error);
}
else { # An error was generated by Moneris
return (-1, $pay->error);
}
}
}
sub _collect_data {
# -----------------------------------------------------------------------------
# Collect data from the payment data saved in the admin, and any valid columns
# in $IN. Anything from $IN is checked for validity, and $INVALID{column} is
# set if invalid.
%INVALID = %EMPTY = ();
return unless $CFG->{payment}->{direct}->{used}->{Moneris};
my %data = %{$CFG->{payment}->{direct}->{used}->{Moneris}};
return unless keys %data;
my $pay = GT::Payment::Direct::Moneris->new(debug_level => $CFG->{debug});
my %required = map { $_ => 1 } @{$GT::Payment::Direct::Moneris::REQUIRED{AUTHORIZE}};
for my $field (@FIELDS) {
# The account_*, capture_*, currency_*, etc. fields should not be user-settable.
next if exists $data{$field} or $field =~ /^(?:account|capture|currency|test)/;
if (my $value = $IN->param($field)) {
if ($pay->$field($value)) {
$data{$field} = $value;
}
else {
$INVALID{$field}++;
$data{$field} = undef;
}
}
elsif ($required{$field}) {
$EMPTY{$field}++;
$data{$field} = undef;
}
}
return if keys %INVALID or keys %EMPTY;
return $pay;
}
1;