diff --git a/Block/System/Config/TestConnection.php b/Block/System/Config/TestConnection.php
new file mode 100644
index 0000000..86fa7e2
--- /dev/null
+++ b/Block/System/Config/TestConnection.php
@@ -0,0 +1,35 @@
+unsScope()->unsCanUseWebsiteValue()->unsCanUseDefaultValue();
+ return parent::render($element);
+ }
+
+ protected function _getElementHtml(AbstractElement $element)
+ {
+ return $this->_toHtml();
+ }
+
+ public function getCustomUrl()
+ {
+ return $this->getUrl('whiorders/connection/index');
+ }
+
+ public function getButtonHtml()
+ {
+ $button = $this->getLayout()->createBlock('Magento\Backend\Block\Widget\Button')->setData(['id' => 'whi_test_connection', 'label' => 'Test Connection',]);
+ return $button->toHtml();
+ }
+}
\ No newline at end of file
diff --git a/Controller/Adminhtml/Connection/Index.php b/Controller/Adminhtml/Connection/Index.php
new file mode 100644
index 0000000..948d0d8
--- /dev/null
+++ b/Controller/Adminhtml/Connection/Index.php
@@ -0,0 +1,41 @@
+clientFactory = $clientFactory;
+ $this->configHelper = $configHelper;
+
+ parent::__construct($context);
+
+ $baseUrl = $this->configHelper->getBaseUrl();
+ $token = $this->configHelper->getApiToken();
+
+ $client = $this->clientFactory->create(['config' => [
+ 'http_errors' => false,
+ 'base_uri' => $baseUrl,
+ 'headers' => [
+ 'Content-type' => 'application/json',
+ 'Authorization' => "Bearer $token"
+ ]
+ ]]);
+
+ $result = $client->request('GET', 'whi/connectiontest');
+ http_response_code($result->getStatusCode());
+ exit;
+ }
+
+ public function execute() { }
+}
\ No newline at end of file
diff --git a/Helper/ConfigHelper.php b/Helper/ConfigHelper.php
new file mode 100644
index 0000000..dab6185
--- /dev/null
+++ b/Helper/ConfigHelper.php
@@ -0,0 +1,26 @@
+scopeConfig = $scopeConfig;
+ }
+
+ public function getApiToken()
+ {
+ return $this->scopeConfig->getValue('whiorders/api/api_token', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
+ }
+
+ public function getBaseUrl()
+ {
+ return $this->scopeConfig->getValue('whiorders/api/base_url', \Magento\Store\Model\ScopeInterface::SCOPE_STORE);
+ }
+}
\ No newline at end of file
diff --git a/Observer/Checkout/SendWHIOrder.php b/Observer/Checkout/SendWHIOrder.php
new file mode 100644
index 0000000..e3feeef
--- /dev/null
+++ b/Observer/Checkout/SendWHIOrder.php
@@ -0,0 +1,99 @@
+clientFactory = $clientFactory;
+ $this->configHelper = $configHelper;
+ $this->logger = $logger;
+ }
+
+ function execute(Observer $observer)
+ {
+ $order = $observer->getEvent()->getOrder();
+ $shippingAddress = $order->getShippingAddress();
+ $billingAddress = $order->getBillingAddress();
+
+ $whiOrder = [
+ 'metadata' => [
+ 'platform' => 'Magento',
+ 'plaformOrderId' => $order->getId(),
+ ],
+ 'billingAddress' => [
+ 'firstName' => $billingAddress->getFirstname(),
+ 'lastName' => $billingAddress->getLastname(),
+ 'address1' => $billingAddress->getStreet()[0],
+ 'address2' => count($billingAddress->getStreet()) > 1 ? $billingAddress->getStreet()[1] : null,
+ 'city' => $billingAddress->getCity(),
+ 'state' => $billingAddress->getRegion(),
+ 'zip' => $billingAddress->getPostCode(),
+ 'email' => $billingAddress->getEmail(),
+ 'phone' => $billingAddress->getTelephone()
+ ],
+ 'shippingAddress' => [
+ 'firstName' => $shippingAddress->getFirstname(),
+ 'lastName' => $shippingAddress->getLastname(),
+ 'address1' => $shippingAddress->getStreet()[0],
+ 'address2' => count($shippingAddress->getStreet()) > 1 ? $shippingAddress->getStreet()[1] : null,
+ 'city' => $shippingAddress->getCity(),
+ 'state' => $shippingAddress->getRegion(),
+ 'zip' => $shippingAddress->getPostCode(),
+ ],
+ 'amounts' => [
+ 'shipping' => $order->getShippingAmount(),
+ 'tax' => $order->getTaxAmount(),
+ 'subtotal' => $order->getSubtotal(),
+ 'total' => $order->getGrandTotal(),
+ ],
+ 'parts' => []
+ ];
+
+ foreach ($order->getAllItems() as $item) {
+ $part = [
+ 'sku' => $item->getSku(),
+ 'price' => $item->getPrice(),
+ 'salesTax' => $item->getTaxAmount(),
+ 'discount' => $item->getDiscountAmount(),
+ 'quantity' => $item->getQtyOrdered(),
+ ];
+
+ array_push($whiOrder['parts'], $part);
+ }
+
+ $baseUrl = $this->configHelper->getBaseUrl();
+ $token = $this->configHelper->getApiToken();
+
+ $client = $this->clientFactory->create(['config' => [
+ 'base_uri' => $baseUrl,
+ 'headers' => [
+ 'Content-type' => 'application/json',
+ 'Authorization' => "Bearer $token"
+ ]
+ ]]);
+
+ try {
+ $client->request('POST', 'whi/orders', [
+ 'body' => json_encode($whiOrder)
+ ]);
+ } catch (GuzzleException $exception) {
+ $this->logger->error('Error sending ' . $order->getId() . ' to WHI for processing. Server returned HTTP response code ' . $exception->getCode());
+ }
+ }
+}
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..f984f8a
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,26 @@
+{
+ "name": "soundpress/whi-orders",
+ "description": "An integration with WHI's Orderlink API",
+ "require": {
+ "php": "8.1|8.2",
+ "magento/project-community-edition": "2.4.6-p9"
+ },
+ "authors": [
+ {
+ "name": "Tom Raterman",
+ "email": "tom@soundpress.com",
+ "homepage": "https://www.soundpress.com",
+ "role": "Developer"
+ }
+ ],
+ "type": "magento2-module",
+ "license": "proprietary",
+ "autoload": {
+ "files": [
+ "registration.php"
+ ],
+ "psr-4": {
+ "SoundPress\\WhiOrders\\": ""
+ }
+ }
+ }
\ No newline at end of file
diff --git a/etc/adminhtml/routes.xml b/etc/adminhtml/routes.xml
new file mode 100644
index 0000000..8522ff0
--- /dev/null
+++ b/etc/adminhtml/routes.xml
@@ -0,0 +1,11 @@
+
+
Note: Currently only works in Chromium-based browsers (Firefox blocks script execution).
\ No newline at end of file