Magento customization for
webhooks support
Abstract This document describes customization for webhooks support in Magento, to enable events in
Magento to trigger event-driven flows in IBM App Connect.
CONTENTS
1 Introduction ......................................................................................................................................................................... 3
2 Customization for webhooks support in magento ........................................................................................................ 3
2.1 Overview: Implement event logic in all required modules ................................................................................... 3
Background ....................................................................................................................................................... 3
2.2 High-level steps to configure Magento webhooks TO use with IBM App Connect .......................................... 4
2.3 Implementing event logic for Magento objects ...................................................................................................... 6
2.3.1 Cart ......................................................................................................................................................... 6
2.3.2 Category .............................................................................................................................................. 14
2.3.3 Credit Memo ....................................................................................................................................... 19
2.3.4 Customer ............................................................................................................................................. 27
2.3.5 Invoice ................................................................................................................................................. 34
2.3.6 Order .................................................................................................................................................... 42
2.3.7 Product ................................................................................................................................................ 53
2.3.8 Shipment ............................................................................................................................................. 60
2.4 Applying changes to Magento logic ........................................................................................................................ 68
3 Considerations before Upgrading the Magento Version ............................................................................................. 68
4 Alternative technique: Implement the logic in a singular module (Plugin approach) ........................................... 68
5 Magento Logging ............................................................................................................................................................... 69
1 INTRODUCTION
To enable Magento events to trigger event-driven flows in IBM App Connect, some customization for webhooks
support is needed in Magento, as described in this document.
Magento (1 and 2) offers a way for some code to trigger an event, that is then picked by an EventManager which allows observer classes to react to that event.
Working with events and observers is one of the ways to extend the core functionalities of the Magento
Platform. The implementation of the events and observers in Magento 2 is based on the Publish-Subscribe
pattern. Using Magento 2 events and observers, you can create and run custom code in response to a specific
native or custom Magento event.
The required logic needs to be incorporated into the desired Magento modules with help of events and observer classes.
2 CUSTOMIZATION FOR WEBHOOKS SUPPORT IN MAGENTO
This document describes the Magento customization using the technique to configure a Magento webhook for
specific events, for specific objects or operations, in multiple modules across the Magento. This involves some
administration changes and changing Magento codebase files.
An alternative technique is to implement the logic for all supported events in one module. This module can be
treated as a new extension and imported directly into your Magento instance. This technique is outlined below,
but is not described in detail in this document.
2.1 OVERVIEW: IMPLEMENT EVENT LOGIC IN ALL REQUIRED MODULES
Magento is made of numerous default modules like checkout, customer, products, and so on. So, if you only
want to handle events for specific objects or operations in Magento, you need update or add files for only the
modules required for those events.
BACKGROUND
If you are not familiar with Magento concepts and code structure for implementing event
logic, this section provides an overview.
If you want to get started implementing the logic required, see High-level steps to be
performed by user to configure webhooks for Magento.
The code changes required for Magento events are in different modules across the Magento
codebase. The root path where the modules exist is \<magento-root-folder>\vendor\magento\
Within this folder, there are module subfolders for different objects; for example, see the
image on the right.
To enable events for a Magento object to trigger flows in IBM App Connect, you complete the following
general steps to implement the logic needed in Magento:
1. Define the events in the events.xml file for the module in it’s /etc folder
2. For each event, create an observer file in the module’s /observer folder
3. When you have implemented the logic for the Magento object events that you want to use, you apply the
changes made in the preceding steps, by running CLI commands
More overview information is provided in the following sections.
2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT
To enable an event on a Magento object to trigger flows in IBM App Connect, you start by creating a flow in App
Connect to get a callback URL for the Magento event, and then as a Magento administrator configure the URL
and logic needed to implement the event. You need do this only once for the Magento event in the IBM App
Connect instance; thereafter, other flows in that IBM App Connect instance can be triggered by the same
Magento event.
1. In IBM App Connect, connect to your Magento system
2. Create a new event-driven flow to be triggered by a Magento event
3. Select the Magento object and event that you want to use; for example: SalesOrder / New sales order
For the event, a Webhooks callback URL is generated and displayed. The URL would look like the following:
https:// webhook-connector-provider-produk.eu-gb.appconnect.ibm.com /webhooks/0swtfru7o/magento/Product/81a4469b-dcaf-5117-831179734c82e597
4. Copy the generated URL
5. Login to the Magento installation Admin panel, using admin credentials
6. Go to System > Other settings > Custom variables
7. Click Add New Variable, and configure the custom variable for the Magento event. The custom variable has
a name in the following format (lowercase): <objectName>_<action> where:
• <objectName> is the lowercase name of the object in Magento (as a single word); for example, cart,
creditmemo, or customer
• <action> is one of created, updated, or deleted (for the App Connect events New, Update, or Delete)
For example: In IBM App Connect, you choose to trigger a flow with the Magento / New customer event,
then in Magento you would add the custom variable customer_created as shown in the following figure:
ADMIN > SYSTEM > OTHER SETTINGS > CUSTOM VARIABLES
8. Click Save
9. Add the code (logic) required for the Magento event and then apply the changes:
a. Add the logic for the Magento object, as described in Implementing logic for Magento events.
Generally:
i. Define the event in the events.xml file for the module
ii. Create an observer file for the event in the module’s observer folder
b. Apply the changes made in the preceding steps, by running CLI commands, as described in
Applying changes to Magento logic
Note: The information in this document is to customize a Magento system for use with one IBM App Connect
service. If you want to use the same Magento system with several IBM App Connect services, you will need to
configure a different custom variable (callback URL) for each IBM App Connect service, and update the PHP
logic to handle all those custom variables.
2.3 IMPLEMENTING EVENT LOGIC FOR MAGENTO OBJECTS
This section explains what you should do to implement the logic for the different events on Magento objects.
• Cart
• Category
• Credit memo
• Customer
• Invoice
• Order
• Product
• Shipment
2.3.1 CART
If you want to trigger an App Connect flow with a Cart event, like in App Connect the Magento event New cart,
complete the following steps.
Note: In addition to the following steps, you must configure a custom variable for each Magento event that you want to use, as described in the section 2.2 High-level steps to configure webhooks for Magento for use with IBM App Connect. The custom variable names for the events in App Connect are as follows:
Magento event in App Connect Custom variable name in Magento Observer file name in Magento New sales cart cart_created SetCartProductAddObserver.php Updated sales cart cart_updated SetCartProductUpdateObserver.php Deleted sales cart cart_deleted SetCartProductDeleteObserver.php
Steps to implement event logic:
1. Add following events to the events.xml file located at: <root-magento-folder>/vendor/magento/module-checkout/etc/events.xml
If the events.xml file does not exist, then create a new file with same name.
<?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="checkout_cart_add_product_complete">
<observer name="checkout_cart_product_add_action3"
instance="Magento\Checkout\Observer\SetCartProductAddObserver" />
</event>
<event name="checkout_cart_update_items_after">
<observer name="checkout_cart_product_update_action"
instance="Magento\Checkout\Observer\SetCartProductUpdateObserver" /> </event>
<event name="sales_quote_remove_item">
<observer name="checkout_cart_product_delete_action"
instance="Magento\Checkout\Observer\SetCartProductDeleteObserver" /> </event>
</config>
2. For each event create an observer file in the module’s observer folder with the same name mentioned in the instance variable for the events created in the preceding step.
So, the <root-magento-folder>/vendor/magento/module-checkout/observer/ folder will
include the following .php files, which you should ensure have the file contents given in the following code
examples:
o SetCartProductAddObserver.php o SetCartProductUpdateObserver.php o SetCartProductDeleteObserver.php
If the /observer folder does not exist, then create a new folder with the same name.
3. Apply the changes by running CLI commands, as described in Applying changes to Magento logic. (Note: If
you want to configure Magento for multiple objects' events, you can make the changes for each object that
you want to use, and then apply the changes for all objects in one step by running the CLI commands once.)
Contents of SetCartProductAddObserver.php
<?php
namespace Magento\Checkout\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class SetCartProductAddObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'cart_created';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
$cart = $objectManager->get('\Magento\Checkout\Model\Cart'); //
retrieve quote items array
$items = $cart->getQuote()->getAllItems();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
//This logic is added to only add the last added item to the cart, so as to
know the newly added item
$max = 0;
$lastItem = null;
foreach ($itemsNew as $key => $value) {
if ( $value["item_id"] > $max) {
$max = $value["item_id"];
$lastItem = $value;
}
}
$lastItemdata = array();
array_push( $lastItemdata, $lastItem);
//if the method is post
$urlPost = $modelActionURL;
$product = $observer->getEvent()->getProduct();
$params = array('Action' => 'CART_ADDED',
'Module' => 'CART',
'posturl'=> $modelActionURL,
"cart_id" => $cart->getQuote()->getId(),
"id" => $cart->getQuote()->getId()
);
foreach ($cart->getQuote()->getData() as $key => $value) {
$params[$key] = $value;
}
$params["store_id"] = $cart->getQuote()->getStoreId();
$params["items"] = $lastItemdata; //$itemsNew;
$params["billing_address"] = ($cart->getQuote()->getBillingAddress()-
>getData());
$params["billing_address"]["id"] = ($cart->getQuote()-
>getBillingAddress()->getId());
$params["shipping_address"] = ($cart->getQuote()->getShippingAddress()-
>getData());
$params["shipping_address"]["id"] = ($cart->getQuote()-
>getShippingAddress()->getId());
$customerFactory = $objectManager-
>get('\Magento\Customer\Model\CustomerFactory')->create();
$customerdetails = $customerFactory->load($params["customer_id"]);
//$params["customer"] = json_encode($customerdetails->getData());
$params["customer"] = ($customerdetails->getData());
$params["customer"]["id"] = $params["customer_id"];
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed----
----------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-----------------------------------------------------
----------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed------------------
--------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
Contents of SetCartProductUpdateObserver. php
<?php
namespace Magento\Checkout\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class SetCartProductUpdateObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$quoteItems = $observer->getCart()->getQuote()->getAllVisibleItems();
$customVar = 'cart_updated';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
//if the method is post
$urlPost = $modelActionURL;
$cart = $objectManager->get('\Magento\Checkout\Model\Cart');
// retrieve quote items collection
$itemsCollection = $cart->getQuote()->getItemsCollection();
// get array of all items what can be display directly
$itemsVisible = $cart->getQuote()->getAllVisibleItems();
// retrieve quote items array
$items = $cart->getQuote()->getAllItems();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
$params = array('Action' => 'CART_UPDATED',
'Module' => 'CART',
'posturl'=> $modelActionURL,
"cart_id" => $cart->getQuote()->getId(),
"id" => $cart->getQuote()->getId()
);
foreach ($cart->getQuote()->getData() as $key => $value) {
$params[$key] = $value;
}
$params["items"] = $itemsNew;
$params["billing_address"] = ($cart->getQuote()->getBillingAddress()-
>getData());
$params["billing_address"]["id"] = ($cart->getQuote()-
>getBillingAddress()->getId());
$params["shipping_address"] = ($cart->getQuote()->getShippingAddress()-
>getData());
$params["shipping_address"]["id"] = ($cart->getQuote()-
>getShippingAddress()->getId());
$customerFactory = $objectManager-
>get('\Magento\Customer\Model\CustomerFactory')->create();
$customerdetails = $customerFactory->load($params["customer_id"]);
//$params["customer"] = json_encode($customerdetails->getData());
$params["customer"] = ($customerdetails->getData());
$params["customer"]["id"] = $params["customer_id"];
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed----
----------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-----------------------------------------------------
----------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed------------------
--------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
Contents of SetCartProductDeleteObserver.php
<?php
namespace Magento\Checkout\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class SetCartProductDeleteObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$item = $observer->getEvent()->getData('quote_item');
$cartData = $this->checkoutSession->getQuote()->getAllVisibleItems();
$cartDataCount = count( $cartData );
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'cart_deleted';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode('cart_deleted');
$modelActionURL = $modelAction->getPlainValue();
$cart = $objectManager->get('\Magento\Checkout\Model\Cart');
// retrieve quote items collection
$itemsCollection = $cart->getQuote()->getItemsCollection();
// get array of all items what can be display directly
$itemsVisible = $cart->getQuote()->getAllVisibleItems();
// retrieve quote items array
$items = $cart->getQuote()->getAllItems();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
//if the method is post
$urlPost = $modelActionURL;
$product = $observer->getEvent()->getProduct();
$params = array('Action' => 'CART_DELETED',
'Module' => 'CART',
'posturl'=> $modelActionURL,
"cart_id" => $cart->getQuote()->getId(),
"id" => $cart->getQuote()->getId()
);
foreach ($item->getData() as $key => $value) {
$params[$key] = $value;
}
foreach ($cart->getQuote()->getData() as $key => $value) {
$params[$key] = $value;
}
$params["items"] = $itemsNew;
$params["billing_address"] = ($cart->getQuote()->getBillingAddress()-
>getData());
$params["billing_address"]["id"] = ($cart->getQuote()-
>getBillingAddress()->getId());
$params["shipping_address"] = ($cart->getQuote()->getShippingAddress()-
>getData());
$params["shipping_address"]["id"] = ($cart->getQuote()-
>getShippingAddress()->getId());
$customerFactory = $objectManager-
>get('\Magento\Customer\Model\CustomerFactory')->create();
$customerdetails = $customerFactory->load($params["customer_id"]);
$params["customer"] = ($customerdetails->getData());
$params["customer"]["id"] = $params["customer_id"];
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION
> 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed----
----------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-----------------------------------------------------
----------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed------------------
--------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
2.3.2 CATEGORY
If you want to trigger an App Connect flow with a category event, like in App Connect the Magento event New
category, complete the following steps.
Note: In addition to the following steps, you must configure a custom variable for each Magento event that you want to use, as described in the section 2.2 High-level steps to configure webhooks for Magento for use with IBM App Connect. The custom variable names for the events in App Connect are as follows:
Magento event in App Connect Custom variable name in Magento Observer file name in Magento New category category_created CategoryCatalogSave.php Updated category category_updated CategoryCatalogSave.php Deleted category category_deleted CategoryCatalogDelete.php
Steps to implement event logic:
1. Add the following events to the events.xml file located at: <root-magento-folder>/vendor/magento/module-catalog/etc/events.xml
If the events.xml file does not exist, then create a new file with that name.
<?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="catalog_category_save_after">
<observer name="CategoryCatalogSave"
instance="Magento\Catalog\Observer\CategoryCatalogSave" />
</event>
<event name="catalog_controller_category_delete">
<observer name="CategoryCatalogDelete"
instance="Magento\Catalog\Observer\CategoryCatalogDelete" />
</event>
</config>
2. For each event create an observer file in the module’s observer folder with the same name mentioned in the instance variable for the events created in the preceding step.
So, the <root-magento-folder>/vendor/magento/module-catalog/observer/ folder will include
the following php files, for which the file contents are given in the following code examples:
• CategoryCatalogSave.php
• CategoryCatalogDelete.php
If the /observer folder does not exist, then create a new folder with the same name.
3. Apply the changes by running CLI commands, as described in Applying changes to Magento logic. (Note: If
you want to configure Magento for multiple objects' events, you can make the changes for each object that
you want to use, and then apply the changes for all objects in one step by running the CLI commands once.)
Content of CategoryCatalogSave.php
<?php
namespace Magento\Catalog\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class CategoryCatalogSave implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$this->category = $observer->getEvent()->getCategory();
//$product = $observer->getProduct();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
//Logic to check if category created or updated
if($this->category['created_at'] && $this->category['updated_at']) { $cDt =
($this->category['created_at']);
$uDt = ($this->category['updated_at']);
if ($uDt > $cDt) {
$customVar = 'category_updated';
$modelAction = $objectManager-
>get('Magento\Variable\Model\Variable')->loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
$EventAction = 'CATEGORY_UPDATED';
}else {
$customVar = 'category_created';
$modelAction = $objectManager-
>get('Magento\Variable\Model\Variable')->loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
$EventAction = 'CATEGORY_CREATED';
}
}
$category1 = $observer->getEvent()->getCategory();
//if the method is post
$urlPost = $modelActionURL;
$params = array('Action' => $EventAction, 'Module'
=> 'CATEGORY', 'posturl'=>
$modelActionURL
);
foreach ($category1->getData() as $key => $value) {
$params[$key] = $value;
}
foreach ($this->category as $key => $value) {
$params[$key] = $value;
}
$params['id'] = $this->category['entity_id'];
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin" =>
"*", CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION =>
1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed----
----------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-----------------------------------------------------
----------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed------------------
--------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
Content of CategoryCatalogDelete.php
<?php
namespace Magento\Catalog\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class CategoryCatalogDelete implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$this->category = $observer->getEvent()->getCategory();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'category_deleted';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
$category1 = $observer->getEvent()->getCategory();
//if the method is post
$urlPost = $modelActionURL;
$params = array( 'Action' => "CATEGORY_DELETED",
'Module' => 'CATEGORY',
'posturl'=> $modelActionURL);
foreach ($category1->getData() as $key => $value) {
$params[$key] = $value;
}
foreach ($this->category as $key => $value) {
$params[$key] = $value;
}
$params['id'] = $this->category['entity_id'];
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed----
----------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-----------------------------------------------------
----------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed------------------
--------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
2.3.3 CREDIT MEMO
If you want to trigger an App Connect flow with a credit memo event, like in App Connect the Magento event
New sales credit memo, complete the following steps.
Note: In addition to the following steps, you must configure a custom variable for each Magento event that you want to use, as described in the section 2.2 High-level steps to configure webhooks for Magento for use with IBM App Connect. The custom variable names for the events in App Connect are as follows:
Magento event in App Connect Custom variable name in Magento Observer file name in Magento New sales credit memo creditmemo_created CreditMemoSaveObserver.php Updated sales credit memo creditmemo_updated CreditMemoUpdateObserver.php Deleted sales credit memo creditmemo_deleted CreditMemoDeleteObserver.php
Steps to implement event logic:
1. Add the following events to the events.xml file located at <root-magento-folder>/vendor/magento/module-quote/etc/events.xml
If the events.xml file does not exist, then create a new file with same name.
<?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_creditmemo_save_after">
<observer name="CreditMemoSaveAction"
instance="Magento\Quote\Observer\CreditMemoSaveObserver" />
</event>
<event name="sales_order_creditmemo_save_after">
<observer name="CreditMemoUpdateAction"
instance="Magento\Quote\Observer\CreditMemoUpdateObserver" />
</event>
<event name="sales_order_creditmemo_delete_after">
<observer name="CreditMemoDeleteAction"
instance="Magento\Quote\Observer\CreditMemoDeleteObserver" />
</event>
</config>
Note: In Magento the event, sales_order_creditmemo_save_after, triggers both the _created and _updated
actions, so in IBM App Connect triggers flows with the events ‘New credit memo’ and ‘Updated credit memo’. If
you want to perform different actions for updated credit memos, you can use a ‘Retrieve credit memos’ action
and then an If node with logic based on the created date and updated date.
2. For each event create an observer file in the module’s observer folder with the same name mentioned in the instance variable for the events created in the preceding step.
So, the <root-magento-folder>/vendor/magento/module-quote/observer/ folder will include
the following php files, which you should ensure have the file contents given in the following code
examples:
o CreditMemoSaveObserver.php
o CreditMemoUpdateObserver.php
o CreditMemoDeleteObserver.php
If the /observer folder does not exist, then create a new folder with the same name.
3. Apply the changes by running CLI commands, as described in Applying changes to Magento logic. (Note: If
you want to configure Magento for multiple objects' events, you can make the changes for each object that
you want to use, and then apply the changes for all objects in one step by running the CLI commands once.)
Content of CreditMemoSaveObserver.php
<?php
namespace Magento\Quote\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class CreditMemoSaveObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$creditMemo = $observer->getEvent()->getCreditmemo();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'creditmemo_created';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
//if the method is post
$urlPost = $modelActionURL;
$params = array( 'Action' => 'CREDITMEMO_CREATED',
'Module' => 'CREDIT MEMO',
'posturl'=> $modelActionURL);
foreach ($creditMemo->getData() as $key => $value) {
$params[$key] = $value;
}
$order1 = $objectManager->create('\Magento\Sales\Model\Order')-
>load($params["order_id"]);
$order_data= $order1->getData();
foreach ($order_data as $key => $value) {
$params[$key] = $value;
}
$customer = $objectManager->create('Magento\Customer\Model\Customer')-
>load($params["customer_id"]);
foreach ($customer->getData() as $key => $value) {
$params[$key] = $value;
}
$items = $order1->getAllItems();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
$params["items"] = $itemsNew;
$params["billing_address"] = ($order1->getBillingAddress()->getData());
$params["billing_address"]["id"] = ($order1->getBillingAddress()-
>getId());
$params["shipping_address"] = ($order1->getShippingAddress()-
>getData());
$params["shipping_address"]["id"] = ($order1->getBillingAddress()-
>getId());
$params["customer"] = ($customer->getData());
$params["customer"]["id"] = $params["customer_id"];
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n------------------------------------------------------
---------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed---------
-----------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n----------------------------------------------------------
-----------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed-----------------------
---------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
Content of CreditMemoUpdateObserver.php
<?php
namespace Magento\Quote\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class CreditMemoUpdateObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository
*/
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg)
{
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$creditMemo = $observer->getEvent()
->getCreditmemo();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'creditmemo_updated';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')
->loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
//if the method is post
$urlPost = $modelActionURL;
$params = array(
'Action' => 'CREDITMEMO_UPDATED',
'Module' => 'CREDIT MEMO',
'posturl' => $modelActionURL
);
foreach ($creditMemo->getData() as $key => $value)
{
$params[$key] = $value;
}
$order1 = $objectManager->create('\Magento\Sales\Model\Order')
->load($params["order_id"]);
$order_data = $order1->getData();
foreach ($order_data as $key => $value)
{
$params[$key] = $value;
}
$customer = $objectManager->create('Magento\Customer\Model\Customer')
->load($params["customer_id"]);
foreach ($customer->getData() as $key => $value)
{
$params[$key] = $value;
}
$items = $order1->getAllItems();
$itemsNew = array();
foreach ($items as $item)
{
array_push($itemsNew, $item->getData());
}
$params["items"] = $itemsNew;
$params["billing_address"] = ($order1->getBillingAddress()
->getData());
$params["billing_address"]["id"] = ($order1->getBillingAddress()
->getId());
$params["shipping_address"] = ($order1->getShippingAddress()
->getData());
$params["shipping_address"]["id"] = ($order1->getBillingAddress()
->getId());
$params["customer"] = ($customer->getData());
$params["customer"]["id"] = $params["customer_id"];
if (!empty($modelActionURL))
{
try
{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-Length"
=> strlen($params_json) , "Access-Control-Request-Headers" => "X-Requested-With",
"AccessControl-Allow-Origin" => "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false];
$this
->_curl
->setHeaders($headers);
$this
->_curl
->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this
->_curl
->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this
->_curl
->post($urlPost, $params_json);
$response2 = $this
->_curl
->getBody();
if ($response2 && $response2 != "Message published")
{
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n---------------------------------------------------
------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch(\Exception $e)
{
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed------
--------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------------
--------------------------------";
$this->logWebhookErrors($msg);
}
}
else
{
$msg = "";
$msg .= "\n--------------The event was not relayed--------------------
------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not defined
in Magento Admin";
$msg .= "\n-----------------------------------------------------------
------------------";
$this->logWebhookErrors($msg);
}
}
}
Content of CreditMemoDeleteObserver.php
<?php
namespace Magento\Quote\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class CreditMemoDeleteObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$creditMemo = $observer->getEvent()->getCreditmemo();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'creditmemo_deleted';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
//if the method is post
$urlPost = $modelActionURL;
$params = array( 'Action' => 'CREDITMEMO_DELETED',
'Module' => 'CREDIT MEMO', 'posturl'=>
$modelActionURL);
foreach ($creditMemo->getData() as $key => $value) {
$params[$key] = $value;
}
$order1 = $objectManager->create('\Magento\Sales\Model\Order')-
>load($params["order_id"]);
$order_data= $order1->getData();
foreach ($order_data as $key => $value) {
$params[$key] = $value;
}
$customer = $objectManager->create('Magento\Customer\Model\Customer')-
>load($params["customer_id"]);
foreach ($customer->getData() as $key => $value) {
$params[$key] = $value;
}
$items = $order1->getAllItems();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
$params["items"] = $itemsNew;
$params["billing_address"] = ($order1->getBillingAddress()->getData());
$params["billing_address"]["id"] = ($order1->getBillingAddress()-
>getId());
$params["shipping_address"] = ($order1->getShippingAddress()-
>getData());
$params["shipping_address"]["id"] = ($order1->getBillingAddress()-
>getId());
$params["customer"] = ($customer->getData());
$params["customer"]["id"] = $params["customer_id"];
if(!empty($modelActionURL)) { try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed----
----------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-----------------------------------------------------
----------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed------------------
--------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
2.3.4 CUSTOMER
If you want to trigger an App Connect flow with a customer event, like in App Connect the Magento event New
customer, complete the following steps.
Note: In addition to the following steps, you must configure a custom variable for each Magento event that you want to use, as described in the section 2.2 High-level steps to configure webhooks for Magento for use with IBM App Connect. The custom variable names for the events in App Connect are as follows:
Magento event in App Connect Custom variable name in Magento Observer file name in Magento New customer customer_created CustomerAfterAddrSaveObserver.php Updated customer customer_updated CustomerAfterAddrSaveObserver.php Deleted customer customer_deleted CustomerDeleteAfter.php
Steps to implement event logic:
1. Add the following events to the events.xml file located at: <root-magento-folder>/vendor/magento/module-customer/etc/events.xml
If the events.xml file does not exist, then create a new file with that name.
<?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="customer_save_after">
<observer name="obs_customer_account_before"
instance="Magento\Customer\Observer\CustomerAfterAddrSaveObserver"
shared="false" />
</event>
<event name="customer_delete_commit_after">
<observer name="CustomerDeleteAfter"
instance="Magento\Customer\Observer\CustomerDeleteAfter" />
</event>
</config>
2. For each event create an observer file in the module’s observer folder with the same name mentioned in the instance variable for the events created in the preceding step.
So, the <root-magento-folder>/vendor/magento/module-customer/observer/ folder will
include the following php files, which you should ensure have the file contents given in the following code
examples:
o CustomerAfterAddrSaveObserver.php
o CustomerDeleteAfter.php
If the /observer folder does not exist, then create a new folder with the same name.
3. Apply the changes by running CLI commands, as described in Applying changes to Magento logic. (Note: If
you want to configure Magento for multiple objects' events, you can make the changes for each object that
you want to use, and then apply the changes for all objects in one step by running the CLI commands once.)
Content of CustomerAfterAddrSaveObserver.php
<?php
namespace Magento\Customer\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface; use
Magento\Sales\Model\Order;
use Magento\Customer\Api\GroupManagementInterface; use
Magento\Customer\Helper\Address as HelperAddress; use
Magento\Customer\Model\Address;
use Magento\Customer\Model\Address\AbstractAddress; use
Magento\Customer\Model\Session as CustomerSession; use
Magento\Customer\Model\Vat; use Magento\Framework\App\Area;
use Magento\Framework\App\Config\ScopeConfigInterface; use
Magento\Framework\App\State as AppState; use
Magento\Framework\DataObject;
use Magento\Framework\Escaper;
use Magento\Framework\Message\ManagerInterface; use
Magento\Framework\Registry;
use Magento\Store\Model\ScopeInterface;
class CustomerAfterAddrSaveObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Sales\Model\Order $order,
\Magento\Sales\Model\ResourceModel\Order\Status\History\CollectionFactory
$historyCollectionFactory,
\Magento\Framework\Stdlib\CookieManagerInterface $cookieManager,
Vat $customerVat,
\Magento\Framework\Stdlib\DateTime\DateTime $date,
HelperAddress $customerAddress,
Registry $coreRegistry,
GroupManagementInterface $groupManagement,
ScopeConfigInterface $scopeConfig,
ManagerInterface $messageManager,
Escaper $escaper,
AppState $appState,
CustomerSession $customerSession )
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
$this->order = $order;
$this->historyCollectionFactory = $historyCollectionFactory;
$this->_customerVat = $customerVat;
$this->_customerAddress = $customerAddress;
$this->_coreRegistry = $coreRegistry;
$this->_groupManagement = $groupManagement;
$this->scopeConfig = $scopeConfig;
$this->messageManager = $messageManager;
$this->escaper = $escaper;
$this->appState = $appState;
$this->customerSession = $customerSession;
$this->_cookieManager = $cookieManager;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$event = $observer->getEvent();
$customer = $event->getCustomer();
//Get custom variable from Admin
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$executeCode = true;
//Logic to check if customer created or updated
if($customer->getCreatedAt() && $customer->getUpdatedAt()) {
$cDt = ($customer->getCreatedAt());
$uDt = ($customer->getUpdatedAt());
$dtdifff = strtotime($uDt) - strtotime($cDt);
if ($uDt > $cDt) {
$customVar = 'customer_updated';
$modelAction = $objectManager-
>get('Magento\Variable\Model\Variable')->loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
$EventAction = "CUSTOMER UPDATED";
//added to prevent double trigger of customer_save after event for
new customer registration
if($dtdifff <=8 ) $executeCode = false;
}else {
$customVar = 'customer_created';
$modelAction = $objectManager-
>get('Magento\Variable\Model\Variable')->loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
$EventAction = "CUSTOMER CREATED";
}
} //end date check
$customer1 = $observer->getEvent()->getCustomer();
sleep(2);
//if the method is post
$urlPost = $modelActionURL;
$params = array('Action' => $EventAction,
'Module' => 'CUSTOMER',
'posturl'=> $modelActionURL);
foreach ($customer1->getData() as $key => $value) {
$params[$key] = $value;
}
$params['id'] = $params['entity_id'];
$params["prefix"] = $customer1->getPrefix();
$params["suffix"] = $customer1->getSuffix();
$params["middlename"] = $customer1->getMiddlename();
$customerObj = $objectManager-
>create('Magento\Customer\Model\Customer')->load( $params["entity_id"]);
$customerAddress = array();
foreach ($customerObj->getAddresses() as $address) {
$customerAddress[] = $address->toArray();
}
foreach ($customerAddress as $customerAddres) {
foreach ($customerAddres as $key => $value) {
if($key != "entity_id")
$params[$key] = $value;
else $params["address_id"] = $value;
}
}
if($executeCode) {
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not
relayed since the configured webhooks URL is either incorrect or the flow is in
stopped state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n---------------------------------------------
------------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not
relayed--------------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed--------------
------------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n-----------------------------------------------------
------------------------";
$this->logWebhookErrors($msg);
}
} //end $executeCode code check
}
}
Content of CustomerDeleteAfter.php
<?php
namespace Magento\Customer\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface; use
Magento\Sales\Model\Order;
use Magento\Customer\Api\GroupManagementInterface; use
Magento\Customer\Helper\Address as HelperAddress; use
Magento\Customer\Model\Address;
use Magento\Customer\Model\Address\AbstractAddress; use
Magento\Customer\Model\Session as CustomerSession; use
Magento\Customer\Model\Vat; use
Magento\Framework\App\Area;
use Magento\Framework\App\Config\ScopeConfigInterface; use
Magento\Framework\App\State as AppState; use
Magento\Framework\DataObject;
use Magento\Framework\Escaper;
use Magento\Framework\Message\ManagerInterface; use
Magento\Framework\Registry;
use Magento\Store\Model\ScopeInterface;
class CustomerDeleteAfter implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Sales\Model\Order $order,
\Magento\Sales\Model\ResourceModel\Order\Status\History\CollectionFactory
$historyCollectionFactory,
Vat $customerVat,
HelperAddress $customerAddress,
Registry $coreRegistry,
GroupManagementInterface $groupManagement,
ScopeConfigInterface $scopeConfig,
ManagerInterface $messageManager,
Escaper $escaper,
AppState $appState,
CustomerSession $customerSession )
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
$this->order = $order;
$this->historyCollectionFactory = $historyCollectionFactory;
$this->_customerVat = $customerVat;
$this->_customerAddress = $customerAddress;
$this->_coreRegistry = $coreRegistry;
$this->_groupManagement = $groupManagement;
$this->scopeConfig = $scopeConfig;
$this->messageManager = $messageManager;
$this->escaper = $escaper;
$this->appState = $appState;
$this->customerSession = $customerSession;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$event = $observer->getEvent();
$customer = $event->getCustomer();
//Get custom variable from Admin
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'customer_deleted';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
$customer1 = $observer->getEvent()->getCustomer();
//if the method is post
$urlPost = $modelActionURL;
$params = array('Action' => "CUSTOMER DELETED",
'Module' => 'CUSTOMER',
'posturl'=> $modelActionURL);
foreach ($customer1->getData() as $key => $value) {
$params[$key] = $value;
}
$params['id'] = $params['entity_id'];
$params["prefix"] = $customer1->getPrefix();
$params["suffix"] = $customer1->getSuffix();
$params["middlename"] = $customer1->getMiddlename();
$customerObj = $objectManager-
>create('Magento\Customer\Model\Customer')->load( $params["entity_id"]);
$customerAddress = array();
foreach ($customerObj->getAddresses() as $address) {
$customerAddress[] = $address->toArray();
}
if(!empty($modelActionURL)) {
try {
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed----
----------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-----------------------------------------------------
----------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed------------------
--------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
2.3.5 INVOICE
If you want to trigger an App Connect flow with an invoice event, like in App Connect the Magento event New
sales invoice, complete the following steps.
Note: In addition to the following steps, you must configure a custom variable for each Magento event that you want to use, as described in the section 2.2 High-level steps to configure webhooks for Magento for use with IBM App Connect. The custom variable names for the events in App Connect are as follows:
Magento event in App Connect Custom variable name in Magento Observer file name in Magento New sales invoice invoice_created InvoiceNewObserver.php Updated sales invoice invoice_updated InvoiceUpdateObserver.php Deleted sales invoice invoice_deleted InvoiceDeleteObserver.php
Steps to implement event logic:
1. Add the following events to the events.xml file located at: <root-magento-folder>/vendor/magento/module-quote/etc/events.xml
If the events.xml file does not exist, then create a new file with that name.
<?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_invoice_save_after">
<observer name="InvoiceNewAction"
instance="Magento\Quote\Observer\InvoiceNewObserver" />
</event>
<event name="sales_order_invoice_save_after">
<observer name="InvoiceUpdateAction"
instance="Magento\Quote\Observer\InvoiceUpdateObserver" />
</event>
<event name="sales_order_invoice_delete_after">
<observer name="InvoiceDeleteAction"
instance="Magento\Quote\Observer\InvoiceDeleteObserver" /> </event>
</config>
Note: In Magento the event, sales_order_invoice_save_after, triggers both the _created and _updated
actions, so in IBM App Connect triggers flows with the events ‘New sales invoice’ and ‘Updated sales invoice’. If
you want to perform different actions for updated sales invoices, you can use a ‘Retrieve sales invoices’ action
and then an If node with logic based on the created date and updated date.
2. For each event create an observer file in the module’s observer folder with the same name mentioned in the instance variable for the events created in the preceding step.
So, the <root-magento-folder>/vendor/magento/module-quote/observer/ folder will include
the following php files, for which the file contents are given in the following code examples:
• InvoiceNewObserver.php
• InvoiceUpdateObserver.php
• InvoiceDeleteObserver.php
If the /observer folder does not exist, then create a new folder with the same name.
3. Apply the changes by running CLI commands, as described in Applying changes to Magento logic. (Note: If
you want to configure Magento for multiple objects' events, you can make the changes for each object that
you want to use, and then apply the changes for all objects in one step by running the CLI commands once.)
Contents of InvoiceNewObserver.php
<?php
namespace Magento\Quote\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class InvoiceNewObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$invoice = $observer->getEvent()->getInvoice();
$order = $invoice->getOrder();
$shipping_address = $order->getShippingAddress();
$billing_address = $order->getBillingAddress(); $items
= $invoice->getAllItems();
$total = $invoice->getGrandTotal();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order = $observer->getEvent()->getOrder();
$customVar = 'invoice_created';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
//if the method is post
$urlPost = $modelActionURL;
$params = array(
'Action' => 'INVOICE_CREATED',
'Module' => 'INVOICE',
'posturl'=> $modelActionURL
);
foreach ($invoice->getData() as $key => $value) {
$params[$key] = $value;
}
$order1 = $objectManager->create('\Magento\Sales\Model\Order') -
>load($params["order_id"]);
$order_data= $order1->getData();
foreach ($order_data as $key => $value) {
$params[$key] = $value;
}
$customer = $objectManager->create('Magento\Customer\Model\Customer')-
>load($params["customer_id"]);
foreach ($customer->getData() as $key => $value) {
$params[$key] = $value;
}
$params["items"] = $itemsNew;
$params["billing_address"] = ($order1->getBillingAddress()->getData());
$params["billing_address"]["id"] = ($order1->getBillingAddress()-
>getId());
$params["shipping_address"] = ($order1->getShippingAddress()-
>getData());
$params["shipping_address"]["id"] = ($order1->getBillingAddress()-
>getId());
$params["customer"] = ($customer->getData());
$params["customer"]["id"] = $params["customer_id"];
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed----
----------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-----------------------------------------------------
----------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed------------------
--------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
Contents of InvoiceUpdateObserver.php
<?php
namespace Magento\Quote\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class InvoiceUpdateObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$invoice = $observer->getEvent()->getInvoice(); $order = $invoice->getOrder();
$shipping_address = $order->getShippingAddress(); $billing_address = $order-
>getBillingAddress(); $items = $invoice->getAllItems();
$total = $invoice->getGrandTotal();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$order = $observer->getEvent()->getOrder();
$customVar = 'invoice_updated';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
//if the method is post
$urlPost = $modelActionURL;
$params = array(
'Action' => 'INVOICE_UPDATED',
'Module' => 'INVOICE',
'posturl'=> $modelActionURL
);
foreach ($invoice->getData() as $key => $value) { $params[$key] = $value;
}
$order1 = $objectManager->create('\Magento\Sales\Model\Order') -
>load($params["order_id"]);
$order_data= $order1->getData();
foreach ($order_data as $key => $value) {
$params[$key] = $value;
}
$customer = $objectManager->create('Magento\Customer\Model\Customer')-
>load($params["customer_id"]);
foreach ($customer->getData() as $key => $value) { $params[$key] = $value;
}
$params["items"] = $itemsNew;
$params["billing_address"] = ($order1->getBillingAddress()->getData());
$params["billing_address"]["id"] = ($order1->getBillingAddress()->getId());
$params["shipping_address"] = ($order1->getShippingAddress()->getData());
$params["shipping_address"]["id"] = ($order1->getBillingAddress()->getId());
$params["customer"] = ($customer->getData());
$params["customer"]["id"] = $params["customer_id"];
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-Length" =>
strlen($params_json), "Access-Control-Request-Headers" => "X-Requested-With",
"AccessControl-Allow-Origin" => "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if ($response2 && $response2 != "Message published")
{
$msg = "";
$msg .= "\n--------------The following event was not relayed since the
configured webhooks URL is either incorrect or the flow is in stopped state-------
-------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n---------------------------------------------------------------
------------------------";
$this->logWebhookErrors($msg);
}
}
catch(\Exception $e)
{
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed------
--------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------------
--------------------------------";
$this->logWebhookErrors($msg);
}
}else
{
$msg = "";
$msg .= "\n--------------The event was not relayed----------------------------
----------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not defined in
Magento Admin";
$msg .= "\n-------------------------------------------------------------------
----------";
$this->logWebhookErrors($msg);
}
}
}
Contents of InvoiceDeleteObserver.php
<?php
namespace Magento\Quote\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class InvoiceDeleteObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$invoice = $observer->getEvent()->getInvoice();
$order = $invoice->getOrder();
$shipping_address = $order->getShippingAddress();
$billing_address = $order->getBillingAddress();
$items = $order->getAllItems();
$total = $invoice->getGrandTotal();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'invoice_deleted';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
//if the method is post
$urlPost = $modelActionURL;
$params = array( 'Action' => 'INVOICE_DELETED',
'Module' => 'INVOICE',
'posturl'=> $modelActionURL);
foreach ($invoice->getData() as $key => $value) {
$params[$key] = $value;
}
$order1 = $objectManager->create('\Magento\Sales\Model\Order') -
>load($params["order_id"]);
$order_data= $order1->getData();
foreach ($order_data as $key => $value) {
$params[$key] = $value;
}
$customer = $objectManager->create('Magento\Customer\Model\Customer')-
>load($params["customer_id"]);
foreach ($customer->getData() as $key => $value) {
$params[$key] = $value;
}
$params["items"] = $itemsNew;
$params["billing_address"] = ($order1->getBillingAddress()->getData());
$params["billing_address"]["id"] = ($order1->getBillingAddress()-
>getId());
$params["shipping_address"] = ($order1->getShippingAddress()-
>getData());
$params["shipping_address"]["id"] = ($order1->getBillingAddress()-
>getId());
$params["customer"] = ($customer->getData());
$params["customer"]["id"] = $params["customer_id"];
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not
relayed since the configured webhooks URL is either incorrect or the flow is in
stopped state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n--------------------------------------------
-------------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed---
-----------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n----------------------------------------------------
-----------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed-------------
-------------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n----------------------------------------------------
-------------------------";
$this->logWebhookErrors($msg);
}
}
}
2.3.6 ORDER
If you want to trigger an App Connect flow with an Order event, like in App Connect the Magento event New
sales order, complete the following steps.
Note: In addition to the following steps, you must configure a custom variable for each Magento event that you want to use, as described in the section 2.2 High-level steps to configure webhooks for Magento for use with IBM App Connect. The custom variable names for the events in App Connect are as follows:
Magento event in App Connect Custom variable name in Magento Observer file name in Magento New sales order order_created SetCheckoutOrderObserver.php Updated sales order order_updated SalesOrderUpdateObserver.php
SalesOrderComment.php Deleted sales order order_deleted SalesOrderDeleteObserver.php
Steps to implement event logic:
1. Add the following events code to the events.xml file located at:
<root-magento-folder>/vendor/magento/module-checkout/etc/events.xml
If the events.xml file does not exist, then create a new file with that name.
<?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="checkout_onepage_controller_success_action">
<observer name="checkout_order_observer_success_action"
instance="Magento\Checkout\Observer\SetCheckoutOrderObserver" />
</event>
<event name="sales_order_save_after">
<observer name="SalesOrderStateChange2"
instance="Magento\Checkout\Observer\SalesOrderUpdateObserver"
shared="false" />
</event>
<event name="sales_order_status_history_save_after">
<observer name="SalesOrderComment"
instance="Magento\Checkout\Observer\SalesOrderComment" shared="false" />
</event>
<event name="sales_order_custom_delete_event">
<observer name="SalesOrderDelete"
instance="Magento\Checkout\Observer\SalesOrderDeleteObserver"
shared="false" />
</event>
</config>
2. For each event create an observer file in the module’s observer folder with the same name mentioned in the instance variable for the events created in the preceding step.
So, the <root-magento-folder>/vendor/magento/module-checkout/observer/ folder will
include the following php files, which you should ensure have the file contents given in the following code
examples:
• SetCheckoutOrderObserver.php
• SalesOrderUpdateObserver.php
• SalesOrderComment.php
• SalesOrderDeleteObserver.php
If the /observer folder does not exist, then create a new folder with the same name.
3. Apply the changes by running CLI commands, as described in Applying changes to Magento logic. (Note: If
you want to configure Magento for multiple objects' events, you can make the changes for each object that
you want to use, and then apply the changes for all objects in one step by running the CLI commands once.)
Contents of SetCheckoutOrderObserver.php
<?php
namespace Magento\Checkout\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Sales\Model\Order;
class SetCheckoutOrderObserver implements ObserverInterface
{
protected $_curl;
public function __construct(
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP .
'/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$orderId = $observer->getEvent()->getOrderIds();
$base_url = $this->_storeManager->getStore()->getBaseUrl();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance(); $order =
$objectManager->create('\Magento\Sales\Model\Order') -
>load($orderId[0]);
$payment = $order->getPayment();
$order_data= $order->getData();
$status = $this->checkoutSession->getLastOrderStatus();
//Get custom variable from Admin
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'order_created';
$modelAction = $objectManager-
>get('Magento\Variable\Model\Variable')->loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
//if the method is post
$urlPost = $modelActionURL;
$params = array('Action' => 'ORDER_CREATED',
'Module' => 'ORDER',
'posturl'=> $modelActionURL
);
foreach ($order_data as $key => $value) {
$params[$key] = $value;
}
$params['order_id'] = $params['entity_id'];
$params['id'] = $params['entity_id'];
$params["payment"] = json_encode($payment->getData()); $items =
$order->getAllItems(); $itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData()); } $params["items"] = $itemsNew;
$params["payment"] = json_encode($order->getPayment()->getData());
$params["billing_address"] = ($order->getBillingAddress()- >getData());
$params["billing_address"]["id"] = ($order->getBillingAddress()->getId());
$params["shipping_address"] = ($order->getShippingAddress()->getData());
$params["shipping_address"]["id"] = ($order->getBillingAddress()->getId());
$customerFactory = $objectManager- >get('\Magento\Customer\Model\CustomerFactory')->create();
$customerdetails = $customerFactory->load($params["customer_id"]);
$params["customer"] = ($customerdetails->getData()); $params["customer"]["id"] =
$params["customer_id"];
if(!empty($modelActionURL)) { try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-Length" =>
strlen($params_json), "Access-Control-Request-Headers" => "X-
Requested-With", "AccessControl-Allow-Origin" => "*",
CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_SSL_VERIFYPEER=>false, CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not
relayed since the configured webhooks URL is either incorrect or the flow is
in stopped state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n----------------------------------------------
-----------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed-
-------------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n--------------------------------------------------
-------------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed---------------
-----------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not defined in
Magento Admin";
$msg .= "\n------------------------------------------------------
-----------------------";
$this->logWebhookErrors($msg);
}
}
}
Contents of SalesOrderUpdateObserver.php
<?php
namespace Magento\Checkout\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class SalesOrderUpdateObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP .
'/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'order_updated';
$modelAction = $objectManager-
>get('Magento\Variable\Model\Variable')->loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
$order = $observer->getEvent()->getOrder();
//if the method is post
$urlPost = $modelActionURL;
$params = array('Action' => 'ORDER_UPDATED',
'Module' => 'ORDER',
'posturl'=> $modelActionURL
);
foreach ($order->getData() as $key => $value) { $params[$key]
= $value;
}
$params['order_id'] = $params['entity_id'];
$params['id'] = $params['entity_id'];
$items = $order->getAllItems();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
$params["items"] = $itemsNew;
$params["payment"] = ($order->getPayment()->getData());
$params["billing_address"] = ($order->getBillingAddress()->getData());
$params["billing_address"]["id"] = ($order->getBillingAddress()->getId());
$params["shipping_address"] = ($order->getShippingAddress()->getData());
$params["shipping_address"]["id"] = ($order->getBillingAddress()->getId());
$customerFactory = $objectManager-
>get('\Magento\Customer\Model\CustomerFactory')->create();
$customerdetails = $customerFactory->load($params["customer_id"]);
$params["customer"] = ($customerdetails->getData()); $params["customer"]["id"] =
$params["customer_id"];
$triggerEvent = false;
if($params["created_at"] && $params["updated_at"] &&
$params["state"] && $params["status"]) {
$cDt = ($params["created_at"]);
$uDt = ($params["updated_at"]);
if (($uDt == $cDt) && ($params["state"] != $params["status"])) { $triggerEvent =
true;
}elseif (($uDt != $cDt) && ($params["state"] ==
$params["status"])) {
$triggerEvent = true;
}elseif (($uDt != $cDt) && ($params["state"] !=
$params["status"]) && (array_key_exists("relation_child_id",$params)) ) {
$triggerEvent = true;
}
}
if($triggerEvent)
{
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-Length" =>
strlen($params_json), "Access-Control-Request-Headers" => "X-
Requested-With", "AccessControl-Allow-Origin" => "*",
CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_SSL_VERIFYPEER=>false, CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not
relayed since the configured webhooks URL is either incorrect or the flow is
in stopped state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n------------------------------------------
---------------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not
relayed--------------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n----------------------------------------------
-----------------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed-----------
---------------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not defined in
Magento Admin";
$msg .= "\n--------------------------------------------------
---------------------------";
$this->logWebhookErrors($msg);
}
}
}
}
Contents of SalesOrderComment.php
<?php
namespace Magento\Checkout\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface; use
Magento\Sales\Model\Order;
class SalesOrderComment implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Sales\Model\Order $order,
\Magento\Sales\Model\ResourceModel\Order\Status\History\CollectionFactory
$historyCollectionFactory)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
$this->order = $order;
$this->historyCollectionFactory = $historyCollectionFactory;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP .
'/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'order_updated';
$modelAction = $objectManager-
>get('Magento\Variable\Model\Variable')->loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
//if the method is post
$urlPost = $modelActionURL;
$ordHistory = $observer->getEvent()->getStatusHistory();
$params = array('Action' => 'ORDER_COMMENT',
'Module' => 'ORDER',
'posturl'=> $modelActionURL
);
foreach ($ordHistory->getData() as $key => $value) {
$params[$key] = $value;
}
if($params['parent_id']) {
$order = $objectManager-
>create('Magento\Sales\Api\Data\OrderInterface')->load($params['parent_id']);
foreach ($order->getData() as $key => $value) {
$params[$key] = $value;
}
$items = $order->getAllItems();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
$params["items"] = $itemsNew;
$params["payment"] = ($order->getPayment()->getData());
$params["billing_address"] = ($order->getBillingAddress()-
>getData());
$params["billing_address"]["id"] = ($order->getBillingAddress()-
>getId());
$params["shipping_address"] = ($order->getShippingAddress()-
>getData());
$params["shipping_address"]["id"] = ($order->getBillingAddress()-
>getId());
$customerFactory = $objectManager-
>get('\Magento\Customer\Model\CustomerFactory')->create();
$customerdetails = $customerFactory-
>load($params["customer_id"]);
$params["customer"] = ($customerdetails->getData());
$params["customer"]["id"] = $params["customer_id"];
}
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-
Origin" => "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not
relayed since the configured webhooks URL is either incorrect or the flow is
in stopped state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n----------------------------------------------
-----------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed-
-------------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n--------------------------------------------------
-------------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed---------------
-----------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n------------------------------------------------------
-----------------------";
$this->logWebhookErrors($msg);
}
}
}
Contents of SalesOrderDeleteObserver.php
<?php
namespace Magento\Checkout\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class SalesOrderDeleteObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP .
'/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'order_deleted';
$modelAction = $objectManager-
>get('Magento\Variable\Model\Variable')->loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
$orderId = $observer->getData('orderId');
//if the method is post
$urlPost = $modelActionURL;
$params = array('Action' => 'ORDER_DELETED',
'Module' => 'ORDER',
'posturl'=> $modelActionURL,
'order_id' => $orderId
);
$order1 = $objectManager->create('\Magento\Sales\Model\Order')-
>load($orderId);
$order_data= $order1->getData();
foreach ($order_data as $key => $value) {
$params[$key] = $value;
}
$params['order_id'] = $params['entity_id'];
$params['id'] = $params['entity_id'];
$customer = $objectManager-
>create('Magento\Customer\Model\Customer')->load($params["customer_id"]);
foreach ($customer->getData() as $key => $value) {
$params[$key] = $value;
}
$items = $order1->getAllItems();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
$params["items"] = $itemsNew;
$params["payment"] = ($order1->getPayment()->getData());
$params["billing_address"] = ($order1->getBillingAddress()-
>getData());
$params["billing_address"]["id"] = ($order1->getBillingAddress()-
>getId());
$params["shipping_address"] = ($order1->getShippingAddress()-
>getData());
$params["shipping_address"]["id"] = ($order1->getBillingAddress()-
>getId());
$customerFactory = $objectManager-
>get('\Magento\Customer\Model\CustomerFactory')->create();
$customerdetails = $customerFactory->load($params["customer_id"]);
$params["customer"] = ($customerdetails->getData());
$params["customer"]["id"] = $params["customer_id"];
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-
Origin" => "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not
relayed since the configured webhooks URL is either incorrect or the flow is
in stopped state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n----------------------------------------------
-----------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed- -------------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n--------------------------------------------------
-------------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed---------------
-----------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n------------------------------------------------------
-----------------------";
$this->logWebhookErrors($msg);
}
}
}
2.3.7 PRODUCT
If you want to trigger an App Connect flow with a product event, like in App Connect the Magento event New
product, complete the following steps.
Note: In addition to the following steps, you must configure a custom variable for each Magento event that you want to use, as described in the section 2.2 High-level steps to configure webhooks for Magento for use with IBM App Connect. The custom variable names for the events in App Connect are as follows:
Magento event in App Connect Custom variable name in Magento Observer file name in Magento New product product_created ProductAddObserver.php Updated product product_updated ProductAddObserver.php
ProductReviewObserver.php Deleted product product_deleted ProductDeleteObserver.php
Steps to implement event logic:
1. Add the following events to the events.xml file located at <root-magento-folder>/vendor/magento/module-store/etc/events.xml
If the events.xml file does not exist, then create a new file with same name.
<?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="catalog_product_save_after">
<observer name="ProductAddAction"
instance="Magento\Store\Observer\ProductAddObserver" />
</event>
<event name="review_save_after">
<observer name="ProductReviewAction"
instance="Magento\Store\Observer\ProductReviewObserver" />
</event>
<event name="catalog_product_delete_before">
<observer name="ProductDeleteAction"
instance="Magento\Store\Observer\ProductDeleteObserver" />
</event>
</config>
2. For each event create an observer file in the module’s observer folder with the same name mentioned in the instance variable for the events created in the preceding step.
So, the <root-magento-folder>/vendor/magento/module-store/observer/ folder will include
the following php files, for which the file contents are given in the following code examples:
• ProductAddObserver.php
• ProductReviewObserver.php
• ProductDeleteObserver.php
If the /observer folder does not exist, then create a new folder with the same name.
3. Apply the changes by running CLI commands, as described in Applying changes to Magento logic. (Note: If
you want to configure Magento for multiple objects' events, you can make the changes for each object that
you want to use, and then apply the changes for all objects in one step by running the CLI commands once.)
Contents of ProductAddObserver.php
<?php
namespace Magento\Store\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class ProductAddObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository
*/
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$product = $observer->getProduct();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
if($product->isObjectNew()) {
$customVar = 'product_created';
$EventAction = 'ADD_PRODUCT';
$modelAction = $objectManager-
>get('Magento\Variable\Model\Variable')->loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
}else {
$customVar = 'product_updated';
$EventAction = 'EDIT_PRODUCT';
$modelAction = $objectManager-
>get('Magento\Variable\Model\Variable')->loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
}
$product1 = $observer->getEvent()->getProduct();
//if the method is post
$urlPost = $modelActionURL;
$params = array(
'Action' => $EventAction,
'Module' => 'PRODUCT',
'posturl'=> $modelActionURL);
foreach ($product1->getData() as $key => $value) {
$params[$key] = $value;
}
$params['id'] = $product1->getId();
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed----
----------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-----------------------------------------------------
----------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed------------------
--------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
Content of ProductReviewObserver.php
<?php
namespace Magento\Store\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class ProductReviewObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$product = $observer->getProduct();
$event = $observer->getEvent();
$product = $this->registry->registry("current_product"); $name
= $product->getName();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'product_updated';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
//if the method is post
$urlPost = $modelActionURL;
$product1 = $observer->getEvent()->getProduct();
$params = array(
'Action' => 'PRODUCT_COMMENT',
'Module' => 'PRODUCT',
'posturl'=> $modelActionURL
);
$product_1 = $objectManager->create('Magento\Catalog\Model\Product')-
>load($product->getId());
foreach ($product_1->getData() as $key => $value) {
$params[$key] = $value;
}
$params['id'] = $product_1->getId();
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed----
----------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-----------------------------------------------------
----------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed------------------
--------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
Content of ProductDeleteObserver.php
<?php
namespace Magento\Store\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class ProductDeleteObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$product = $observer->getProduct();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode('product_deleted');
$modelActionURL = $modelAction->getPlainValue();
$customVar = 'product_deleted';
$product1 = $observer->getEvent()->getProduct();
//if the method is post
$model = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode('prod_url');
$plain_value = $model->getPlainValue();
$urlPost = $plain_value;
//$urlPost = $modelActionURL;
$params = array(
'Action' => 'PRODUCT_DELETE',
'Module' => 'PRODUCT',
'posturl'=> $modelActionURL);
foreach ($product1->getData() as $key => $value) {
$params[$key] = $value;
}
$params['id'] = $product1->getId();
$product_1 = $objectManager->create('Magento\Catalog\Model\Product')-
>load($product1->getData('entity_id'));
foreach ($product_1->getData() as $key => $value) {
$params[$key] = $value;
}
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed----
----------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-----------------------------------------------------
----------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed------------------
--------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
2.3.8 SHIPMENT
If you want to trigger an App Connect flow with a shipment event, like in App Connect the Magento event New
sales shipment, complete the following steps.
Note: In addition to the following steps, you must configure a custom variable for each Magento event that you want to use, as described in the section 2.2 High-level steps to configure webhooks for Magento for use with IBM App Connect. The custom variable names for the events in App Connect are as follows:
Magento event in App Connect Custom variable name in Magento Observer file name in Magento New sales shipment shipment_created ShipmentSaveObserver.php Updated sales shipment shipment_updated ShipmentUpdateObserver.php Deleted sales shipment shipment_deleted ShipmentDeleteObserver.php
Steps to implement event logic:
1. Add the following events to the events.xml file located at: <root-magento-folder>/vendor/magento/module-shipping/etc/events.xml
If the events.xml file does not exist, then create a new file with that name.
<?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_shipment_save_after">
<observer name="ShipmentSaveAction"
instance="Magento\Shipping\Observer\ShipmentSaveObserver" />
</event>
<event name="sales_order_shipment_save_after">
<observer name="ShipmentUpdateAction"
instance="Magento\Shipping\Observer\ShipmentUpdateObserver" />
</event>
<event name="sales_order_shipment_delete_after">
<observer name="ShipmentDeleteAction"
instance="Magento\Shipping\Observer\ShipmentDeleteObserver" />
</event>
</config>
Note: In Magento the event, sales_order_shipment_save_after, triggers both the _created and _updated
actions, so in IBM App Connect triggers flows with the events ‘New shipment’ and ‘Updated shipment’. If you
want to perform different actions for updated shipments, you can use a ‘Retrieve shipments’ action and then an
If node with logic based on the created date and updated date.
2. For each event create an observer file in the module’s observer folder with the same name mentioned in the instance variable for the events created in the preceding step.
So, the <root-magento-folder>/vendor/magento/module-shipping/observer/ folder will
include the following php files, for which the file contents are given in the following code examples:
• ShipmentSaveObserver.php
• ShipmentUpdateObserver.php
• ShipmentDeleteObserver.php
If the /observer folder does not exist, then create a new folder with the same name.
3. Apply the changes by running CLI commands, as described in Applying changes to Magento logic. (Note: If
you want to configure Magento for multiple objects' events, you can make the changes for each object that
you want to use, and then apply the changes for all objects in one step by running the CLI commands once.)
Contents of ShipmentSaveObserver.php
<?php
namespace Magento\Shipping\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class ShipmentSaveObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg); }
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$shipment = $observer->getEvent()->getShipment();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'shipment_created';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
//if the method is post
$urlPost = $modelActionURL;
$params = array( 'Action' => 'SHIPMENT_CREATED',
'Module' => 'SHIPMENT',
'posturl'=> $modelActionURL);
foreach ($shipment->getData() as $key => $value) {
$params[$key] = $value;
}
$order1 = $objectManager->create('\Magento\Sales\Model\Order')-
>load($params["order_id"]);
$order_data= $order1->getData();
foreach ($order_data as $key => $value) {
$params[$key] = $value;
}
$customer = $objectManager->create('Magento\Customer\Model\Customer')-
>load($params["customer_id"]);
foreach ($customer->getData() as $key => $value) {
$params[$key] = $value;
}
$items = $order1->getAllItems();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
$params["items"] = $itemsNew;
$params["billing_address"] = ($order1->getBillingAddress()->getData());
$params["billing_address"]["id"] = ($order1->getBillingAddress()- >getId());
$params["shipping_address"] = ($order1->getShippingAddress()-
>getData());
$params["shipping_address"]["id"] = ($order1->getBillingAddress()-
>getId());
$params["customer"] = ($customer->getData());
$params["customer"]["id"] = $params["customer_id"];
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed----
----------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-----------------------------------------------------
----------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed------------------
--------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
Contents of ShipmentUpdateObserver.php
<?php
namespace Magento\Shipping\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class ShipmentUpdateObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository */
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$shipment = $observer->getEvent()->getShipment();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$customVar = 'shipment_updated';
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode($customVar);
$modelActionURL = $modelAction->getPlainValue();
//if the method is post
$urlPost = $modelActionURL;
$params = array( 'Action' => 'SHIPMENT_UPDATED', 'Module' => 'SHIPMENT',
'posturl'=> $modelActionURL);
foreach ($shipment->getData() as $key => $value)
{
$params[$key] = $value;
}
$order1 = $objectManager->create('\Magento\Sales\Model\Order')-
>load($params["order_id"]);
$order_data= $order1->getData();
foreach ($order_data as $key => $value) {
$params[$key] = $value;
}
$customer = $objectManager->create('Magento\Customer\Model\Customer')-
>load($params["customer_id"]);
foreach ($customer->getData() as $key => $value) { $params[$key] = $value;
}
$items = $order1->getAllItems();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
$params["items"] = $itemsNew;
$params["billing_address"] = ($order1->getBillingAddress()->getData());
$params["billing_address"]["id"] = ($order1->getBillingAddress()->getId());
$params["shipping_address"] = ($order1->getShippingAddress()->getData());
$params["shipping_address"]["id"] = ($order1->getBillingAddress()->getId());
$params["customer"] = ($customer->getData());
$params["customer"]["id"] = $params["customer_id"];
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-Length" =>
strlen($params_json), "Access-Control-Request-Headers" => "X-Requested-With",
"AccessControl-Allow-Origin" => "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if ($response2 && $response2 != "Message published")
{
$msg = "";
$msg .= "\n--------------The following event was not relayed since the
configured webhooks URL is either incorrect or the flow is in stopped state-------
-------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n---------------------------------------------------------------
------------------------";
$this->logWebhookErrors($msg);
}
}
catch(\Exception $e)
{
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed--------------
------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n---------------------------------------------------------------
------------------------";
$this->logWebhookErrors($msg);
}
}else
{
$msg = "";
$msg .= "\n--------------The event was not relayed----------------------------
----------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not defined in
Magento Admin";
$msg .= "\n-------------------------------------------------------------------
----------";
$this->logWebhookErrors($msg);
}
}
}
Contents of ShipmentDeleteObserver.php
<?php
namespace Magento\Shipping\Observer;
use Magento\Framework\Event\ObserverInterface; use
Magento\Framework\Event\Observer;
use Magento\Customer\Api\CustomerRepositoryInterface;
class ShipmentDeleteObserver implements ObserverInterface
{
/** @var CustomerRepositoryInterface */
protected $customerRepository;
protected $_curl;
/**
* @param CustomerRepositoryInterface $customerRepository
*/
public function __construct(
CustomerRepositoryInterface $customerRepository,
\Magento\Framework\Registry $registry,
\Magento\Framework\App\Action\Context $context,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\HTTP\Client\Curl $curl,
\Magento\Checkout\Model\Session $checkoutSession)
{
$this->customerRepository = $customerRepository;
$this->_storeManager = $storeManager;
$this->checkoutSession = $checkoutSession;
$this->registry = $registry;
$this->_curl = $curl;
}
public function logWebhookErrors($msg) {
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/webhooklogs.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$logger->info($msg);
}
public function execute(Observer $observer)
{
$modelActionURL = "";
$plain_value = "";
$EventAction = '';
$customVar = '';
$shipment = $observer->getEvent()->getShipment();
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$modelAction = $objectManager->get('Magento\Variable\Model\Variable')-
>loadByCode('shipment_deleted');
$modelActionURL = $modelAction->getPlainValue();
$customVar = 'shipment_deleted';
//if the method is post
$urlPost = $modelActionURL;
$params = array('Action' => 'SHIPMENT_DELETED',
'Module' => 'SHIPMENT',
'posturl'=> $modelActionURL);
foreach ($shipment->getData() as $key => $value) {
$params[$key] = $value;
}
$order1 = $objectManager->create('\Magento\Sales\Model\Order')-
>load($params["order_id"]);
$order_data= $order1->getData();
foreach ($order_data as $key => $value) {
$params[$key] = $value;
}
$customer = $objectManager->create('Magento\Customer\Model\Customer')-
>load($params["customer_id"]);
foreach ($customer->getData() as $key => $value) {
$params[$key] = $value;
}
$items = $order1->getAllItems();
$itemsNew = array();
foreach($items as $item) {
array_push( $itemsNew, $item->getData());
}
$params["items"] = $itemsNew;
$params["billing_address"] = ($order1->getBillingAddress()->getData());
$params["billing_address"]["id"] = ($order1->getBillingAddress()-
>getId());
$params["shipping_address"] = ($order1->getShippingAddress()-
>getData());
$params["shipping_address"]["id"] = ($order1->getBillingAddress()-
>getId());
$params["customer"] = ($customer->getData());
$params["customer"]["id"] = $params["customer_id"];
if(!empty($modelActionURL)) {
try{
$params_json = json_encode($params);
$headers = ["Content-Type" => "application/json", "Content-
Length" => strlen($params_json), "Access-Control-Request-
Headers" => "X-Requested-With", "AccessControl-Allow-Origin"
=> "*", CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1, CURLOPT_SSL_VERIFYPEER=>false,
CURLOPT_SSL_VERIFYHOST=>false];
$this->_curl->setHeaders($headers);
$this->_curl->setOption(CURLOPT_SSL_VERIFYPEER, false);
$this->_curl->setOption(CURLOPT_SSL_VERIFYHOST, false);
$this->_curl->post($urlPost, $params_json);
$response2 = $this->_curl->getBody();
if($response2 && $response2 != "Message published") {
$msg = "";
$msg .= "\n--------------The following event was not relayed
since the configured webhooks URL is either incorrect or the flow is in stopped
state--------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n-------------------------------------------------
--------------------------------------";
$this->logWebhookErrors($msg);
}
}
catch (\Exception $e) {
//Remote url not reachable
$msg = "";
$msg .= "\n--------------The following event was not relayed-----
---------------------------------";
$msg .= "\n" . json_encode($params) . "";
$msg .= "\n------------------------------------------------------
---------------------------------";
$this->logWebhookErrors($msg);
}
}else{
$msg = "";
$msg .= "\n--------------The event was not relayed------------------
--------------------";
$msg .= "\n Webhooks URL variable '" . $customVar . "' is not
defined in Magento Admin";
$msg .= "\n---------------------------------------------------------
--------------------";
$this->logWebhookErrors($msg);
}
}
}
2.4 APPLYING CHANGES TO MAGENTO LOGIC
To apply the changes made in 2.1.6 Integrating logic, run the following CLI commands:
rm -rf var/di/* var/generation/* var/cache/* var/log/* var/page_cache/*
php bin/magento cache:clean
php bin/magento cache:flush
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento indexer:reindex
3 CONSIDERATIONS BEFORE UPGRADING THE MAGENTO VERSION
A word of advice: always backup your files and database before attempting an upgrade. With a platform as
complex as Magento you can’t anticipate what is going to happen next. A lot of things might go wrong. So, the
changes made to core Magento modules as suggested above in the above sections to handle event notifications
may be lost post upgrade. Rework is what may be required.
4 ALTERNATIVE TECHNIQUE: IMPLEMENT THE LOGIC IN A SINGULAR MODULE (PLUGIN
APPROACH)
An alternative to the technique described in this document is to implement the logic for all supported events
in one module. This module can be treated as a new extension and imported directly into your Magento
instance.
The alternative technique might require a few high-level configuration changes, but none related to
modifying the codebase files. For this technique, the Magento admin needs to add the new module in the
app/code folder of the Magento setup code base and run a few commands on the Magento CLI to enable the
module.
For more information about this alternative technique, see the Magento DevDocs; for example:
• Create a New Module
5 MAGENTO LOGGING
Magento logs are used to maintain a record of lost event notifications that were not relayed to the destination.
In this Magento customization for webhooks support, we maintain a special log file to track down the lost
events.
This log file can be accessed at location: <root-magento-folder>/var/log/webhooklogs.log
Top Related