package HBCU::Payment;

use warnings;
use strict;

use CGI;
use HBCU::Database;
use SimLib;

require './lib/config.pl';

our $VERSION = '0.01';

for my $data ( qw(
		  payment_url
		  redirect_name
		  redirect_url
		  db
		  transaction
		  visa
		  mastercard
		  amex
		  testing
		  mailprog
		 ) ) {
  no strict "refs";
  *$data = sub {
    my $self = shift;
    $self->{uc $data} = shift if @_;
    return $self->{uc $data};
  }
}

my $q = new CGI;
my $config = &getConfiguration();


################################################################################
sub new {
  my $invocant = shift;
  my %params = @_;

  $invocant = ref $invocant || $invocant;

  my $self = {
	      PAYMENT_URL => &getConfigValue('ROOT_URL') . &getConfigValue('SECURE_PAY_URL'),
	      REDIRECT_NAME => &getConfigValue('SITE'),
	      REDIRECT_URL => &getConfigValue('ROOT_URL'),
	      DB => HBCU::Database->new,
              TRANSACTION => undef,
	      VISA => &getConfigValue('VISA'),
	      MASTERCARD => &getConfigValue('MASTERCARD'),
	      AMEX => &getConfigValue('AMEX'),
	      TESTING => 0,
              MAILPROG => '/usr/sbin/sendmail',
             };

  while (my ($k, $v) = each %params) {
    $self->{uc $k} = $v;
  }

  bless($self, $invocant);

  print STDERR "url = ", $self->payment_url, "\n";
  return $self->_init;
}

sub DESTROY {}

sub _init {
  my $self = shift;

  return $self;
}

################################################################################
sub addTransaction {
  my ($self, $params) = @_;

  my $id = $self->db->addTransaction($params);

  $self->transaction( $self->getTransaction($id) );

  return $id;
}

################################################################################
sub getTransaction {
  my ($self, $id) = @_;

  # Get the site wide parameters of interest
  return $self->db->getTransaction({transaction_id => $id});
}

################################################################################
sub markTransactionPaid {
  my ($self, $id) = @_;

  return $self->db->updateTransaction(PARAMS => {paid => 1, date_paid => 'now()'},
				      WHERE => {transaction_id => $id || $self->transaction->{transaction_id}});
}

################################################################################
sub gotoPayment {
  my ($self, $id) = @_;
  my $url = $self->payment_url . '?transaction_id=';

  if ($id) {
    $url .= $id;
  } else {
    $url .= $self->transaction->{transaction_id};
  }

  $url .= ('&redirect=' . $self->redirect_url) if $self->redirect_url;
  $url .= ('&redirect_name=' . $self->redirect_name) if $self->redirect_name;
  $url .= '&testing=1' if $self->testing;

  print $q->redirect($url);
}

