From 0b0e189623afe1e385670e49e0fe8a6076315082 Mon Sep 17 00:00:00 2001 From: Jason Etheridge Date: Tue, 26 Oct 2021 10:52:42 -0400 Subject: [PATCH] LP1993305 Comprise SmartPay support, UI bits Squashed commits: * ui * 0.50 minimum across the board Signed-off-by: Jason Etheridge Signed-off-by: Jane Sandberg --- .../lib/OpenILS/WWW/EGCatLoader/Account.pm | 122 +++++++++++++++++--- .../opac/myopac/main_payment_form.tt2 | 15 ++- .../opac/myopac/smartpay_payment_form.tt2 | 39 ++++++ .../templates/opac/myopac/main_payment_form.tt2 | 17 ++- .../opac/myopac/smartpay_payment_form.tt2 | 39 ++++++ 5 files changed, 205 insertions(+), 27 deletions(-) create mode 100644 Open-ILS/src/templates-bootstrap/opac/myopac/smartpay_payment_form.tt2 create mode 100644 Open-ILS/src/templates/opac/myopac/smartpay_payment_form.tt2 diff --git a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm index 78bba4a..f4b0d3e 100644 --- a/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm +++ b/Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm @@ -18,6 +18,9 @@ use DateTime; use DateTime::Format::ISO8601; my $U = 'OpenILS::Application::AppUtils'; use List::MoreUtils qw/uniq/; +use LWP::UserAgent; +use HTTP::Request::Common qw(POST GET); +use CGI; sub prepare_extended_user_info { my $self = shift; @@ -2323,22 +2326,98 @@ sub load_myopac_payment_form { $r = $self->prepare_fines(undef, undef, [$self->cgi->param('xact'), $self->cgi->param('xact_misc')]); - if ( ! $self->cgi->param('last_chance') # only do this once - && $self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.stripe.enabled') - && $self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.default') eq 'Stripe') { - my $skey = $self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.stripe.secretkey'); - my $currency = $self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.stripe.currency'); - my $stripe = Business::Stripe->new(-api_key => $skey); - my $intent = $stripe->api('post', 'payment_intents', - amount => $self->ctx->{fines}->{balance_owed} * 100, - currency => $currency || 'usd', - description => 'User Database ID: ' . $self->ctx->{user}->id - ); - if ($stripe->success) { - $self->ctx->{stripe_client_secret} = $stripe->success()->{client_secret}; - } else { - $logger->error('Error initializing Stripe: ' . Dumper($stripe->error)); - $self->ctx->{cc_configuration_error} = 1; + if ( ! $self->cgi->param('last_chance')) { # only do this once + if ($self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.default') eq 'Stripe') { + if ($self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.stripe.enabled')) { + my $skey = $self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.stripe.secretkey'); + my $currency = $self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.stripe.currency'); + my $stripe = Business::Stripe->new(-api_key => $skey); + my $intent = $stripe->api('post', 'payment_intents', + amount => $self->ctx->{fines}->{balance_owed} * 100, + currency => $currency || 'usd', + description => 'User Database ID: ' . $self->ctx->{user}->id + ); + if ($stripe->success) { + $self->ctx->{stripe_client_secret} = $stripe->success()->{client_secret}; + } else { + $logger->error('Error initializing Stripe: ' . Dumper($stripe->error)); + $self->ctx->{cc_configuration_error} = 1; + } + } + } elsif ($self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.default') eq 'SmartPAY') { + if ($self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.smartpay.enabled')) { + my $location_id = CGI::escapeHTML($self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.smartpay.location_id')); + $self->ctx->{smartpay_locationid} = $location_id; + my $customer_id = CGI::escapeHTML($self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.smartpay.customer_id')); + $self->ctx->{smartpay_customerid} = $customer_id; + my $login = CGI::escapeHTML($self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.smartpay.login')); + my $password = CGI::escapeHTML($self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.smartpay.password')); + my $api_key = CGI::escapeHTML($self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.smartpay.api_key')); + my $server = CGI::escapeHTML($self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.smartpay.server')); + my $port = CGI::escapeHTML($self->ctx->{get_org_setting}->($e->requestor->home_ou, 'credit.processor.smartpay.port')); + my $base_target = "https://$server"; + $base_target .= ":$port" if $port; + $base_target .= "/SMARTPAYAPI/WEBSMARTPAY.dll"; + + # first api call + my $target = $base_target . "?RequestSessionKey"; + $target .= "&CustomerID=$customer_id"; + $target .= "&LocationID=$location_id"; + $target .= "&UserName=$login"; + $target .= "&Password=$password"; + $target .= "&APIKey=$api_key"; + + my @payment_xacts = ($self->cgi->param('xact'), $self->cgi->param('xact_misc')); + #$logger->error('SmartPAY debug, cache_args = ' . Dumper($cache_args) ); + + # generate a temporary cache token for our secret + my $token = 'smartpay_' . md5_hex($$ . time() . rand()); + $target .= "&Secret=$token"; + + #$logger->error('SmartPAY debug, target= $target ' . Dumper($target) ); + + my $ua = new LWP::UserAgent; + + # there has been API flux with whether to send API-Key and Secret as HTTP headers or URL params + #my $req = GET($target, 'API-Key' => "$api_key", 'Secret' => "$token"); + my $req = GET($target); + my $response = $ua->request($req); + + if ($response->is_success() && $response->content() !~ /HTML/) { + $logger->info('SmartPAY initialized for ' . $self->editor->authtoken); + + my $session_key = $response->content(); + + # we'll test this secret key again in the create payment method + my $cache_args = { + user => $self->ctx->{user}->id, + session_key => $session_key + }; + my $cache = OpenSRF::Utils::Cache->new('global'); + $cache->put_cache($token, $cache_args, 300); + + # this will be for our follow-up call client-side + + $self->ctx->{smartpay_target} = $base_target . '?GetCreditForm'; + $self->ctx->{smartpay_target} .= '&SessionKey=' . $session_key; + $self->ctx->{smartpay_target} .= "&CustomerID=$customer_id"; + $self->ctx->{smartpay_target} .= "&LocationID=$location_id"; + $self->ctx->{smartpay_target} .= '&PatronID=' . $self->ctx->{user}->id; # $e->requestor->id; + $self->ctx->{smartpay_target} .= '&InvNum=1234'; + $self->ctx->{smartpay_target} .= '&Amount=' . $self->ctx->{fines}->{balance_owed}; + $self->ctx->{smartpay_target} .= '&URLPostBack=' . CGI::escapeHTML( $self->ctx->{hostname} ); + #$self->ctx->{smartpay_target} .= '&ScriptPostBack=' . CGI::escapeHTML('/cgi-bin/offline/echo1.pl'); + $self->ctx->{smartpay_target} .= '&URLReturn=' . CGI::escapeHTML( $self->ctx->{opac_root} . '/myopac/main_pay_init' ); + $self->ctx->{smartpay_target} .= '&URLCancel=' . CGI::escapeHTML( 'https://' . $self->ctx->{hostname} . $self->ctx->{opac_root} . '/myopac/charges'); + $self->ctx->{smartpay_target} .= '&UserName=&Password=&Field1=smartpay&Field2=&Field3=&ItemsData='; + + } else { + my $error = $response->content(); + $error =~ s/[\r\n]//g; + $logger->error("Error initializing SmartPAY: $error"); + $self->ctx->{cc_configuration_error} = 1; + } + } } } @@ -2412,6 +2491,17 @@ sub load_myopac_pay_init { billing_zip stripe_payment_intent stripe_client_secret /); + # mapping SmartPAY CGI parameters + if ($self->cgi->param('Result')) { + $cc_args->{smartpay_result} = $self->cgi->param('Result'); + } + if ($self->cgi->param('Secret')) { + $cc_args->{smartpay_secret} = $self->cgi->param('Secret'); + } + if ($self->cgi->param('CCNumber')) { + $cc_args->{number} = $self->cgi->param('CCNumber'); + } + my $cache_args = { cc_args => $cc_args, user => $self->ctx->{user}->id, diff --git a/Open-ILS/src/templates-bootstrap/opac/myopac/main_payment_form.tt2 b/Open-ILS/src/templates-bootstrap/opac/myopac/main_payment_form.tt2 index a774bb7..5234233 100755 --- a/Open-ILS/src/templates-bootstrap/opac/myopac/main_payment_form.tt2 +++ b/Open-ILS/src/templates-bootstrap/opac/myopac/main_payment_form.tt2 @@ -6,16 +6,19 @@ last_chance = CGI.param("last_chance"); - IF myopac_main_page == "payment_form" AND - ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.stripe.enabled') AND ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.default') == 'Stripe'; - ctx.use_stripe = 1; + IF myopac_main_page == "payment_form"; + IF ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.stripe.enabled') AND ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.default') == 'Stripe'; + ctx.use_stripe = 1; + ELSIF ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.smartpay.enabled') AND ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.default') == 'SmartPAY'; + ctx.use_smartpay = 1; + END; END %]

[% l('Pay Charges') %]

-[% IF ctx.fines.balance_owed <= 0 %] +[% IF ctx.fines.balance_owed <= 0.49 %]
- [% l("The minimum amount you can pay is \$0.01.") %] + [% l("The minimum amount you can pay is \$0.50.") %]
[% ELSE %]
@@ -29,6 +32,8 @@ [% ELSE %] [% IF ctx.use_stripe %] [% PROCESS "opac/myopac/stripe_payment_form.tt2"; %] + [% ELSIF ctx.use_smartpay %] + [% PROCESS "opac/myopac/smartpay_payment_form.tt2"; %] [% ELSE %] [% PROCESS "opac/myopac/generic_payment_form.tt2"; %] [% END %] diff --git a/Open-ILS/src/templates-bootstrap/opac/myopac/smartpay_payment_form.tt2 b/Open-ILS/src/templates-bootstrap/opac/myopac/smartpay_payment_form.tt2 new file mode 100644 index 0000000..537b266 --- /dev/null +++ b/Open-ILS/src/templates-bootstrap/opac/myopac/smartpay_payment_form.tt2 @@ -0,0 +1,39 @@ +

[% l("Click Submit to temporarily leave this website for the payment processor. After payment, you will be returned to these pages.") %]

+[% l('Submit') %] +[% l('Cancel') %] + + + + + + + + + + [% + FOR f IN ctx.fines.circulation; + NEXT IF CGI.param('xact').size && + !CGI.param('xact').grep(f.xact.id).size; + attrs = {marc_xml => f.marc_xml}; + IF f.marc_xml; + PROCESS get_marc_attrs args=attrs; + ELSIF f.xact.reservation; + attrs.title = f.xact.reservation.target_resource_type.name; + END %] + + + + + [% + END; + FOR f IN ctx.fines.grocery; + NEXT IF CGI.param('xact_misc').size && + !CGI.param('xact_misc').grep(f.xact.id).size %] + + + + + [% END %] + +
[% l('Charge/Fee') %][% l('Amount') %]
[% attrs.title | html %][% money(f.xact.balance_owed) %]
[% f.xact.last_billing_type | html %][% money(f.xact.balance_owed) %]
diff --git a/Open-ILS/src/templates/opac/myopac/main_payment_form.tt2 b/Open-ILS/src/templates/opac/myopac/main_payment_form.tt2 index ab83442..3b6a409 100644 --- a/Open-ILS/src/templates/opac/myopac/main_payment_form.tt2 +++ b/Open-ILS/src/templates/opac/myopac/main_payment_form.tt2 @@ -6,16 +6,19 @@ last_chance = CGI.param("last_chance"); - IF myopac_main_page == "payment_form" AND - ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.stripe.enabled') AND ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.default') == 'Stripe'; - ctx.use_stripe = 1; + IF myopac_main_page == "payment_form"; + IF ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.stripe.enabled') AND ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.default') == 'Stripe'; + ctx.use_stripe = 1; + ELSIF ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.smartpay.enabled') AND ctx.get_org_setting(ctx.user.home_ou.id, 'credit.processor.default') == 'SmartPAY'; + ctx.use_smartpay = 1; + END; END %]

[% l('Pay Charges') %]

-[% IF ctx.fines.balance_owed <= 0 %] +[% IF ctx.fines.balance_owed <= 0.49 %]
- [% l("The minimum amount you can pay is \$0.01.") %] + [% l("The minimum amount you can pay is \$0.50.") %]
[% ELSE %]
@@ -27,11 +30,13 @@ [% ELSE %] [% IF ctx.use_stripe %] [% PROCESS "opac/myopac/stripe_payment_form.tt2"; %] + [% ELSIF ctx.use_smartpay %] + [% PROCESS "opac/myopac/smartpay_payment_form.tt2"; %] [% ELSE %] [% PROCESS "opac/myopac/generic_payment_form.tt2"; %] [% END %] [% END %] [% END %]
-[% END %] +[% END %] [% END %] diff --git a/Open-ILS/src/templates/opac/myopac/smartpay_payment_form.tt2 b/Open-ILS/src/templates/opac/myopac/smartpay_payment_form.tt2 new file mode 100644 index 0000000..537b266 --- /dev/null +++ b/Open-ILS/src/templates/opac/myopac/smartpay_payment_form.tt2 @@ -0,0 +1,39 @@ +

[% l("Click Submit to temporarily leave this website for the payment processor. After payment, you will be returned to these pages.") %]

+[% l('Submit') %] +[% l('Cancel') %] + + + + + + + + + + [% + FOR f IN ctx.fines.circulation; + NEXT IF CGI.param('xact').size && + !CGI.param('xact').grep(f.xact.id).size; + attrs = {marc_xml => f.marc_xml}; + IF f.marc_xml; + PROCESS get_marc_attrs args=attrs; + ELSIF f.xact.reservation; + attrs.title = f.xact.reservation.target_resource_type.name; + END %] + + + + + [% + END; + FOR f IN ctx.fines.grocery; + NEXT IF CGI.param('xact_misc').size && + !CGI.param('xact_misc').grep(f.xact.id).size %] + + + + + [% END %] + +
[% l('Charge/Fee') %][% l('Amount') %]
[% attrs.title | html %][% money(f.xact.balance_owed) %]
[% f.xact.last_billing_type | html %][% money(f.xact.balance_owed) %]
-- 1.7.2.5