diff --git a/CRM/Stripe/Check.php b/CRM/Stripe/Check.php index 2b6a10bd42a609ae3519c1f1f813941f0c1bed5c..55549a47f96158dec36313cd1830ce3c4c005166 100644 --- a/CRM/Stripe/Check.php +++ b/CRM/Stripe/Check.php @@ -51,6 +51,7 @@ class CRM_Stripe_Check { $this->checkExtensionFirewall(); $this->checkUpgradeMessages(); $this->checkWebhooks(); + $this->checkFailedPaymentIntents(); return $this->messages; } @@ -210,4 +211,38 @@ class CRM_Stripe_Check { } } + /** + * Try to detect if a client is being spammed / credit card fraud. + */ + private function checkFailedPaymentIntents(&$messages) { + // Check for a high volume of failed/pending contributions + $count = CRM_Core_DAO::singleValueQuery('SELECT count(*) + FROM civicrm_stripe_paymentintent + WHERE status = "failed" + AND TIMESTAMPDIFF(minute, created_date, NOW()) < 60 + ORDER BY id DESC + LIMIT 1000'); + + if ($count > 20) { + $message = new CRM_Utils_Check_Message( + 'stripe_paymentintentspam', + E::ts('%1 failed Stripe Payment Intents in the past hour. Please check the logs. They are problably hitting the CiviCRM REST API.', [1 => $count]), + E::ts('Stripe - High rate of failed contributions'), + \Psr\Log\LogLevel::CRITICAL, + 'fa-check' + ); + $this->messages[] = $message; + } + else { + $message = new CRM_Utils_Check_Message( + 'stripe_paymentintentspam', + E::ts('%1 failed Stripe Payment Intents in the past hour.', [1 => $count]) . ' ' . E::ts('We monitor this in case someone malicious is testing stolen credit cards on public contribution forms.'), + E::ts('Stripe - Failed Stripe Payment Intents'), + \Psr\Log\LogLevel::INFO, + 'fa-check' + ); + $this->messages[] = $message; + } + } + }