################################################################################
sub printPaymentForm {
  my ($self) = @_;
  my $transaction = $self->transaction;
  my $redirect_name = $q->param('redirect_name');
  my $redirect = $q->param('redirect');

  # Prep the redirect
  $redirect = "http://$redirect" unless $redirect =~ /^http/;
  if ($redirect =~ /.+\?.+/) {
    $redirect .= "\&payment_success=1&transaction_id=$transaction->{transaction_id}";
  } else {
    if ($redirect =~ /\/$/) {
      $redirect =~ s/\/$//;
    }
    $redirect .= "\?payment_success=1&transaction_id=$transaction->{transaction_id}";
  }

  print $q->header;

  print qq(
$transaction->{header}
<script language=javascript>

function setMonth() {
  document.payform.x_Exp_Date.value= document.payform.x_Exp_Month[document.payform.x_Exp_Month.selectedIndex].value + document.payform.x_Exp_Year[document.payform.x_Exp_Year.selectedIndex].value
}

function setYear() {
  document.payform.x_Exp_Date.value= document.payform.x_Exp_Month[document.payform.x_Exp_Month.selectedIndex].value + document.payform.x_Exp_Year[document.payform.x_Exp_Year.selectedIndex].value

  msg="Exp Date:"+document.payform.x_Exp_Date.value;
}

function validateForm() {
  if ( document.payform.x_Card_Num.value == '' ) {
    alert('You must enter a valid credit card number!');
    return false;
  }

  return true;
}

function submitOnce()
    {

     if ( validateForm() ) {
       //if IE 4+ or NS 6+
       if (document.all)
        {
          document.payform.Go.disabled=true
          return true;
        }
     } else {
        return false;
     }
    }
</script>
    <table align=center class=data>
      <thead>
	<tr>
	  <th colspan=2>Payment Form</th>
	</tr>
      </thead>
      <form name=payform method=post action="https://secure.authorize.net/gateway/transact.dll" onSubmit="return submitOnce();">

);

  #### Get variables ready for after payment
  foreach my $x ( $q->param('item_id') ) {
    print "<input type=hidden name=x_item_id value=$x>";
  }

  # We need this stuff
  &SimLib::InsertFP('hbcu03', 'dSo3lGKLv6GVvDAf', $transaction->{payment_amount}, 'USD');

  ### if 'testing' is passed in on the query string we don't want a real transaction
  print "<input type=hidden name=\"x_Test_Request\" value=\"TRUE\" />\n" if $self->testing;

  print qq(
	<input type=hidden name="x_Exp_Date" value="" />
	<input type=hidden name="x_Version" value="3.0" />
	<input type=hidden name="x_Login" value="hbcu03" />
	<input type=hidden name="x_ADC_Relay_Response" value="True" />
	<input type=hidden name="x_ADC_URL" value="https://hbcuconnect.com/core/cgi-bin/secure_response.cgi" />
        <input type=hidden name="x_Cust_ID" value="$transaction->{member_id}" />
        <input type=hidden name="x_description" value="$transaction->{payment_description}" />
        <input type=hidden name="x_Amount" value="$transaction->{payment_amount}" />
        <input type=hidden name="x_transaction_id" value="$transaction->{transaction_id}" />
        <input type=hidden name="x_redirect" value="$redirect" />
        <input type=hidden name="x_redirect_name" value="$redirect_name" />
);

  $transaction->{payment_amount} = sprintf("\$%.2f", $transaction->{payment_amount});

print qq(
	<tbody>
	  <tr>
	    <th>
	      Purchase Description :
	    </th>
	    <td>
	      $transaction->{payment_description}
	    </td>
	  </tr>
	  <tr>
	    <th>
	      Amount To Be Billed :
	    </th>
	    <td>
	      <b>$transaction->{payment_amount}</b>
	    </td>
	  </tr>
	  <tr>
	    <th>
	      <font class=required>*</font>First Name On Card :
	    </th>
	    <td>
	      <input type="text" name="x_First_Name" size="30" />
	    </td>
	  </tr>
	  <tr>
	    <th>
	      <font class=required>*</font>Last Name On Card :
	    </th>
	    <td>
	      <input type="text" name="x_Last_Name" size="30" />
	    </td>
	  </tr>
	  <tr>
	    <th>
	      <font class=required>*</font>Billing Address :
	    </th>
	    <td>
	      <input type="text" name="x_address" size="30" />
	    </td>
	  </tr>
	  <tr>
	    <th>
	      <font class=required>*</font>City :
	    </th>
	    <td>
	      <input type="text" name="x_city" size="30" />
	    </td>
	  </tr>
	  <tr>
	    <th>
	      <font class=required>*</font>State/Province :
	    </th>
	    <td>
	      <input type="text" name="x_state" size="30" />
	    </td>
	  </tr>
	  <tr>
	    <th>
	      <font class=required>*</font>Zip/Postal Code :
	    </th>
	    <td>
	      <input type="text" name="x_zip" size="30" />
	    </td>
	  </tr>
	  <tr>
	    <th>
	      <font class=required>*</font>Country :
	    </th>
	    <td>
	      <input type="text" name="x_country" size="30" />
	    </td>
	  </tr>
	  <tr>
	    <th>
	      <font class=required>*</font>Credit Card Type :
	    </th>
	    <td>
	      <input type="radio" name="CardType" value="Visa" checked />
);
  print '<img src="', $self->visa, '" alt="Visa" align="middle">';
  print qq(
	      &nbsp;&nbsp;
	      <input type="radio" name="CardType" value="MasterCard" />
);
  print '<img src="', $self->mastercard, '" alt="MasterCard" align="middle">';
  print qq(
	      &nbsp;&nbsp;
	      <input type="radio" name="CardType" value="Amex" />
);
  print '<img src="', $self->amex, '" alt="American Express" align="middle">';
  print qq(
	    </td>
	  </tr>
	  <tr>
	    <th>
	      <font class=required>*</font>Credit Card Number (No Dashes or Spaces) :
	    </th>
	    <td>
	      <input type="text" name="x_Card_Num" size="30"
);
  print "value='4007000000027'" if $self->testing;
  print qq(
              />
	    </td>
	  </tr>
	  <tr>
	    <th>
	      <font class=required>*</font>Credit Card Expiration :
	    </th>
	    <td>
	      Month:
	      <select Name="x_Exp_Month" onChange=setMonth()>
                <Option Value="" Selected></Option>
                <Option Value="01" >01</Option>
                <Option Value="02">02</Option>
                <Option Value="03">03</Option>
                <Option Value="04">04</Option>
                <Option Value="05">05</Option>
                <Option Value="06">06</Option>
                <Option Value="07">07</Option>
                <Option Value="08">08</Option>
                <Option Value="09">09</Option>
                <Option Value="10">10</Option>
                <Option Value="11">11</Option>
                <Option Value="12">12</Option></select> /

	      Year:
	      <select Name="x_Exp_Year" onChange=setYear()>
                <Option Value="" Selected></Option>
                <Option Value="03">2003</Option>
                <Option Value="04">2004</Option>
                <Option Value="05">2005</Option>
                <Option Value="06">2006</Option>
                <Option Value="07">2007</Option>
                <Option Value="08">2008</Option>
                <Option Value="09">2009</Option>
                <Option Value="10">2010</Option>
                <Option Value="11">2011</Option>
                <Option Value="12">2012</Option>
                <Option Value="13">2013</Option>
                <Option Value="14">2014</Option>
                <Option Value="15">2015</Option>
                <Option Value="16">2016</Option>
                <Option Value="17">2017</Option>
                <Option Value="18">2018</Option>
                <Option Value="19">2019</Option>
	      </select>
	    </td>
	  </tr>
	  <tr class=buttons>
	    <td colspan=2 align=center>
	      <input type="submit" name=Go value="Process Payment">
	    </td>
	  </tr>
	</tbody>
    </table>
    <br />

    <div align=center>
      <b>Please be patient while we verify your payment information<br />
        Allow 15-30 seconds....<font class=required>DO NOT</font> press the payment button twice!</b>
      <br /><br />
      <b>NOTE:</b>
        We does not store any credit card information on our servers.
	Payment processing is handled by a secure protocol transaction with
	the internet's most trusted payment gateway.
    </div>
    <br />
$transaction->{footer}
);
}

