From 500707307c24ff55d83719d1fbd929a51f59be90 Mon Sep 17 00:00:00 2001
From: "@ChristelLoftus" <christel@bob.co.za>
Date: Tue, 27 Aug 2024 11:28:10 +0200
Subject: [PATCH] Start webhook implementation

---
 Model/Carrier/UData.php         |   7 ++
 Observer/OrderCreateWebhook.php | 119 ++++++++++++++++++++++++++++++++
 Observer/OrderUpdateWebhook.php |  76 ++++++++++++++++++++
 etc/events.xml                  |   6 ++
 etc/frontend/di.xml             |   8 +++
 5 files changed, 216 insertions(+)
 create mode 100644 Observer/OrderCreateWebhook.php
 create mode 100644 Observer/OrderUpdateWebhook.php

diff --git a/Model/Carrier/UData.php b/Model/Carrier/UData.php
index d173baa..a7e5d2e 100644
--- a/Model/Carrier/UData.php
+++ b/Model/Carrier/UData.php
@@ -20,4 +20,11 @@ class UData
      * @var string
      */
     public const RATES_ENDPOINT = 'https://api.dev.bobgo.co.za/rates-at-checkout/magento';
+
+    /**
+     * Order create/update webhook URL
+     *
+     * @var string
+     */
+    public const WEBHOOK_URL = 'https://api.dev.bobgo.co.za/webhook/channel';
 }
