153 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
			
		
		
	
	
			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;
 |