diff --git a/CRM/Stripe/Utils/Check/Webhook.php b/CRM/Stripe/Utils/Check/Webhook.php
new file mode 100644
index 0000000000000000000000000000000000000000..4328799dcd6b11df2dcfdbb5cbc61549ad6f0910
--- /dev/null
+++ b/CRM/Stripe/Utils/Check/Webhook.php
@@ -0,0 +1,83 @@
+<?php
+
+use CRM_Stripe_ExtensionUtil as E;
+
+class CRM_Stripe_Utils_Check_Webhook {
+
+  /**
+   * Checks whether the live Stripe processors have a correctly configured
+   * webhook (we may want to check the test processors too, at some point, but
+   * for now, avoid having false alerts that will annoy people).
+   *
+   * @see stripe_civicrm_check()
+   */
+  public static function check(&$messages) {
+    $result = civicrm_api3('PaymentProcessor', 'get', [
+      'class_name' => 'Payment_Stripe',
+      'is_active' => 1,
+      'is_test' => 0,
+    ]);
+
+    foreach ($result['values'] as $pp) {
+      $sk = $pp['user_name'];
+
+      $webhook_path = stripe_get_webhook_path(TRUE);
+      $webhook_path = str_replace('NN', $pp['id'], $webhook_path);
+
+      \Stripe\Stripe::setApiKey($sk);
+      $webhooks = \Stripe\WebhookEndpoint::all(["limit" => 100]);
+
+      if (empty($webhooks->data)) {
+        $messages[] = new CRM_Utils_Check_Message(
+          'stripe_webhook',
+          E::ts('The %1 (%2) Payment Processor does not have a webhook configured. This is only required for recurring contributions. You can review from your Stripe account, under Developers > Webhooks. The webhook URL is: %3', [
+            1 => $pp['name'],
+            2 => $pp['id'],
+            3 => $webhook_path,
+          ]),
+          E::ts('Stripe - Webhook'),
+          \Psr\Log\LogLevel::INFO,
+          'fa-money'
+        );
+
+        continue;
+      }
+
+      $found_wh = FALSE;
+
+      foreach ($webhooks->data as $wh) {
+        if ($wh->url == $webhook_path) {
+          $found_wh = TRUE;
+        }
+      }
+
+      if ($found_wh) {
+        $messages[] = new CRM_Utils_Check_Message(
+          'stripe_webhook',
+          E::ts('The %1 (%2) Payment Processor has a webhook configured (%3).', [
+            1 => $pp['name'],
+            2 => $pp['id'],
+            3 => $webhook_path,
+          ]),
+          E::ts('Stripe - Webhook'),
+          \Psr\Log\LogLevel::INFO,
+          'fa-money'
+        );
+      }
+      else {
+        $messages[] = new CRM_Utils_Check_Message(
+          'stripe_webhook',
+          E::ts('The %1 (%2) Payment Processor does not have a webhook configured. This is only required for recurring contributions. You can review from your Stripe account, under Developers > Webhooks. The webhook URL is: %3', [
+            1 => $pp['name'],
+            2 => $pp['id'],
+            3 => $webhook_path,
+          ]),
+          E::ts('Stripe - Webhook'),
+          \Psr\Log\LogLevel::WARNING,
+          'fa-money'
+        );
+      }
+    }
+  }
+
+}
diff --git a/stripe.php b/stripe.php
index 8fda3cd6a8d09db52c90234f66c83bb2a72550c3..4572c2551e61532695990e83233f4e9920a1d905 100644
--- a/stripe.php
+++ b/stripe.php
@@ -204,25 +204,13 @@ function stripe_civicrm_buildForm($formName, &$form) {
  * Get the path of the webhook depending on the UF (eg Drupal, Joomla, Wordpress)
  *
  * @param bool $includeBaseUrl
+ * @param string $pp_id
  *
  * @return string
  */
-function stripe_get_webhook_path($includeBaseUrl = TRUE) {
-  $UFWebhookPaths = [
-    "Drupal"    => "civicrm/payment/ipn/NN",
-    "Joomla"    => "?option=com_civicrm&task=civicrm/payment/ipn/NN",
-    "WordPress" => "?page=CiviCRM&q=civicrm/payment/ipn/NN"
-  ];
-
-
-  // Use Drupal path as default if the UF isn't in the map above
-  $UFWebhookPath = (array_key_exists(CIVICRM_UF, $UFWebhookPaths)) ?
-    $UFWebhookPaths[CIVICRM_UF] :
-    $UFWebhookPaths['Drupal'];
-  if ($includeBaseUrl) {
-    return CIVICRM_UF_BASEURL . '/' . $UFWebhookPath;
-  }
-  return $UFWebhookPath;
+function stripe_get_webhook_path($includeBaseUrl = TRUE, $pp_id = 'NN') {
+  // Assuming frontend URL because that's how the function behaved before.
+  return CRM_Utils_System::url('civicrm/payment/ipn/' . $pp_id, NULL, $includeBaseUrl, NULL, TRUE, TRUE);
 }
 
 /*
@@ -234,3 +222,10 @@ function stripe_civicrm_idsException(&$skip) {
   // Path is always set to civicrm/payment/ipn (checked on Drupal/Joomla)
   $skip[] = 'civicrm/payment/ipn';
 }
+
+/**
+ * Implements hook_civicrm_check().
+ */
+function stripe_civicrm_check(&$messages) {
+  CRM_Stripe_Utils_Check_Webhook::check($messages);
+}