diff --git a/Observer/OrderCreateWebhook.php b/Observer/OrderCreateWebhook.php
new file mode 100644
index 0000000..f301cc8
--- /dev/null
+++ b/Observer/OrderCreateWebhook.php
@@ -0,0 +1,119 @@
+<?php
+
+namespace BobGroup\BobGo\Observer;
+
+use Magento\Framework\Event\Observer;
+use Magento\Framework\Event\ObserverInterface;
+use Magento\Framework\HTTP\Client\Curl;
+use BobGroup\BobGo\Model\Carrier\UData;
+use Psr\Log\LoggerInterface;
+use Magento\Store\Model\StoreManagerInterface;
+
+class OrderCreateWebhook implements ObserverInterface
+{
+    protected Curl $curl;
+    protected LoggerInterface $logger;
+    protected StoreManagerInterface $storeManager;
+
+    public function __construct(LoggerInterface $logger, Curl $curl, StoreManagerInterface $storeManager)
+    {
+        $this->logger = $logger;
+        $this->curl = $curl; // Initialize the Curl instance
+        $this->storeManager = $storeManager;
+    }
+
+    public function execute(Observer $observer)
+    {
+        $this->logger->info('OrderCreateWebhook: execute method started');
+
+        $order = $observer->getEvent()->getOrder();
+        if (!$order) {
+            $this->logger->error('OrderCreateWebhook: No order object found in observer');
+            return;
+        }
+
+        // Log order creation data
+        $this->logger->info('Order Created:', ['order_id' => $order->getId(), 'order_data' => $order->getData()]);
+
+        // Extract order data and send to the webhook URL
+        $this->sendWebhook($order, 'order_created');
+
+        $this->logger->info('OrderCreateWebhook: execute method finished');
+    }
+
+    private function sendWebhook($order, $eventType)
+    {
+        $this->logger->info('OrderCreateWebhook: sendWebhook method started');
+
+        // Webhook URL
+        $url = $this->getWebhookUrl();
+        $this->logger->info('OrderCreateWebhook: Webhook URL', ['url' => $url]);
+
+        // Get Store UUID and add to query parameters
+        $storeUuid = $this->getStoreUuid();
+        $this->logger->info('UUID: ', ['uuid' => $storeUuid]);
+        $url .= '?channel=' . urlencode($storeUuid);
+        $this->logger->info('Webhook URL', ['url' => $url]);
+
+        // Prepare payload
+        $data = [
+            'event' => $eventType,
+            'order_id' => $order->getId(),
+            'order_data' => $order->getData()
+        ];
+
+        // Log webhook payload
+        $this->logger->info('Sending Webhook:', ['url' => $url, 'payload' => $data]);
+
+        // Send the webhook
+        $this->makeHttpPostRequest($url, $data);
+
+        $this->logger->info('OrderCreateWebhook: sendWebhook method finished');
+    }
+
+
+    private function makeHttpPostRequest($url, $data)
+    {
+        $this->logger->info('URL:', ['url' => $url]);
+        $this->logger->info('Data:', ['data' => $data]);
+
+        // Perform the API request
+        $payloadJson = json_encode($data);
+        if ($payloadJson === false) {
+            $this->logger->error('Payload Webhook failed: Unable to encode JSON.');
+            throw new \RuntimeException('Failed to encode payload to JSON.');
+        }
+
+        $this->logger->info('Payload Webhook:', ['response' => $payloadJson]);
+
+        // Set headers and post the data
+        $this->curl->addHeader('Content-Type', 'application/json');
+        $this->curl->post($url, $payloadJson);
+        $statusCode = $this->curl->getStatus();
+        $responseBody = $this->curl->getBody();
+
+        // Log status code and response body
+        $this->logger->info('Webhook Response Status:', ['status' => $statusCode]);
+        $this->logger->info('Webhook Response Body:', ['response' => $responseBody]);
+
+        // Decode the response
+        $response = json_decode($responseBody, true);
+        if (json_last_error() !== JSON_ERROR_NONE) {
+            $this->logger->error('Failed to decode webhook response:', ['error' => json_last_error_msg()]);
+        } else {
+            $this->logger->info('Response Webhook:', ['response' => $response]);
+        }
+    }
+
+    private function getWebhookUrl(): string
+    {
+        return UData::WEBHOOK_URL;
+    }
+
+    private function getStoreUuid(): string
+    {
+        $storeId = $this->storeManager->getStore()->getId();
+        return $storeId;
+        //return $this->storeManager->getStore()->getConfig('general/store_information/store_id');
+    }
+}
diff --git a/Observer/OrderUpdateWebhook.php b/Observer/OrderUpdateWebhook.php
new file mode 100644
index 0000000..ad2a4ad
--- /dev/null
+++ b/Observer/OrderUpdateWebhook.php
@@ -0,0 +1,76 @@
+<?php
+
+namespace BobGroup\BobGo\Observer;
+
+use Magento\Framework\Event\Observer;
+use Magento\Framework\Event\ObserverInterface;
+use Magento\Framework\HTTP\Client\Curl;
+use Magento\Store\Model\StoreManagerInterface;
+use BobGroup\BobGo\Model\Carrier\UData;
+use Psr\Log\LoggerInterface;
+
+class OrderUpdateWebhook implements ObserverInterface
+{
+    protected Curl $curl;
+    protected LoggerInterface $logger;
+    protected StoreManagerInterface $storeManager;
+
+    public function __construct(LoggerInterface $logger, Curl $curl, StoreManagerInterface $storeManager)
+    {
+        $this->logger = $logger;
+        $this->curl = $curl;
+        $this->storeManager = $storeManager;
+    }
+
+    public function execute(Observer $observer)
+    {
+        $order = $observer->getEvent()->getOrder();
+        if (!$order) {
+            return;
+        }
+
+        $this->sendWebhook($order, 'order_updated');
+    }
+
+    private function sendWebhook($order, $eventType)
+    {
+        $url = $this->getWebhookUrl();
+
+        // Get Store UUID and add to query parameters
+        $storeUuid = $this->getStoreUuid();
+        $url .= '?channel=' . urlencode($storeUuid);
+
+        $data = [
+            'event' => $eventType,
+            'order_id' => $order->getId(),
+            'order_data' => $order->getData()
+        ];
+
+        $this->makeHttpPostRequest($url, $data);
+    }
+
+    private function makeHttpPostRequest($url, $data)
+    {
+        $payloadJson = json_encode($data);
+        if ($payloadJson === false) {
+            throw new \RuntimeException('Failed to encode payload to JSON.');
+        }
+
+        $this->curl->addHeader('Content-Type', 'application/json');
+        $this->curl->post($url, $payloadJson);
+        $statusCode = $this->curl->getStatus();
+        $responseBody = $this->curl->getBody();
+
+        $response = json_decode($responseBody, true);
+    }
+
+    private function getWebhookUrl(): string
+    {
+        return UData::WEBHOOK_URL;
+    }
+
+    private function getStoreUuid(): string
+    {
+        return $this->storeManager->getStore()->getConfig('general/store_information/store_id');
+    }
+}
diff --git a/etc/events.xml b/etc/events.xml
index bfb5e96..3e71bc3 100644
--- a/etc/events.xml
+++ b/etc/events.xml
@@ -1,3 +1,9 @@
 <?xml version="1.0"?>
 <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
+    <event name="sales_order_place_after">
+        <observer name="order_create_webhook" instance="BobGroup\BobGo\Observer\OrderCreateWebhook"/>
+    </event>
+    <event name="sales_order_save_after">
+        <observer name="order_update_webhook" instance="BobGroup\BobGo\Observer\OrderUpdateWebhook"/>
+    </event>
 </config>
diff --git a/etc/frontend/di.xml b/etc/frontend/di.xml
index bc1aaeb..25a80a9 100644
--- a/etc/frontend/di.xml
+++ b/etc/frontend/di.xml
@@ -13,4 +13,12 @@
             <argument name="logger" xsi:type="object">Psr\Log\LoggerInterface</argument>
         </arguments>
     </type>
+    <type name="BobGroup\BobGo\Observer\OrderCreateWebhook">
+        <arguments>
+            <argument name="logger" xsi:type="object">Psr\Log\LoggerInterface</argument>
+            <argument name="curl" xsi:type="object">Magento\Framework\HTTP\Client\Curl</argument>
+            <argument name="storeManager" xsi:type="object">Magento\Store\Model\StoreManagerInterface</argument>
+        </arguments>
+    </type>
+
 </config>
-- 
GitLab