magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/magento...guide.pdf ·...

70
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.

Upload: others

Post on 30-Jun-2020

13 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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.

Page 2: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To
Page 3: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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

Page 4: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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.

Page 5: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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

Page 6: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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.

Page 7: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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:

Page 8: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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();

Page 9: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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") {

Page 10: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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;

Page 11: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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{

Page 12: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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;

Page 13: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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) {

Page 14: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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---------------------------------------------------------

Page 15: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

--------------------";

$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.)

Page 16: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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';

Page 17: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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------------------

--------------------";

Page 18: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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;

Page 19: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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);

}

}

}

Page 20: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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.

Page 21: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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;

}

Page 22: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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----------------------------------------------------------

-----------------------------";

Page 23: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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);

Page 24: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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()

Page 25: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

->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)

Page 26: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

{

//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;

Page 27: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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"

Page 28: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

=> "*", 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

Page 29: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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

Page 30: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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)

{

Page 31: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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)) {

Page 32: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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;

Page 33: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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');

Page 34: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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);

Page 35: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

}

}

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>

Page 36: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

<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;

}

Page 37: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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)) {

Page 38: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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

{

Page 39: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

/** @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;

Page 40: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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---------------------------------------------------------------

------------------------";

Page 41: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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)

Page 42: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

{

$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()-

Page 43: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

>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.

Page 44: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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.

Page 45: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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

);

Page 46: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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--------------------------------------------------

-------------------------------------";

Page 47: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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-

Page 48: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

>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);

Page 49: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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,

Page 50: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

\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()-

Page 51: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

>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);

}

}

}

Page 52: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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'];

Page 53: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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--------------------------------------------------

-------------------------------------";

Page 54: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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>

Page 55: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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 = '';

Page 56: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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-----------------------------------------------------

----------------------------------";

Page 57: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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

Page 58: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

= $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------------------

--------------------";

Page 59: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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();

Page 60: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

//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

Page 61: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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.

Page 62: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

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')-

Page 63: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

>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);

Page 64: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

}

}

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;

Page 65: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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());

Page 66: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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";

Page 67: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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',

Page 68: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

'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-----

---------------------------------";

Page 69: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

$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:

Page 70: Magento customization for webhooks supportpublic.dhe.ibm.com/.../appconnect/Magento...guide.pdf · 2.2 HIGH-LEVEL STEPS TO CONFIGURE MAGENTO WEBHOOKS TO USE WITH IBM APP CONNECT To

• 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