}
$tokens->{$_} = $cgi->param($_) for
- (qw/RESULT PNREF AVSADDR AVSZIP PROCCVV2/);
+ (qw/RESULT PNREF AVSADDR AVSZIP PROCCVV2 AMT/);
$tokens->{pay_result_code} = $result;
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(