diff --git a/Model/System/Message/Cron.php b/Model/System/Message/Cron.php
new file mode 100644
index 00000000..5b994c1f
--- /dev/null
+++ b/Model/System/Message/Cron.php
@@ -0,0 +1,63 @@
+collectionFactory = $collectionFactory;
+ }
+
+ /**
+ * Message identity
+ */
+ private const MESSAGE_IDENTITY = 'rvvup_missing_crons';
+
+ public function getIdentity()
+ {
+ return self::MESSAGE_IDENTITY;
+ }
+
+ public function isDisplayed()
+ {
+ /** @var Collection $collection */
+ $collection = $this->collectionFactory->create();
+
+ return empty($collection->getAllIds());
+ }
+
+ public function getText()
+ {
+ $warning = "WARNING: ";
+ $message = $warning . 'Rvvup requires Magento cron jobs to be enabled in order to handle payment';
+ $message .= " events that complete asynchronously.";
+ $message .= "
It appears that cron jobs may not be configured on your Magento instance.";
+ $documentationLink = "https://articles.rvvup.com/getting-started-with-magento-and-rvvup";
+ $documentation = "our documentation";
+ $message .= "
See " . $documentation . " for more information.";
+
+ return $message;
+ }
+
+ public function getSeverity()
+ {
+ return self::SEVERITY_NOTICE;
+ }
+}
diff --git a/Model/System/Message/Queue.php b/Model/System/Message/Queue.php
new file mode 100644
index 00000000..7aa9255c
--- /dev/null
+++ b/Model/System/Message/Queue.php
@@ -0,0 +1,76 @@
+collectionFactory = $collectionFactory;
+ $this->config = $config;
+ }
+
+ /**
+ * Message identity
+ */
+ private const MESSAGE_IDENTITY = 'rvvup_missing_queues';
+
+ public function getIdentity()
+ {
+ return self::MESSAGE_IDENTITY;
+ }
+
+ public function isDisplayed()
+ {
+ /** @var Collection $collection */
+ $collection = $this->collectionFactory->create();
+
+ $collection->addFieldToFilter('job_code', ['eq' => 'consumers_runner']);
+
+ $rabbitMq = $this->config->get('amqp');
+
+ return empty($collection->getAllIds()) && !$rabbitMq;
+ }
+
+ public function getText()
+ {
+ $warning = "WARNING: ";
+ $message = $warning . "Rvvup requires Magento MessageQueue to be enabled in order to handle payment";
+ $message .= " events that complete asynchronously.";
+ $message .= "
It appears that this may not be configured on your Magento instance.";
+ $documentationLink = "https://articles.rvvup.com/getting-started-with-magento-and-rvvup";
+ $documentation = "our documentation";
+ $message .= "
See " . $documentation . " for more information.";
+
+ return $message;
+ }
+
+ public function getSeverity()
+ {
+ return self::SEVERITY_NOTICE;
+ }
+}
diff --git a/Test/Unit/Model/System/CronTest.php b/Test/Unit/Model/System/CronTest.php
new file mode 100644
index 00000000..831b61fc
--- /dev/null
+++ b/Test/Unit/Model/System/CronTest.php
@@ -0,0 +1,71 @@
+collectionFactory = $this->getMockBuilder(CollectionFactory::class)->disableOriginalConstructor()->getMock();
+ $this->configureCollection();
+
+ $this->cron = new Cron(
+ $this->collectionFactory
+ );
+ }
+
+ private function configureCollection($array = []) {
+ $collection = $this->getMockBuilder(Collection::class)->disableOriginalConstructor()->getMock();
+ $collection->method('getAllIds')->willReturn($array);
+ $this->collectionFactory->method('create')->willReturn($collection);
+ }
+
+ /**
+ * @return void
+ */
+ protected function tearDown(): void
+ {
+ $this->cron = null;
+ }
+
+ /**
+ * @return void
+ */
+ public function testDisplayWithCronEnabled()
+ {
+ $this->configureCollection([1]);
+ $this->assertEquals(
+ true,
+ $this->cron->isDisplayed()
+ );
+ }
+
+ /**
+ * @return void
+ */
+ public function testDisplayWithCronDisabled()
+ {
+ $this->configureCollection();
+ $this->assertEquals(
+ true,
+ $this->cron->isDisplayed()
+ );
+ }
+}
diff --git a/Test/Unit/Model/System/QueueTest.php b/Test/Unit/Model/System/QueueTest.php
new file mode 100644
index 00000000..efd6c44b
--- /dev/null
+++ b/Test/Unit/Model/System/QueueTest.php
@@ -0,0 +1,96 @@
+collectionFactory = $this->getMockBuilder(CollectionFactory::class)->disableOriginalConstructor()->getMock();
+ $this->config = $this->getMockBuilder(DeploymentConfig::class)->disableOriginalConstructor()->getMock();
+ $this->configure(false);
+
+ $this->queue = new Queue(
+ $this->collectionFactory,
+ $this->config
+ );
+ }
+
+ /** @inheirtDoc */
+ private function configure($amqp, array $ids = []) {
+ $collection = $this->getMockBuilder(Collection::class)->disableOriginalConstructor()->getMock();
+ $collection->method('getAllIds')->willReturn($ids);
+ $this->config->method('get')->willReturn($amqp);
+ $this->collectionFactory->method('create')->willReturn($collection);
+ }
+
+ /**
+ * @return void
+ */
+ protected function tearDown(): void
+ {
+ $this->queue = null;
+ }
+
+ /**
+ * @return void
+ */
+ public function testDisplayWithAmqpEnabled()
+ {
+ $this->configure(true);
+ $this->assertEquals(
+ true,
+ $this->queue->isDisplayed()
+ );
+ }
+
+ /**
+ * @return void
+ */
+ public function testDisplayWithAmqpDisabled()
+ {
+ $this->configure(false);
+ $this->assertEquals(
+ true,
+ $this->queue->isDisplayed()
+ );
+ }
+
+
+ /**
+ * @return void
+ */
+ public function testDisplayWithCronEnabled()
+ {
+ $this->configure(false, [1]);
+ $this->assertEquals(
+ true,
+ $this->queue->isDisplayed()
+ );
+ }
+}
+
diff --git a/etc/adminhtml/di.xml b/etc/adminhtml/di.xml
index 744bf432..cfd7cc2d 100644
--- a/etc/adminhtml/di.xml
+++ b/etc/adminhtml/di.xml
@@ -22,4 +22,12 @@
type="Rvvup\Payments\Plugin\PaymentMethod"
sortOrder="1"/>
+
+
+
+ - Rvvup\Payments\Model\System\Message\Queue
+ - Rvvup\Payments\Model\System\Message\Cron
+
+
+