[open-ils-commits] SPAM: r9321 -
trunk/Open-ILS/src/perlmods/OpenILS/Application
svn at svn.open-ils.org
svn at svn.open-ils.org
Sun Apr 13 09:10:16 EDT 2008
Author: erickson
Date: 2008-04-13 08:32:26 -0400 (Sun, 13 Apr 2008)
New Revision: 9321
Added:
trunk/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm
Log:
initial credit card and paypal processing code. this still needs some refactoring to accomodate the staff and patron workflows.
Added: trunk/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm
===================================================================
--- trunk/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm (rev 0)
+++ trunk/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm 2008-04-13 12:32:26 UTC (rev 9321)
@@ -0,0 +1,304 @@
+# --------------------------------------------------------------------
+# Copyright (C) 2008 Niles Ingalls
+# Niles Ingalls <nilesi at zionsville.lib.in.us>
+# Bill Erickson <erickson at esilibrary.com>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+# --------------------------------------------------------------------
+package OpenILS::Application::CreditCard;
+use base qw/OpenSRF::Application/;
+use strict; use warnings;
+
+use DateTime;
+use DateTime::Format::ISO8601;
+use OpenILS::Application::AppUtils;
+use OpenSRF::Utils qw/:datetime/;
+use OpenILS::Event;
+use OpenSRF::EX qw(:try);
+use OpenSRF::Utils::Logger qw(:logger);
+use OpenILS::Utils::Fieldmapper;
+use OpenILS::Utils::CStoreEditor q/:funcs/;
+use OpenILS::Const qw/:const/;
+use OpenSRF::Utils::SettingsClient;
+use Business::CreditCard;
+use Business::CreditCard::Object;
+use Business::OnlinePayment;
+
+
+__PACKAGE__->register_method(
+ method => 'process_payment',
+ api_name => 'open-ils.credit.process',
+ signature => {
+ desc => 'Creates a new provider',
+ params => [
+ { desc => 'Authentication token', type => 'string' },
+ { desc => q/Hash of arguments. Options include:
+ XXX add docs as API stablilizes...
+ /, type => 'hash' }
+ ],
+ return => { desc => 'Hash of status information', type=>'hash' }
+ }
+);
+
+sub process_payment {
+ my $self = shift;
+ my $client = shift;
+ my $argshash = shift;
+
+ my $e = new_editor();
+ my $patron = $e->retrieve_actor_user(
+ [
+ $argshash->{patron_id},
+ {
+ flesh => 1,
+ flesh_fields => { au => ["mailing_address"] }
+ }
+ ]
+ ) or return $e->event;
+
+ return OpenILS::Event->new('BAD_PARAMS')
+ unless $argshash->{login}
+ and $argshash->{password}
+ and $argshash->{action};
+
+ if ( $argshash->{processor} eq 'PayPal' ) {
+ # XXX not ready for prime time
+ return handle_paypal($e, $argshash, $patron);
+
+ } elsif ( $argshash->{processor} eq 'AuthorizeNet' ) {
+ return handle_authorizenet($e, $argshash, $patron);
+ }
+}
+
+sub handle_paypal {
+ my($e, $argshash, $patron) = @_;
+
+ require Business::PayPal::API;
+ require Business::OnlinePayment::PayPal;
+ my $card = Business::CreditCard::Object->new( $argshash->{cc} );
+
+ $logger->debug("applying paypal payment");
+
+ if ( !$card->is_valid ) {
+ return {
+ statusText => "should return address:(patron_id):",
+ processor => $argshash->{processor},
+ testmode => $argshash->{testmode},
+ card => $card->number(),
+ expiration => $argshash->{expiration},
+ name => $patron->first_given_name,
+ patron_id => $patron->id,
+ patron_patron_id => $patron->mailing_address,
+ statusCode => 500
+ };
+ }
+
+ my $type = $card->type();
+
+ if ( substr( $type, -5, 5 ) =~ / card/ ) {
+ $type = substr( $type, 0, -5 );
+ }
+
+ my $transaction = Business::OnlinePayment->new(
+ $argshash->{processor},
+ "Username" => $argshash->{PayPal_Username},
+ "Password" => $argshash->{PayPal_Password},
+ "Signature" => $argshash->{PayPal_Signature}
+ );
+
+ $transaction->content(
+ action => $argshash->{action},
+ amount => $argshash->{amount},
+ type => "$type",
+ card_number => $card->number(),
+ expiration => $argshash->{expiration},
+ cvv2 => $argshash->{cvv2},
+ name => $patron->first_given_name . ' ' . $patron->family_name,
+ address => $patron->mailing_address->street1,
+ city => $patron->mailing_address->city,
+ state => $patron->mailing_address->state,
+ zip => $patron->mailing_address->post_code
+ );
+
+ $transaction->test_transaction(1); # XXX
+ $transaction->submit;
+
+ if ( $transaction->is_success ) {
+ return {
+ statusText => "Card approved: ".$transaction->authorization,
+ statusCode => 200,
+ approvalCode => $transaction->authorization,
+ CorrelationID => $transaction->correlationid
+ };
+
+ } else {
+ return {
+ statusText => "Card declined: " . $transaction->error_message,
+ statusCode => 500
+
+ };
+ }
+}
+
+sub handle_authorizenet {
+ my($e, $argshash, $patron) = @_;
+
+ require Business::OnlinePayment::AuthorizeNet;
+ my $card = Business::CreditCard::Object->new( $argshash->{cc} );
+
+ $logger->debug("applying authorize.net payment");
+
+ if ( ! $card->is_valid ) {
+ $logger->warn("authorize.net card number is invalid");
+
+ return {
+ statusText => "should return address:(patron_id):",
+ processor => $argshash->{processor},
+ testmode => $argshash->{testmode},
+ card => $card->number(),
+ expiration => $argshash->{expiration},
+ name => $patron->first_given_name,
+ patron_id => $patron->id,
+ patron_patron_id => $patron->mailing_address,
+ statusCode => 500
+ };
+ }
+
+ my $type = $card->type();
+
+ if ( substr( $type, -5, 5 ) =~ / card/ ) {
+ $type = substr( $type, 0, -5 );
+ }
+
+ my $transaction = new Business::OnlinePayment(
+ $argshash->{processor}, 'test_transaction' => $argshash->{testmode});
+
+ $transaction->content(
+ type => "$type", #'American Express', 'VISA', 'MasterCard'
+ login => $argshash->{login},
+ password => $argshash->{password},
+ action => $argshash->{action},
+ description => $argshash->{description},
+ amount => $argshash->{amount},
+ card_number => $card->number(),
+ expiration => $argshash->{expiration},
+ cvv2 => $argshash->{cvv2},
+ first_name => $patron->first_given_name,
+ last_name => $patron->family_name,
+ address => $patron->mailing_address->street1,
+ city => $patron->mailing_address->city,
+ state => $patron->mailing_address->state,
+ zip => $patron->mailing_address->post_code,
+ customer_id => $patron->id
+ );
+
+ $transaction->submit();
+
+ if ( $transaction->is_success() ) {
+ $logger->info("authorize.net payment succeeded");
+ return {
+ statusText => "Card approved: "
+ . $transaction->authorization,
+ statusCode => 200,
+ approvalCode => $transaction->authorization,
+ server_response => $transaction->server_response
+
+ };
+
+ } else {
+ $logger->info("authorize.net card declined");
+ return {
+ statusText => "Card decliined: " . $transaction->error_message,
+ statusCode => 500,
+ approvalCode => $transaction->error_message,
+ server_response => $transaction->server_response
+ };
+ }
+}
+
+
+__PACKAGE__->register_method(
+ method => 'retrieve_payable_balance',
+ api_name => 'open-ils.credit.payable_balance.retrieve',
+ signature => {
+ desc => '',
+ params => [
+ { desc => 'Authentication token', type => 'string' },
+ { desc => 'Authentication token', type => 'string' },
+ { desc => 'User id', type => 'number' }
+ ],
+ return => { desc => 'The ID of the new provider' }
+ }
+);
+
+sub retrieve_payable_balance {
+ my ( $self, $conn, $auth, $user_id ) = @_;
+ my $e = new_editor( authtoken => $auth );
+ return $e->event unless $e->checkauth;
+
+ if ( $e->requestor->id != $user_id ) {
+ # XXX check perm
+ }
+
+ my $circ_orgs = $e->json_query({
+ "select" => { "circ" => ["circ_lib"] },
+ from => "circ",
+ "where" => { "usr" => $user_id, xact_finish => undef },
+ distinct => 1
+ });
+
+ my $groc_orgs = $e->json_query({
+ "select" => { "mg" => ["billing_location"] },
+ from => "mg",
+ "where" => { "usr" => $user_id, xact_finish => undef },
+ distinct => 1
+ });
+
+ my %hash;
+ my @orgs;
+ for my $org ( @$circ_orgs, @$groc_orgs ) {
+ my $o = $org->{billing_location};
+ $o = $org->{circ_lib} unless $o;
+ next if $hash{$org};
+ $hash{$o} =
+ OpenILS::Application::AppUtils->simplereq( 'open-ils.actor',
+ 'open-ils.actor.ou_setting.ancestor_default',
+ $o, 'credit.allow' );
+ }
+
+ my @credit_orgs = map { $hash{$_} ? ($_) : () } keys %hash;
+
+ my $xact_summaries =
+ OpenILS::Application::AppUtils->simplereq( 'open-ils.actor',
+ 'open-ils.actor.user.transactions.have_charge',
+ $auth, $user_id );
+
+ my $sum = 0.0;
+
+ for my $xact (@$xact_summaries) {
+
+ # make two lists and grab them in batch XXX
+ if ( $xact->xact_type eq 'circulation' ) {
+ my $circ =
+ $e->search_action_circulation( { id => $xact->id } )->[0];
+ next unless grep { $_ == $circ->circ_lib } @credit_orgs;
+ }
+ else {
+ my $bill = $e->search_money_grocery( { id => $xact } )->[0];
+ next unless grep { $_ == $bill->billing_location } @credit_orgs;
+ }
+ $sum += $xact->ballance_owed();
+ }
+
+ return $sum;
+}
+
+1;
More information about the open-ils-commits
mailing list