################################################################################
sub printPaymentReceipt {
  my ($self) = @_;
  my $transaction = $self->transaction;
  my $response_reason_text = $q->param('x_response_reason_text');
  my $response_reason_code = $q->param('x_response_reason_code');
  my $redirect = $q->param('x_redirect');
  my $redirect_name = $q->param('x_redirect_name');

  print $q->header;

  print qq(
$transaction->{header}
    <table class=data width=100%>
      <thead>
	<tr>
	  <th colspan=2>Payment Processing Center</th>
	</tr>
      </thead>
      <tbody>
	<tr>
          <th>
            RESULTS :
          </th>
          <td>
            $response_reason_text($response_reason_code)
          </td>
        </tr>
	<tr>
          <th>
            Return :
          </th>
          <td>
            <a href=$redirect>:: $redirect_name ::</a>
          </td>
        </tr>
      </tbody>
    </table>
    <br />
$transaction->{footer}
);
}

################################################################################
sub printPaymentError {
  my ($self) = @_;
  my $transaction = $self->transaction;
  my $response_reason_text = $q->param('x_response_reason_text');
  my $response_reason_code = $q->param('x_response_reason_code');

  print $q->header;

  print qq(
$transaction->{header}
    <table class=data width=100%>
      <thead>
	<tr>
	  <th colspan=2>Payment Processing Center</th>
	</tr>
      </thead>
      <tbody>
	<tr>
          <td align=center>
            <br /><br />
            ERROR :
            $response_reason_text($response_reason_code)
            <br /><br /><br />
          </td>
        </tr>
	<tr class=buttons>
          <td align=center>
            <input type=button name=back value="Go Back" onClick="javascript:history.go(-1)">
          </td>
        </tr>
      </tbody>
    </table>
    <br />
$transaction->{footer}
);
}


1;

=pod

=head1 NAME

HBCU::Payment -
Configurable Payment Module


=head1 SYNOPSIS

### In "foo.cgi"...

use HBCU::Payment;

my $payment = HBCU::Payment->new;

my %transaction = {
  member_id => '99999',
  member_type => 'Member',
  payment_type => 'Testing',
  payment_services => 'Testing',
  payment_amount => 9.95,
  payment_description => '$9.95 for Test Transaction',
  payment_site => 9999,
  header => $header,
  footer => $footer,
  date_created => 'now()',
};

$payment->addTransaction(\%transaction);

$payment->testing( 1 );

$payment->redirect_url( 'http://foo.com' );

$payment->redirect_name( 'Foo Bar' );

$payment->gotoPayment;

=head1 INTRODUCTION

HBCU::Payment is intended to make it easy to add payment functionality to a web
application. This module can be used by the Connect Platform to hook in payment
functionality.

=head1 BUGS

None that I am aware of.

=head1 AUTHOR

Larwence Williams (law@hbcuconnect.com)

=head1 COPYRIGHT

This program is the property of HBCUConnect.com

=head1 SEE ALSO

HBCU::Database::CareerCenter
