JBAS-1588 CC payment balances match active data
authorBill Erickson <berickxx@gmail.com>
Fri, 16 Sep 2016 15:26:29 +0000 (11:26 -0400)
committerBill Erickson <berickxx@gmail.com>
Thu, 21 Mar 2019 19:46:23 +0000 (15:46 -0400)
Ensure that the total amount to be tracked as payments in EG after a
successfull PayPal payment match the PP payment amount.  Exit early and
return a non-success to PP when the totals don't match.

This imbalance can occur when a transaction is paid by some other client
(secondary PP instance, staff client) after the PP transaction has been
initiated with the original transaction balance owed amount.

IOW, don't accept payments for transactions that were paid off through
some other mechanism while the PP transaction was in process.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Open-ILS/src/perlmods/lib/OpenILS/WWW/EGCatLoader/Account.pm

index 57ab865..24a8294 100644 (file)
@@ -1971,7 +1971,7 @@ sub load_myopac_payflow_silent_post {
     }
 
     $tokens->{$_} = $cgi->param($_) for
-        (qw/RESULT PNREF AVSADDR AVSZIP PROCCVV2/);
+        (qw/RESULT PNREF AVSADDR AVSZIP PROCCVV2 AMT/);
 
     $tokens->{pay_result_code} = $result;
 
@@ -2027,6 +2027,27 @@ sub payflow_create_payment {
         payment_type => "credit_card_payment"
     };
 
+    # prepare_fines() collects xact data for the requested transactions,
+    # but excludes any that no longer have a positive balance.
+    # If the current balance owed across all requested transactions no
+    # longer matches the payment amount made at PayPal, exit early by
+    # returning a non-OK status to PayPal to void the payment.
+    # This can happen if the same transactions are paid by 2 separate
+    # PP instances at the same time.
+    my @xact_balances = map {$_->[1]} @{$args->{payments}};
+    my $cur_total = $U->fpsum(@xact_balances); # current balance of selected.
+    my $paid_total = $tokens->{AMT}; # original paypal payment amount
+
+    if ($paid_total != $cur_total) {
+        my @xacts = $tokens->{xacts};
+
+        $logger->error("PayflowHosted requested payment amount of ".
+            "$paid_total does not match total balance owed ($cur_total) of ".
+            "selected transactions (@xacts). Reverting CC payment");
+
+        return Apache2::Const::HTTP_BAD_REQUEST;
+    }
+
     $logger->info("PayflowHosted sending payments: ".Dumper($args));
 
     my $resp = $U->simplereq(