From 6aa910c2ece9cd5bcae3c45e383c89c0b70539fe Mon Sep 17 00:00:00 2001 From: erickson Date: Mon, 19 Oct 2009 15:44:32 +0000 Subject: [PATCH] Patch from Lebbeous Fogle-Weekley which integrates credit card payments into the existing staff client payment API call. Also updates some unnecessarily long org unit settings names git-svn-id: svn://svn.open-ils.org/ILS/trunk@14492 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- Open-ILS/src/extras/ils_events.xml | 11 ++++++- .../src/perlmods/OpenILS/Application/Circ/Money.pm | 37 +++++++++++++++++++--- .../src/perlmods/OpenILS/Application/CreditCard.pm | 23 +++++++++++--- Open-ILS/src/sql/Pg/002.schema.config.sql | 3 +- Open-ILS/src/sql/Pg/950.data.seed-values.sql | 29 ++++++++++------- .../0038.data.org-setting-credit-default-proc.sql | 35 ++++++++++++++++++++ .../support-scripts/test-scripts/payment_test.pl | 8 +++-- 7 files changed, 120 insertions(+), 26 deletions(-) create mode 100644 Open-ILS/src/sql/Pg/upgrade/0038.data.org-setting-credit-default-proc.sql diff --git a/Open-ILS/src/extras/ils_events.xml b/Open-ILS/src/extras/ils_events.xml index 696d36a3af..56c40da1d8 100644 --- a/Open-ILS/src/extras/ils_events.xml +++ b/Open-ILS/src/extras/ils_events.xml @@ -745,7 +745,16 @@ Not enough parameters to use credit card processor - The credit card processor you have named is not allowed. + The credit card processor you have named is not allowed + + + No credit card processor specified either in org unit settings or in call to credit service API method. + + + No default credit processor is selected + + + The credit card processor has declined the transaction. diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Money.pm b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Money.pm index 0d27690161..9b15e55e3a 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Circ/Money.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Circ/Money.pm @@ -200,11 +200,38 @@ sub make_payments { } if($type eq 'credit_card_payment') { - # TODO send to credit card processor - # amount == $total_paid - # user == $user_id - # other args == $cc_args (hash, see api docs) - # $e->rollback if processing fails. This will undo everything. + my $this_ou = $e->requestor->ws_ou; + my $response = $apputils->simplereq( + 'open-ils.credit', + 'open-ils.credit.process', + { + "desc" => $payments->{note}, + "amount" => $total_paid, + "patron_id" => $user_id, + "cc" => $payments->{cc_number}, + "expiration" => sprintf( + "%02d-%04d", + $payments->{expire_month}, + $payments->{expire_year} + ), + "ou" => $this_ou + } + ); + # senator: Should failures and/or declines be logged somewhere? Is + # some other cog taking care of this? Actually, what about the + # successes, too? There's an approval code from the payment processor + # that could go somewhere... + if (exists $response->{ilsevent}) { + $e->rollback; + return $response; + } + if ($response->{statusCode} != 200) { + $e->rollback; + return OpenILS::Event->new( + 'CREDIT_PROCESSOR_DECLINED_TRANSACTION', + note => $response->{statusText} + ); + } } $e->commit; diff --git a/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm b/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm index 7250c9f4e8..bd1a845326 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/CreditCard.pm @@ -21,6 +21,7 @@ use strict; use warnings; use Business::CreditCard; use Business::OnlinePayment; +use Locale::Country; use OpenILS::Event; use OpenSRF::Utils::Logger qw/:logger/; @@ -28,7 +29,7 @@ use OpenILS::Utils::CStoreEditor qw/:funcs/; use OpenILS::Application::AppUtils; my $U = "OpenILS::Application::AppUtils"; -use constant CREDIT_OPTS_NS => "global.credit.processor"; +use constant CREDIT_NS => "credit"; # Given the argshash from process_payment(), this helper function just finds # a function in the current namespace named "bop_args_{processor}" and calls @@ -73,7 +74,7 @@ sub get_processor_settings { +{ map { ($_ => $U->ou_ancestor_setting_value( - $org_unit, CREDIT_OPTS_NS . ".${processor}.${_}" + $org_unit, CREDIT_NS . ".processor.${processor}.${_}" )) } qw/enabled login password signature server testmode/ }; } @@ -115,9 +116,15 @@ sub process_payment { and $argshash->{cc} and $argshash->{amount} and $argshash->{expiration} - and $argshash->{ou} - and $argshash->{processor}; + and $argshash->{ou}; + if (!$argshash->{processor}) { + if (!($argshash->{processor} = + $U->ou_ancestor_setting_value( + $argshash->{ou}, CREDIT_NS . '.processor.default'))) { + return OpenILS::Event->new('CREDIT_PROCESSOR_NOT_SPECIFIED'); + } + } # Basic sanity check on processor name. if ($argshash->{processor} !~ /^[a-z0-9_\-]+$/i) { return OpenILS::Event->new('CREDIT_PROCESSOR_NOT_ALLOWED'); @@ -199,6 +206,12 @@ sub prepare_bop_content { $content{zip} ||= $patron->mailing_address->post_code; $content{country} ||= $patron->mailing_address->country; + # Yet another fantastic kludge. country2code() comes from Locale::Country. + # PayPal must have 2 letter country field (ISO 3166) that's uppercase. + if (length($content{country}) > 2 && $argshash->{processor} eq 'PayPal') { + $content{country} = uc country2code($content{country}); + } + %content; } @@ -322,7 +335,7 @@ sub retrieve_payable_balance { my $o = $org->{billing_location}; $o = $org->{circ_lib} unless $o; next if $hash{$o}; # was $hash{$org}, but that doesn't make sense. $org is a hashref and $o gets added in the next line. - $hash{$o} = $U->ou_ancestor_setting_value($o, 'global.credit.allow', $e); + $hash{$o} = $U->ou_ancestor_setting_value($o, CREDIT_NS . '.payments.allow', $e); } my @credit_orgs = map { $hash{$_} ? ($_) : () } keys %hash; diff --git a/Open-ILS/src/sql/Pg/002.schema.config.sql b/Open-ILS/src/sql/Pg/002.schema.config.sql index 01fbc694d5..b68623605b 100644 --- a/Open-ILS/src/sql/Pg/002.schema.config.sql +++ b/Open-ILS/src/sql/Pg/002.schema.config.sql @@ -51,7 +51,8 @@ CREATE TABLE config.upgrade_log ( install_date TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW() ); -INSERT INTO config.upgrade_log (version) VALUES ('0037'); -- atz +INSERT INTO config.upgrade_log (version) VALUES ('0038'); -- senator + CREATE TABLE config.bib_source ( id SERIAL PRIMARY KEY, diff --git a/Open-ILS/src/sql/Pg/950.data.seed-values.sql b/Open-ILS/src/sql/Pg/950.data.seed-values.sql index 679a24fac0..bf1ada0a28 100644 --- a/Open-ILS/src/sql/Pg/950.data.seed-values.sql +++ b/Open-ILS/src/sql/Pg/950.data.seed-values.sql @@ -1205,7 +1205,7 @@ INSERT INTO permission.perm_list VALUES (325,'UPDATE_ORG_UNIT_SETTING.org.bounced_emails', oils_i18n_gettext(325,'FIXME: Need description for UPDATE_ORG_UNIT_SETTING.org.bounced_emails', 'ppl', 'description')), (326,'UPDATE_ORG_UNIT_SETTING.circ.hold_expire_alert_interval', oils_i18n_gettext(326,'FIXME: Need description for UPDATE_ORG_UNIT_SETTING.circ.hold_expire_alert_interval', 'ppl', 'description')), (327,'UPDATE_ORG_UNIT_SETTING.circ.hold_expire_interval', oils_i18n_gettext(327,'FIXME: Need description for UPDATE_ORG_UNIT_SETTING.circ.hold_expire_interval', 'ppl', 'description')), - (328,'UPDATE_ORG_UNIT_SETTING.global.credit.allow', oils_i18n_gettext(328,'FIXME: Need description for UPDATE_ORG_UNIT_SETTING.global.credit.allow', 'ppl', 'description')), + (328,'UPDATE_ORG_UNIT_SETTING.credit.payments.allow', oils_i18n_gettext(328,'FIXME: Need description for UPDATE_ORG_UNIT_SETTING.credit.payments.allow', 'ppl', 'description')), (329,'UPDATE_ORG_UNIT_SETTING.circ.void_overdue_on_lost', oils_i18n_gettext(329,'FIXME: Need description for UPDATE_ORG_UNIT_SETTING.circ.void_overdue_on_lost', 'ppl', 'description')), (330,'UPDATE_ORG_UNIT_SETTING.circ.hold_stalling.soft', oils_i18n_gettext(330,'FIXME: Need description for UPDATE_ORG_UNIT_SETTING.circ.hold_stalling.soft', 'ppl', 'description')), (331,'UPDATE_ORG_UNIT_SETTING.circ.hold_boundary.hard', oils_i18n_gettext(331,'FIXME: Need description for UPDATE_ORG_UNIT_SETTING.circ.hold_boundary.hard', 'ppl', 'description')), @@ -1475,7 +1475,7 @@ INSERT into config.org_unit_setting_type 'Amount of time after a hold is placed before the hold expires. Example "100 days"', 'interval' ), -( 'global.credit.allow', +( 'credit.payments.allow', '', 'If enabled, patrons will be able to pay fines accrued at this location via credit card', 'bool' ), @@ -1695,48 +1695,53 @@ INSERT into config.org_unit_setting_type 'When true, the Date of Birth column in patron lists will default to Not Visible, and in the Patron Summary sidebar the value will display as unless the field label is clicked.', 'bool' ), -( 'global.credit.processor.authorizenet.enabled', +( 'credit.processor.default', + 'Credit card processing: Name default credit processor', + 'This might be "AuthorizeNet", "PayPal", etc.', + 'string' ), + +( 'credit.processor.authorizenet.enabled', 'Credit card processing: Enable AuthorizeNet payments', '', 'bool' ), -( 'global.credit.processor.authorizenet.login', +( 'credit.processor.authorizenet.login', 'Credit card processing: AuthorizeNet login', '', 'string' ), -( 'global.credit.processor.authorizenet.password', +( 'credit.processor.authorizenet.password', 'Credit card processing: AuthorizeNet password', '', 'string' ), -( 'global.credit.processor.authorizenet.server', +( 'credit.processor.authorizenet.server', 'Credit card processing: AuthorizeNet server', 'Required if using a developer/test account with AuthorizeNet', 'string' ), -( 'global.credit.processor.authorizenet.testmode', +( 'credit.processor.authorizenet.testmode', 'Credit card processing: AuthorizeNet test mode', '', 'bool' ), -( 'global.credit.processor.paypal.enabled', +( 'credit.processor.paypal.enabled', 'Credit card processing: Enable PayPal payments', '', 'bool' ), -( 'global.credit.processor.paypal.login', +( 'credit.processor.paypal.login', 'Credit card processing: PayPal login', '', 'string' ), -( 'global.credit.processor.paypal.password', +( 'credit.processor.paypal.password', 'Credit card processing: PayPal password', '', 'string' ), -( 'global.credit.processor.paypal.signature', +( 'credit.processor.paypal.signature', 'Credit card processing: PayPal signature', '', 'string' ), -( 'global.credit.processor.paypal.testmode', +( 'credit.processor.paypal.testmode', 'Credit card processing: PayPal test mode', '', 'bool' ) diff --git a/Open-ILS/src/sql/Pg/upgrade/0038.data.org-setting-credit-default-proc.sql b/Open-ILS/src/sql/Pg/upgrade/0038.data.org-setting-credit-default-proc.sql new file mode 100644 index 0000000000..b20237b9fb --- /dev/null +++ b/Open-ILS/src/sql/Pg/upgrade/0038.data.org-setting-credit-default-proc.sql @@ -0,0 +1,35 @@ +BEGIN; + +INSERT INTO config.upgrade_log (version) VALUES ('0038'); -- senator + +UPDATE permission.perm_list + SET code = 'UPDATE_ORG_UNIT_SETTING.credit.payments.allow' + WHERE code = 'UPDATE_ORG_UNIT_SETTING.global.credit.allow'; + +UPDATE config.org_unit_setting_type + SET name = 'credit.payments.allow' + WHERE name = 'global.credit.allow'; + +UPDATE config.org_unit_setting_type + SET name = REGEXP_REPLACE(name, E'global\.', '') + WHERE name LIKE 'global.credit.%'; + +UPDATE config.org_unit_setting_type + SET label = 'Credit card processing: AuthorizeNet enabled' + WHERE name = 'credit.processor.authorizenet.enabled'; + +UPDATE config.org_unit_setting_type + SET label = 'Credit card processing: PayPal enabled' + WHERE name = 'credit.processor.paypal.enabled'; + +INSERT INTO + config.org_unit_setting_type ( name, label, description, datatype ) + VALUES ( + 'credit.processor.default', + 'Credit card processing: Name default credit processor', + 'This might be "AuthorizeNet", "PayPal", etc.', + 'string' + ); + + +COMMIT; diff --git a/Open-ILS/src/support-scripts/test-scripts/payment_test.pl b/Open-ILS/src/support-scripts/test-scripts/payment_test.pl index bb8fc30bc7..41ece54d6d 100644 --- a/Open-ILS/src/support-scripts/test-scripts/payment_test.pl +++ b/Open-ILS/src/support-scripts/test-scripts/payment_test.pl @@ -16,6 +16,7 @@ $0 [-h] --login=UserName --password==MyPass [OPTIONS] [Transaction data] Required Arguments: -l --login Assigned by your processor API (specified in -t) -p --password Assigned by your processor API (specified in -t) + -o --org-unit What library/branch is making this payment (numeric) Options: -t --target Payment processor (default PayPal) @@ -48,11 +49,12 @@ my $expires = '12-2014'; my $id = 5; ### Empties -my ($login, $password, $signature, $help, $amount, $server); +my ($login, $password, $ou, $signature, $help, $amount, $server); GetOptions( 'config_file=s' => \$config, 'target=s' => \$processor, + 'org-unit=i' => \$ou, 'login=s' => \$login, 'password=s' => \$password, 's|signature=s' => \$signature, @@ -66,7 +68,7 @@ GetOptions( $help and print usage and exit; -unless ($login and $processor and $password) { +unless ($login and $processor and $password and $ou) { print usage; exit; } @@ -81,6 +83,7 @@ Attempting transaction: login => $login, password => $password, signature => $signature, + ou => $ou, amount => $amount, cc => $number, expiration => $expires, @@ -99,6 +102,7 @@ my( $user, $evt ) = simplereq('open-ils.credit', 'open-ils.credit.process', login => $login, password => $password, signature => $signature, + ou => $ou, amount => $amount, cc => $number, expiration => $expires, -- 2.11.0