diff --git a/app/code/Magento/Authorizenet/Block/Adminhtml/Order/View/Info/FraudDetails.php b/app/code/Magento/Authorizenet/Block/Adminhtml/Order/View/Info/FraudDetails.php
new file mode 100644
index 0000000000000000000000000000000000000000..e62ac087d0533520fce2b9e1bb754e13b0481a1d
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Block/Adminhtml/Order/View/Info/FraudDetails.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Block\Adminhtml\Order\View\Info;
+
+use Magento\Authorizenet\Model\Directpost;
+
+class FraudDetails extends \Magento\Backend\Block\Template
+{
+    /**
+     * @var \Magento\Framework\Registry
+     */
+    protected $registry;
+
+    /**
+     * @param \Magento\Backend\Block\Template\Context $context
+     * @param \Magento\Framework\Registry $registry
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Backend\Block\Template\Context $context,
+        \Magento\Framework\Registry $registry,
+        array $data = []
+    ) {
+        $this->registry = $registry;
+        parent::__construct($context, $data);
+    }
+
+    /**
+     * @return \Magento\Sales\Model\Order\Payment
+     */
+    public function getPayment()
+    {
+        $order = $this->registry->registry('current_order');
+        return $order->getPayment();
+    }
+
+    /**
+     * @return string
+     */
+    protected function _toHtml()
+    {
+        return ($this->getPayment()->getMethod() === Directpost::METHOD_CODE) ? parent::_toHtml() : '';
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Block/Transparent/Iframe.php b/app/code/Magento/Authorizenet/Block/Transparent/Iframe.php
new file mode 100644
index 0000000000000000000000000000000000000000..a98839f5d3912bd9af47373f7188f25b8b8d4666
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Block/Transparent/Iframe.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Block\Transparent;
+
+use Magento\Payment\Block\Transparent\Iframe as TransparentIframe;
+
+/**
+ * Class Iframe
+ */
+class Iframe extends TransparentIframe
+{
+    /**
+     * @var \Magento\Authorizenet\Helper\DataFactory
+     */
+    protected $dataFactory;
+
+    /**
+     * Constructor
+     *
+     * @param \Magento\Framework\View\Element\Template\Context $context
+     * @param \Magento\Framework\Registry $registry
+     * @param \Magento\Authorizenet\Helper\DataFactory $dataFactory
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\Template\Context $context,
+        \Magento\Framework\Registry $registry,
+        \Magento\Authorizenet\Helper\DataFactory $dataFactory,
+        array $data = []
+    ) {
+        $this->dataFactory = $dataFactory;
+        parent::__construct($context, $registry, $data);
+    }
+
+    /**
+     * Get helper data
+     *
+     * @param string $area
+     * @return \Magento\Authorizenet\Helper\Backend\Data|\Magento\Authorizenet\Helper\Data
+     */
+    public function getHelper($area)
+    {
+        return $this->dataFactory->create($area);
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/AddConfigured.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/AddConfigured.php
new file mode 100644
index 0000000000000000000000000000000000000000..a0915a18f0cf7d5741054c0b1560591d50c6fcd0
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/AddConfigured.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class AddConfigured extends \Magento\Sales\Controller\Adminhtml\Order\Create\AddConfigured
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Cancel.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Cancel.php
new file mode 100644
index 0000000000000000000000000000000000000000..8d29a522653730c0b3d00572fc956ddf92fd7659
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Cancel.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class Cancel extends \Magento\Sales\Controller\Adminhtml\Order\Create\Cancel
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ConfigureProductToAdd.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ConfigureProductToAdd.php
new file mode 100644
index 0000000000000000000000000000000000000000..8a848e6cacb7a278caa83680892151f869f09056
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ConfigureProductToAdd.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class ConfigureProductToAdd extends \Magento\Sales\Controller\Adminhtml\Order\Create\ConfigureProductToAdd
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ConfigureQuoteItems.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ConfigureQuoteItems.php
new file mode 100644
index 0000000000000000000000000000000000000000..fa5a813a4b4e635185720cdf4e07c5c108da56b0
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ConfigureQuoteItems.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class ConfigureQuoteItems extends \Magento\Sales\Controller\Adminhtml\Order\Create\ConfigureQuoteItems
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Index.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Index.php
new file mode 100644
index 0000000000000000000000000000000000000000..a6698ad1f13becfe93031c2cdc10071b44ca7ca1
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Index.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class Index extends \Magento\Sales\Controller\Adminhtml\Order\Create\Index
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/LoadBlock.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/LoadBlock.php
new file mode 100644
index 0000000000000000000000000000000000000000..0fec8013d50c10ff65fed128ab8156735753a1ed
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/LoadBlock.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class LoadBlock extends \Magento\Sales\Controller\Adminhtml\Order\Create\LoadBlock
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Place.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Place.php
new file mode 100644
index 0000000000000000000000000000000000000000..0bf4db360d23081fc5e8f9603363aa3e231ef8eb
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Place.php
@@ -0,0 +1,150 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+use Magento\Framework\Escaper;
+use Magento\Catalog\Helper\Product;
+use Magento\Backend\App\Action\Context;
+use Magento\Framework\View\Result\PageFactory;
+use Magento\Backend\Model\View\Result\ForwardFactory;
+use Magento\Authorizenet\Helper\Backend\Data as DataHelper;
+
+/**
+ * Class Place
+ */
+class Place extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * @var DataHelper
+     */
+    protected $helper;
+
+    /**
+     * Constructor
+     *
+     * @param Context $context
+     * @param Product $productHelper
+     * @param Escaper $escaper
+     * @param PageFactory $resultPageFactory
+     * @param ForwardFactory $resultForwardFactory
+     * @param DataHelper $helper
+     */
+    public function __construct(
+        Context $context,
+        Product $productHelper,
+        Escaper $escaper,
+        PageFactory $resultPageFactory,
+        ForwardFactory $resultForwardFactory,
+        DataHelper $helper
+    ) {
+        $this->helper = $helper;
+        parent::__construct($context, $productHelper, $escaper, $resultPageFactory, $resultForwardFactory);
+    }
+
+    /**
+     * Send request to authorize.net
+     *
+     * @return void
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
+     */
+    public function execute()
+    {
+        $paymentParam = $this->getRequest()->getParam('payment');
+        $controller = $this->getRequest()->getParam('controller');
+        $this->getRequest()->setPostValue('collect_shipping_rates', 1);
+        $this->_processActionData('save');
+
+        //get confirmation by email flag
+        $orderData = $this->getRequest()->getPost('order');
+        $sendConfirmationFlag = 0;
+        if ($orderData) {
+            $sendConfirmationFlag = !empty($orderData['send_confirmation']) ? 1 : 0;
+        } else {
+            $orderData = [];
+        }
+
+        if (isset($paymentParam['method'])) {
+            $result = [];
+            //create order partially
+            $this->_getOrderCreateModel()->setPaymentData($paymentParam);
+            $this->_getOrderCreateModel()->getQuote()->getPayment()->addData($paymentParam);
+
+            $orderData['send_confirmation'] = 0;
+            $this->getRequest()->setPostValue('order', $orderData);
+
+            try {
+                //do not cancel old order.
+                $oldOrder = $this->_getOrderCreateModel()->getSession()->getOrder();
+                $oldOrder->setActionFlag(\Magento\Sales\Model\Order::ACTION_FLAG_CANCEL, false);
+
+                $order = $this->_getOrderCreateModel()->setIsValidate(
+                    true
+                )->importPostData(
+                    $this->getRequest()->getPost('order')
+                )->createOrder();
+
+                $payment = $order->getPayment();
+                if ($payment && $payment->getMethod() == $this->_objectManager->create(
+                    'Magento\Authorizenet\Model\Directpost'
+                )->getCode()
+                ) {
+                    //return json with data.
+                    $session = $this->_objectManager->get('Magento\Authorizenet\Model\Directpost\Session');
+                    $session->addCheckoutOrderIncrementId($order->getIncrementId());
+                    $session->setLastOrderIncrementId($order->getIncrementId());
+
+                    /** @var \Magento\Authorizenet\Model\Directpost $method */
+                    $method = $payment->getMethodInstance();
+                    $method->setDataHelper($this->helper);
+                    $requestToAuthorizenet = $method->generateRequestFromOrder($order);
+                    $requestToAuthorizenet->setControllerActionName($controller);
+                    $requestToAuthorizenet->setOrderSendConfirmation($sendConfirmationFlag);
+                    $requestToAuthorizenet->setStoreId($this->_getOrderCreateModel()->getQuote()->getStoreId());
+
+                    $adminUrl = $this->_objectManager->get('Magento\Backend\Model\UrlInterface');
+                    if ($adminUrl->useSecretKey()) {
+                        $requestToAuthorizenet->setKey(
+                            $adminUrl->getSecretKey('adminhtml', 'authorizenet_directpost_payment', 'redirect')
+                        );
+                    }
+                    $result['directpost'] = ['fields' => $requestToAuthorizenet->getData()];
+                }
+
+                $result['success'] = 1;
+                $isError = false;
+            } catch (\Magento\Framework\Exception\LocalizedException $e) {
+                $message = $e->getMessage();
+                if (!empty($message)) {
+                    $this->messageManager->addError($message);
+                }
+                $isError = true;
+            } catch (\Exception $e) {
+                $this->messageManager->addException($e, __('Order saving error: %1', $e->getMessage()));
+                $isError = true;
+            }
+
+            if ($isError) {
+                $result['success'] = 0;
+                $result['error'] = 1;
+                $result['redirect'] = $this->_objectManager->get(
+                    'Magento\Backend\Model\UrlInterface'
+                )->getUrl(
+                    'sales/order_create/'
+                );
+            }
+
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode($result)
+            );
+        } else {
+            $result = ['error_messages' => __('Please choose a payment method.')];
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ProcessData.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ProcessData.php
new file mode 100644
index 0000000000000000000000000000000000000000..25668a9cc3393314070ed9c21544e4b2d0987d43
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ProcessData.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class ProcessData extends \Magento\Sales\Controller\Adminhtml\Order\Create\ProcessData
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Redirect.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Redirect.php
new file mode 100644
index 0000000000000000000000000000000000000000..d147c3d91e1ff1b829d9e4cee9160e59ac0d61ec
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Redirect.php
@@ -0,0 +1,132 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+use Magento\Backend\App\Action;
+use Magento\Backend\Model\View\Result\ForwardFactory;
+use Magento\Framework\View\Result\LayoutFactory;
+use Magento\Framework\View\Result\PageFactory;
+use Magento\Payment\Block\Transparent\Iframe;
+
+class Redirect extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry;
+
+    /**
+     * @var LayoutFactory
+     */
+    protected $resultLayoutFactory;
+
+    /**
+     * @var \Magento\Authorizenet\Helper\Backend\Data
+     */
+    protected $helper;
+
+    /**
+     * @param Action\Context $context
+     * @param \Magento\Catalog\Helper\Product $productHelper
+     * @param \Magento\Framework\Escaper $escaper
+     * @param PageFactory $resultPageFactory
+     * @param ForwardFactory $resultForwardFactory
+     * @param \Magento\Framework\Registry $coreRegistry
+     * @param LayoutFactory $resultLayoutFactory
+     * @param \Magento\Authorizenet\Helper\Backend\Data $helper
+     */
+    public function __construct(
+        Action\Context $context,
+        \Magento\Catalog\Helper\Product $productHelper,
+        \Magento\Framework\Escaper $escaper,
+        PageFactory $resultPageFactory,
+        ForwardFactory $resultForwardFactory,
+        \Magento\Framework\Registry $coreRegistry,
+        LayoutFactory $resultLayoutFactory,
+        \Magento\Authorizenet\Helper\Backend\Data $helper
+    ) {
+        $this->_coreRegistry = $coreRegistry;
+        $this->resultLayoutFactory = $resultLayoutFactory;
+        $this->helper = $helper;
+        parent::__construct(
+            $context,
+            $productHelper,
+            $escaper,
+            $resultPageFactory,
+            $resultForwardFactory
+        );
+    }
+
+    /**
+     * Return quote
+     *
+     * @param bool $cancelOrder
+     * @param string $errorMsg
+     * @return void
+     */
+    protected function _returnQuote($cancelOrder, $errorMsg)
+    {
+        $directpostSession = $this->_objectManager->get('Magento\Authorizenet\Model\Directpost\Session');
+        $incrementId = $directpostSession->getLastOrderIncrementId();
+        if ($incrementId && $directpostSession->isCheckoutOrderIncrementIdExist($incrementId)) {
+            /* @var $order \Magento\Sales\Model\Order */
+            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId($incrementId);
+            if ($order->getId()) {
+                $directpostSession->removeCheckoutOrderIncrementId($order->getIncrementId());
+                if ($cancelOrder && $order->getState() == \Magento\Sales\Model\Order::STATE_PENDING_PAYMENT) {
+                    $order->registerCancellation($errorMsg)->save();
+                }
+            }
+        }
+    }
+
+    /**
+     * Retrieve params and put javascript into iframe
+     *
+     * @return \Magento\Framework\View\Result\Layout
+     */
+    public function execute()
+    {
+        $redirectParams = $this->getRequest()->getParams();
+        $params = [];
+        if (!empty($redirectParams['success'])
+            && isset($redirectParams['x_invoice_num'])
+            && isset($redirectParams['controller_action_name'])
+        ) {
+            $params['redirect_parent'] = $this->helper->getSuccessOrderUrl($redirectParams);
+            $directpostSession = $this->_objectManager->get('Magento\Authorizenet\Model\Directpost\Session');
+            $directpostSession->unsetData('quote_id');
+            //cancel old order
+            $oldOrder = $this->_getOrderCreateModel()->getSession()->getOrder();
+            if ($oldOrder->getId()) {
+                /* @var $order \Magento\Sales\Model\Order */
+                $order = $this->_objectManager->create('Magento\Sales\Model\Order')
+                    ->loadByIncrementId($redirectParams['x_invoice_num']);
+
+                if ($order->getId()) {
+                    $oldOrder->cancel()->save();
+                    $order->save();
+                    $this->_getOrderCreateModel()->getSession()->unsOrderId();
+                }
+            }
+            //clear sessions
+            $this->_getSession()->clearStorage();
+            $directpostSession->removeCheckoutOrderIncrementId($redirectParams['x_invoice_num']);
+            $this->_objectManager->get('Magento\Backend\Model\Session')->clearStorage();
+            $this->messageManager->addSuccess(__('You created the order.'));
+        }
+
+        if (!empty($redirectParams['error_msg'])) {
+            $cancelOrder = empty($redirectParams['x_invoice_num']);
+            $this->_returnQuote($cancelOrder, $redirectParams['error_msg']);
+        }
+
+        $this->_coreRegistry->register(Iframe::REGISTRY_KEY, array_merge($params, $redirectParams));
+        return $this->resultLayoutFactory->create();
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Reorder.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Reorder.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b485b09e257b49cef5186fd48139ad337898a85
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Reorder.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class Reorder extends \Magento\Sales\Controller\Adminhtml\Order\Create\Reorder
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ReturnQuote.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ReturnQuote.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ac7153fecf4b9530677dc01627bb916ac912b5c
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ReturnQuote.php
@@ -0,0 +1,41 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class ReturnQuote extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+    /**
+     * Return quote
+     *
+     * @return void
+     */
+    protected function _returnQuote()
+    {
+        $directpostSession = $this->_objectManager->get('Magento\Authorizenet\Model\Directpost\Session');
+        $incrementId = $directpostSession->getLastOrderIncrementId();
+        if ($incrementId && $directpostSession->isCheckoutOrderIncrementIdExist($incrementId)) {
+            /* @var $order \Magento\Sales\Model\Order */
+            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId($incrementId);
+            if ($order->getId()) {
+                $directpostSession->removeCheckoutOrderIncrementId($order->getIncrementId());
+            }
+        }
+    }
+
+    /**
+     * Return order quote by ajax
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_returnQuote();
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode(['success' => 1])
+        );
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Save.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Save.php
new file mode 100644
index 0000000000000000000000000000000000000000..72a332f26b2e3965a59019207250638424ba895b
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Save.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class Save extends \Magento\Sales\Controller\Adminhtml\Order\Create\Save
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ShowUpdateResult.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ShowUpdateResult.php
new file mode 100644
index 0000000000000000000000000000000000000000..63343be8340b1d203feb8334388064170b451eb5
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/ShowUpdateResult.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class ShowUpdateResult extends \Magento\Sales\Controller\Adminhtml\Order\Create\ShowUpdateResult
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Start.php b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Start.php
new file mode 100644
index 0000000000000000000000000000000000000000..88bf9a3c1fcc10ae815f668bedc42430be1ad469
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/Start.php
@@ -0,0 +1,11 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+class Start extends \Magento\Sales\Controller\Adminhtml\Order\Create
+{
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php
new file mode 100644
index 0000000000000000000000000000000000000000..7149d6c567d06e0b15d9aa1d320a222168b594a4
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Directpost;
+
+use Magento\Payment\Block\Transparent\Iframe;
+
+/**
+ * DirectPost Payment Controller
+ *
+ * @author     Magento Core Team <core@magentocommerce.com>
+ */
+class Payment extends \Magento\Framework\App\Action\Action
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry = null;
+
+    /**
+     * @var \Magento\Authorizenet\Helper\DataFactory
+     */
+    protected $dataFactory;
+
+    /**
+     * Constructor
+     *
+     * @param \Magento\Framework\App\Action\Context $context
+     * @param \Magento\Framework\Registry $coreRegistry
+     * @param \Magento\Authorizenet\Helper\DataFactory $dataFactory
+     */
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Framework\Registry $coreRegistry,
+        \Magento\Authorizenet\Helper\DataFactory $dataFactory
+    ) {
+        $this->_coreRegistry = $coreRegistry;
+        $this->dataFactory = $dataFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * @return \Magento\Checkout\Model\Session
+     */
+    protected function _getCheckout()
+    {
+        return $this->_objectManager->get('Magento\Checkout\Model\Session');
+    }
+
+    /**
+     * Get session model
+     *
+     * @return \Magento\Authorizenet\Model\Directpost\Session
+     */
+    protected function _getDirectPostSession()
+    {
+        return $this->_objectManager->get('Magento\Authorizenet\Model\Directpost\Session');
+    }
+
+    /**
+     * Response action.
+     * Action for Authorize.net SIM Relay Request.
+     *
+     * @param string $area
+     * @return void
+     */
+    protected function _responseAction($area = 'frontend')
+    {
+        $helper = $this->dataFactory->create($area);
+
+        $params = [];
+        $data = $this->getRequest()->getPostValue();
+        /* @var $paymentMethod \Magento\Authorizenet\Model\DirectPost */
+        $paymentMethod = $this->_objectManager->create('Magento\Authorizenet\Model\Directpost');
+
+        $result = [];
+        if (!empty($data['x_invoice_num'])) {
+            $result['x_invoice_num'] = $data['x_invoice_num'];
+            $params['order_success'] = $helper->getSuccessOrderUrl($result);
+        }
+
+        try {
+            if (!empty($data['store_id'])) {
+                $paymentMethod->setStore($data['store_id']);
+            }
+            $paymentMethod->process($data);
+            $result['success'] = 1;
+        } catch (\Magento\Framework\Exception\LocalizedException $e) {
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
+            $result['success'] = 0;
+            $result['error_msg'] = $e->getMessage();
+        } catch (\Exception $e) {
+            $this->_objectManager->get('Psr\Log\LoggerInterface')->critical($e);
+            $result['success'] = 0;
+            $result['error_msg'] = __('We can\'t process your order right now. Please try again later.');
+        }
+
+        if (!empty($data['controller_action_name'])
+            && strpos($data['controller_action_name'], 'sales_order_') === false
+        ) {
+            if (!empty($data['key'])) {
+                $result['key'] = $data['key'];
+            }
+            $result['controller_action_name'] = $data['controller_action_name'];
+            $result['is_secure'] = isset($data['is_secure']) ? $data['is_secure'] : false;
+            $params['redirect'] = $helper->getRedirectIframeUrl($result);
+        }
+
+        $this->_coreRegistry->register(Iframe::REGISTRY_KEY, $params);
+        $this->_view->addPageLayoutHandles();
+        $this->_view->loadLayout(false)->renderLayout();
+    }
+
+    /**
+     * Return customer quote
+     *
+     * @param bool $cancelOrder
+     * @param string $errorMsg
+     * @return void
+     */
+    protected function _returnCustomerQuote($cancelOrder = false, $errorMsg = '')
+    {
+        $incrementId = $this->_getDirectPostSession()->getLastOrderIncrementId();
+        if ($incrementId && $this->_getDirectPostSession()->isCheckoutOrderIncrementIdExist($incrementId)) {
+            /* @var $order \Magento\Sales\Model\Order */
+            $order = $this->_objectManager->create('Magento\Sales\Model\Order')->loadByIncrementId($incrementId);
+            if ($order->getId()) {
+                try {
+                    /** @var \Magento\Quote\Model\QuoteRepository $quoteRepository */
+                    $quoteRepository = $this->_objectManager->create('Magento\Quote\Model\QuoteRepository');
+                    /** @var \Magento\Quote\Model\Quote $quote */
+                    $quote = $quoteRepository->get($order->getQuoteId());
+
+                    $quote->setIsActive(1)->setReservedOrderId(null);
+                    $quoteRepository->save($quote);
+                    $this->_getCheckout()->replaceQuote($quote);
+                } catch (\Magento\Framework\Exception\NoSuchEntityException $e) {
+                }
+                $this->_getDirectPostSession()->removeCheckoutOrderIncrementId($incrementId);
+                $this->_getDirectPostSession()->unsetData('quote_id');
+                if ($cancelOrder) {
+                    $order->registerCancellation($errorMsg)->save();
+                }
+            }
+        }
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/BackendResponse.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/BackendResponse.php
new file mode 100644
index 0000000000000000000000000000000000000000..6f0696fbf9d1e883f39a129c8a47b6d2fd007615
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/BackendResponse.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Directpost\Payment;
+
+class BackendResponse extends \Magento\Authorizenet\Controller\Directpost\Payment
+{
+    /**
+     * Response action.
+     * Action for Authorize.net SIM Relay Request.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_responseAction('adminhtml');
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Place.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Place.php
new file mode 100644
index 0000000000000000000000000000000000000000..a51be3b1c912278a8dcde44716f23157786d436b
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Place.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Directpost\Payment;
+
+class Place extends \Magento\Authorizenet\Controller\Directpost\Payment
+{
+    /**
+     * @var \Magento\Quote\Api\CartManagementInterface
+     */
+    protected $cartManagement;
+
+    /**
+     * @var \Magento\Framework\Event\ManagerInterface
+     */
+    protected $eventManager;
+
+    /**
+     * @param \Magento\Framework\App\Action\Context $context
+     * @param \Magento\Framework\Registry $coreRegistry
+     * @param \Magento\Authorizenet\Helper\DataFactory $dataFactory
+     * @param \Magento\Quote\Api\CartManagementInterface $cartManagement
+     */
+    public function __construct(
+        \Magento\Framework\App\Action\Context $context,
+        \Magento\Framework\Registry $coreRegistry,
+        \Magento\Authorizenet\Helper\DataFactory $dataFactory,
+        \Magento\Quote\Api\CartManagementInterface $cartManagement
+    ) {
+        $this->eventManager = $context->getEventManager();
+        $this->cartManagement = $cartManagement;
+        parent::__construct($context, $coreRegistry, $dataFactory);
+    }
+
+    /**
+     * Send request to authorize.net
+     *
+     * @return string
+     */
+    public function execute()
+    {
+        $paymentParam = $this->getRequest()->getParam('payment');
+        $controller = $this->getRequest()->getParam('controller');
+        if (isset($paymentParam['method'])) {
+            $this->_getDirectPostSession()->setQuoteId($this->_getCheckout()->getQuote()->getId());
+
+            if ($controller == \Magento\Payment\Model\IframeConfigProvider::CHECKOUT_IDENTIFIER) {
+                return $this->placeCheckoutOrder();
+            }
+
+            $params = $this->_objectManager->get(
+                'Magento\Authorizenet\Helper\Data'
+            )->getSaveOrderUrlParams(
+                $controller
+            );
+            $this->_forward(
+                $params['action'],
+                $params['controller'],
+                $params['module'],
+                $this->getRequest()->getParams()
+            );
+        } else {
+            $result = ['error_messages' => __('Please choose a payment method.'), 'goto_section' => 'payment'];
+            $this->getResponse()->representJson(
+                $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode($result)
+            );
+        }
+    }
+
+    /**
+     * Place order for checkout flow
+     *
+     * @return string
+     */
+    protected function placeCheckoutOrder()
+    {
+        $result = new \Magento\Framework\Object();
+        try {
+            $this->cartManagement->placeOrder($this->_getCheckout()->getQuote()->getId());
+            $result->setData('success', true);
+            $this->eventManager->dispatch(
+                'checkout_directpost_placeOrder',
+                [
+                    'result' => $result,
+                    'action' => $this
+                ]
+            );
+        } catch (\Exception $exception) {
+            $result->setData('error', true);
+            $result->setData('error_messages', __('Cannot place order.'));
+        }
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode($result)
+        );
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Redirect.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Redirect.php
new file mode 100644
index 0000000000000000000000000000000000000000..0a0fc1a99066842bd1f581897718898058bacd89
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Redirect.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Directpost\Payment;
+
+use Magento\Payment\Block\Transparent\Iframe;
+
+class Redirect extends \Magento\Authorizenet\Controller\Directpost\Payment
+{
+    /**
+     * Retrieve params and put javascript into iframe
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $helper = $this->dataFactory->create('frontend');
+
+        $redirectParams = $this->getRequest()->getParams();
+        $params = [];
+        if (!empty($redirectParams['success'])
+            && isset($redirectParams['x_invoice_num'])
+            && isset($redirectParams['controller_action_name'])
+        ) {
+            $this->_getDirectPostSession()->unsetData('quote_id');
+            $params['redirect_parent'] = $helper->getSuccessOrderUrl([]);
+        }
+        if (!empty($redirectParams['error_msg'])) {
+            $cancelOrder = empty($redirectParams['x_invoice_num']);
+            $this->_returnCustomerQuote($cancelOrder, $redirectParams['error_msg']);
+        }
+
+        if (isset($redirectParams['controller_action_name'])
+            && strpos($redirectParams['controller_action_name'], 'sales_order_') !== false
+        ) {
+            unset($redirectParams['controller_action_name']);
+            unset($params['redirect_parent']);
+        }
+
+        $this->_coreRegistry->register(Iframe::REGISTRY_KEY, array_merge($params, $redirectParams));
+        $this->_view->addPageLayoutHandles();
+        $this->_view->loadLayout(false)->renderLayout();
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Response.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Response.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a25db11b46f627a6119add42650d8d3c887b503
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/Response.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Directpost\Payment;
+
+class Response extends \Magento\Authorizenet\Controller\Directpost\Payment
+{
+    /**
+     * Response action.
+     * Action for Authorize.net SIM Relay Request.
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_responseAction('frontend');
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Controller/Directpost/Payment/ReturnQuote.php b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/ReturnQuote.php
new file mode 100644
index 0000000000000000000000000000000000000000..1cef3b032864d0a2a5b7caa61b61940b62cec0b2
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Controller/Directpost/Payment/ReturnQuote.php
@@ -0,0 +1,23 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Directpost\Payment;
+
+class ReturnQuote extends \Magento\Authorizenet\Controller\Directpost\Payment
+{
+    /**
+     * Return customer quote by ajax
+     *
+     * @return void
+     */
+    public function execute()
+    {
+        $this->_returnCustomerQuote();
+        $this->getResponse()->representJson(
+            $this->_objectManager->get('Magento\Framework\Json\Helper\Data')->jsonEncode(['success' => 1])
+        );
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Helper/Backend/Data.php b/app/code/Magento/Authorizenet/Helper/Backend/Data.php
new file mode 100644
index 0000000000000000000000000000000000000000..1adfc4a25d95a72f07d5ccd7f2342357d98dad09
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Helper/Backend/Data.php
@@ -0,0 +1,101 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Helper\Backend;
+
+use Magento\Authorizenet\Helper\Data as FrontendDataHelper;
+use Magento\Framework\App\Helper\Context;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\Sales\Model\OrderFactory;
+use Magento\Backend\Model\UrlInterface;
+
+/**
+ * Authorize.net Backend Data Helper
+ */
+class Data extends FrontendDataHelper
+{
+    /**
+     * @param \Magento\Framework\App\Helper\Context $context
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     * @param \Magento\Backend\Model\UrlInterface $backendUrl
+     */
+    public function __construct(
+        Context $context,
+        StoreManagerInterface $storeManager,
+        OrderFactory $orderFactory,
+        UrlInterface $backendUrl
+    ) {
+        $this->_urlBuilder = $backendUrl;
+        parent::__construct($context, $storeManager, $orderFactory);
+    }
+
+    /**
+     * Return URL for admin area
+     *
+     * @param string $route
+     * @param array $params
+     * @return string
+     */
+    protected function _getUrl($route, $params = [])
+    {
+        return $this->_urlBuilder->getUrl($route, $params);
+    }
+
+    /**
+     * Retrieve place order url in admin
+     *
+     * @return  string
+     */
+    public function getPlaceOrderAdminUrl()
+    {
+        return $this->_getUrl('adminhtml/authorizenet_directpost_payment/place', []);
+    }
+
+    /**
+     * Retrieve place order url
+     *
+     * @param array $params
+     * @return  string
+     */
+    public function getSuccessOrderUrl($params)
+    {
+        $param = [];
+        $route = 'sales/order/view';
+        $order = $this->orderFactory->create()->loadByIncrementId($params['x_invoice_num']);
+        $param['order_id'] = $order->getId();
+        return $this->_getUrl($route, $param);
+    }
+
+    /**
+     * Retrieve redirect iframe url
+     *
+     * @param array $params
+     * @return string
+     */
+    public function getRedirectIframeUrl($params)
+    {
+        return $this->_getUrl('adminhtml/authorizenet_directpost_payment/redirect', $params);
+    }
+
+    /**
+     * Get direct post relay url
+     *
+     * @param null|int|string $storeId
+     * @return string
+     */
+    public function getRelayUrl($storeId = null)
+    {
+        $defaultStore = $this->storeManager->getDefaultStoreView();
+        if (!$defaultStore) {
+            $allStores = $this->storeManager->getStores();
+            if (isset($allStores[0])) {
+                $defaultStore = $allStores[0];
+            }
+        }
+        $baseUrl = $defaultStore->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK);
+        return $baseUrl . 'authorizenet/directpost_payment/backendResponse';
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Helper/Data.php b/app/code/Magento/Authorizenet/Helper/Data.php
new file mode 100644
index 0000000000000000000000000000000000000000..ae9e7b55ffb78e807ce69bee3e2f81865ca40ca9
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Helper/Data.php
@@ -0,0 +1,336 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Helper;
+
+use Magento\Framework\App\Helper\AbstractHelper;
+use Magento\Framework\App\Helper\Context;
+use Magento\Store\Model\StoreManagerInterface;
+use Magento\Sales\Model\OrderFactory;
+use Magento\Authorizenet\Model\Directpost;
+use Magento\Authorizenet\Model\Authorizenet;
+
+/**
+ * Authorize.net Data Helper
+ */
+class Data extends AbstractHelper
+{
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Sales\Model\OrderFactory
+     */
+    protected $orderFactory;
+
+    /**
+     * Allowed currencies
+     *
+     * @var array
+     */
+    protected $allowedCurrencyCodes = ['USD'];
+
+    /**
+     * Transaction statuses key to value map
+     *
+     * @var array
+     */
+    protected $transactionStatuses = [
+        'authorizedPendingCapture' => 'Authorized/Pending Capture',
+        'capturedPendingSettlement' => 'Captured/Pending Settlement',
+        'refundSettledSuccessfully' => 'Refund/Settled Successfully',
+        'refundPendingSettlement' => 'Refund/Pending Settlement',
+        'declined' => 'Declined',
+        'expired' => 'Expired',
+        'voided' => 'Voided',
+        'FDSPendingReview' => 'FDS - Pending Review',
+        'FDSAuthorizedPendingReview' => 'FDS - Authorized/Pending Review'
+    ];
+
+    /**
+     * Fraud filter actions key to value map
+     *
+     * @var array
+     */
+    protected $fdsFilterActions = [
+        'decline ' => 'Decline',
+        'hold' => 'Hold',
+        'authAndHold' => 'Authorize and Hold',
+        'report' => 'Report Only'
+    ];
+
+    /**
+     * @param \Magento\Framework\App\Helper\Context $context
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     */
+    public function __construct(
+        Context $context,
+        StoreManagerInterface $storeManager,
+        OrderFactory $orderFactory
+    ) {
+        $this->storeManager = $storeManager;
+        $this->orderFactory = $orderFactory;
+        parent::__construct($context);
+    }
+
+    /**
+     * Set secure url checkout is secure for current store.
+     *
+     * @param string $route
+     * @param array $params
+     * @return string
+     */
+    protected function _getUrl($route, $params = [])
+    {
+        $params['_type'] = \Magento\Framework\UrlInterface::URL_TYPE_LINK;
+        if (isset($params['is_secure'])) {
+            $params['_secure'] = (bool)$params['is_secure'];
+        } elseif ($this->storeManager->getStore()->isCurrentlySecure()) {
+            $params['_secure'] = true;
+        }
+        return parent::_getUrl($route, $params);
+    }
+
+    /**
+     * Retrieve save order url params
+     *
+     * @param string $controller
+     * @return array
+     */
+    public function getSaveOrderUrlParams($controller)
+    {
+        $route = [];
+        switch ($controller) {
+            case 'onepage':
+                $route['action'] = 'saveOrder';
+                $route['controller'] = 'onepage';
+                $route['module'] = 'checkout';
+                break;
+
+            case 'sales_order_create':
+            case 'sales_order_edit':
+                $route['action'] = 'save';
+                $route['controller'] = 'sales_order_create';
+                $route['module'] = 'admin';
+                break;
+
+            default:
+                break;
+        }
+
+        return $route;
+    }
+
+    /**
+     * Retrieve redirect iframe url
+     *
+     * @param array $params
+     * @return string
+     */
+    public function getRedirectIframeUrl($params)
+    {
+        return $this->_getUrl('authorizenet/directpost_payment/redirect', $params);
+    }
+
+    /**
+     * Retrieve place order url
+     *
+     * @param array $params
+     * @return  string
+     */
+    public function getSuccessOrderUrl($params)
+    {
+        return $this->_getUrl('checkout/onepage/success', $params);
+    }
+
+    /**
+     * Update all child and parent order's edit increment numbers.
+     * Needed for Admin area.
+     *
+     * @param \Magento\Sales\Model\Order $order
+     * @return void
+     */
+    public function updateOrderEditIncrements(\Magento\Sales\Model\Order $order)
+    {
+        if ($order->getId() && $order->getOriginalIncrementId()) {
+            $collection = $order->getCollection();
+            $quotedIncrId = $collection->getConnection()->quote($order->getOriginalIncrementId());
+            $collection->getSelect()->where(
+                "original_increment_id = {$quotedIncrId} OR increment_id = {$quotedIncrId}"
+            );
+
+            foreach ($collection as $orderToUpdate) {
+                $orderToUpdate->setEditIncrement($order->getEditIncrement());
+                $orderToUpdate->save();
+            }
+        }
+    }
+
+    /**
+     * Converts a lot of messages to message
+     *
+     * @param  array $messages
+     * @return string
+     */
+    public function convertMessagesToMessage($messages)
+    {
+        return implode(' | ', $messages);
+    }
+
+    /**
+     * Return message for gateway transaction request
+     *
+     * @param \Magento\Payment\Model\InfoInterface $payment
+     * @param string $requestType
+     * @param string $lastTransactionId
+     * @param \Magento\Framework\Object $card
+     * @param bool|float $amount
+     * @param bool|string $exception
+     * @param bool|string $additionalMessage
+     * @return bool|string
+     */
+    public function getTransactionMessage(
+        $payment,
+        $requestType,
+        $lastTransactionId,
+        $card,
+        $amount = false,
+        $exception = false,
+        $additionalMessage = false
+    ) {
+        $message[] = __('Credit Card: xxxx-%1', $card->getCcLast4());
+        if ($amount) {
+            $message[] = __('amount %1', $this->formatPrice($payment, $amount));
+        }
+        $operation = $this->getOperation($requestType);
+        if (!$operation) {
+            return false;
+        } else {
+            $message[] = $operation;
+        }
+        $message[] = ($exception) ? '- ' . __('failed.') : '- ' . __('successful.');
+        if ($lastTransactionId !== null) {
+            $message[] = __('Authorize.Net Transaction ID %1.', $lastTransactionId);
+        }
+        if ($additionalMessage) {
+            $message[] = $additionalMessage;
+        }
+        if ($exception) {
+            $message[] = $exception;
+        }
+        return implode(' ', $message);
+    }
+
+    /**
+     * Return operation name for request type
+     *
+     * @param  string $requestType
+     * @return \Magento\Framework\Phrase|bool
+     */
+    protected function getOperation($requestType)
+    {
+        switch ($requestType) {
+            case Authorizenet::REQUEST_TYPE_AUTH_ONLY:
+                return __('authorize');
+            case Authorizenet::REQUEST_TYPE_AUTH_CAPTURE:
+                return __('authorize and capture');
+            case Authorizenet::REQUEST_TYPE_PRIOR_AUTH_CAPTURE:
+                return __('capture');
+            case Authorizenet::REQUEST_TYPE_CREDIT:
+                return __('refund');
+            case Authorizenet::REQUEST_TYPE_VOID:
+                return __('void');
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Format price with currency sign
+     * @param  \Magento\Payment\Model\InfoInterface $payment
+     * @param float $amount
+     * @return string
+     */
+    protected function formatPrice($payment, $amount)
+    {
+        return $payment->getOrder()->getBaseCurrency()->formatTxt($amount);
+    }
+
+    /**
+     * Get payment method step html
+     *
+     * @param \Magento\Framework\App\ViewInterface $view
+     * @return string
+     */
+    public function getPaymentMethodsHtml(\Magento\Framework\App\ViewInterface $view)
+    {
+        $layout = $view->getLayout();
+        $update = $layout->getUpdate();
+        $update->load('checkout_onepage_paymentmethod');
+        $layout->generateXml();
+        $layout->generateElements();
+        $output = $layout->getOutput();
+        return $output;
+    }
+
+    /**
+     * Get direct post relay url
+     *
+     * @param null|int|string $storeId
+     * @return string
+     */
+    public function getRelayUrl($storeId = null)
+    {
+        $baseUrl = $this->storeManager->getStore($storeId)
+            ->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_LINK);
+        return $baseUrl . 'authorizenet/directpost_payment/response';
+    }
+
+    /**
+     * Get allowed currencies
+     *
+     * @return array
+     */
+    public function getAllowedCurrencyCodes()
+    {
+        return $this->allowedCurrencyCodes;
+    }
+
+    /**
+     * Get translated filter action label
+     *
+     * @param string $key
+     * @return \Magento\Framework\Phrase|string
+     */
+    public function getFdsFilterActionLabel($key)
+    {
+        return isset($this->fdsFilterActions[$key]) ? __($this->fdsFilterActions[$key]) : $key;
+    }
+
+    /**
+     * Get translated transaction status label
+     *
+     * @param string $key
+     * @return \Magento\Framework\Phrase|string
+     */
+    public function getTransactionStatusLabel($key)
+    {
+        return isset($this->transactionStatuses[$key]) ? __($this->transactionStatuses[$key]) : $key;
+    }
+
+    /**
+     * Gateway error response wrapper
+     *
+     * @param string $text
+     * @return \Magento\Framework\Phrase
+     */
+    public function wrapGatewayError($text)
+    {
+        return __('Gateway error: %1', $text);
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Helper/DataFactory.php b/app/code/Magento/Authorizenet/Helper/DataFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..9e2bb3ef195ebc3b10f27ee6f5b86501b1d1c6d2
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Helper/DataFactory.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Helper;
+
+use Magento\Framework\Exception\LocalizedException;
+use Magento\Framework\ObjectManagerInterface;
+
+/**
+ * Class DataFactory
+ */
+class DataFactory
+{
+    /**
+     * @var ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * @var array
+     */
+    protected $helperMap = [
+        'frontend' => 'Magento\Authorizenet\Helper\Data',
+        'adminhtml' => 'Magento\Authorizenet\Helper\Backend\Data'
+    ];
+
+    /**
+     * Constructor
+     *
+     * @param ObjectManagerInterface $objectManager
+     */
+    public function __construct(ObjectManagerInterface $objectManager)
+    {
+        $this->objectManager = $objectManager;
+    }
+
+    /**
+     * Create data helper
+     *
+     * @param string $area
+     * @return \Magento\Authorizenet\Helper\Backend\Data|\Magento\Authorizenet\Helper\Data
+     * @throws LocalizedException
+     */
+    public function create($area)
+    {
+        if (!isset($this->helperMap[$area])) {
+            throw new LocalizedException(__(sprintf('For this area <%s> no suitable helper', $area)));
+        }
+
+        return $this->objectManager->get($this->helperMap[$area]);
+    }
+}
diff --git a/app/code/Magento/Authorizenet/LICENSE.txt b/app/code/Magento/Authorizenet/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..49525fd99da9c51e6d85420266d41cb3d6b7a648
--- /dev/null
+++ b/app/code/Magento/Authorizenet/LICENSE.txt
@@ -0,0 +1,48 @@
+
+Open Software License ("OSL") v. 3.0
+
+This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work:
+
+Licensed under the Open Software License version 3.0
+
+   1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following:
+
+         1. to reproduce the Original Work in copies, either alone or as part of a collective work;
+
+         2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work;
+
+         3. to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License;
+
+         4. to perform the Original Work publicly; and
+
+         5. to display the Original Work publicly. 
+
+   2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works.
+
+   3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work.
+
+   4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license.
+
+   5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).
+
+   6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.
+
+   7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer.
+
+   8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation.
+
+   9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including 'fair use' or 'fair dealing'). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c).
+
+  10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.
+
+  11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.
+
+  12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.
+
+  13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.
+
+  14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+  15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
+
+  16. Modification of This License. This License is Copyright (C) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.
\ No newline at end of file
diff --git a/app/code/Magento/Authorizenet/LICENSE_AFL.txt b/app/code/Magento/Authorizenet/LICENSE_AFL.txt
new file mode 100644
index 0000000000000000000000000000000000000000..87943b95d43a5bb8736093275afe3cb8e1d93d26
--- /dev/null
+++ b/app/code/Magento/Authorizenet/LICENSE_AFL.txt
@@ -0,0 +1,48 @@
+
+Academic Free License ("AFL") v. 3.0
+
+This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work:
+
+Licensed under the Academic Free License version 3.0
+
+   1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following:
+
+         1. to reproduce the Original Work in copies, either alone or as part of a collective work;
+
+         2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work;
+
+         3. to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License;
+
+         4. to perform the Original Work publicly; and
+
+         5. to display the Original Work publicly.
+
+   2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works.
+
+   3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work.
+
+   4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license.
+
+   5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).
+
+   6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.
+
+   7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer.
+
+   8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation.
+
+   9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c).
+
+  10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.
+
+  11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.
+
+  12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.
+
+  13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.
+
+  14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+  15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
+
+  16. Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.
\ No newline at end of file
diff --git a/app/code/Magento/Authorizenet/Model/Authorizenet.php b/app/code/Magento/Authorizenet/Model/Authorizenet.php
new file mode 100644
index 0000000000000000000000000000000000000000..a10f6ef75a2faecd6a9a7a1ab94a2aff01980110
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Authorizenet.php
@@ -0,0 +1,512 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model;
+
+/**
+ * @SuppressWarnings(PHPMD.TooManyFields)
+ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+abstract class Authorizenet extends \Magento\Payment\Model\Method\Cc
+{
+    /**
+     * AIM gateway url
+     */
+    const CGI_URL = 'https://secure.authorize.net/gateway/transact.dll';
+
+    /**
+     * Transaction Details gateway url
+     */
+    const CGI_URL_TD = 'https://apitest.authorize.net/xml/v1/request.api';
+
+    const REQUEST_METHOD_CC = 'CC';
+
+    const REQUEST_TYPE_AUTH_CAPTURE = 'AUTH_CAPTURE';
+
+    const REQUEST_TYPE_AUTH_ONLY = 'AUTH_ONLY';
+
+    const REQUEST_TYPE_CAPTURE_ONLY = 'CAPTURE_ONLY';
+
+    const REQUEST_TYPE_CREDIT = 'CREDIT';
+
+    const REQUEST_TYPE_VOID = 'VOID';
+
+    const REQUEST_TYPE_PRIOR_AUTH_CAPTURE = 'PRIOR_AUTH_CAPTURE';
+
+    const RESPONSE_DELIM_CHAR = '(~)';
+
+    const RESPONSE_CODE_APPROVED = 1;
+
+    const RESPONSE_CODE_DECLINED = 2;
+
+    const RESPONSE_CODE_ERROR = 3;
+
+    const RESPONSE_CODE_HELD = 4;
+
+    const RESPONSE_REASON_CODE_APPROVED = 1;
+
+    const RESPONSE_REASON_CODE_PENDING_REVIEW_AUTHORIZED = 252;
+
+    const RESPONSE_REASON_CODE_PENDING_REVIEW = 253;
+
+    const RESPONSE_REASON_CODE_PENDING_REVIEW_DECLINED = 254;
+
+    /**
+     * Transaction fraud state key
+     */
+    const TRANSACTION_FRAUD_STATE_KEY = 'is_transaction_fraud';
+
+    /**
+     * Real transaction id key
+     */
+    const REAL_TRANSACTION_ID_KEY = 'real_transaction_id';
+
+    /**
+     * Gateway actions locked state key
+     */
+    const GATEWAY_ACTIONS_LOCKED_STATE_KEY = 'is_gateway_actions_locked';
+
+    /**
+     * @var \Magento\Authorizenet\Helper\Data
+     */
+    protected $dataHelper;
+
+    /**
+     * Request factory
+     *
+     * @var \Magento\Authorizenet\Model\RequestFactory
+     */
+    protected $requestFactory;
+
+    /**
+     * Response factory
+     *
+     * @var \Magento\Authorizenet\Model\ResponseFactory
+     */
+    protected $responseFactory;
+
+    /**
+     * Stored information about transaction
+     *
+     * @var array
+     */
+    protected $transactionDetails = [];
+
+    /**
+     * @param \Magento\Framework\Model\Context $context
+     * @param \Magento\Framework\Registry $registry
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+     * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
+     * @param \Magento\Payment\Helper\Data $paymentData
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Payment\Model\Method\Logger $logger
+     * @param \Magento\Framework\Module\ModuleListInterface $moduleList
+     * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
+     * @param \Magento\Authorizenet\Helper\Data $dataHelper
+     * @param \Magento\Authorizenet\Model\Request\Factory $requestFactory
+     * @param \Magento\Authorizenet\Model\Response\Factory $responseFactory
+     * @param \Magento\Framework\Model\Resource\AbstractResource $resource
+     * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
+     * @param array $data
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     */
+    public function __construct(
+        \Magento\Framework\Model\Context $context,
+        \Magento\Framework\Registry $registry,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
+        \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
+        \Magento\Payment\Helper\Data $paymentData,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Payment\Model\Method\Logger $logger,
+        \Magento\Framework\Module\ModuleListInterface $moduleList,
+        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
+        \Magento\Authorizenet\Helper\Data $dataHelper,
+        \Magento\Authorizenet\Model\Request\Factory $requestFactory,
+        \Magento\Authorizenet\Model\Response\Factory $responseFactory,
+        \Magento\Framework\Model\Resource\AbstractResource $resource = null,
+        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
+        array $data = []
+    ) {
+        $this->dataHelper = $dataHelper;
+        $this->requestFactory = $requestFactory;
+        $this->responseFactory = $responseFactory;
+
+        parent::__construct(
+            $context,
+            $registry,
+            $extensionFactory,
+            $customAttributeFactory,
+            $paymentData,
+            $scopeConfig,
+            $logger,
+            $moduleList,
+            $localeDate,
+            $resource,
+            $resourceCollection,
+            $data
+        );
+    }
+
+    /**
+     * Check method for processing with base currency
+     *
+     * @param string $currencyCode
+     * @return bool
+     */
+    public function canUseForCurrency($currencyCode)
+    {
+        if (!in_array($currencyCode, $this->getAcceptedCurrencyCodes())) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Return array of currency codes supplied by Payment Gateway
+     *
+     * @return array
+     */
+    public function getAcceptedCurrencyCodes()
+    {
+        if (!$this->hasData('_accepted_currency')) {
+            $acceptedCurrencyCodes = $this->dataHelper->getAllowedCurrencyCodes();
+            $acceptedCurrencyCodes[] = $this->getConfigData('currency');
+            $this->setData('_accepted_currency', $acceptedCurrencyCodes);
+        }
+        return $this->_getData('_accepted_currency');
+    }
+
+    /**
+     * Cancel the payment through gateway
+     *
+     * @param  \Magento\Payment\Model\InfoInterface $payment
+     * @return $this
+     */
+    public function cancel(\Magento\Payment\Model\InfoInterface $payment)
+    {
+        return $this->void($payment);
+    }
+
+    /**
+     * Fetch fraud details
+     *
+     * @param string $transactionId
+     * @return \Magento\Framework\Object
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function fetchTransactionFraudDetails($transactionId)
+    {
+        $responseXmlDocument = $this->getTransactionDetails($transactionId);
+        $response = new \Magento\Framework\Object();
+
+        if (empty($responseXmlDocument->transaction->FDSFilters->FDSFilter)) {
+            return $response;
+        }
+
+        $response->setFdsFilterAction(
+            $this->dataHelper->getFdsFilterActionLabel((string)$responseXmlDocument->transaction->FDSFilterAction)
+        );
+        $response->setAvsResponse((string)$responseXmlDocument->transaction->AVSResponse);
+        $response->setCardCodeResponse((string)$responseXmlDocument->transaction->cardCodeResponse);
+        $response->setCavvResponse((string)$responseXmlDocument->transaction->CAVVResponse);
+        $response->setFraudFilters($this->getFraudFilters($responseXmlDocument->transaction->FDSFilters));
+
+        return $response;
+    }
+
+    /**
+     * Get fraud filters
+     *
+     * @param \Magento\Framework\Simplexml\Element $fraudFilters
+     * @return array
+     */
+    protected function getFraudFilters($fraudFilters)
+    {
+        $result = [];
+
+        foreach ($fraudFilters->FDSFilter as $filer) {
+            $result[] = [
+                'name' => (string)$filer->name,
+                'action' => $this->dataHelper->getFdsFilterActionLabel((string)$filer->action)
+            ];
+        }
+
+        return $result;
+    }
+
+    /**
+     * Return authorize payment request
+     *
+     * @return \Magento\Authorizenet\Model\Request
+     */
+    protected function getRequest()
+    {
+        $request = $this->requestFactory->create()
+            ->setXVersion(3.1)
+            ->setXDelimData('True')
+            ->setXRelayResponse('False')
+            ->setXTestRequest($this->getConfigData('test') ? 'TRUE' : 'FALSE')
+            ->setXLogin($this->getConfigData('login'))
+            ->setXTranKey($this->getConfigData('trans_key'));
+        return $request;
+    }
+
+    /**
+     * Prepare request to gateway
+     *
+     * @param \Magento\Framework\Object|\Magento\Payment\Model\InfoInterface $payment
+     * @return \Magento\Authorizenet\Model\Request
+     * @link http://www.authorize.net/support/AIM_guide.pdf
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    protected function buildRequest(\Magento\Framework\Object $payment)
+    {
+        /** @var \Magento\Sales\Model\Order $order */
+        $order = $payment->getOrder();
+        $this->setStore($order->getStoreId());
+        $request = $this->getRequest()
+            ->setXType($payment->getAnetTransType())
+            ->setXMethod(self::REQUEST_METHOD_CC);
+
+        if ($order && $order->getIncrementId()) {
+            $request->setXInvoiceNum($order->getIncrementId());
+        }
+
+        if ($payment->getAmount()) {
+            $request->setXAmount($payment->getAmount(), 2);
+            $request->setXCurrencyCode($order->getBaseCurrencyCode());
+        }
+
+        switch ($payment->getAnetTransType()) {
+            case self::REQUEST_TYPE_AUTH_CAPTURE:
+                $request->setXAllowPartialAuth($this->getConfigData('allow_partial_authorization') ? 'True' : 'False');
+                break;
+            case self::REQUEST_TYPE_AUTH_ONLY:
+                $request->setXAllowPartialAuth($this->getConfigData('allow_partial_authorization') ? 'True' : 'False');
+                break;
+            case self::REQUEST_TYPE_CREDIT:
+                /**
+                 * Send last 4 digits of credit card number to authorize.net
+                 * otherwise it will give an error
+                 */
+                $request->setXCardNum($payment->getCcLast4());
+                $request->setXTransId($payment->getXTransId());
+                break;
+            case self::REQUEST_TYPE_VOID:
+                $request->setXTransId($payment->getXTransId());
+                break;
+            case self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE:
+                $request->setXTransId($payment->getXTransId());
+                break;
+            case self::REQUEST_TYPE_CAPTURE_ONLY:
+                $request->setXAuthCode($payment->getCcAuthCode());
+                break;
+        }
+
+        if (!empty($order)) {
+            $billing = $order->getBillingAddress();
+            if (!empty($billing)) {
+                $request->setXFirstName($billing->getFirstname())
+                    ->setXLastName($billing->getLastname())
+                    ->setXCompany($billing->getCompany())
+                    ->setXAddress($billing->getStreetLine(1))
+                    ->setXCity($billing->getCity())
+                    ->setXState($billing->getRegion())
+                    ->setXZip($billing->getPostcode())
+                    ->setXCountry($billing->getCountry())
+                    ->setXPhone($billing->getTelephone())
+                    ->setXFax($billing->getFax())
+                    ->setXCustId($order->getCustomerId())
+                    ->setXCustomerIp($order->getRemoteIp())
+                    ->setXCustomerTaxId($billing->getTaxId())
+                    ->setXEmail($order->getCustomerEmail())
+                    ->setXEmailCustomer($this->getConfigData('email_customer'))
+                    ->setXMerchantEmail($this->getConfigData('merchant_email'));
+            }
+
+            $shipping = $order->getShippingAddress();
+            if (!empty($shipping)) {
+                $request->setXShipToFirstName($shipping->getFirstname())
+                    ->setXShipToLastName($shipping->getLastname())
+                    ->setXShipToCompany($shipping->getCompany())
+                    ->setXShipToAddress($shipping->getStreetLine(1))
+                    ->setXShipToCity($shipping->getCity())
+                    ->setXShipToState($shipping->getRegion())
+                    ->setXShipToZip($shipping->getPostcode())
+                    ->setXShipToCountry($shipping->getCountry());
+            }
+
+            $request->setXPoNum($payment->getPoNumber())
+                ->setXTax($order->getBaseTaxAmount())
+                ->setXFreight($order->getBaseShippingAmount());
+        }
+
+        if ($payment->getCcNumber()) {
+            $request->setXCardNum($payment->getCcNumber())
+                ->setXExpDate(sprintf('%02d-%04d', $payment->getCcExpMonth(), $payment->getCcExpYear()))
+                ->setXCardCode($payment->getCcCid());
+        }
+
+        return $request;
+    }
+
+    /**
+     * Post request to gateway and return response
+     *
+     * @param \Magento\Authorizenet\Model\Request $request
+     * @return \Magento\Authorizenet\Model\Response
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    protected function postRequest(\Magento\Authorizenet\Model\Request $request)
+    {
+        $debugData = ['request' => $request->getData()];
+        $result = $this->responseFactory->create();
+        $client = new \Magento\Framework\HTTP\ZendClient();
+        $uri = $this->getConfigData('cgi_url');
+        $client->setUri($uri ? $uri : self::CGI_URL);
+        $client->setConfig(['maxredirects' => 0, 'timeout' => 30]);
+
+        foreach ($request->getData() as $key => $value) {
+            $request->setData($key, str_replace(self::RESPONSE_DELIM_CHAR, '', $value));
+        }
+
+        $request->setXDelimChar(self::RESPONSE_DELIM_CHAR);
+        $client->setParameterPost($request->getData());
+        $client->setMethod(\Zend_Http_Client::POST);
+
+        try {
+            $response = $client->request();
+        } catch (\Exception $e) {
+            $result->setXResponseCode(-1)
+                ->setXResponseReasonCode($e->getCode())
+                ->setXResponseReasonText($e->getMessage());
+
+            $debugData['result'] = $result->getData();
+            $this->_debug($debugData);
+            throw new \Magento\Framework\Exception\LocalizedException(
+                $this->dataHelper->wrapGatewayError($e->getMessage())
+            );
+        }
+
+        $responseBody = $response->getBody();
+        $r = explode(self::RESPONSE_DELIM_CHAR, $responseBody);
+
+        if ($r) {
+            $result->setXResponseCode((int)str_replace('"', '', $r[0]))
+                ->setXResponseReasonCode((int)str_replace('"', '', $r[2]))
+                ->setXResponseReasonText($r[3])
+                ->setXAvsCode($r[5])
+                ->setXTransId($r[6])
+                ->setXInvoiceNum($r[7])
+                ->setXAmount($r[9])
+                ->setXMethod($r[10])
+                ->setXType($r[11])
+                ->setData('x_MD5_Hash', $r[37])
+                ->setXAccountNumber($r[50]);
+        } else {
+            throw new \Magento\Framework\Exception\LocalizedException(
+                __('Something went wrong in the payment gateway.')
+            );
+        }
+
+        $debugData['result'] = $result->getData();
+        $this->_debug($debugData);
+
+        return $result;
+    }
+
+    /**
+     * If gateway actions are locked return true
+     *
+     * @param  \Magento\Payment\Model\InfoInterface $payment
+     * @return bool
+     */
+    protected function isGatewayActionsLocked($payment)
+    {
+        return $payment->getAdditionalInformation(self::GATEWAY_ACTIONS_LOCKED_STATE_KEY);
+    }
+
+    /**
+     * This function returns full transaction details for a specified transaction ID.
+     *
+     * @param string $transactionId
+     * @return \Magento\Framework\Object
+     * @throws \Magento\Framework\Exception\LocalizedException
+     * @link http://www.authorize.net/support/ReportingGuide_XML.pdf
+     * @link http://developer.authorize.net/api/transaction_details/
+     */
+    protected function getTransactionResponse($transactionId)
+    {
+        $responseXmlDocument = $this->getTransactionDetails($transactionId);
+
+        $response = new \Magento\Framework\Object();
+        $response->setXResponseCode((string)$responseXmlDocument->transaction->responseCode)
+            ->setXResponseReasonCode((string)$responseXmlDocument->transaction->responseReasonCode)
+            ->setTransactionStatus((string)$responseXmlDocument->transaction->transactionStatus);
+
+        return $response;
+    }
+
+    /**
+     * Load transaction details
+     *
+     * @param string $transactionId
+     * @return \Magento\Framework\Simplexml\Element
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    protected function loadTransactionDetails($transactionId)
+    {
+        $requestBody = sprintf(
+            '<?xml version="1.0" encoding="utf-8"?>' .
+            '<getTransactionDetailsRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">' .
+            '<merchantAuthentication><name>%s</name><transactionKey>%s</transactionKey></merchantAuthentication>' .
+            '<transId>%s</transId>' .
+            '</getTransactionDetailsRequest>',
+            $this->getConfigData('login'),
+            $this->getConfigData('trans_key'),
+            $transactionId
+        );
+
+        $client = new \Magento\Framework\HTTP\ZendClient();
+        $uri = $this->getConfigData('cgi_url_td');
+        $client->setUri($uri ? $uri : self::CGI_URL_TD);
+        $client->setConfig(['timeout' => 45]);
+        $client->setHeaders(['Content-Type: text/xml']);
+        $client->setMethod(\Zend_Http_Client::POST);
+        $client->setRawData($requestBody);
+
+        $debugData = ['request' => $requestBody];
+
+        try {
+            $responseBody = $client->request()->getBody();
+            $debugData['result'] = $responseBody;
+            $this->_debug($debugData);
+            libxml_use_internal_errors(true);
+            $responseXmlDocument = new \Magento\Framework\Simplexml\Element($responseBody);
+            libxml_use_internal_errors(false);
+        } catch (\Exception $e) {
+            throw new \Magento\Framework\Exception\LocalizedException(__('Payment updating error.'));
+        }
+
+        $this->transactionDetails[$transactionId] = $responseXmlDocument;
+        return $responseXmlDocument;
+    }
+
+    /**
+     * Get transaction information
+     *
+     * @param string $transactionId
+     * @return \Magento\Framework\Simplexml\Element
+     */
+    protected function getTransactionDetails($transactionId)
+    {
+        return isset($this->transactionDetails[$transactionId])
+            ? $this->transactionDetails[$transactionId]
+            : $this->loadTransactionDetails($transactionId);
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Debug.php b/app/code/Magento/Authorizenet/Model/Debug.php
new file mode 100644
index 0000000000000000000000000000000000000000..4cde70deb0fd684478c1e6b4c096ecbc405a54fb
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Debug.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model;
+
+/**
+ * @method \Magento\Authorizenet\Model\Resource\Debug _getResource()
+ * @method \Magento\Authorizenet\Model\Resource\Debug getResource()
+ * @method string getRequestBody()
+ * @method \Magento\Authorizenet\Model\Debug setRequestBody(string $value)
+ * @method string getResponseBody()
+ * @method \Magento\Authorizenet\Model\Debug setResponseBody(string $value)
+ * @method string getRequestSerialized()
+ * @method \Magento\Authorizenet\Model\Debug setRequestSerialized(string $value)
+ * @method string getResultSerialized()
+ * @method \Magento\Authorizenet\Model\Debug setResultSerialized(string $value)
+ * @method string getRequestDump()
+ * @method \Magento\Authorizenet\Model\Debug setRequestDump(string $value)
+ * @method string getResultDump()
+ * @method \Magento\Authorizenet\Model\Debug setResultDump(string $value)
+ */
+class Debug extends \Magento\Framework\Model\AbstractModel
+{
+    /**
+     * @return void
+     */
+    protected function _construct()
+    {
+        $this->_init('Magento\Authorizenet\Model\Resource\Debug');
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Directpost.php b/app/code/Magento/Authorizenet/Model/Directpost.php
new file mode 100644
index 0000000000000000000000000000000000000000..27270490c51a05a6fee0b760ed82cab1bcc531a0
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Directpost.php
@@ -0,0 +1,901 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model;
+
+use Magento\Payment\Model\Method\ConfigInterface;
+use Magento\Payment\Model\Method\TransparentInterface;
+use Magento\Sales\Model\Order\Email\Sender\OrderSender;
+
+/**
+ * Authorize.net DirectPost payment method model.
+ * @SuppressWarnings(PHPMD.TooManyFields)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
+ */
+class Directpost extends \Magento\Authorizenet\Model\Authorizenet implements TransparentInterface, ConfigInterface
+{
+    const METHOD_CODE = 'authorizenet_directpost';
+
+    /**
+     * @var string
+     */
+    protected $_formBlockType = 'Magento\Payment\Block\Transparent\Info';
+
+    /**
+     * @var string
+     */
+    protected $_infoBlockType = 'Magento\Payment\Block\Info';
+
+    /**
+     * Payment Method feature
+     *
+     * @var bool
+     */
+    protected $_isGateway = true;
+
+    /**
+     * Payment Method feature
+     *
+     * @var bool
+     */
+    protected $_canAuthorize = true;
+
+    /**
+     * Payment Method feature
+     *
+     * @var bool
+     */
+    protected $_canCapture = true;
+
+    /**
+     * Payment Method feature
+     *
+     * @var bool
+     */
+    protected $_canRefund = true;
+
+    /**
+     * Payment Method feature
+     *
+     * @var bool
+     */
+    protected $_canRefundInvoicePartial = true;
+
+    /**
+     * Payment Method feature
+     *
+     * @var bool
+     */
+    protected $_canVoid = true;
+
+    /**
+     * Payment Method feature
+     *
+     * @var bool
+     */
+    protected $_canFetchTransactionInfo = true;
+
+    /**
+     * Payment Method feature
+     *
+     * @var bool
+     */
+    protected $_isInitializeNeeded = true;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $storeManager;
+
+    /**
+     * @var \Magento\Quote\Model\QuoteRepository
+     */
+    protected $quoteRepository;
+
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost\Response
+     */
+    protected $response;
+
+    /**
+     * @var OrderSender
+     */
+    protected $orderSender;
+
+    /**
+     * Order factory
+     *
+     * @var \Magento\Sales\Model\OrderFactory
+     */
+    protected $orderFactory;
+
+    /**
+     * @param \Magento\Framework\Model\Context $context
+     * @param \Magento\Framework\Registry $registry
+     * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
+     * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
+     * @param \Magento\Payment\Helper\Data $paymentData
+     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
+     * @param \Magento\Payment\Model\Method\Logger $logger
+     * @param \Magento\Framework\Module\ModuleListInterface $moduleList
+     * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
+     * @param \Magento\Authorizenet\Helper\Data $dataHelper
+     * @param \Magento\Authorizenet\Model\Directpost\Request\Factory $requestFactory
+     * @param \Magento\Authorizenet\Model\Directpost\Response\Factory $responseFactory
+     * @param \Magento\Sales\Model\OrderFactory $orderFactory
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     * @param \Magento\Quote\Model\QuoteRepository $quoteRepository
+     * @param \Magento\Sales\Model\Order\Email\Sender\OrderSender $orderSender
+     * @param \Magento\Framework\Model\Resource\AbstractResource $resource
+     * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
+     * @param array $data
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     */
+    public function __construct(
+        \Magento\Framework\Model\Context $context,
+        \Magento\Framework\Registry $registry,
+        \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
+        \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
+        \Magento\Payment\Helper\Data $paymentData,
+        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
+        \Magento\Payment\Model\Method\Logger $logger,
+        \Magento\Framework\Module\ModuleListInterface $moduleList,
+        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
+        \Magento\Authorizenet\Helper\Data $dataHelper,
+        \Magento\Authorizenet\Model\Directpost\Request\Factory $requestFactory,
+        \Magento\Authorizenet\Model\Directpost\Response\Factory $responseFactory,
+        \Magento\Sales\Model\OrderFactory $orderFactory,
+        \Magento\Store\Model\StoreManagerInterface $storeManager,
+        \Magento\Quote\Model\QuoteRepository $quoteRepository,
+        \Magento\Sales\Model\Order\Email\Sender\OrderSender $orderSender,
+        \Magento\Framework\Model\Resource\AbstractResource $resource = null,
+        \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
+        array $data = []
+    ) {
+        $this->orderFactory = $orderFactory;
+        $this->storeManager = $storeManager;
+        $this->quoteRepository = $quoteRepository;
+        $this->response = $responseFactory->create();
+        $this->orderSender = $orderSender;
+        $this->_code = static::METHOD_CODE;
+
+        parent::__construct(
+            $context,
+            $registry,
+            $extensionFactory,
+            $customAttributeFactory,
+            $paymentData,
+            $scopeConfig,
+            $logger,
+            $moduleList,
+            $localeDate,
+            $dataHelper,
+            $requestFactory,
+            $responseFactory,
+            $resource,
+            $resourceCollection,
+            $data
+        );
+    }
+
+    /**
+     * Set data helper
+     *
+     * @param \Magento\Authorizenet\Helper\Data $dataHelper
+     * @return void
+     */
+    public function setDataHelper(\Magento\Authorizenet\Helper\Data $dataHelper)
+    {
+        $this->dataHelper = $dataHelper;
+    }
+
+    /**
+     * Do not validate payment form using server methods
+     *
+     * @return bool
+     */
+    public function validate()
+    {
+        return true;
+    }
+
+    /**
+     * Send authorize request to gateway
+     *
+     * @param \Magento\Framework\Object|\Magento\Payment\Model\InfoInterface $payment
+     * @param  float $amount
+     * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function authorize(\Magento\Payment\Model\InfoInterface $payment, $amount)
+    {
+        $payment->setAdditionalInformation('payment_type', $this->getConfigData('payment_action'));
+    }
+
+    /**
+     * Send capture request to gateway
+     *
+     * @param \Magento\Framework\Object|\Magento\Payment\Model\InfoInterface $payment
+     * @param float $amount
+     * @return $this
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function capture(\Magento\Payment\Model\InfoInterface $payment, $amount)
+    {
+        if ($amount <= 0) {
+            throw new \Magento\Framework\Exception\LocalizedException(__('Invalid amount for capture.'));
+        }
+
+        $payment->setAmount($amount);
+
+        if ($payment->getParentTransactionId()) {
+            $payment->setAnetTransType(self::REQUEST_TYPE_PRIOR_AUTH_CAPTURE);
+            $payment->setXTransId($this->getRealParentTransactionId($payment));
+        } else {
+            $payment->setAnetTransType(self::REQUEST_TYPE_AUTH_CAPTURE);
+        }
+
+        $result = $this->getResponse();
+        if (empty($result->getData())) {
+            $request = $this->buildRequest($payment);
+            $result = $this->postRequest($request);
+        }
+
+        return $this->processCapture($result, $payment);
+    }
+
+    /**
+     * Process capture request
+     *
+     * @param \Magento\Authorizenet\Model\Directpost\Response $result
+     * @param \Magento\Payment\Model\InfoInterface $payment
+     * @return $this
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    protected function processCapture($result, $payment)
+    {
+        switch ($result->getXResponseCode()) {
+            case self::RESPONSE_CODE_APPROVED:
+            case self::RESPONSE_CODE_HELD:
+                if (
+                    in_array(
+                        $result->getXResponseReasonCode(),
+                        [
+                            self::RESPONSE_REASON_CODE_APPROVED,
+                            self::RESPONSE_REASON_CODE_PENDING_REVIEW,
+                            self::RESPONSE_REASON_CODE_PENDING_REVIEW_AUTHORIZED
+                        ]
+                    )
+                ) {
+                    if (!$payment->getParentTransactionId()
+                        || $result->getXTransId() != $payment->getParentTransactionId()
+                    ) {
+                        $payment->setTransactionId($result->getXTransId());
+                    }
+                    $payment->setIsTransactionClosed(0)
+                        ->setTransactionAdditionalInfo(
+                            self::REAL_TRANSACTION_ID_KEY,
+                            $result->getXTransId()
+                        );
+                    return $this;
+                }
+                throw new \Magento\Framework\Exception\LocalizedException(
+                    $this->dataHelper->wrapGatewayError($result->getXResponseReasonText())
+                );
+            case self::RESPONSE_CODE_DECLINED:
+            case self::RESPONSE_CODE_ERROR:
+                throw new \Magento\Framework\Exception\LocalizedException(
+                    $this->dataHelper->wrapGatewayError($result->getXResponseReasonText())
+                );
+            default:
+                throw new \Magento\Framework\Exception\LocalizedException(__('Payment capturing error.'));
+        }
+    }
+
+    /**
+     * Void the payment through gateway
+     *
+     * @param \Magento\Framework\Object|\Magento\Payment\Model\InfoInterface $payment
+     * @return $this
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function void(\Magento\Payment\Model\InfoInterface $payment)
+    {
+        if (!$payment->getParentTransactionId()) {
+            throw new \Magento\Framework\Exception\LocalizedException(__('Invalid transaction ID.'));
+        }
+
+        $payment->setAnetTransType(self::REQUEST_TYPE_VOID);
+        $payment->setXTransId($this->getRealParentTransactionId($payment));
+
+        $request = $this->buildRequest($payment);
+        $result = $this->postRequest($request);
+
+        switch ($result->getXResponseCode()) {
+            case self::RESPONSE_CODE_APPROVED:
+                if ($result->getXResponseReasonCode() == self::RESPONSE_REASON_CODE_APPROVED) {
+                    if ($result->getXTransId() != $payment->getParentTransactionId()) {
+                        $payment->setTransactionId($result->getXTransId());
+                    }
+                    $payment->setIsTransactionClosed(1)
+                        ->setShouldCloseParentTransaction(1)
+                        ->setTransactionAdditionalInfo(self::REAL_TRANSACTION_ID_KEY, $result->getXTransId());
+                    return $this;
+                }
+                throw new \Magento\Framework\Exception\LocalizedException(
+                    $this->dataHelper->wrapGatewayError($result->getXResponseReasonText())
+                );
+            case self::RESPONSE_CODE_DECLINED:
+            case self::RESPONSE_CODE_ERROR:
+                throw new \Magento\Framework\Exception\LocalizedException(
+                    $this->dataHelper->wrapGatewayError($result->getXResponseReasonText())
+                );
+            default:
+                throw new \Magento\Framework\Exception\LocalizedException(__('Payment voiding error.'));
+        }
+    }
+
+    /**
+     * Refund the amount
+     * Need to decode last 4 digits for request.
+     *
+     * @param \Magento\Framework\Object|\Magento\Payment\Model\InfoInterface $payment
+     * @param float $amount
+     * @return $this
+     * @throws \Exception
+     */
+    public function refund(\Magento\Payment\Model\InfoInterface $payment, $amount)
+    {
+        $last4 = $payment->getCcLast4();
+        $payment->setCcLast4($payment->decrypt($last4));
+        try {
+            $this->processRefund($payment, $amount);
+        } catch (\Exception $e) {
+            $payment->setCcLast4($last4);
+            throw $e;
+        }
+        $payment->setCcLast4($last4);
+        return $this;
+    }
+
+    /**
+     * Refund the amount with transaction id
+     *
+     * @param \Magento\Framework\Object $payment
+     * @param float $amount
+     * @return $this
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    protected function processRefund(\Magento\Framework\Object $payment, $amount)
+    {
+        if ($amount <= 0) {
+            throw new \Magento\Framework\Exception\LocalizedException(__('Invalid amount for refund.'));
+        }
+
+        if (!$payment->getParentTransactionId()) {
+            throw new \Magento\Framework\Exception\LocalizedException(__('Invalid transaction ID.'));
+        }
+
+        $payment->setAnetTransType(self::REQUEST_TYPE_CREDIT);
+        $payment->setAmount($amount);
+        $payment->setXTransId($this->getRealParentTransactionId($payment));
+
+        $request = $this->buildRequest($payment);
+        $result = $this->postRequest($request);
+
+        switch ($result->getXResponseCode()) {
+            case self::RESPONSE_CODE_APPROVED:
+                if ($result->getXResponseReasonCode() == self::RESPONSE_REASON_CODE_APPROVED) {
+                    if ($result->getXTransId() != $payment->getParentTransactionId()) {
+                        $payment->setTransactionId($result->getXTransId());
+                    }
+                    $shouldCloseCaptureTransaction = $payment->getOrder()->canCreditmemo() ? 0 : 1;
+                    $payment->setIsTransactionClosed(1)
+                        ->setShouldCloseParentTransaction($shouldCloseCaptureTransaction)
+                        ->setTransactionAdditionalInfo(self::REAL_TRANSACTION_ID_KEY, $result->getXTransId());
+                    return $this;
+                }
+                throw new \Magento\Framework\Exception\LocalizedException(
+                    $this->dataHelper->wrapGatewayError($result->getXResponseReasonText())
+                );
+            case self::RESPONSE_CODE_DECLINED:
+            case self::RESPONSE_CODE_ERROR:
+                throw new \Magento\Framework\Exception\LocalizedException(
+                    $this->dataHelper->wrapGatewayError($result->getXResponseReasonText())
+                );
+            default:
+                throw new \Magento\Framework\Exception\LocalizedException(__('Payment refunding error.'));
+        }
+    }
+
+    /**
+     * Get CGI url
+     *
+     * @return string
+     */
+    public function getCgiUrl()
+    {
+        $uri = $this->getConfigData('cgi_url');
+        return $uri ? $uri : self::CGI_URL;
+    }
+
+    /**
+     * Return URL on which Authorize.net server will return payment result data in hidden request.
+     *
+     * @param int $storeId
+     * @return string
+     */
+    public function getRelayUrl($storeId = null)
+    {
+        if ($storeId == null && $this->getStore()) {
+            $storeId = $this->getStore();
+        }
+        return $this->dataHelper->getRelayUrl($storeId);
+    }
+
+    /**
+     * Return response.
+     *
+     * @return \Magento\Authorizenet\Model\Directpost\Response
+     */
+    public function getResponse()
+    {
+        return $this->response;
+    }
+
+    /**
+     * Instantiate state and set it to state object
+     *
+     * @param string $paymentAction
+     * @param \Magento\Framework\Object $stateObject
+     * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
+     */
+    public function initialize($paymentAction, $stateObject)
+    {
+        $requestType = null;
+        switch ($paymentAction) {
+            case self::ACTION_AUTHORIZE:
+                $requestType = self::REQUEST_TYPE_AUTH_ONLY;
+                //intentional
+            case self::ACTION_AUTHORIZE_CAPTURE:
+                $requestType = $requestType ?: self::REQUEST_TYPE_AUTH_CAPTURE;
+                $payment = $this->getInfoInstance();
+                $order = $payment->getOrder();
+                $order->setCanSendNewEmailFlag(false);
+                $payment->setBaseAmountAuthorized($order->getBaseTotalDue());
+                $payment->setAmountAuthorized($order->getTotalDue());
+                $payment->setAnetTransType($requestType);
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * Generate request object and fill its fields from Quote or Order object
+     *
+     * @param \Magento\Sales\Model\Order $order Quote or order object.
+     * @return \Magento\Authorizenet\Model\Directpost\Request
+     */
+    public function generateRequestFromOrder(\Magento\Sales\Model\Order $order)
+    {
+        $request = $this->requestFactory->create()
+            ->setConstantData($this)
+            ->setDataFromOrder($order, $this)
+            ->signRequestData();
+
+        $this->_debug(['request' => $request->getData()]);
+
+        return $request;
+    }
+
+    /**
+     * Fill response with data.
+     *
+     * @param array $postData
+     * @return $this
+     */
+    public function setResponseData(array $postData)
+    {
+        $this->getResponse()->setData($postData);
+        return $this;
+    }
+
+    /**
+     * Validate response data. Needed in controllers.
+     *
+     * @return bool true in case of validation success.
+     * @throws \Magento\Framework\Exception\LocalizedException In case of validation error
+     */
+    public function validateResponse()
+    {
+        $response = $this->getResponse();
+        //md5 check
+        if (
+            !$this->getConfigData('trans_md5')
+            || !$this->getConfigData('login')
+            || !$response->isValidHash($this->getConfigData('trans_md5'), $this->getConfigData('login'))
+        ) {
+            throw new \Magento\Framework\Exception\LocalizedException(
+                __('The transaction was declined because the response hash validation failed.')
+            );
+        }
+        return true;
+    }
+
+    /**
+     * Operate with order using data from $_POST which came from authorize.net by Relay URL.
+     *
+     * @param array $responseData data from Authorize.net from $_POST
+     * @return void
+     * @throws \Magento\Framework\Exception\LocalizedException In case of validation error or order creation error
+     */
+    public function process(array $responseData)
+    {
+        $this->_debug(['response' => $responseData]);
+
+        $this->setResponseData($responseData);
+
+        //check MD5 error or others response errors
+        //throws exception on false.
+        $this->validateResponse();
+
+        $response = $this->getResponse();
+        //operate with order
+        $orderIncrementId = $response->getXInvoiceNum();
+        $responseText = $this->dataHelper->wrapGatewayError($response->getXResponseReasonText());
+        $isError = false;
+        if ($orderIncrementId) {
+            /* @var $order \Magento\Sales\Model\Order */
+            $order = $this->orderFactory->create()->loadByIncrementId($orderIncrementId);
+            //check payment method
+            $payment = $order->getPayment();
+            if (!$payment || $payment->getMethod() != $this->getCode()) {
+                throw new \Magento\Framework\Exception\LocalizedException(
+                    __('This payment didn\'t work out because we can\'t find this order.')
+                );
+            }
+            if ($order->getId()) {
+                //operate with order
+                $this->processOrder($order);
+            } else {
+                $isError = true;
+            }
+        } else {
+            $isError = true;
+        }
+
+        if ($isError) {
+            $responseText = $responseText && !$response->isApproved()
+                ? $responseText
+                : __('This payment didn\'t work out because we can\'t find this order.');
+            throw new \Magento\Framework\Exception\LocalizedException($responseText);
+        }
+    }
+
+    /**
+     * Fill payment with credit card data from response from Authorize.net.
+     *
+     * @param \Magento\Framework\Object $payment
+     * @return void
+     */
+    protected function fillPaymentByResponse(\Magento\Framework\Object $payment)
+    {
+        $response = $this->getResponse();
+        $payment->setTransactionId($response->getXTransId())
+            ->setParentTransactionId(null)
+            ->setIsTransactionClosed(0)
+            ->setTransactionAdditionalInfo(self::REAL_TRANSACTION_ID_KEY, $response->getXTransId());
+
+        if ($response->getXMethod() == self::REQUEST_METHOD_CC) {
+            $payment->setCcAvsStatus($response->getXAvsCode())
+                ->setCcLast4($payment->encrypt(substr($response->getXAccountNumber(), -4)));
+        }
+
+        if ($response->getXResponseCode() == self::RESPONSE_CODE_HELD) {
+            $payment->setIsTransactionPending(true)
+                ->setIsFraudDetected(true);
+        }
+    }
+
+    /**
+     * Check response code came from Authorize.net.
+     *
+     * @return true in case of Approved response
+     * @throws \Magento\Framework\Exception\LocalizedException In case of Declined or Error response from Authorize.net
+     */
+    public function checkResponseCode()
+    {
+        switch ($this->getResponse()->getXResponseCode()) {
+            case self::RESPONSE_CODE_APPROVED:
+            case self::RESPONSE_CODE_HELD:
+                return true;
+            case self::RESPONSE_CODE_DECLINED:
+            case self::RESPONSE_CODE_ERROR:
+                throw new \Magento\Framework\Exception\LocalizedException(
+                    $this->dataHelper->wrapGatewayError($this->getResponse()->getXResponseReasonText())
+                );
+            default:
+                throw new \Magento\Framework\Exception\LocalizedException(
+                    __('There was a payment authorization error.')
+                );
+        }
+    }
+
+    /**
+     * Check transaction id came from Authorize.net
+     *
+     * @return true in case of right transaction id
+     * @throws \Magento\Framework\Exception\LocalizedException In case of bad transaction id.
+     */
+    public function checkTransId()
+    {
+        if (!$this->getResponse()->getXTransId()) {
+            throw new \Magento\Framework\Exception\LocalizedException(
+                __('Please enter a transaction ID to authorize this payment.')
+            );
+        }
+        return true;
+    }
+
+    /**
+     * Compare amount with amount from the response from Authorize.net.
+     *
+     * @param float $amount
+     * @return bool
+     */
+    protected function matchAmount($amount)
+    {
+        return sprintf('%.2F', $amount) == sprintf('%.2F', $this->getResponse()->getXAmount());
+    }
+
+    /**
+     * Operate with order using information from Authorize.net.
+     * Authorize order or authorize and capture it.
+     *
+     * @param \Magento\Sales\Model\Order $order
+     * @return void
+     * @throws \Magento\Framework\Exception\LocalizedException
+     * @throws \Exception
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    protected function processOrder(\Magento\Sales\Model\Order $order)
+    {
+        try {
+            $this->checkResponseCode();
+            $this->checkTransId();
+        } catch (\Exception $e) {
+            //decline the order (in case of wrong response code) but don't return money to customer.
+            $message = $e->getMessage();
+            $this->declineOrder($order, $message, false);
+            throw $e;
+        }
+
+        $response = $this->getResponse();
+
+        //create transaction. need for void if amount will not match.
+        $payment = $order->getPayment();
+        $this->fillPaymentByResponse($payment);
+        $payment->getMethodInstance()->setIsInitializeNeeded(false);
+        $payment->getMethodInstance()->setResponseData($response->getData());
+        $this->processPaymentFraudStatus($payment);
+        $payment->place();
+        $this->addStatusComment($payment);
+        $order->save();
+
+        //match amounts. should be equals for authorization.
+        //decline the order if amount does not match.
+        if (!$this->matchAmount($payment->getBaseAmountAuthorized())) {
+            $message = __(
+                'Something went wrong: the paid amount doesn\'t match the order amount.'
+                . ' Please correct this and try again.'
+            );
+            $this->declineOrder($order, $message, true);
+            throw new \Magento\Framework\Exception\LocalizedException($message);
+        }
+
+        try {
+            if (!$response->hasOrderSendConfirmation() || $response->getOrderSendConfirmation()) {
+                $this->orderSender->send($order);
+            }
+
+            $quote = $this->quoteRepository->get($order->getQuoteId())->setIsActive(false);
+            $this->quoteRepository->save($quote);
+        } catch (\Exception $e) {
+            // do not cancel order if we couldn't send email
+        }
+    }
+
+    /**
+     * Process fraud status
+     *
+     * @param \Magento\Sales\Model\Order\Payment $payment
+     * @return $this
+     */
+    protected function processPaymentFraudStatus(\Magento\Sales\Model\Order\Payment $payment)
+    {
+        $fraudDetailsResponse = $payment->getMethodInstance()
+            ->fetchTransactionFraudDetails($this->getResponse()->getXTransId());
+        $fraudData = $fraudDetailsResponse->getData();
+
+        if (empty($fraudData)) {
+            $payment->setIsFraudDetected(false);
+            return $this;
+        }
+
+        $payment->setIsFraudDetected(true);
+        $payment->setAdditionalInformation('fraud_details', $fraudData);
+
+        return $this;
+    }
+
+    /**
+     * Add status comment
+     *
+     * @param \Magento\Sales\Model\Order\Payment $payment
+     * @return $this
+     */
+    protected function addStatusComment(\Magento\Sales\Model\Order\Payment $payment)
+    {
+        $transactionId = $this->getResponse()->getXTransId();
+        $data = $payment->getMethodInstance()->getTransactionDetails($transactionId);
+        $transactionStatus = (string)$data->transaction->transactionStatus;
+        $fdsFilterAction = (string)$data->transaction->FDSFilterAction;
+
+        if ($payment->getIsTransactionPending()) {
+            $message = 'Amount of %1 is pending approval on the gateway.<br/>'
+                . 'Transaction "%2" status is "%3".<br/>'
+                . 'Transaction FDS Filter Action is "%4"';
+            $message = __(
+                $message,
+                $payment->getOrder()->getBaseCurrency()->formatTxt($this->getResponse()->getXAmount()),
+                $transactionId,
+                $this->dataHelper->getTransactionStatusLabel($transactionStatus),
+                $this->dataHelper->getFdsFilterActionLabel($fdsFilterAction)
+            );
+            $payment->getOrder()->addStatusHistoryComment($message);
+        }
+        return $this;
+    }
+
+    /**
+     * Register order cancellation. Return money to customer if needed.
+     *
+     * @param \Magento\Sales\Model\Order $order
+     * @param string $message
+     * @param bool $voidPayment
+     * @return void
+     */
+    protected function declineOrder(\Magento\Sales\Model\Order $order, $message = '', $voidPayment = true)
+    {
+        try {
+            $response = $this->getResponse();
+            if (
+                $voidPayment && $response->getXTransId() && strtoupper($response->getXType())
+                == self::REQUEST_TYPE_AUTH_ONLY
+            ) {
+                $order->getPayment()->setTransactionId(null)->setParentTransactionId($response->getXTransId())->void();
+            }
+            $order->registerCancellation($message)->save();
+        } catch (\Exception $e) {
+            //quiet decline
+            $this->logger->critical($e);
+        }
+    }
+
+    /**
+     * Return additional information`s transaction_id value of parent transaction model
+     *
+     * @param \Magento\Sales\Model\Order\Payment $payment
+     * @return string
+     */
+    protected function getRealParentTransactionId($payment)
+    {
+        $transaction = $payment->getTransaction($payment->getParentTransactionId());
+        return $transaction->getAdditionalInformation(self::REAL_TRANSACTION_ID_KEY);
+    }
+
+    /**
+     * {inheritdoc}
+     */
+    public function getConfigInterface()
+    {
+        return $this;
+    }
+
+    /**
+     * Getter for specified value according to set payment method code
+     *
+     * @param mixed $key
+     * @param null $storeId
+     * @return mixed
+     */
+    public function getValue($key, $storeId = null)
+    {
+        return $this->getConfigData($key, $storeId);
+    }
+
+    /**
+     * Set initialization requirement state
+     *
+     * @param bool $isInitializeNeeded
+     * @return void
+     */
+    public function setIsInitializeNeeded($isInitializeNeeded = true)
+    {
+        $this->_isInitializeNeeded = (bool)$isInitializeNeeded;
+    }
+
+    /**
+     * Get whether it is possible to capture
+     *
+     * @return bool
+     */
+    public function canCapture()
+    {
+        return !$this->isGatewayActionsLocked($this->getInfoInstance());
+    }
+
+    /**
+     * Fetch transaction details info
+     *
+     * Update transaction info if there is one placing transaction only
+     *
+     * @param \Magento\Payment\Model\InfoInterface $payment
+     * @param string $transactionId
+     * @return array
+     */
+    public function fetchTransactionInfo(\Magento\Payment\Model\InfoInterface $payment, $transactionId)
+    {
+        $transaction = $payment->getTransaction($transactionId);
+
+        $response = $this->getTransactionResponse($transactionId);
+        if ($response->getXResponseCode() == self::RESPONSE_CODE_APPROVED) {
+            if ($response->getTransactionStatus() == 'voided') {
+                $payment->setIsTransactionDenied(true);
+            } else {
+                $transaction->setAdditionalInformation(self::TRANSACTION_FRAUD_STATE_KEY, false);
+                $payment->setIsTransactionApproved(true);
+            }
+        } elseif ($response->getXResponseReasonCode() == self::RESPONSE_REASON_CODE_PENDING_REVIEW_DECLINED) {
+            $payment->setIsTransactionDenied(true);
+        }
+        $this->addStatusCommentOnUpdate($payment, $response, $transactionId);
+        return parent::fetchTransactionInfo($payment, $transactionId);
+    }
+
+    /**
+     * @param \Magento\Sales\Model\Order\Payment $payment
+     * @param \Magento\Framework\Object $response
+     * @param string $transactionId
+     * @return $this
+     */
+    protected function addStatusCommentOnUpdate(
+        \Magento\Sales\Model\Order\Payment $payment,
+        \Magento\Framework\Object $response,
+        $transactionId
+    ) {
+        if ($payment->getIsTransactionApproved()) {
+            $message = __(
+                'Transaction %1 has been approved. Amount %2. Transaction status is "%3"',
+                $transactionId,
+                $payment->getOrder()->getBaseCurrency()->formatTxt($payment->getAmountAuthorized()),
+                $this->dataHelper->getTransactionStatusLabel($response->getTransactionStatus())
+            );
+            $payment->getOrder()->addStatusHistoryComment($message);
+        } elseif ($payment->getIsTransactionDenied()) {
+            $message = __(
+                'Transaction %1 has been voided/declined. Transaction status is "%2". Amount %3.',
+                $transactionId,
+                $this->dataHelper->getTransactionStatusLabel($response->getTransactionStatus()),
+                $payment->getOrder()->getBaseCurrency()->formatTxt($payment->getAmountAuthorized())
+            );
+            $payment->getOrder()->addStatusHistoryComment($message);
+        }
+        return $this;
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Directpost/Observer.php b/app/code/Magento/Authorizenet/Model/Directpost/Observer.php
new file mode 100644
index 0000000000000000000000000000000000000000..ce55e5f287927f6de836326656ac68b6df81b1fc
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Directpost/Observer.php
@@ -0,0 +1,150 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model\Directpost;
+
+use Magento\Authorizenet\Model\Directpost;
+use Magento\Sales\Model\Order;
+
+/**
+ * Authorize.net directpayment observer
+ *
+ * @author      Magento Core Team <core@magentocommerce.com>
+ */
+class Observer
+{
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $_coreRegistry;
+
+    /**
+     * Authorizenet helper
+     *
+     * @var \Magento\Authorizenet\Helper\Data
+     */
+    protected $_authorizenetData;
+
+    /**
+     * @var Directpost
+     */
+    protected $_payment;
+
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost\Session
+     */
+    protected $_session;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface
+     */
+    protected $_storeManager;
+
+    /**
+     * Constructor
+     *
+     * @param \Magento\Authorizenet\Helper\Data $authorizenetData
+     * @param \Magento\Framework\Registry $coreRegistry
+     * @param Directpost $payment
+     * @param \Magento\Authorizenet\Model\Directpost\Session $session
+     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
+     */
+    public function __construct(
+        \Magento\Authorizenet\Helper\Data $authorizenetData,
+        \Magento\Framework\Registry $coreRegistry,
+        Directpost $payment,
+        \Magento\Authorizenet\Model\Directpost\Session $session,
+        \Magento\Store\Model\StoreManagerInterface $storeManager
+    ) {
+        $this->_coreRegistry = $coreRegistry;
+        $this->_authorizenetData = $authorizenetData;
+        $this->_payment = $payment;
+        $this->_session = $session;
+        $this->_storeManager = $storeManager;
+    }
+
+    /**
+     * Save order into registry to use it in the overloaded controller.
+     *
+     * @param \Magento\Framework\Event\Observer $observer
+     * @return $this
+     */
+    public function saveOrderAfterSubmit(\Magento\Framework\Event\Observer $observer)
+    {
+        /* @var $order Order */
+        $order = $observer->getEvent()->getData('order');
+        $this->_coreRegistry->register('directpost_order', $order, true);
+
+        return $this;
+    }
+
+    /**
+     * Set data for response of frontend saveOrder action
+     *
+     * @param \Magento\Framework\Event\Observer $observer
+     * @return $this
+     */
+    public function addFieldsToResponse(\Magento\Framework\Event\Observer $observer)
+    {
+        /* @var $order Order */
+        $order = $this->_coreRegistry->registry('directpost_order');
+
+        if (!$order || !$order->getId()) {
+            return $this;
+        }
+
+        $payment = $order->getPayment();
+
+        if (!$payment || $payment->getMethod() != $this->_payment->getCode()) {
+            return $this;
+        }
+
+        $result = $observer->getData('result')->getData();
+
+        if (!empty($result['error'])) {
+            return $this;
+        }
+
+        // if success, then set order to session and add new fields
+        $this->_session->addCheckoutOrderIncrementId($order->getIncrementId());
+        $this->_session->setLastOrderIncrementId($order->getIncrementId());
+
+        $requestToAuthorizenet = $payment->getMethodInstance()
+            ->generateRequestFromOrder($order);
+        $requestToAuthorizenet->setControllerActionName(
+            $observer->getData('action')
+                ->getRequest()
+                ->getControllerName()
+        );
+        $requestToAuthorizenet->setIsSecure(
+            (string)$this->_storeManager->getStore()
+                ->isCurrentlySecure()
+        );
+
+        $result[$this->_payment->getCode()] = ['fields' => $requestToAuthorizenet->getData()];
+
+        $observer->getData('result')->setData($result);
+
+        return $this;
+    }
+
+    /**
+     * Update all edit increments for all orders if module is enabled.
+     * Needed for correct work of edit orders in Admin area.
+     *
+     * @param \Magento\Framework\Event\Observer $observer
+     * @return $this
+     */
+    public function updateAllEditIncrements(\Magento\Framework\Event\Observer $observer)
+    {
+        /* @var $order Order */
+        $order = $observer->getEvent()->getData('order');
+        $this->_authorizenetData->updateOrderEditIncrements($order);
+
+        return $this;
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Directpost/Request.php b/app/code/Magento/Authorizenet/Model/Directpost/Request.php
new file mode 100644
index 0000000000000000000000000000000000000000..430db3cc9e76e3d3584fdb4cc1a3494e18a983f5
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Directpost/Request.php
@@ -0,0 +1,184 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Authorizenet\Model\Directpost;
+
+use Magento\Authorizenet\Model\Request as AuthorizenetRequest;
+
+/**
+ * Authorize.net request model for DirectPost model
+ */
+class Request extends AuthorizenetRequest
+{
+    /**
+     * @var string
+     */
+    protected $_transKey = null;
+
+    /**
+     * Return merchant transaction key.
+     * Needed to generate sign.
+     *
+     * @return string
+     */
+    protected function _getTransactionKey()
+    {
+        return $this->_transKey;
+    }
+
+    /**
+     * Set merchant transaction key.
+     * Needed to generate sign.
+     *
+     * @param string $transKey
+     * @return $this
+     */
+    protected function _setTransactionKey($transKey)
+    {
+        $this->_transKey = $transKey;
+        return $this;
+    }
+
+    /**
+     * Generates the fingerprint for request.
+     *
+     * @param string $merchantApiLoginId
+     * @param string $merchantTransactionKey
+     * @param string $amount
+     * @param string $currencyCode
+     * @param string $fpSequence An invoice number or random number.
+     * @param string $fpTimestamp
+     * @return string The fingerprint.
+     */
+    public function generateRequestSign(
+        $merchantApiLoginId,
+        $merchantTransactionKey,
+        $amount,
+        $currencyCode,
+        $fpSequence,
+        $fpTimestamp
+    ) {
+        return hash_hmac(
+            "md5",
+            $merchantApiLoginId . "^" . $fpSequence . "^" . $fpTimestamp . "^" . $amount . "^" . $currencyCode,
+            $merchantTransactionKey
+        );
+    }
+
+    /**
+     * Set Authorizenet data to request.
+     *
+     * @param \Magento\Authorizenet\Model\Directpost $paymentMethod
+     * @return $this
+     */
+    public function setConstantData(\Magento\Authorizenet\Model\Directpost $paymentMethod)
+    {
+        $this->setXVersion('3.1')->setXDelimData('FALSE')->setXRelayResponse('TRUE');
+
+        $this->setXTestRequest($paymentMethod->getConfigData('test') ? 'TRUE' : 'FALSE');
+
+        $this->setXLogin($paymentMethod->getConfigData('login'))
+            ->setXMethod(\Magento\Authorizenet\Model\Authorizenet::REQUEST_METHOD_CC)
+            ->setXRelayUrl($paymentMethod->getRelayUrl());
+
+        $this->_setTransactionKey($paymentMethod->getConfigData('trans_key'));
+        return $this;
+    }
+
+    /**
+     * Set entity data to request
+     *
+     * @param \Magento\Sales\Model\Order $order
+     * @param \Magento\Authorizenet\Model\Directpost $paymentMethod
+     * @return $this
+     */
+    public function setDataFromOrder(
+        \Magento\Sales\Model\Order $order,
+        \Magento\Authorizenet\Model\Directpost $paymentMethod
+    ) {
+        $payment = $order->getPayment();
+
+        $this->setXType($payment->getAnetTransType());
+        $this->setXFpSequence($order->getQuoteId());
+        $this->setXInvoiceNum($order->getIncrementId());
+        $this->setXAmount($payment->getBaseAmountAuthorized());
+        $this->setXCurrencyCode($order->getBaseCurrencyCode());
+        $this->setXTax(
+            sprintf('%.2F', $order->getBaseTaxAmount())
+        )->setXFreight(
+            sprintf('%.2F', $order->getBaseShippingAmount())
+        );
+
+        //need to use strval() because NULL values IE6-8 decodes as "null" in JSON in JavaScript,
+        //but we need "" for null values.
+        $billing = $order->getBillingAddress();
+        if (!empty($billing)) {
+            $this->setXFirstName(strval($billing->getFirstname()))
+                ->setXLastName(strval($billing->getLastname()))
+                ->setXCompany(strval($billing->getCompany()))
+                ->setXAddress(strval($billing->getStreetLine(1)))
+                ->setXCity(strval($billing->getCity()))
+                ->setXState(strval($billing->getRegion()))
+                ->setXZip(strval($billing->getPostcode()))
+                ->setXCountry(strval($billing->getCountry()))
+                ->setXPhone(strval($billing->getTelephone()))
+                ->setXFax(strval($billing->getFax()))
+                ->setXCustId(strval($billing->getCustomerId()))
+                ->setXCustomerIp(strval($order->getRemoteIp()))
+                ->setXCustomerTaxId(strval($billing->getTaxId()))
+                ->setXEmail(strval($order->getCustomerEmail()))
+                ->setXEmailCustomer(strval($paymentMethod->getConfigData('email_customer')))
+                ->setXMerchantEmail(strval($paymentMethod->getConfigData('merchant_email')));
+        }
+
+        $shipping = $order->getShippingAddress();
+        if (!empty($shipping)) {
+            $this->setXShipToFirstName(
+                strval($shipping->getFirstname())
+            )->setXShipToLastName(
+                strval($shipping->getLastname())
+            )->setXShipToCompany(
+                strval($shipping->getCompany())
+            )->setXShipToAddress(
+                strval($shipping->getStreetLine(1))
+            )->setXShipToCity(
+                strval($shipping->getCity())
+            )->setXShipToState(
+                strval($shipping->getRegion())
+            )->setXShipToZip(
+                strval($shipping->getPostcode())
+            )->setXShipToCountry(
+                strval($shipping->getCountry())
+            );
+        }
+
+        $this->setXPoNum(strval($payment->getPoNumber()));
+
+        return $this;
+    }
+
+    /**
+     * Set sign hash into the request object.
+     * All needed fields should be placed in the object fist.
+     *
+     * @return $this
+     */
+    public function signRequestData()
+    {
+        $fpTimestamp = time();
+        $hash = $this->generateRequestSign(
+            $this->getXLogin(),
+            $this->_getTransactionKey(),
+            $this->getXAmount(),
+            $this->getXCurrencyCode(),
+            $this->getXFpSequence(),
+            $fpTimestamp
+        );
+        $this->setXFpTimestamp($fpTimestamp);
+        $this->setXFpHash($hash);
+        return $this;
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Directpost/Request/Factory.php b/app/code/Magento/Authorizenet/Model/Directpost/Request/Factory.php
new file mode 100644
index 0000000000000000000000000000000000000000..49ead3ecc94c81298ab2bcd9b3260a6e831143a4
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Directpost/Request/Factory.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model\Directpost\Request;
+
+use Magento\Authorizenet\Model\Request\Factory as AuthorizenetRequestFactory;
+
+/**
+ * Factory class for @see \Magento\Authorizenet\Model\Directpost\Request
+ */
+class Factory extends AuthorizenetRequestFactory
+{
+    /**
+     * Factory constructor
+     *
+     * @param \Magento\Framework\ObjectManagerInterface $objectManager
+     * @param string $instanceName
+     */
+    public function __construct(
+        \Magento\Framework\ObjectManagerInterface $objectManager,
+        $instanceName = 'Magento\Authorizenet\Model\Directpost\Request'
+    ) {
+        parent::__construct($objectManager, $instanceName);
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Directpost/Response.php b/app/code/Magento/Authorizenet/Model/Directpost/Response.php
new file mode 100644
index 0000000000000000000000000000000000000000..481f0f20a1cc4f664e2d05e02d4f9e91c2e0616b
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Directpost/Response.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model\Directpost;
+
+use Magento\Authorizenet\Model\Response as AuthorizenetResponse;
+
+/**
+ * Authorize.net response model for DirectPost model
+ */
+class Response extends AuthorizenetResponse
+{
+    /**
+     * Generates an Md5 hash to compare against AuthNet's.
+     *
+     * @param string $merchantMd5
+     * @param string $merchantApiLogin
+     * @param string $amount
+     * @param string $transactionId
+     * @return string
+     */
+    public function generateHash($merchantMd5, $merchantApiLogin, $amount, $transactionId)
+    {
+        if (!$amount) {
+            $amount = '0.00';
+        }
+        return strtoupper(md5($merchantMd5 . $merchantApiLogin . $transactionId . $amount));
+    }
+
+    /**
+     * Return if is valid order id.
+     *
+     * @param string $merchantMd5
+     * @param string $merchantApiLogin
+     * @return bool
+     */
+    public function isValidHash($merchantMd5, $merchantApiLogin)
+    {
+        $hash = $this->generateHash($merchantMd5, $merchantApiLogin, $this->getXAmount(), $this->getXTransId());
+        return $hash == $this->getData('x_MD5_Hash');
+    }
+
+    /**
+     * Return if this is approved response from Authorize.net auth request.
+     *
+     * @return bool
+     */
+    public function isApproved()
+    {
+        return $this->getXResponseCode() == \Magento\Authorizenet\Model\Directpost::RESPONSE_CODE_APPROVED;
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Directpost/Response/Factory.php b/app/code/Magento/Authorizenet/Model/Directpost/Response/Factory.php
new file mode 100644
index 0000000000000000000000000000000000000000..91905eaf9792ca235b6f7eae97423787c4e5704e
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Directpost/Response/Factory.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model\Directpost\Response;
+
+use Magento\Authorizenet\Model\Response\Factory as AuthorizenetResponseFactory;
+
+/**
+ * Factory class for @see \Magento\Authorizenet\Model\Directpost\Response
+ */
+class Factory extends AuthorizenetResponseFactory
+{
+    /**
+     * Factory constructor
+     *
+     * @param \Magento\Framework\ObjectManagerInterface $objectManager
+     * @param string $instanceName
+     */
+    public function __construct(
+        \Magento\Framework\ObjectManagerInterface $objectManager,
+        $instanceName = 'Magento\Authorizenet\Model\Directpost\Response'
+    ) {
+        parent::__construct($objectManager, $instanceName);
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Directpost/Session.php b/app/code/Magento/Authorizenet/Model/Directpost/Session.php
new file mode 100644
index 0000000000000000000000000000000000000000..d9f6f6f85576f9cb64542f62c4164ad3e6be0659
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Directpost/Session.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model\Directpost;
+
+/**
+ * Authorize.net DirectPost session model
+ */
+class Session extends \Magento\Framework\Session\SessionManager
+{
+    /**
+     * Add order IncrementId to session
+     *
+     * @param string $orderIncrementId
+     * @return void
+     */
+    public function addCheckoutOrderIncrementId($orderIncrementId)
+    {
+        $orderIncIds = $this->getDirectPostOrderIncrementIds();
+        if (!$orderIncIds) {
+            $orderIncIds = [];
+        }
+        $orderIncIds[$orderIncrementId] = 1;
+        $this->setDirectPostOrderIncrementIds($orderIncIds);
+    }
+
+    /**
+     * Remove order IncrementId from session
+     *
+     * @param string $orderIncrementId
+     * @return void
+     */
+    public function removeCheckoutOrderIncrementId($orderIncrementId)
+    {
+        $orderIncIds = $this->getDirectPostOrderIncrementIds();
+
+        if (!is_array($orderIncIds)) {
+            return;
+        }
+
+        if (isset($orderIncIds[$orderIncrementId])) {
+            unset($orderIncIds[$orderIncrementId]);
+        }
+        $this->setDirectPostOrderIncrementIds($orderIncIds);
+    }
+
+    /**
+     * Return if order incrementId is in session.
+     *
+     * @param string $orderIncrementId
+     * @return bool
+     */
+    public function isCheckoutOrderIncrementIdExist($orderIncrementId)
+    {
+        $orderIncIds = $this->getDirectPostOrderIncrementIds();
+        if (is_array($orderIncIds) && isset($orderIncIds[$orderIncrementId])) {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Request.php b/app/code/Magento/Authorizenet/Model/Request.php
new file mode 100644
index 0000000000000000000000000000000000000000..df2be82cbe111d34ebb84ea0c18a804205f2a074
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Request.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model;
+
+use Magento\Framework\Object;
+
+/**
+ * Request object
+ */
+class Request extends Object
+{
+}
diff --git a/app/code/Magento/Authorizenet/Model/Request/Factory.php b/app/code/Magento/Authorizenet/Model/Request/Factory.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ba5cf07146c8820f38ddc785c7709cf900b4bea
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Request/Factory.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model\Request;
+
+/**
+ * Factory class for @see \Magento\Authorizenet\Model\Request
+ */
+class Factory
+{
+    /**
+     * Object Manager instance
+     *
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * Instance name to create
+     *
+     * @var string
+     */
+    protected $instanceName;
+
+    /**
+     * Factory constructor
+     *
+     * @param \Magento\Framework\ObjectManagerInterface $objectManager
+     * @param string $instanceName
+     */
+    public function __construct(
+        \Magento\Framework\ObjectManagerInterface $objectManager,
+        $instanceName = 'Magento\Authorizenet\Model\Request'
+    ) {
+        $this->objectManager = $objectManager;
+        $this->instanceName = $instanceName;
+    }
+
+    /**
+     * Create class instance with specified parameters
+     *
+     * @param array $data
+     * @return \Magento\Authorizenet\Model\Request
+     */
+    public function create(array $data = [])
+    {
+        return $this->objectManager->create($this->instanceName, $data);
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Resource/Debug.php b/app/code/Magento/Authorizenet/Model/Resource/Debug.php
new file mode 100644
index 0000000000000000000000000000000000000000..db5ab62c9b8745565ad797167e19c3100a4ac639
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Resource/Debug.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model\Resource;
+
+/**
+ * Resource Authorize.net debug model
+ */
+class Debug extends \Magento\Framework\Model\Resource\Db\AbstractDb
+{
+    /**
+     * Resource initialization
+     *
+     * @return void
+     */
+    protected function _construct()
+    {
+        $this->_init('authorizenet_debug', 'debug_id');
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Resource/Debug/Collection.php b/app/code/Magento/Authorizenet/Model/Resource/Debug/Collection.php
new file mode 100644
index 0000000000000000000000000000000000000000..39ea6789279f825e240b42645a441420774f28bf
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Resource/Debug/Collection.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model\Resource\Debug;
+
+/**
+ * Resource Authorize.net debug collection model
+ */
+class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
+{
+    /**
+     * Resource initialization
+     *
+     * @return void
+     */
+    protected function _construct()
+    {
+        $this->_init(
+            'Magento\Authorizenet\Model\Debug',
+            'Magento\Authorizenet\Model\Resource\Debug'
+        );
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Response.php b/app/code/Magento/Authorizenet/Model/Response.php
new file mode 100644
index 0000000000000000000000000000000000000000..d22475163610eb23412686ab723180215908478d
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Response.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model;
+
+use Magento\Framework\Object;
+
+/**
+ * Response object
+ */
+class Response extends Object
+{
+}
diff --git a/app/code/Magento/Authorizenet/Model/Response/Factory.php b/app/code/Magento/Authorizenet/Model/Response/Factory.php
new file mode 100644
index 0000000000000000000000000000000000000000..1a11f9ca3a3ef3e699de860a9a96cb530da9f131
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Response/Factory.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model\Response;
+
+/**
+ * Factory class for @see \Magento\Authorizenet\Model\Response
+ */
+class Factory
+{
+    /**
+     * Object Manager instance
+     *
+     * @var \Magento\Framework\ObjectManagerInterface
+     */
+    protected $objectManager;
+
+    /**
+     * Instance name to create
+     *
+     * @var string
+     */
+    protected $instanceName;
+
+    /**
+     * Factory constructor
+     *
+     * @param \Magento\Framework\ObjectManagerInterface $objectManager
+     * @param string $instanceName
+     */
+    public function __construct(
+        \Magento\Framework\ObjectManagerInterface $objectManager,
+        $instanceName = 'Magento\Authorizenet\Model\Response'
+    ) {
+        $this->objectManager = $objectManager;
+        $this->instanceName = $instanceName;
+    }
+
+    /**
+     * Create class instance with specified parameters
+     *
+     * @param array $data
+     * @return \Magento\Authorizenet\Model\Response
+     */
+    public function create(array $data = [])
+    {
+        return $this->objectManager->create($this->instanceName, $data);
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Source/Cctype.php b/app/code/Magento/Authorizenet/Model/Source/Cctype.php
new file mode 100644
index 0000000000000000000000000000000000000000..ce39818e04e068e5bbb42483ea474719c5910573
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Source/Cctype.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model\Source;
+
+use Magento\Payment\Model\Source\Cctype as PaymentCctype;
+
+/**
+ * Authorize.net Payment CC Types Source Model
+ */
+class Cctype extends PaymentCctype
+{
+    /**
+     * @return string[]
+     */
+    public function getAllowedTypes()
+    {
+        return ['VI', 'MC', 'AE', 'DI', 'OT'];
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Model/Source/PaymentAction.php b/app/code/Magento/Authorizenet/Model/Source/PaymentAction.php
new file mode 100644
index 0000000000000000000000000000000000000000..2f312f864bb3097fa681e2f08e24bc1f2ec3c3fa
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Model/Source/PaymentAction.php
@@ -0,0 +1,32 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Model\Source;
+
+use Magento\Framework\Option\ArrayInterface;
+
+/**
+ *
+ * Authorize.net Payment Action Dropdown source
+ */
+class PaymentAction implements ArrayInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function toOptionArray()
+    {
+        return [
+            [
+                'value' => \Magento\Authorizenet\Model\Authorizenet::ACTION_AUTHORIZE,
+                'label' => __('Authorize Only'),
+            ],
+            [
+                'value' => \Magento\Authorizenet\Model\Authorizenet::ACTION_AUTHORIZE_CAPTURE,
+                'label' => __('Authorize and Capture')
+            ]
+        ];
+    }
+}
diff --git a/app/code/Magento/Authorizenet/README.md b/app/code/Magento/Authorizenet/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..380161d8b264e3a34fa46344d77e51b001e9a821
--- /dev/null
+++ b/app/code/Magento/Authorizenet/README.md
@@ -0,0 +1 @@
+The Magento_Authorizenet module implements the integration with the Authorize.Net payment gateway and makes the latter available as a payment method in Magento.
diff --git a/app/code/Magento/Authorizenet/Test/Unit/Controller/Adminhtml/Authorizenet/Directpost/Payment/RedirectTest.php b/app/code/Magento/Authorizenet/Test/Unit/Controller/Adminhtml/Authorizenet/Directpost/Payment/RedirectTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad7bb7b5c0245be5122b03c3a9c68eca22afc715
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Test/Unit/Controller/Adminhtml/Authorizenet/Directpost/Payment/RedirectTest.php
@@ -0,0 +1,312 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Test\Unit\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+use Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment\Redirect;
+use Magento\Payment\Block\Transparent\Iframe;
+
+/**
+ * Class RedirectTest
+ *
+ * @SuppressWarnings(PHPMD.TooManyFields)
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class RedirectTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost
+     */
+    protected $directpost;
+
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost\Session|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $directpostSessionMock;
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectManagerMock;
+
+    /**
+     * @var \Magento\Sales\Model\Order|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $orderMock;
+
+    /**
+     * @var \Magento\Sales\Model\AdminOrder\Create|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $adminOrderCreateMock;
+
+    /**
+     * @var \Magento\Backend\Model\Session\Quote|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $sessionQuoteMock;
+
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \Magento\Framework\Message\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $messageManagerMock;
+
+    /**
+     * @var \Magento\Backend\App\Action\Context|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var \Magento\Catalog\Helper\Product|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $productHelperMock;
+
+    /**
+     * @var \Magento\Framework\Escaper|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $escaperMock;
+
+    /**
+     * @var \Magento\Framework\View\Result\PageFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultPageFactoryMock;
+
+    /**
+     * @var \Magento\Backend\Model\View\Result\ForwardFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $forwardFactoryMock;
+
+    /**
+     * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $coreRegistryMock;
+
+    /**
+     * @var \Magento\Framework\View\Result\LayoutFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultLayoutFactoryMock;
+
+    /**
+     * @var \Magento\Authorizenet\Helper\Backend\Data|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $helperMock;
+
+    protected function setUp()
+    {
+        $this->directpostSessionMock = $this->getMockBuilder('Magento\Authorizenet\Model\Directpost\Session')
+            ->setMethods([
+                    'getLastOrderIncrementId',
+                    'removeCheckoutOrderIncrementId',
+                    'isCheckoutOrderIncrementIdExist',
+                    'unsetData'
+                ])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface');
+        $this->orderMock = $this->getMockBuilder('Magento\Sales\Model\Order')
+            ->setMethods(['getId', 'getState', 'getIncrementId', 'registerCancellation', 'loadByIncrementId', 'save'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->adminOrderCreateMock = $this->getMockBuilder('Magento\Sales\Model\AdminOrder\Create')
+            ->setMethods(['getSession'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $sessionMock = $this->getMockBuilder('Magento\Backend\Model\Session')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->sessionQuoteMock = $this->getMockBuilder('Magento\Backend\Model\Session\Quote')
+            ->setMethods(['getOrder', 'clearStorage'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->objectManagerMock->expects($this->atLeastOnce())
+            ->method('get')
+            ->willReturnMap([
+                ['Magento\Authorizenet\Model\Directpost\Session', $this->directpostSessionMock],
+                ['Magento\Sales\Model\AdminOrder\Create', $this->adminOrderCreateMock],
+                ['Magento\Backend\Model\Session\Quote', $this->sessionQuoteMock],
+                ['Magento\Backend\Model\Session', $sessionMock],
+            ]);
+        $this->objectManagerMock->expects($this->any())
+            ->method('create')
+            ->with('Magento\Sales\Model\Order')
+            ->willReturn($this->orderMock);
+        $this->requestMock = $this->getMockBuilder('Magento\Framework\App\RequestInterface')
+            ->setMethods(['getParams'])
+            ->getMockForAbstractClass();
+        $responseMock = $this->getMockForAbstractClass('Magento\Framework\App\ResponseInterface');
+        $redirectMock = $this->getMock('Magento\Framework\App\Response\RedirectInterface');
+        $this->messageManagerMock = $this->getMock('Magento\Framework\Message\ManagerInterface');
+
+        $this->contextMock = $this->getMockBuilder('Magento\Backend\App\Action\Context')
+            ->setMethods(['getObjectManager', 'getRequest', 'getResponse', 'getRedirect', 'getMessageManager'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->contextMock->expects($this->any())->method('getObjectManager')->willReturn($this->objectManagerMock);
+        $this->contextMock->expects($this->any())->method('getRequest')->willReturn($this->requestMock);
+        $this->contextMock->expects($this->any())->method('getResponse')->willReturn($responseMock);
+        $this->contextMock->expects($this->any())->method('getRedirect')->willReturn($redirectMock);
+        $this->contextMock->expects($this->any())->method('getMessageManager')->willReturn($this->messageManagerMock);
+
+        $this->productHelperMock = $this->getMockBuilder('Magento\Catalog\Helper\Product')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->escaperMock = $this->getMockBuilder('Magento\Framework\Escaper')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultPageFactoryMock = $this->getMockBuilder('Magento\Framework\View\Result\PageFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->forwardFactoryMock = $this->getMockBuilder('Magento\Backend\Model\View\Result\ForwardFactory')
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->coreRegistryMock = $this->getMockBuilder('Magento\Framework\Registry')
+            ->setMethods(['register'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $resultLayoutMock = $this->getMockBuilder('Magento\Framework\View\Result\Layout')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultLayoutFactoryMock = $this->getMockBuilder('Magento\Framework\View\Result\LayoutFactory')
+            ->setMethods(['create'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultLayoutFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($resultLayoutMock);
+        $this->helperMock = $this->getMockBuilder('Magento\Authorizenet\Helper\Backend\Data')
+            ->setMethods(['getSuccessOrderUrl'])
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->controller = new Redirect(
+            $this->contextMock,
+            $this->productHelperMock,
+            $this->escaperMock,
+            $this->resultPageFactoryMock,
+            $this->forwardFactoryMock,
+            $this->coreRegistryMock,
+            $this->resultLayoutFactoryMock,
+            $this->helperMock
+        );
+    }
+
+    public function testExecuteErrorMsgWithoutCancelOrder()
+    {
+        $params = ['success' => 0, 'error_msg' => 'Error message'];
+        $incrementId = 1;
+        $this->requestMock->expects($this->once())
+            ->method('getParams')
+            ->willReturn($params);
+        $this->directpostSessionMock->expects($this->once())
+            ->method('getLastOrderIncrementId')
+            ->willReturn($incrementId);
+        $this->directpostSessionMock->expects($this->once())
+            ->method('isCheckoutOrderIncrementIdExist')
+            ->with($incrementId)
+            ->willReturn(true);
+
+        $this->orderMock->expects($this->once())
+            ->method('loadByIncrementId')
+            ->with($incrementId)
+            ->willReturnSelf();
+        $this->orderMock->expects($this->once())
+            ->method('getId')
+            ->willReturn(true);
+        $this->orderMock->expects($this->once())
+            ->method('getIncrementId')
+            ->willReturn($incrementId);
+        $this->orderMock->expects($this->once())
+            ->method('getState')
+            ->willReturn(\Magento\Sales\Model\Order::STATE_PENDING_PAYMENT);
+        $this->orderMock->expects($this->once())
+            ->method('registerCancellation')
+            ->with($params['error_msg'])
+            ->willReturnSelf();
+        $this->orderMock->expects($this->once())
+            ->method('save');
+
+        $this->directpostSessionMock->expects($this->once())
+            ->method('removeCheckoutOrderIncrementId')
+            ->with($incrementId);
+        $this->coreRegistryMock->expects($this->once())
+            ->method('register')
+            ->with(Iframe::REGISTRY_KEY);
+
+        $this->assertInstanceOf('\Magento\Framework\View\Result\Layout', $this->controller->execute());
+    }
+
+    public function testExecuteErrorMsgWithCancelOrder()
+    {
+        $params = ['success' => 0, 'error_msg' => 'Error message', 'x_invoice_num' => 1];
+        $incrementId = 1;
+        $this->requestMock->expects($this->once())
+            ->method('getParams')
+            ->willReturn($params);
+        $this->directpostSessionMock->expects($this->once())
+            ->method('getLastOrderIncrementId')
+            ->willReturn($incrementId);
+        $this->directpostSessionMock->expects($this->once())
+            ->method('isCheckoutOrderIncrementIdExist')
+            ->with($incrementId)
+            ->willReturn(true);
+        $this->orderMock->expects($this->once())
+            ->method('loadByIncrementId')
+            ->with($incrementId)
+            ->willReturnSelf();
+        $this->orderMock->expects($this->once())
+            ->method('getId')
+            ->willReturn(true);
+        $this->orderMock->expects($this->once())
+            ->method('getIncrementId')
+            ->willReturn($incrementId);
+        $this->directpostSessionMock->expects($this->once())
+            ->method('removeCheckoutOrderIncrementId')
+            ->with($incrementId);
+
+        $this->coreRegistryMock->expects($this->once())
+            ->method('register')
+            ->with(Iframe::REGISTRY_KEY);
+
+        $this->assertInstanceOf('\Magento\Framework\View\Result\Layout', $this->controller->execute());
+    }
+
+    public function testExecuteSuccess()
+    {
+        $params = ['success' => 1, 'controller_action_name' => 'action', 'x_invoice_num' => 1];
+        $this->requestMock->expects($this->once())
+            ->method('getParams')
+            ->willReturn($params);
+
+        $this->helperMock->expects($this->once())
+            ->method('getSuccessOrderUrl')
+            ->willReturn('redirect_parent_url');
+
+        $this->directpostSessionMock->expects($this->once())
+            ->method('unsetData')
+            ->with('quote_id');
+
+        $this->orderMock->expects($this->once())
+            ->method('getId')
+            ->willReturn(null);
+
+        $this->sessionQuoteMock->expects($this->atLeastOnce())
+            ->method('getOrder')
+            ->willReturn($this->orderMock);
+
+        $this->adminOrderCreateMock->expects($this->atLeastOnce())
+            ->method('getSession')
+            ->willReturn($this->sessionQuoteMock);
+
+        $this->coreRegistryMock->expects($this->once())
+            ->method('register')
+            ->with(Iframe::REGISTRY_KEY);
+
+        $this->assertInstanceOf('\Magento\Framework\View\Result\Layout', $this->controller->execute());
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Test/Unit/Helper/Backend/DataTest.php b/app/code/Magento/Authorizenet/Test/Unit/Helper/Backend/DataTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..59be93bd3db52654835be52005d5ccc97be2699b
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Test/Unit/Helper/Backend/DataTest.php
@@ -0,0 +1,138 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Test\Unit\Helper\Backend;
+
+/**
+ * Class DataTest
+ */
+class DataTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Authorizenet\Helper\Backend\Data
+     */
+    protected $dataHelper;
+
+    /**
+     * @var \Magento\Backend\Model\Url|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderMock;
+
+    /**
+     * @var \Magento\Sales\Model\OrderFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $orderFactoryMock;
+
+    /**
+     * @var \Magento\Store\Model\StoreManager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    protected function setUp()
+    {
+        $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->urlBuilderMock = $this->getMock('Magento\Backend\Model\Url', ['getUrl'], [], '', false);
+
+        $contextMock = $this->getMock('Magento\Framework\App\Helper\Context', [], [], '', false);
+        $contextMock->expects($this->any())
+            ->method('getUrlBuilder')
+            ->willReturn($this->urlBuilderMock);
+
+        $this->orderFactoryMock = $this->getMock('Magento\Sales\Model\OrderFactory', ['create'], [], '', false);
+        $this->storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+
+        $this->dataHelper = $helper->getObject(
+            'Magento\Authorizenet\Helper\Backend\Data',
+            [
+                'context' => $contextMock,
+                'storeManager' =>$this->storeManagerMock,
+                'orderFactory' =>$this->orderFactoryMock,
+                'backendUrl' =>$this->urlBuilderMock
+            ]
+        );
+    }
+
+    public function testGetPlaceOrderAdminUrl()
+    {
+        $this->urlBuilderMock->expects($this->once())
+            ->method('getUrl')
+            ->with('adminhtml/authorizenet_directpost_payment/place')
+            ->willReturn('some value');
+
+        $this->assertEquals('some value', $this->dataHelper->getPlaceOrderAdminUrl());
+    }
+
+    public function testGetSuccessOrderUrl()
+    {
+        $orderMock = $this->getMock(
+            'Magento\Sales\Model\Order',
+            ['loadByIncrementId', 'getId', '__wakeup'],
+            [],
+            '',
+            false
+        );
+        $orderMock->expects($this->once())
+            ->method('loadByIncrementId')
+            ->with('invoice number')
+            ->willReturnSelf();
+
+        $orderMock->expects($this->once())
+            ->method('getId')
+            ->willReturn('order id');
+
+        $this->orderFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($orderMock);
+
+        $this->urlBuilderMock->expects($this->once())
+            ->method('getUrl')
+            ->with('sales/order/view', ['order_id' => 'order id'])
+            ->willReturn('some value');
+
+        $this->assertEquals(
+            'some value',
+            $this->dataHelper->getSuccessOrderUrl(['x_invoice_num' => 'invoice number', 'some param'])
+        );
+    }
+
+    public function testGetRedirectIframeUrl()
+    {
+        $params = ['some params', '_secure' => true];
+        $this->urlBuilderMock->expects($this->once())
+            ->method('getUrl')
+            ->with('adminhtml/authorizenet_directpost_payment/redirect', $params)
+            ->willReturn('some value');
+
+        $this->assertEquals('some value', $this->dataHelper->getRedirectIframeUrl($params));
+    }
+
+    public function testGetRelayUrl()
+    {
+        $baseUrl = 'http://base.url/';
+
+        $defaultStoreMock = $this->getMockBuilder('Magento\Store\Model\Store')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $defaultStoreMock->expects($this->once())
+            ->method('getBaseUrl')
+            ->with(\Magento\Framework\UrlInterface::URL_TYPE_LINK)
+            ->willReturn($baseUrl);
+
+        $this->storeManagerMock->expects($this->once())
+            ->method('getDefaultStoreView')
+            ->willReturn(null);
+
+        $this->storeManagerMock->expects($this->once())
+            ->method('getStores')
+            ->willReturn([$defaultStoreMock]);
+
+        $this->assertSame(
+            'http://base.url/authorizenet/directpost_payment/backendResponse',
+            $this->dataHelper->getRelayUrl()
+        );
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Test/Unit/Helper/DataTest.php b/app/code/Magento/Authorizenet/Test/Unit/Helper/DataTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b444dfb68c0a98403770e993c62e749edf8aeb45
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Test/Unit/Helper/DataTest.php
@@ -0,0 +1,193 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Test\Unit\Helper;
+
+class DataTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * Last 4 digit of cc
+     */
+    const LAST4 = 1111;
+
+    /**
+     * Transaction ID
+     */
+    const TRID = '2217041665';
+
+    /**
+     * @var \Magento\Authorizenet\Helper\Data
+     */
+    protected $dataHelper;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    protected function setUp()
+    {
+        $helper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->storeManagerMock = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface')
+            ->getMockForAbstractClass();
+
+        $this->dataHelper = $helper->getObject(
+            'Magento\Authorizenet\Helper\Data',
+            ['storeManager' => $this->storeManagerMock]
+        );
+    }
+
+    /**
+     * @param $type
+     * @param $amount
+     * @param $exception
+     * @param $additionalMessage
+     * @param $expected
+     * @dataProvider getMessagesParamDataProvider
+     */
+    public function testGetTransactionMessage($type, $amount, $exception, $additionalMessage, $expected)
+    {
+        $currency = $this->getMock('Magento\Directory\Model\Currency', ['formatTxt', '__wakeup'], [], '', false);
+        $currency->expects($this->any())
+            ->method('formatTxt')
+            ->will($this->returnValue($amount));
+        $order = $this->getMock('Magento\Sales\Model\Order', ['getBaseCurrency', '__wakeup'], [], '', false);
+        $order->expects($this->any())
+            ->method('getBaseCurrency')
+            ->will($this->returnValue($currency));
+        $payment = $this->getMock('Magento\Payment\Model\Info', ['getOrder', '__wakeup'], [], '', false);
+        $payment->expects($this->any())
+            ->method('getOrder')
+            ->will($this->returnValue($order));
+        $card = new \Magento\Framework\Object(['cc_last_4' => self::LAST4]);
+        $message = $this->dataHelper->getTransactionMessage(
+            $payment,
+            $type,
+            self::TRID,
+            $card,
+            $amount,
+            $exception,
+            $additionalMessage
+        );
+
+        $this->assertEquals($expected, $message);
+    }
+
+    /**
+     * @return array
+     */
+    public function getMessagesParamDataProvider()
+    {
+        $amount = 12.30;
+        $additionalMessage = 'Addition message.';
+        return [
+            [
+                'AUTH_ONLY',
+                $amount,
+                false,
+                $additionalMessage,
+                'Credit Card: xxxx-' . self::LAST4 . ' amount 12.3 authorize - successful. '
+                . 'Authorize.Net Transaction ID ' . self::TRID . '. Addition message.',
+            ],
+            [
+                'AUTH_CAPTURE',
+                $amount,
+                'some exception',
+                false,
+                'Credit Card: xxxx-' . self::LAST4 . ' amount 12.3 authorize and capture - failed. '
+                . 'Authorize.Net Transaction ID ' . self::TRID . '. some exception'
+            ],
+            [
+                'CREDIT',
+                false,
+                false,
+                $additionalMessage,
+                'Credit Card: xxxx-' . self::LAST4 . ' refund - successful. '
+                . 'Authorize.Net Transaction ID ' . self::TRID . '. Addition message.'
+            ],
+        ];
+    }
+
+    public function testGetRelayUrl()
+    {
+        $storeId = 10;
+        $baseUrl = 'http://base.url/';
+
+        $storeMock = $this->getMockBuilder('Magento\Store\Model\Store')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $storeMock->expects($this->once())
+            ->method('getBaseUrl')
+            ->with(\Magento\Framework\UrlInterface::URL_TYPE_LINK)
+            ->willReturn($baseUrl);
+
+        $this->storeManagerMock->expects($this->once())
+            ->method('getStore')
+            ->with($storeId)
+            ->willReturn($storeMock);
+
+        $this->assertSame(
+            'http://base.url/authorizenet/directpost_payment/response',
+            $this->dataHelper->getRelayUrl($storeId)
+        );
+    }
+
+    /**
+     * @param string $code
+     * @param string $expected
+     *
+     * @dataProvider getFdsFilterActionLabelDataProvider
+     */
+    public function testGetFdsFilterActionLabel($code, $expected)
+    {
+        $this->assertSame($expected, (string)$this->dataHelper->getFdsFilterActionLabel($code));
+    }
+
+    /**
+     * @return array
+     */
+    public function getFdsFilterActionLabelDataProvider()
+    {
+        return [
+            ['decline ', 'Decline'],
+            ['hold', 'Hold'],
+            ['authAndHold', 'Authorize and Hold'],
+            ['report', 'Report Only'],
+            ['unknown_status', 'unknown_status']
+        ];
+    }
+
+    /**
+     * @param string $code
+     * @param string $expected
+     *
+     * @dataProvider getTransactionStatusLabelDataProvider
+     */
+    public function testGetTransactionStatusLabel($code, $expected)
+    {
+        $this->assertSame($expected, (string)$this->dataHelper->getTransactionStatusLabel($code));
+    }
+
+    /**
+     * @return array
+     */
+    public function getTransactionStatusLabelDataProvider()
+    {
+        return [
+            ['authorizedPendingCapture', 'Authorized/Pending Capture'],
+            ['capturedPendingSettlement', 'Captured/Pending Settlement'],
+            ['refundSettledSuccessfully', 'Refund/Settled Successfully'],
+            ['refundPendingSettlement', 'Refund/Pending Settlement'],
+            ['declined', 'Declined'],
+            ['expired', 'Expired'],
+            ['voided', 'Voided'],
+            ['FDSPendingReview', 'FDS - Pending Review'],
+            ['FDSAuthorizedPendingReview', 'FDS - Authorized/Pending Review'],
+            ['unknown_status', 'unknown_status']
+        ];
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/ObserverTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/ObserverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3640a46c577554c75c6b030e8b3de668e21f277e
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/ObserverTest.php
@@ -0,0 +1,247 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Test\Unit\Model\Directpost;
+
+use Magento\Authorizenet\Model\Directpost\Observer;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+/**
+ * Class ObserverTest
+ */
+class ObserverTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var Observer
+     */
+    protected $observer;
+
+    /**
+     * Core registry
+     *
+     * @var \Magento\Framework\Registry|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $coreRegistryMock;
+
+    /**
+     * Authorizenet helper
+     *
+     * @var \Magento\Authorizenet\Helper\Data|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $authorizenetDataMock;
+
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $paymentMock;
+
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost\Session|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $sessionMock;
+
+    /**
+     * @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeManagerMock;
+
+    /**
+     * @var \Magento\Checkout\Controller\Onepage\SaveOrder|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $actionMock;
+
+    /**
+     * @var \Magento\Framework\Object|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultMock;
+
+    /**
+     * Set up
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        $helper = new ObjectManager($this);
+
+        $this->authorizenetDataMock = $this->getMockBuilder('Magento\Authorizenet\Helper\Data')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->coreRegistryMock = $this->getMockBuilder('Magento\Framework\Registry')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->paymentMock = $this->getMockBuilder('Magento\Authorizenet\Model\Directpost')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->sessionMock = $this->getMockBuilder('Magento\Authorizenet\Model\Directpost\Session')
+            ->disableOriginalConstructor()
+            ->setMethods(['setLastOrderIncrementId', 'addCheckoutOrderIncrementId'])
+            ->getMock();
+        $this->storeManagerMock = $this->getMockBuilder('Magento\Store\Model\StoreManagerInterface')
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $this->actionMock = $this->getMockBuilder('Magento\Checkout\Controller\Onepage\SaveOrder')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultMock = $this->getMockBuilder('Magento\Framework\Object')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->observer = $helper->getObject(
+            'Magento\Authorizenet\Model\Directpost\Observer',
+            [
+               'authorizenetData' => $this->authorizenetDataMock,
+               'coreRegistry' => $this->coreRegistryMock,
+               'payment' => $this->paymentMock,
+               'session' => $this->sessionMock,
+               'storeManager' => $this->storeManagerMock,
+            ]
+        );
+    }
+
+    /**
+     * Test for addFieldsToResponse method
+     *
+     * @return void
+     */
+    public function testAddFieldsToResponseSuccess()
+    {
+        $testData = $this->getAddFieldsToResponseSuccessTestData();
+
+        $observerMock = $this->getMockBuilder('Magento\Framework\Event\Observer')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $orderMock = $this->getMockBuilder('Magento\Sales\Model\Order')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $orderPaymentMock = $this->getMockBuilder('Magento\Sales\Model\Order\Payment')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $instanceMock = $this->getMockBuilder('Magento\Authorizenet\Model\Directpost')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $requestToAuthorizenetMock = $this->getMockBuilder('Magento\Authorizenet\Model\Directpost\Request')
+            ->disableOriginalConstructor()
+            ->setMethods(['setControllerActionName', 'setIsSecure', 'getData'])
+            ->getMock();
+        $requestMock = $this->getMockBuilder('Magento\Framework\App\RequestInterface')
+            ->disableOriginalConstructor()
+            ->setMethods(['getControllerName'])
+            ->getMockForAbstractClass();
+        $storeMock = $this->getMockBuilder('Magento\Store\Model\Store')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->coreRegistryMock->expects($this->once())
+            ->method('registry')
+            ->with('directpost_order')
+            ->willReturn($orderMock);
+        $orderMock->expects($this->once())
+            ->method('getId')
+            ->willReturn($testData['order.getId']);
+        $orderMock->expects($this->once())
+            ->method('getPayment')
+            ->willReturn($orderPaymentMock);
+        $orderPaymentMock->expects($this->once())
+            ->method('getMethod')
+            ->willReturn($testData['orderPayment.getMethod']);
+        $this->paymentMock->expects($this->exactly(2))
+            ->method('getCode')
+            ->willReturn($testData['payment.getCode']);
+        $observerMock->expects($this->atLeastOnce())
+            ->method('getData')
+            ->willReturnMap($testData['observer.getData']);
+        $this->resultMock->expects($this->once())
+            ->method('getData')
+            ->willReturn($testData['result.getData']);
+        $orderMock->expects($this->atLeastOnce())
+            ->method('getIncrementId')
+            ->willReturn($testData['order.getIncrementId']);
+        $this->sessionMock->expects($this->once())
+            ->method('addCheckoutOrderIncrementId')
+            ->with($testData['session.addCheckoutOrderIncrementId']);
+        $this->sessionMock->expects($this->once())
+            ->method('setLastOrderIncrementId')
+            ->with($testData['session.setLastOrderIncrementId']);
+        $orderPaymentMock->expects($this->once())
+            ->method('getMethodInstance')
+            ->willReturn($instanceMock);
+        $instanceMock->expects($this->once())
+            ->method('generateRequestFromOrder')
+            ->with($orderMock)
+            ->willReturn($requestToAuthorizenetMock);
+        $this->actionMock->expects($this->once())
+            ->method('getRequest')
+            ->willReturn($requestMock);
+        $requestMock->expects($this->once())
+            ->method('getControllerName')
+            ->willReturn($testData['request.getControllerName']);
+        $requestToAuthorizenetMock->expects($this->once())
+            ->method('setControllerActionName')
+            ->with($testData['requestToAuthorizenet.setControllerActionName']);
+        $this->storeManagerMock->expects($this->once())
+            ->method('getStore')
+            ->willReturn($storeMock);
+        $storeMock->expects($this->once())
+            ->method('isCurrentlySecure')
+            ->willReturn($testData['store.isCurrentlySecure']);
+        $requestToAuthorizenetMock->expects($this->once())
+            ->method('setIsSecure')
+            ->with($testData['requestToAuthorizenet.setIsSecure']);
+        $requestToAuthorizenetMock->expects($this->once())
+            ->method('getData')
+            ->willReturn($testData['requestToAuthorizenet.getData']);
+        $this->resultMock->expects($this->once())
+            ->method('setData')
+            ->with($testData['result.setData']);
+
+        $this->observer->addFieldsToResponse($observerMock);
+    }
+
+    /**
+     * Get data for test testAddFieldsToResponseSuccess
+     *
+     * @return array
+     */
+    protected function getAddFieldsToResponseSuccessTestData()
+    {
+        $requestFields = [
+            'field-1' => 'field-value-1',
+            'field-2' => 'field-value-2',
+            'field-3' => 'field-value-3',
+        ];
+        $secure = 'test-currently-secure';
+        $controllerName = 'test-controller-name';
+        $incrementId = '0000000001';
+        $paymentCode = 'test-payment-code';
+
+        return [
+            'order.getId' => 77,
+            'orderPayment.getMethod' => $paymentCode,
+            'payment.getCode' => $paymentCode,
+            'observer.getData' => [
+                ['action', null, $this->actionMock],
+                ['result', null, $this->resultMock],
+            ],
+            'result.getData' => [
+                'error' => false
+            ],
+            'order.getIncrementId' => $incrementId,
+            'session.addCheckoutOrderIncrementId' => $incrementId,
+            'session.setLastOrderIncrementId' => $incrementId,
+            'request.getControllerName' => $controllerName,
+            'requestToAuthorizenet.setControllerActionName' => $controllerName,
+            'store.isCurrentlySecure' => $secure,
+            'requestToAuthorizenet.setIsSecure' => $secure,
+            'requestToAuthorizenet.getData' => $requestFields,
+            'result.setData' => [
+                'error' => false,
+                'test-payment-code' => [
+                    'fields' => $requestFields
+                ]
+            ]
+        ];
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/Request/FactoryTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/Request/FactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0ea5132fbe47d9449a4b46e0991bd5a4e42a72b4
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/Request/FactoryTest.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Test\Unit\Model\Directpost\Request;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class FactoryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost\Request\Factory
+     */
+    protected $requestFactory;
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectManagerMock;
+
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost\Request|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    protected function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+
+        $this->requestMock = $this->getMock('Magento\Authorizenet\Model\Directpost\Request', [], [], '', false);
+
+        $this->objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface', [], [], '', false);
+        $this->objectManagerMock->expects($this->once())
+            ->method('create')
+            ->with('Magento\Authorizenet\Model\Directpost\Request', [])
+            ->willReturn($this->requestMock);
+
+        $this->requestFactory = $objectManager->getObject(
+            'Magento\Authorizenet\Model\Directpost\Request\Factory',
+            ['objectManager' => $this->objectManagerMock]
+        );
+    }
+
+    public function testCreate()
+    {
+        $this->assertSame($this->requestMock, $this->requestFactory->create());
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/Response/FactoryTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/Response/FactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..82f05c5cd12f16184f6ba67a7d1ba4b03beceb46
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/Response/FactoryTest.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Test\Unit\Model\Directpost\Response;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class FactoryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost\Response\Factory
+     */
+    protected $responseFactory;
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectManagerMock;
+
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost\Response|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $responseMock;
+
+    protected function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+
+        $this->responseMock = $this->getMock('Magento\Authorizenet\Model\Directpost\Response', [], [], '', false);
+
+        $this->objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface', [], [], '', false);
+        $this->objectManagerMock->expects($this->once())
+            ->method('create')
+            ->with('Magento\Authorizenet\Model\Directpost\Response', [])
+            ->willReturn($this->responseMock);
+
+        $this->responseFactory = $objectManager->getObject(
+            'Magento\Authorizenet\Model\Directpost\Response\Factory',
+            ['objectManager' => $this->objectManagerMock]
+        );
+    }
+
+    public function testCreate()
+    {
+        $this->assertSame($this->responseMock, $this->responseFactory->create());
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/ResponseTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/ResponseTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..bca5ff480a61bb15900575a820c5f7b423629d65
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Test/Unit/Model/Directpost/ResponseTest.php
@@ -0,0 +1,130 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Test\Unit\Model\Directpost;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Authorizenet\Model\Directpost;
+
+class ResponseTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost\Response
+     */
+    protected $responseModel;
+
+    protected function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+        $this->responseModel = $objectManager->getObject('Magento\Authorizenet\Model\Directpost\Response');
+    }
+
+    /**
+     * @param string $merchantMd5
+     * @param string $merchantApiLogin
+     * @param float|null $amount
+     * @param float|string $amountTestFunc
+     * @param string $transactionId
+     * @dataProvider generateHashDataProvider
+     */
+    public function testGenerateHash($merchantMd5, $merchantApiLogin, $amount, $amountTestFunc, $transactionId)
+    {
+        $this->assertEquals(
+            $this->generateHash($merchantMd5, $merchantApiLogin, $amountTestFunc, $transactionId),
+            $this->responseModel->generateHash($merchantMd5, $merchantApiLogin, $amount, $transactionId)
+        );
+    }
+
+    public function generateHashDataProvider()
+    {
+        return [
+            [
+                'merchantMd5' => 'FCD7F001E9274FDEFB14BFF91C799306',
+                'merchantApiLogin' => 'Magento',
+                'amount' => null,
+                'amountTestFunc' => '0.00',
+                'transactionId' => '1'
+            ],
+            [
+                'merchantMd5' => '8AEF4E508261A287C3E2F544720FCA3A',
+                'merchantApiLogin' => 'Magento2',
+                'amount' => 100.50,
+                'amountTestFunc' => 100.50,
+                'transactionId' => '2'
+            ]
+        ];
+    }
+
+    protected function generateHash($merchantMd5, $merchantApiLogin, $amount, $transactionId)
+    {
+        return strtoupper(md5($merchantMd5 . $merchantApiLogin . $transactionId . $amount));
+    }
+
+    /**
+     * @param string $merchantMd5
+     * @param string $merchantApiLogin
+     * @param float|null $amount
+     * @param string $transactionId
+     * @param string $hash
+     * @param bool $expectedValue
+     * @dataProvider isValidHashDataProvider
+     */
+    public function testIsValidHash($merchantMd5, $merchantApiLogin, $amount, $transactionId, $hash, $expectedValue)
+    {
+        $this->responseModel->setXAmount($amount);
+        $this->responseModel->setXTransId($transactionId);
+        $this->responseModel->setData('x_MD5_Hash', $hash);
+        $this->assertEquals($expectedValue, $this->responseModel->isValidHash($merchantMd5, $merchantApiLogin));
+    }
+
+    /**
+     * @return array
+     */
+    public function isValidHashDataProvider()
+    {
+        return [
+            [
+                'merchantMd5' => 'FCD7F001E9274FDEFB14BFF91C799306',
+                'merchantApiLogin' => 'Magento',
+                'amount' => null,
+                'transactionId' => '1',
+                'hash' => '1F24A4EC9A169B2B2A072A5F168E16DC',
+                'expectedValue' => true
+            ],
+            [
+                'merchantMd5' => '8AEF4E508261A287C3E2F544720FCA3A',
+                'merchantApiLogin' => 'Magento2',
+                'amount' => 100.50,
+                'transactionId' => '2',
+                'hash' => '1F24A4EC9A169B2B2A072A5F168E16DC',
+                'expectedValue' => false
+            ]
+        ];
+    }
+
+    /**
+     * @param int $xResponseCode
+     * @param bool $expectedValue
+     * @dataProvider isApprovedDataProvider
+     */
+    public function testIsApproved($xResponseCode, $expectedValue)
+    {
+        $this->responseModel->setXResponseCode($xResponseCode);
+        $this->assertSame($expectedValue, $this->responseModel->isApproved());
+    }
+
+    /**
+     * @return array
+     */
+    public function isApprovedDataProvider()
+    {
+        return [
+            [Directpost::RESPONSE_CODE_APPROVED, true],
+            [Directpost::RESPONSE_CODE_DECLINED, false],
+            [Directpost::RESPONSE_CODE_ERROR, false],
+            [Directpost::RESPONSE_CODE_HELD, false],
+        ];
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..edfade031c792728831eaff0d4024a885d04fcbb
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Test/Unit/Model/DirectpostTest.php
@@ -0,0 +1,360 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Test\Unit\Model;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+use Magento\Authorizenet\Model\Directpost;
+
+/**
+ * Class DirectpostTest
+ */
+class DirectpostTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost
+     */
+    protected $directpost;
+
+    /**
+     * @var \Magento\Framework\App\Config\ScopeConfigInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $scopeConfigMock;
+
+    /**
+     * @var \Magento\Payment\Model\InfoInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $paymentMock;
+
+    /**
+     * @var \Magento\Authorizenet\Helper\Data|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $dataHelperMock;
+
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost\Response\Factory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $responseFactoryMock;
+
+    /**
+     * @var \Magento\Authorizenet\Model\Directpost\Response|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $responseMock;
+
+    protected function setUp()
+    {
+        $this->scopeConfigMock = $this->getMockBuilder('Magento\Framework\App\Config\ScopeConfigInterface')
+            ->getMock();
+        $this->paymentMock = $this->getMockBuilder('Magento\Payment\Model\InfoInterface')
+            ->getMock();
+        $this->dataHelperMock = $this->getMockBuilder('Magento\Authorizenet\Helper\Data')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->responseFactoryMock = $this->getMockBuilder('Magento\Authorizenet\Model\Directpost\Response\Factory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->responseMock = $this->getMockBuilder('Magento\Authorizenet\Model\Directpost\Response')
+            ->setMethods(
+                [
+                    'setData', 'isValidHash', 'getXTransId',
+                    'getXResponseCode', 'getXResponseReasonText',
+                    'getXAmount'
+                ]
+            )
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->responseFactoryMock->expects($this->any())
+            ->method('create')
+            ->willReturn($this->responseMock);
+
+        $helper = new ObjectManagerHelper($this);
+        $this->directpost = $helper->getObject(
+            'Magento\Authorizenet\Model\Directpost',
+            [
+                'scopeConfig' => $this->scopeConfigMock,
+                'dataHelper' => $this->dataHelperMock,
+                'responseFactory' => $this->responseFactoryMock
+            ]
+        );
+    }
+
+    public function testGetConfigInterface()
+    {
+        $this->assertInstanceOf(
+            'Magento\Payment\Model\Method\ConfigInterface',
+            $this->directpost->getConfigInterface()
+        );
+    }
+
+    public function testGetConfigValue()
+    {
+        $field = 'some_field';
+        $returnValue = 'expected';
+        $this->scopeConfigMock->expects($this->once())
+            ->method('getValue')
+            ->with('payment/authorizenet_directpost/' . $field)
+            ->willReturn($returnValue);
+        $this->assertEquals($returnValue, $this->directpost->getValue($field));
+    }
+
+    public function testSetDataHelper()
+    {
+        $storeId = 'store-id';
+        $expectedResult = 'relay-url';
+
+        $helperDataMock = $this->getMockBuilder('Magento\Authorizenet\Helper\Backend\Data')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $helperDataMock->expects($this->once())
+            ->method('getRelayUrl')
+            ->with($storeId)
+            ->willReturn($expectedResult);
+
+        $this->directpost->setDataHelper($helperDataMock);
+        $this->assertEquals($expectedResult, $this->directpost->getRelayUrl($storeId));
+    }
+
+    public function testAuthorize()
+    {
+        $paymentAction = 'some_action';
+
+        $this->scopeConfigMock->expects($this->any())
+            ->method('getValue')
+            ->with('payment/authorizenet_directpost/payment_action', 'store', null)
+            ->willReturn($paymentAction);
+        $this->paymentMock->expects($this->once())
+            ->method('setAdditionalInformation')
+            ->with('payment_type', $paymentAction);
+
+        $this->directpost->authorize($this->paymentMock, 10);
+    }
+
+    public function testGetCgiUrl()
+    {
+        $url = 'cgi/url';
+
+        $this->scopeConfigMock->expects($this->any())
+            ->method('getValue')
+            ->with('payment/authorizenet_directpost/cgi_url', 'store', null)
+            ->willReturn($url);
+
+        $this->assertEquals($url, $this->directpost->getCgiUrl());
+    }
+
+    public function testGetCgiUrlWithEmptyConfigValue()
+    {
+        $this->scopeConfigMock->expects($this->any())
+            ->method('getValue')
+            ->with('payment/authorizenet_directpost/cgi_url', 'store', null)
+            ->willReturn(null);
+
+        $this->assertEquals(Directpost::CGI_URL, $this->directpost->getCgiUrl());
+    }
+
+    public function testGetRelayUrl()
+    {
+        $storeId = 100;
+        $url = 'relay/url';
+        $this->directpost->setData('store', $storeId);
+
+        $this->dataHelperMock->expects($this->any())
+            ->method('getRelayUrl')
+            ->with($storeId)
+            ->willReturn($url);
+
+        $this->assertEquals($url, $this->directpost->getRelayUrl());
+        $this->assertEquals($url, $this->directpost->getRelayUrl($storeId));
+    }
+
+    public function testGetResponse()
+    {
+        $this->assertSame($this->responseMock, $this->directpost->getResponse());
+    }
+
+    public function testSetResponseData()
+    {
+        $data = [
+            'key' => 'value'
+        ];
+
+        $this->responseMock->expects($this->once())
+            ->method('setData')
+            ->with($data)
+            ->willReturnSelf();
+
+        $this->assertSame($this->directpost, $this->directpost->setResponseData($data));
+    }
+
+    public function testValidateResponseSuccess()
+    {
+        $this->prepareTestValidateResponse('some_md5', 'login', true);
+        $this->assertEquals(true, $this->directpost->validateResponse());
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\LocalizedException
+     */
+    public function testValidateResponseFailure()
+    {
+        $this->prepareTestValidateResponse('some_md5', 'login', false);
+        $this->directpost->validateResponse();
+    }
+
+    /**
+     * @param string $transMd5
+     * @param string $login
+     * @param bool $isValidHash
+     */
+    protected function prepareTestValidateResponse($transMd5, $login, $isValidHash)
+    {
+        $this->scopeConfigMock->expects($this->any())
+            ->method('getValue')
+            ->willReturnMap(
+                [
+                    ['payment/authorizenet_directpost/trans_md5', 'store', null, $transMd5],
+                    ['payment/authorizenet_directpost/login', 'store', null, $login]
+                ]
+            );
+        $this->responseMock->expects($this->any())
+            ->method('isValidHash')
+            ->with($transMd5, $login)
+            ->willReturn($isValidHash);
+    }
+
+    public function testCheckTransIdSuccess()
+    {
+        $this->responseMock->expects($this->once())
+            ->method('getXTransId')
+            ->willReturn('111');
+
+        $this->assertEquals(true, $this->directpost->checkTransId());
+    }
+
+    /**
+     * @expectedException \Magento\Framework\Exception\LocalizedException
+     */
+    public function testCheckTransIdFailure()
+    {
+        $this->responseMock->expects($this->once())
+            ->method('getXTransId')
+            ->willReturn(null);
+
+        $this->directpost->checkTransId();
+    }
+
+    /**
+     * @param bool $responseCode
+     *
+     * @dataProvider checkResponseCodeSuccessDataProvider
+     */
+    public function testCheckResponseCodeSuccess($responseCode)
+    {
+        $this->responseMock->expects($this->once())
+            ->method('getXResponseCode')
+            ->willReturn($responseCode);
+
+        $this->assertEquals(true, $this->directpost->checkResponseCode());
+    }
+
+    /**
+     * @return array
+     */
+    public function checkResponseCodeSuccessDataProvider()
+    {
+        return [
+            ['responseCode' => Directpost::RESPONSE_CODE_APPROVED],
+            ['responseCode' => Directpost::RESPONSE_CODE_HELD]
+        ];
+    }
+
+    /**
+     * @param bool $responseCode
+     *
+     * @expectedException \Magento\Framework\Exception\LocalizedException
+     * @dataProvider checkResponseCodeFailureDataProvider
+     */
+    public function testCheckResponseCodeFailure($responseCode)
+    {
+        $reasonText = 'reason text';
+
+        $this->responseMock->expects($this->once())
+            ->method('getXResponseCode')
+            ->willReturn($responseCode);
+        $this->responseMock->expects($this->any())
+            ->method('getXResponseReasonText')
+            ->willReturn($reasonText);
+        $this->dataHelperMock->expects($this->any())
+            ->method('wrapGatewayError')
+            ->with($reasonText)
+            ->willReturn(__('Gateway error: ' . $reasonText));
+
+        $this->directpost->checkResponseCode();
+    }
+
+    /**
+     * @return array
+     */
+    public function checkResponseCodeFailureDataProvider()
+    {
+        return [
+            ['responseCode' => Directpost::RESPONSE_CODE_DECLINED],
+            ['responseCode' => Directpost::RESPONSE_CODE_ERROR],
+            ['responseCode' => 999999]
+        ];
+    }
+
+    /**
+     * @param bool $isInitializeNeeded
+     *
+     * @dataProvider setIsInitializeNeededDataProvider
+     */
+    public function testSetIsInitializeNeeded($isInitializeNeeded)
+    {
+        $this->directpost->setIsInitializeNeeded($isInitializeNeeded);
+        $this->assertEquals($isInitializeNeeded, $this->directpost->isInitializeNeeded());
+    }
+
+    /**
+     * @return array
+     */
+    public function setIsInitializeNeededDataProvider()
+    {
+        return [
+            ['isInitializationNeeded' => true],
+            ['isInitializationNeeded' => false]
+        ];
+    }
+
+    /**
+     * @param bool $isGatewayActionsLocked
+     * @param bool $canCapture
+     *
+     * @dataProvider canCaptureDataProvider
+     */
+    public function testCanCapture($isGatewayActionsLocked, $canCapture)
+    {
+        $this->directpost->setData('info_instance', $this->paymentMock);
+
+        $this->paymentMock->expects($this->any())
+            ->method('getAdditionalInformation')
+            ->with(Directpost::GATEWAY_ACTIONS_LOCKED_STATE_KEY)
+            ->willReturn($isGatewayActionsLocked);
+
+        $this->assertEquals($canCapture, $this->directpost->canCapture());
+    }
+
+    /**
+     * @return array
+     */
+    public function canCaptureDataProvider()
+    {
+        return [
+            ['isGatewayActionsLocked' => false, 'canCapture' => true],
+            ['isGatewayActionsLocked' => true, 'canCapture' => false]
+        ];
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Request/FactoryTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Request/FactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..42bd4922cd6cc16b18939c13090a52b3be099fe1
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Test/Unit/Model/Request/FactoryTest.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Test\Unit\Model\Request;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class FactoryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Authorizenet\Model\Request\Factory
+     */
+    protected $requestFactory;
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectManagerMock;
+
+    /**
+     * @var \Magento\Authorizenet\Model\Request|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    protected function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+
+        $this->requestMock = $this->getMock('Magento\Authorizenet\Model\Request', [], [], '', false);
+
+        $this->objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface', [], [], '', false);
+        $this->objectManagerMock->expects($this->once())
+            ->method('create')
+            ->with('Magento\Authorizenet\Model\Request', [])
+            ->willReturn($this->requestMock);
+
+        $this->requestFactory = $objectManager->getObject(
+            'Magento\Authorizenet\Model\Request\Factory',
+            ['objectManager' => $this->objectManagerMock]
+        );
+    }
+
+    public function testCreate()
+    {
+        $this->assertSame($this->requestMock, $this->requestFactory->create());
+    }
+}
diff --git a/app/code/Magento/Authorizenet/Test/Unit/Model/Response/FactoryTest.php b/app/code/Magento/Authorizenet/Test/Unit/Model/Response/FactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a8d9a628a8e5d0143c4acf3ca5160a4f84487881
--- /dev/null
+++ b/app/code/Magento/Authorizenet/Test/Unit/Model/Response/FactoryTest.php
@@ -0,0 +1,49 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Test\Unit\Model\Response;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+
+class FactoryTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Authorizenet\Model\Response\Factory
+     */
+    protected $responseFactory;
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectManagerMock;
+
+    /**
+     * @var \Magento\Authorizenet\Model\Response|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $responseMock;
+
+    protected function setUp()
+    {
+        $objectManager = new ObjectManager($this);
+
+        $this->responseMock = $this->getMock('Magento\Authorizenet\Model\Response', [], [], '', false);
+
+        $this->objectManagerMock = $this->getMock('Magento\Framework\ObjectManagerInterface', [], [], '', false);
+        $this->objectManagerMock->expects($this->once())
+            ->method('create')
+            ->with('Magento\Authorizenet\Model\Response', [])
+            ->willReturn($this->responseMock);
+
+        $this->responseFactory = $objectManager->getObject(
+            'Magento\Authorizenet\Model\Response\Factory',
+            ['objectManager' => $this->objectManagerMock]
+        );
+    }
+
+    public function testCreate()
+    {
+        $this->assertSame($this->responseMock, $this->responseFactory->create());
+    }
+}
diff --git a/app/code/Magento/Authorizenet/composer.json b/app/code/Magento/Authorizenet/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..436abe3fc7bfe303d5e9ee52c6387c0f0ae09888
--- /dev/null
+++ b/app/code/Magento/Authorizenet/composer.json
@@ -0,0 +1,29 @@
+{
+    "name": "magento/module-authorizenet",
+    "description": "N/A",
+    "require": {
+        "php": "~5.5.0|~5.6.0",
+        "magento/module-sales": "0.74.0-beta16",
+        "magento/module-store": "0.74.0-beta16",
+        "magento/module-quote": "0.74.0-beta16",
+        "magento/module-checkout": "0.74.0-beta16",
+        "magento/module-backend": "0.74.0-beta16",
+        "magento/module-payment": "0.74.0-beta16",
+        "magento/module-catalog": "0.74.0-beta16",
+        "magento/framework": "0.74.0-beta16",
+        "magento/magento-composer-installer": "*"
+    },
+    "type": "magento2-module",
+    "version": "0.74.0-beta16",
+    "license": [
+        "proprietary"
+    ],
+    "extra": {
+        "map": [
+            [
+                "*",
+                "Magento/Authorizenet"
+            ]
+        ]
+    }
+}
diff --git a/app/code/Magento/Authorizenet/etc/adminhtml/di.xml b/app/code/Magento/Authorizenet/etc/adminhtml/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cad68b99f6da832324a0c67110ade7660b82bd89
--- /dev/null
+++ b/app/code/Magento/Authorizenet/etc/adminhtml/di.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <type name="Magento\Authorizenet\Model\Directpost">
+        <arguments>
+            <argument name="session" xsi:type="object">Magento\Backend\Model\Session\Quote</argument>
+            <argument name="data" xsi:type="array">
+                <item name="formBlockType" xsi:type="string">Magento\Payment\Block\Adminhtml\Transparent\Form</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Authorizenet\Model\Authorizenet">
+        <arguments>
+            <argument name="session" xsi:type="object">Magento\Backend\Model\Session\Quote</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/app/code/Magento/Authorizenet/etc/adminhtml/events.xml b/app/code/Magento/Authorizenet/etc/adminhtml/events.xml
new file mode 100644
index 0000000000000000000000000000000000000000..aefa02b36e3775017b414a476e8af72e3e76237b
--- /dev/null
+++ b/app/code/Magento/Authorizenet/etc/adminhtml/events.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd">
+    <event name="checkout_submit_all_after">
+        <observer name="directpost_update_all_edit_increments" instance="Magento\Authorizenet\Model\Directpost\Observer" method="updateAllEditIncrements" />
+    </event>
+</config>
diff --git a/app/code/Magento/Authorizenet/etc/adminhtml/routes.xml b/app/code/Magento/Authorizenet/etc/adminhtml/routes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a1d23a80590acfcba2af0891af849bb13540549c
--- /dev/null
+++ b/app/code/Magento/Authorizenet/etc/adminhtml/routes.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
+    <router id="admin">
+        <route id="adminhtml">
+            <module name="Magento_Authorizenet" before="Magento_Backend" />
+        </route>
+    </router>
+</config>
diff --git a/app/code/Magento/Authorizenet/etc/adminhtml/system.xml b/app/code/Magento/Authorizenet/etc/adminhtml/system.xml
new file mode 100644
index 0000000000000000000000000000000000000000..591d0951e2d458f0386f4f1f5a28a99fc7024f14
--- /dev/null
+++ b/app/code/Magento/Authorizenet/etc/adminhtml/system.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../Config/etc/system_file.xsd">
+    <system>
+        <section id="payment">
+            <group id="authorizenet_directpost" translate="label" type="text" sortOrder="34" showInDefault="1" showInWebsite="1" showInStore="1">
+                <label>Authorize.net Direct Post</label>
+                <field id="active" translate="label" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Enabled</label>
+                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
+                </field>
+                <field id="payment_action" translate="label" type="select" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Payment Action</label>
+                    <source_model>Magento\Authorizenet\Model\Source\PaymentAction</source_model>
+                </field>
+                <field id="title" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
+                    <label>Title</label>
+                </field>
+                <field id="login" translate="label" type="obscure" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>API Login ID</label>
+                    <backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
+                </field>
+                <field id="trans_key" translate="label" type="obscure" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Transaction Key</label>
+                    <backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
+                </field>
+                <field id="trans_md5" translate="label" type="obscure" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Merchant MD5</label>
+                    <backend_model>Magento\Config\Model\Config\Backend\Encrypted</backend_model>
+                </field>
+                <field id="order_status" translate="label" type="select" sortOrder="70" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>New Order Status</label>
+                    <source_model>Magento\Sales\Model\Config\Source\Order\Status\Processing</source_model>
+                </field>
+                <field id="test" translate="label" type="select" sortOrder="80" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Test Mode</label>
+                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
+                </field>
+                <field id="cgi_url" translate="label" type="text" sortOrder="90" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Gateway URL</label>
+                </field>
+                <field id="currency" translate="label" type="select" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Accepted Currency</label>
+                    <source_model>Magento\Config\Model\Config\Source\Locale\Currency</source_model>
+                </field>
+                <field id="debug" translate="label" type="select" sortOrder="110" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Debug</label>
+                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
+                </field>
+                <field id="email_customer" translate="label" type="select" sortOrder="120" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Email Customer</label>
+                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
+                </field>
+                <field id="merchant_email" translate="label" type="text" sortOrder="130" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Merchant's Email</label>
+                    <validate>validate-email</validate>
+                </field>
+                <field id="cctypes" translate="label" type="multiselect" sortOrder="140" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Credit Card Types</label>
+                    <source_model>Magento\Authorizenet\Model\Source\Cctype</source_model>
+                </field>
+                <field id="useccv" translate="label" type="select" sortOrder="150" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Credit Card Verification</label>
+                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
+                </field>
+                <field id="allowspecific" translate="label" type="allowspecific" sortOrder="160" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Payment from Applicable Countries</label>
+                    <source_model>Magento\Payment\Model\Config\Source\Allspecificcountries</source_model>
+                </field>
+                <field id="specificcountry" translate="label" type="multiselect" sortOrder="170" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Payment from Specific Countries</label>
+                    <source_model>Magento\Directory\Model\Config\Source\Country</source_model>
+                </field>
+                <field id="min_order_total" translate="label" type="text" sortOrder="180" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Minimum Order Total</label>
+                </field>
+                <field id="max_order_total" translate="label" type="text" sortOrder="190" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Maximum Order Total</label>
+                </field>
+                <field id="sort_order" translate="label" type="text" sortOrder="200" showInDefault="1" showInWebsite="1" showInStore="0">
+                    <label>Sort Order</label>
+                    <frontend_class>validate-number</frontend_class>
+                </field>
+            </group>
+        </section>
+    </system>
+</config>
diff --git a/app/code/Magento/Authorizenet/etc/config.xml b/app/code/Magento/Authorizenet/etc/config.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a620f157b10e42ce46364f2ab4875fd63541422d
--- /dev/null
+++ b/app/code/Magento/Authorizenet/etc/config.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../Store/etc/config.xsd">
+    <default>
+        <payment>
+            <authorizenet_directpost>
+                <active>0</active>
+                <cctypes>AE,VI,MC,DI</cctypes>
+                <debug>0</debug>
+                <email_customer>0</email_customer>
+                <login backend_model="Magento\Config\Model\Config\Backend\Encrypted" />
+                <merchant_email />
+                <model>Magento\Authorizenet\Model\Directpost</model>
+                <order_status>processing</order_status>
+                <payment_action>authorize</payment_action>
+                <test>1</test>
+                <title>Credit Card Direct Post (Authorize.net)</title>
+                <trans_key backend_model="Magento\Config\Model\Config\Backend\Encrypted" />
+                <trans_md5 backend_model="Magento\Config\Model\Config\Backend\Encrypted" />
+                <allowspecific>0</allowspecific>
+                <currency>USD</currency>
+                <create_order_before>1</create_order_before>
+                <date_delim>/</date_delim>
+                <ccfields>x_card_code,x_exp_date,x_card_num</ccfields>
+                <place_order_url>authorizenet/directpost_payment/place</place_order_url>
+                <cgi_url_test_mode>https://test.authorize.net/gateway/transact.dll</cgi_url_test_mode>
+                <cgi_url>https://secure.authorize.net/gateway/transact.dll</cgi_url>
+            </authorizenet_directpost>
+        </payment>
+    </default>
+</config>
diff --git a/app/code/Magento/Authorizenet/etc/di.xml b/app/code/Magento/Authorizenet/etc/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..837239dd6eb91bc7aeb21be0919c3267c7c0d344
--- /dev/null
+++ b/app/code/Magento/Authorizenet/etc/di.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <type name="Magento\Authorizenet\Model\Directpost\Observer">
+        <arguments>
+            <argument name="authorizenetData" xsi:type="object">Magento\Authorizenet\Helper\Data\Proxy</argument>
+            <argument name="jsonHelper" xsi:type="object">Magento\Framework\Json\Helper\Data\Proxy</argument>
+        </arguments>
+    </type>
+    <virtualType name="Magento\Authorizenet\Model\Directpost\Session\Storage" type="Magento\Framework\Session\Storage">
+        <arguments>
+            <argument name="namespace" xsi:type="string">authorizenet_directpost</argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\Authorizenet\Model\Directpost\Session">
+        <arguments>
+            <argument name="storage" xsi:type="object">Magento\Authorizenet\Model\Directpost\Session\Storage</argument>
+        </arguments>
+    </type>
+</config>
diff --git a/app/code/Magento/Authorizenet/etc/frontend/di.xml b/app/code/Magento/Authorizenet/etc/frontend/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..516ecb1d6b8c0d76de0d492c6ef9bd33fb626c51
--- /dev/null
+++ b/app/code/Magento/Authorizenet/etc/frontend/di.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <type name="Magento\Authorizenet\Model\Directpost">
+        <arguments>
+            <argument name="session" xsi:type="object">Magento\Checkout\Model\Session</argument>
+        </arguments>
+    </type>
+    <type name="Magento\Framework\Url\SecurityInfo">
+        <arguments>
+            <argument name="secureUrlList" xsi:type="array">
+                <item name="authorizenet" xsi:type="string">/authorizenet/</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\Authorizenet\Model\Authorizenet">
+        <arguments>
+            <argument name="session" xsi:type="object">Magento\Checkout\Model\Session</argument>
+        </arguments>
+    </type>
+    <virtualType name="AuthorizenetCcConfigProvider" type="Magento\Payment\Model\CcGenericConfigProvider">
+        <arguments>
+            <argument name="methodCodes" xsi:type="array">
+                <item name="directpost" xsi:type="const">Magento\Authorizenet\Model\Directpost::METHOD_CODE</item>
+            </argument>
+        </arguments>
+    </virtualType>
+    <virtualType name="DirectpostIframeCcConfigProvider" type="Magento\Payment\Model\IframeConfigProvider">
+        <arguments>
+            <argument name="methodCode" xsi:type="const">Magento\Authorizenet\Model\Directpost::METHOD_CODE</argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\Checkout\Model\CompositeConfigProvider">
+        <arguments>
+            <argument name="configProviders" xsi:type="array">
+                <item name="authorizenet_cc_config_provider" xsi:type="object">AuthorizenetCcConfigProvider</item>
+                <item name="authorizenet_iframe_cc_config_provider" xsi:type="object">DirectpostIframeCcConfigProvider</item>
+            </argument>
+        </arguments>
+    </type>
+</config>
diff --git a/app/code/Magento/Authorizenet/etc/frontend/events.xml b/app/code/Magento/Authorizenet/etc/frontend/events.xml
new file mode 100644
index 0000000000000000000000000000000000000000..948668c6584e2d9b7504ca4d29f5460e896a038f
--- /dev/null
+++ b/app/code/Magento/Authorizenet/etc/frontend/events.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/Event/etc/events.xsd">
+    <event name="checkout_submit_all_after">
+        <observer name="directpost_save_order_after_submit" instance="Magento\Authorizenet\Model\Directpost\Observer" method="saveOrderAfterSubmit" />
+    </event>
+    <event name="checkout_directpost_placeOrder">
+        <observer name="directpost_save_order_onepage" instance="Magento\Authorizenet\Model\Directpost\Observer" method="addFieldsToResponse" />
+    </event>
+</config>
diff --git a/app/code/Magento/Authorizenet/etc/frontend/page_types.xml b/app/code/Magento/Authorizenet/etc/frontend/page_types.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dafa9fe416ee0c78539005ae69932767eac45a06
--- /dev/null
+++ b/app/code/Magento/Authorizenet/etc/frontend/page_types.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page_types xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_types.xsd">
+    <type id="authorizenet_directpost_payment_redirect" label="AuthorizeNet Directpost Redirect"/>
+    <type id="authorizenet_directpost_payment_response" label="AuthorizeNet Directpost Response"/>
+</page_types>
diff --git a/app/code/Magento/Authorizenet/etc/frontend/routes.xml b/app/code/Magento/Authorizenet/etc/frontend/routes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d9ebbfadff20117631558a7ac28c304d4edb76cc
--- /dev/null
+++ b/app/code/Magento/Authorizenet/etc/frontend/routes.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/App/etc/routes.xsd">
+    <router id="standard">
+        <route id="authorizenet" frontName="authorizenet">
+            <module name="Magento_Authorizenet" />
+        </route>
+    </router>
+</config>
\ No newline at end of file
diff --git a/app/code/Magento/Authorizenet/etc/module.xml b/app/code/Magento/Authorizenet/etc/module.xml
new file mode 100644
index 0000000000000000000000000000000000000000..229118564b3f8f477f8dbd6690ec31db16448776
--- /dev/null
+++ b/app/code/Magento/Authorizenet/etc/module.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
+    <module name="Magento_Authorizenet" setup_version="2.0.0">
+        <sequence>
+            <module name="Magento_Sales"/>
+            <module name="Magento_Quote"/>
+            <module name="Magento_Checkout"/>
+        </sequence>
+    </module>
+</config>
diff --git a/app/code/Magento/Authorizenet/i18n/de_DE.csv b/app/code/Magento/Authorizenet/i18n/de_DE.csv
new file mode 100644
index 0000000000000000000000000000000000000000..be595a6db0140bef106615452e5f364e29c7c8d3
--- /dev/null
+++ b/app/code/Magento/Authorizenet/i18n/de_DE.csv
@@ -0,0 +1,100 @@
+Cancel,Abbrechen
+"You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding.","You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding."
+"Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way.","Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way."
+"We canceled your payment and released any money we were holding.","We canceled your payment and released any money we were holding."
+"You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction.","You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction."
+"Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents.","Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents."
+"Are you sure you want to cancel your payment? Click OK to cancel your payment and release the amount on hold. Click Cancel to enter another credit card and continue with your payment.","Sind Sie sicher, dass Sie die Zahlung abbrechen möchten? Klicken Sie auf OK, um Ihre Zahlung abzubrechen und den Betrag wieder frei verfügbar zu machen. Klicken Sie auf Abbrechen, um eine andere Kreditkarte anzugeben und mit der Zahlung fortzufahren."
+"Processed Amount","Bearbeiteter Betrag"
+"Remaining Balance","Verbleibender Betrag"
+"Order saving error: %1","Order saving error: %1"
+"Please choose a payment method.","Please choose a payment method."
+"You created the order.","You created the order."
+"Something went wrong canceling the transactions.","Something went wrong canceling the transactions."
+"There was an error canceling transactions. Please contact us or try again later.","Es ist ein Fehler beim Abbruch der Transaktion aufgetreten. Bitte kontaktieren Sie uns oder probieren Sie es später noch einmal."
+"We couldn't process your order right now. Please try again later.","We couldn't process your order right now. Please try again later."
+"amount %1","amount %1"
+failed,fehlgeschlagen
+successful,erfolgreich
+"Credit Card: xxxx-%1","Credit Card: xxxx-%1"
+"Authorize.Net Transaction ID %1","Authorize.Net Transaction ID %1"
+authorize,Autorisieren
+"authorize and capture","Autorisieren und Erfassen"
+capture,Erfassen
+refund,Rückerstattung
+void,ungültig
+"This is an invalid amount for authorization.","This is an invalid amount for authorization."
+"This is an invalid amount for capture.","This is an invalid amount for capture."
+"This is an invalid amount for refund.","This is an invalid amount for refund."
+"This is an invalid split tenderId ID.","This is an invalid split tenderId ID."
+"Something went wrong while canceling the payment.","Something went wrong while canceling the payment."
+"Something went wrong while authorizing the payment.","Something went wrong while authorizing the payment."
+"Something went wrong while capturing the payment.","Something went wrong while capturing the payment."
+"The shopping cart contents and/or address has been changed.","The shopping cart contents and/or address has been changed."
+"This is an invalid amount for partial authorization.","This is an invalid amount for partial authorization."
+"Parent Authorize.Net transaction (ID %1) expired","Parent Authorize.Net transaction (ID %1) expired"
+"Something went wrong while voiding the payment.","Something went wrong while voiding the payment."
+"Something went wrong while refunding the payment.","Something went wrong while refunding the payment."
+"You have reached the maximum number of credit cards ' 'allowed to be used for the payment.","You have reached the maximum number of credit cards ' 'allowed to be used for the payment."
+"Something went wrong while authorizing the partial payment.","Something went wrong while authorizing the partial payment."
+"Something went wrong in the payment gateway.","Something went wrong in the payment gateway."
+"Gateway error: %1","Gateway error: %1"
+"Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s).","Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s)."
+"Payment updating error.","Fehler beim Zahlungsupdate."
+"Authorize Only","Nur genehmigen"
+"Authorize and Capture","Genehmigen und erfassen"
+"Invalid amount for capture.","Ungültiger Betrag für die Erfassung."
+"Payment capturing error.","Fehler bei Zahlungserfassung."
+"Invalid transaction ID.","Invalid transaction ID."
+"Payment voiding error.","Fehler beim Stornieren der Zahlung."
+"Invalid amount for refund.","Ungültiger Betrag für eine Rückerstattung."
+"Payment refunding error.","Fehler bei der Rückerstattung."
+"The transaction was declined because the response hash validation failed.","The transaction was declined because the response hash validation failed."
+"This payment didn't work out because we can't find this order.","This payment didn't work out because we can't find this order."
+"There was a payment authorization error.","There was a payment authorization error."
+"This payment was not authorized because the transaction ID field is empty.","This payment was not authorized because the transaction ID field is empty."
+"Amount of %1 approved by payment gateway. Transaction ID: ""%2"".","Amount of %1 approved by payment gateway. Transaction ID: ""%2""."
+"Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again.","Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again."
+"Credit Card Type",Kreditkartentyp
+"Credit Card Number",Kreditkartennummer
+"Expiration Date",Ablaufdatum
+"Card Verification Number",Kreditkartenprüfnummer
+"Click ""Cancel"" to remove any pending status and release money already processed during this payment.","Click ""Cancel"" to remove any pending status and release money already processed during this payment."
+"Please enter a different credit card number to complete your purchase.","Please enter a different credit card number to complete your purchase."
+"Credit Card %1","Credit Card %1"
+"Credit Card Information",Kreditkarteninformationen
+"--Please Select--","--Bitte wählen--"
+"Card Verification Number Visual Reference","Kartenprüfnummer Sichtmerkmale"
+"What is this?","Was ist das?"
+"You'll be asked for your payment details before placing an order.","You'll be asked for your payment details before placing an order."
+"To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel.","To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel."
+Processing...,Processing...
+Enabled,Enabled
+"Sort Order","Sort Order"
+Title,Title
+"3D Secure Card Validation","3D Secure Card Validation"
+"New Order Status","New Order Status"
+"No confirmation","No confirmation"
+Authorize.net,Authorize.net
+"Credit Card Types","Credit Card Types"
+"Credit Card Verification","Credit Card Verification"
+"Email Customer","Email Customer"
+"API Login ID","API Login ID"
+"Merchant's Email","Merchant's Email"
+"Test Mode","Test Mode"
+Debug,Debug
+"Transaction Key","Transaction Key"
+"Payment Action","Payment Action"
+"Accepted Currency","Accepted Currency"
+"Payment from Applicable Countries","Payment from Applicable Countries"
+"Payment from Specific Countries","Payment from Specific Countries"
+"Minimum Order Total","Minimum Order Total"
+"Maximum Order Total","Maximum Order Total"
+"Allow Partial Authorization","Allow Partial Authorization"
+"3D Secure","3D Secure"
+"Severe 3D Secure Card Validation","Severe 3D Secure Card Validation"
+"Severe Validation Removes Chargeback Liability on Merchant","Severe Validation Removes Chargeback Liability on Merchant"
+"If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement.","If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement."
+"Authorize.net Direct Post","Authorize.net Direct Post"
+"Merchant MD5","Merchant MD5"
+"Gateway URL","Gateway URL"
diff --git a/app/code/Magento/Authorizenet/i18n/en_US.csv b/app/code/Magento/Authorizenet/i18n/en_US.csv
new file mode 100644
index 0000000000000000000000000000000000000000..7bbbbaf286d5a2a0189c0fb2652b75bb626eae12
--- /dev/null
+++ b/app/code/Magento/Authorizenet/i18n/en_US.csv
@@ -0,0 +1,100 @@
+Cancel,Cancel
+"You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding.","You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding."
+"Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way.","Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way."
+"We canceled your payment and released any money we were holding.","We canceled your payment and released any money we were holding."
+"You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction.","You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction."
+"Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents.","Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents."
+"Are you sure you want to cancel your payment? Click OK to cancel your payment and release the amount on hold. Click Cancel to enter another credit card and continue with your payment.","Are you sure you want to cancel your payment? Click OK to cancel your payment and release the amount on hold. Click Cancel to enter another credit card and continue with your payment."
+"Processed Amount","Processed Amount"
+"Remaining Balance","Remaining Balance"
+"Order saving error: %1","Order saving error: %1"
+"Please choose a payment method.","Please choose a payment method."
+"You created the order.","You created the order."
+"Something went wrong canceling the transactions.","Something went wrong canceling the transactions."
+"There was an error canceling transactions. Please contact us or try again later.","There was an error canceling transactions. Please contact us or try again later."
+"We couldn't process your order right now. Please try again later.","We couldn't process your order right now. Please try again later."
+"amount %1","amount %1"
+failed,failed
+successful,successful
+"Credit Card: xxxx-%1","Credit Card: xxxx-%1"
+"Authorize.Net Transaction ID %1","Authorize.Net Transaction ID %1"
+authorize,authorize
+"authorize and capture","authorize and capture"
+capture,capture
+refund,refund
+void,void
+"This is an invalid amount for authorization.","This is an invalid amount for authorization."
+"This is an invalid amount for capture.","This is an invalid amount for capture."
+"This is an invalid amount for refund.","This is an invalid amount for refund."
+"This is an invalid split tenderId ID.","This is an invalid split tenderId ID."
+"Something went wrong while canceling the payment.","Something went wrong while canceling the payment."
+"Something went wrong while authorizing the payment.","Something went wrong while authorizing the payment."
+"Something went wrong while capturing the payment.","Something went wrong while capturing the payment."
+"The shopping cart contents and/or address has been changed.","The shopping cart contents and/or address has been changed."
+"This is an invalid amount for partial authorization.","This is an invalid amount for partial authorization."
+"Parent Authorize.Net transaction (ID %1) expired","Parent Authorize.Net transaction (ID %1) expired"
+"Something went wrong while voiding the payment.","Something went wrong while voiding the payment."
+"Something went wrong while refunding the payment.","Something went wrong while refunding the payment."
+"You have reached the maximum number of credit cards ' 'allowed to be used for the payment.","You have reached the maximum number of credit cards ' 'allowed to be used for the payment."
+"Something went wrong while authorizing the partial payment.","Something went wrong while authorizing the partial payment."
+"Something went wrong in the payment gateway.","Something went wrong in the payment gateway."
+"Gateway error: %1","Gateway error: %1"
+"Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s).","Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s)."
+"Payment updating error.","Payment updating error."
+"Authorize Only","Authorize Only"
+"Authorize and Capture","Authorize and Capture"
+"Invalid amount for capture.","Invalid amount for capture."
+"Payment capturing error.","Payment capturing error."
+"Invalid transaction ID.","Invalid transaction ID."
+"Payment voiding error.","Payment voiding error."
+"Invalid amount for refund.","Invalid amount for refund."
+"Payment refunding error.","Payment refunding error."
+"The transaction was declined because the response hash validation failed.","The transaction was declined because the response hash validation failed."
+"This payment didn't work out because we can't find this order.","This payment didn't work out because we can't find this order."
+"There was a payment authorization error.","There was a payment authorization error."
+"This payment was not authorized because the transaction ID field is empty.","This payment was not authorized because the transaction ID field is empty."
+"Amount of %1 approved by payment gateway. Transaction ID: ""%2"".","Amount of %1 approved by payment gateway. Transaction ID: ""%2""."
+"Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again.","Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again."
+"Credit Card Type","Credit Card Type"
+"Credit Card Number","Credit Card Number"
+"Expiration Date","Expiration Date"
+"Card Verification Number","Card Verification Number"
+"Click ""Cancel"" to remove any pending status and release money already processed during this payment.","Click ""Cancel"" to remove any pending status and release money already processed during this payment."
+"Please enter a different credit card number to complete your purchase.","Please enter a different credit card number to complete your purchase."
+"Credit Card %1","Credit Card %1"
+"Credit Card Information","Credit Card Information"
+"--Please Select--","--Please Select--"
+"Card Verification Number Visual Reference","Card Verification Number Visual Reference"
+"What is this?","What is this?"
+"You'll be asked for your payment details before placing an order.","You'll be asked for your payment details before placing an order."
+"To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel.","To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel."
+Processing...,Processing...
+Enabled,Enabled
+"Sort Order","Sort Order"
+Title,Title
+"3D Secure Card Validation","3D Secure Card Validation"
+"New Order Status","New Order Status"
+"No confirmation","No confirmation"
+Authorize.net,Authorize.net
+"Credit Card Types","Credit Card Types"
+"Credit Card Verification","Credit Card Verification"
+"Email Customer","Email Customer"
+"API Login ID","API Login ID"
+"Merchant's Email","Merchant's Email"
+"Test Mode","Test Mode"
+Debug,Debug
+"Transaction Key","Transaction Key"
+"Payment Action","Payment Action"
+"Accepted Currency","Accepted Currency"
+"Payment from Applicable Countries","Payment from Applicable Countries"
+"Payment from Specific Countries","Payment from Specific Countries"
+"Minimum Order Total","Minimum Order Total"
+"Maximum Order Total","Maximum Order Total"
+"Allow Partial Authorization","Allow Partial Authorization"
+"3D Secure","3D Secure"
+"Severe 3D Secure Card Validation","Severe 3D Secure Card Validation"
+"Severe Validation Removes Chargeback Liability on Merchant","Severe Validation Removes Chargeback Liability on Merchant"
+"If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement.","If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement."
+"Authorize.net Direct Post","Authorize.net Direct Post"
+"Merchant MD5","Merchant MD5"
+"Gateway URL","Gateway URL"
diff --git a/app/code/Magento/Authorizenet/i18n/es_ES.csv b/app/code/Magento/Authorizenet/i18n/es_ES.csv
new file mode 100644
index 0000000000000000000000000000000000000000..e3f894d4c754451dd56ae6bf83e50cd3721dce8c
--- /dev/null
+++ b/app/code/Magento/Authorizenet/i18n/es_ES.csv
@@ -0,0 +1,100 @@
+Cancel,Cancelar
+"You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding.","You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding."
+"Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way.","Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way."
+"We canceled your payment and released any money we were holding.","We canceled your payment and released any money we were holding."
+"You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction.","You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction."
+"Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents.","Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents."
+"Are you sure you want to cancel your payment? Click OK to cancel your payment and release the amount on hold. Click Cancel to enter another credit card and continue with your payment.","¿Está seguro de que desea cancelar su pago? Pinche en Aceptar para cancelar el pago y liberar la cantidad retenida. Pinche en ""Cancelar"" para introducir otra tarjeta de crédito y continuar con su pago."
+"Processed Amount","Cantidad Procesada"
+"Remaining Balance","Saldo Restante"
+"Order saving error: %1","Order saving error: %1"
+"Please choose a payment method.","Please choose a payment method."
+"You created the order.","You created the order."
+"Something went wrong canceling the transactions.","Something went wrong canceling the transactions."
+"There was an error canceling transactions. Please contact us or try again later.","Ha habido un error en la cancelación de las transacciones. Por favor, póngase en contacto con nosotros o inténtelo más tarde de nuevo."
+"We couldn't process your order right now. Please try again later.","We couldn't process your order right now. Please try again later."
+"amount %1","amount %1"
+failed,error
+successful,exitoso
+"Credit Card: xxxx-%1","Credit Card: xxxx-%1"
+"Authorize.Net Transaction ID %1","Authorize.Net Transaction ID %1"
+authorize,autorizar
+"authorize and capture","autorizar y capturar"
+capture,capturar
+refund,reembolso
+void,vacío
+"This is an invalid amount for authorization.","This is an invalid amount for authorization."
+"This is an invalid amount for capture.","This is an invalid amount for capture."
+"This is an invalid amount for refund.","This is an invalid amount for refund."
+"This is an invalid split tenderId ID.","This is an invalid split tenderId ID."
+"Something went wrong while canceling the payment.","Something went wrong while canceling the payment."
+"Something went wrong while authorizing the payment.","Something went wrong while authorizing the payment."
+"Something went wrong while capturing the payment.","Something went wrong while capturing the payment."
+"The shopping cart contents and/or address has been changed.","The shopping cart contents and/or address has been changed."
+"This is an invalid amount for partial authorization.","This is an invalid amount for partial authorization."
+"Parent Authorize.Net transaction (ID %1) expired","Parent Authorize.Net transaction (ID %1) expired"
+"Something went wrong while voiding the payment.","Something went wrong while voiding the payment."
+"Something went wrong while refunding the payment.","Something went wrong while refunding the payment."
+"You have reached the maximum number of credit cards ' 'allowed to be used for the payment.","You have reached the maximum number of credit cards ' 'allowed to be used for the payment."
+"Something went wrong while authorizing the partial payment.","Something went wrong while authorizing the partial payment."
+"Something went wrong in the payment gateway.","Something went wrong in the payment gateway."
+"Gateway error: %1","Gateway error: %1"
+"Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s).","Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s)."
+"Payment updating error.","Error de actualización del pago."
+"Authorize Only","Sólo autorizar"
+"Authorize and Capture","Autorizar y capturar"
+"Invalid amount for capture.","Cantidad para retención no válida."
+"Payment capturing error.","Error en el pago de retención."
+"Invalid transaction ID.","Invalid transaction ID."
+"Payment voiding error.","Error en la anulación del pago."
+"Invalid amount for refund.","Cantidad de reembolso no válida."
+"Payment refunding error.","Error en el pago de reembolso."
+"The transaction was declined because the response hash validation failed.","The transaction was declined because the response hash validation failed."
+"This payment didn't work out because we can't find this order.","This payment didn't work out because we can't find this order."
+"There was a payment authorization error.","There was a payment authorization error."
+"This payment was not authorized because the transaction ID field is empty.","This payment was not authorized because the transaction ID field is empty."
+"Amount of %1 approved by payment gateway. Transaction ID: ""%2"".","Amount of %1 approved by payment gateway. Transaction ID: ""%2""."
+"Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again.","Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again."
+"Credit Card Type","Tipo de Tarjeta de Crédito"
+"Credit Card Number","Número de Tarjeta de Crédito"
+"Expiration Date","Fecha de Caducidad"
+"Card Verification Number","Número de Verificación de Tarjeta"
+"Click ""Cancel"" to remove any pending status and release money already processed during this payment.","Click ""Cancel"" to remove any pending status and release money already processed during this payment."
+"Please enter a different credit card number to complete your purchase.","Please enter a different credit card number to complete your purchase."
+"Credit Card %1","Credit Card %1"
+"Credit Card Information","Información de la tarjeta de crédito"
+"--Please Select--","--Por favor, seleccione-"
+"Card Verification Number Visual Reference","Referencia visual del número de verificación de tarjeta"
+"What is this?","¿Qué es esto?"
+"You'll be asked for your payment details before placing an order.","You'll be asked for your payment details before placing an order."
+"To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel.","To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel."
+Processing...,Processing...
+Enabled,Enabled
+"Sort Order","Sort Order"
+Title,Title
+"3D Secure Card Validation","3D Secure Card Validation"
+"New Order Status","New Order Status"
+"No confirmation","No confirmation"
+Authorize.net,Authorize.net
+"Credit Card Types","Credit Card Types"
+"Credit Card Verification","Credit Card Verification"
+"Email Customer","Email Customer"
+"API Login ID","API Login ID"
+"Merchant's Email","Merchant's Email"
+"Test Mode","Test Mode"
+Debug,Debug
+"Transaction Key","Transaction Key"
+"Payment Action","Payment Action"
+"Accepted Currency","Accepted Currency"
+"Payment from Applicable Countries","Payment from Applicable Countries"
+"Payment from Specific Countries","Payment from Specific Countries"
+"Minimum Order Total","Minimum Order Total"
+"Maximum Order Total","Maximum Order Total"
+"Allow Partial Authorization","Allow Partial Authorization"
+"3D Secure","3D Secure"
+"Severe 3D Secure Card Validation","Severe 3D Secure Card Validation"
+"Severe Validation Removes Chargeback Liability on Merchant","Severe Validation Removes Chargeback Liability on Merchant"
+"If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement.","If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement."
+"Authorize.net Direct Post","Authorize.net Direct Post"
+"Merchant MD5","Merchant MD5"
+"Gateway URL","Gateway URL"
diff --git a/app/code/Magento/Authorizenet/i18n/fr_FR.csv b/app/code/Magento/Authorizenet/i18n/fr_FR.csv
new file mode 100644
index 0000000000000000000000000000000000000000..8c581352613efec69d9dd21d45b173778cd2cc7c
--- /dev/null
+++ b/app/code/Magento/Authorizenet/i18n/fr_FR.csv
@@ -0,0 +1,100 @@
+Cancel,Annuler
+"You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding.","You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding."
+"Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way.","Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way."
+"We canceled your payment and released any money we were holding.","We canceled your payment and released any money we were holding."
+"You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction.","You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction."
+"Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents.","Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents."
+"Are you sure you want to cancel your payment? Click OK to cancel your payment and release the amount on hold. Click Cancel to enter another credit card and continue with your payment.","Etes-vous sûr de vouloir annuler votre paiement ?  Cliquez sur OK pour annuler le paiement et débloquer le montant en attente. Cliquez sur Quitter pour entrer une autre carte bancaire et continuer le paiemetn."
+"Processed Amount","Montant réalisé"
+"Remaining Balance","Balance restante"
+"Order saving error: %1","Order saving error: %1"
+"Please choose a payment method.","Please choose a payment method."
+"You created the order.","You created the order."
+"Something went wrong canceling the transactions.","Something went wrong canceling the transactions."
+"There was an error canceling transactions. Please contact us or try again later.","Une erreur s'est produite lors de l'annulation de transactions. Veuillez nous contacter ou réessayer ultérieurement."
+"We couldn't process your order right now. Please try again later.","We couldn't process your order right now. Please try again later."
+"amount %1","amount %1"
+failed,échoué
+successful,réussi
+"Credit Card: xxxx-%1","Credit Card: xxxx-%1"
+"Authorize.Net Transaction ID %1","Authorize.Net Transaction ID %1"
+authorize,autoriser
+"authorize and capture","autoriser et saisir"
+capture,saisir
+refund,remboursement
+void,vide
+"This is an invalid amount for authorization.","This is an invalid amount for authorization."
+"This is an invalid amount for capture.","This is an invalid amount for capture."
+"This is an invalid amount for refund.","This is an invalid amount for refund."
+"This is an invalid split tenderId ID.","This is an invalid split tenderId ID."
+"Something went wrong while canceling the payment.","Something went wrong while canceling the payment."
+"Something went wrong while authorizing the payment.","Something went wrong while authorizing the payment."
+"Something went wrong while capturing the payment.","Something went wrong while capturing the payment."
+"The shopping cart contents and/or address has been changed.","The shopping cart contents and/or address has been changed."
+"This is an invalid amount for partial authorization.","This is an invalid amount for partial authorization."
+"Parent Authorize.Net transaction (ID %1) expired","Parent Authorize.Net transaction (ID %1) expired"
+"Something went wrong while voiding the payment.","Something went wrong while voiding the payment."
+"Something went wrong while refunding the payment.","Something went wrong while refunding the payment."
+"You have reached the maximum number of credit cards ' 'allowed to be used for the payment.","You have reached the maximum number of credit cards ' 'allowed to be used for the payment."
+"Something went wrong while authorizing the partial payment.","Something went wrong while authorizing the partial payment."
+"Something went wrong in the payment gateway.","Something went wrong in the payment gateway."
+"Gateway error: %1","Gateway error: %1"
+"Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s).","Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s)."
+"Payment updating error.","Erreur lors de la mise à jour du paiement."
+"Authorize Only","Autoriser uniquement"
+"Authorize and Capture","Autoriser et enregistrer"
+"Invalid amount for capture.","Montant invalide"
+"Payment capturing error.","Erreur lors de la saisie du paiement"
+"Invalid transaction ID.","Invalid transaction ID."
+"Payment voiding error.","Erreur annulant le paiement"
+"Invalid amount for refund.","Montant invalide pour un remboursement"
+"Payment refunding error.","Erreur de remboursement du paiement"
+"The transaction was declined because the response hash validation failed.","The transaction was declined because the response hash validation failed."
+"This payment didn't work out because we can't find this order.","This payment didn't work out because we can't find this order."
+"There was a payment authorization error.","There was a payment authorization error."
+"This payment was not authorized because the transaction ID field is empty.","This payment was not authorized because the transaction ID field is empty."
+"Amount of %1 approved by payment gateway. Transaction ID: ""%2"".","Amount of %1 approved by payment gateway. Transaction ID: ""%2""."
+"Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again.","Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again."
+"Credit Card Type","Type de carte de crédit"
+"Credit Card Number","Numéro de carte de crédit"
+"Expiration Date","Date d'expiration"
+"Card Verification Number","Numéro de vérification de la carte"
+"Click ""Cancel"" to remove any pending status and release money already processed during this payment.","Click ""Cancel"" to remove any pending status and release money already processed during this payment."
+"Please enter a different credit card number to complete your purchase.","Please enter a different credit card number to complete your purchase."
+"Credit Card %1","Credit Card %1"
+"Credit Card Information","Renseignements sur la carte de crédit"
+"--Please Select--","--Veuillez choisir--"
+"Card Verification Number Visual Reference","Référence visuelle du numéro de vérification de la carte"
+"What is this?","Qu'est-ce que c'est ?"
+"You'll be asked for your payment details before placing an order.","You'll be asked for your payment details before placing an order."
+"To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel.","To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel."
+Processing...,Processing...
+Enabled,Enabled
+"Sort Order","Sort Order"
+Title,Title
+"3D Secure Card Validation","3D Secure Card Validation"
+"New Order Status","New Order Status"
+"No confirmation","No confirmation"
+Authorize.net,Authorize.net
+"Credit Card Types","Credit Card Types"
+"Credit Card Verification","Credit Card Verification"
+"Email Customer","Email Customer"
+"API Login ID","API Login ID"
+"Merchant's Email","Merchant's Email"
+"Test Mode","Test Mode"
+Debug,Debug
+"Transaction Key","Transaction Key"
+"Payment Action","Payment Action"
+"Accepted Currency","Accepted Currency"
+"Payment from Applicable Countries","Payment from Applicable Countries"
+"Payment from Specific Countries","Payment from Specific Countries"
+"Minimum Order Total","Minimum Order Total"
+"Maximum Order Total","Maximum Order Total"
+"Allow Partial Authorization","Allow Partial Authorization"
+"3D Secure","3D Secure"
+"Severe 3D Secure Card Validation","Severe 3D Secure Card Validation"
+"Severe Validation Removes Chargeback Liability on Merchant","Severe Validation Removes Chargeback Liability on Merchant"
+"If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement.","If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement."
+"Authorize.net Direct Post","Authorize.net Direct Post"
+"Merchant MD5","Merchant MD5"
+"Gateway URL","Gateway URL"
diff --git a/app/code/Magento/Authorizenet/i18n/nl_NL.csv b/app/code/Magento/Authorizenet/i18n/nl_NL.csv
new file mode 100644
index 0000000000000000000000000000000000000000..24f8616ddc9224932ed0d90822610e0a66e10b74
--- /dev/null
+++ b/app/code/Magento/Authorizenet/i18n/nl_NL.csv
@@ -0,0 +1,100 @@
+Cancel,Annuleren
+"You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding.","You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding."
+"Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way.","Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way."
+"We canceled your payment and released any money we were holding.","We canceled your payment and released any money we were holding."
+"You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction.","You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction."
+"Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents.","Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents."
+"Are you sure you want to cancel your payment? Click OK to cancel your payment and release the amount on hold. Click Cancel to enter another credit card and continue with your payment.","Weet u zeker dat u uw betaling wilt annuleren? Klik op OK om uw betaling te annuleren en het geld vrij te geven. Klik op Cancel om een andere kredietkaart te gebruiken en verder te gaan met uw betaling."
+"Processed Amount","Verwerkte hoeveelheid"
+"Remaining Balance","Resterend balans"
+"Order saving error: %1","Order saving error: %1"
+"Please choose a payment method.","Please choose a payment method."
+"You created the order.","You created the order."
+"Something went wrong canceling the transactions.","Something went wrong canceling the transactions."
+"There was an error canceling transactions. Please contact us or try again later.","Er heeft zich een fout voorgedaan tijdens het annuleren van de transacties. Neem contact met ons op of probeer later."
+"We couldn't process your order right now. Please try again later.","We couldn't process your order right now. Please try again later."
+"amount %1","amount %1"
+failed,mislukt
+successful,succesvol
+"Credit Card: xxxx-%1","Credit Card: xxxx-%1"
+"Authorize.Net Transaction ID %1","Authorize.Net Transaction ID %1"
+authorize,autoriseer
+"authorize and capture","autoriseer en vang"
+capture,vang
+refund,teruggave
+void,ongeldig
+"This is an invalid amount for authorization.","This is an invalid amount for authorization."
+"This is an invalid amount for capture.","This is an invalid amount for capture."
+"This is an invalid amount for refund.","This is an invalid amount for refund."
+"This is an invalid split tenderId ID.","This is an invalid split tenderId ID."
+"Something went wrong while canceling the payment.","Something went wrong while canceling the payment."
+"Something went wrong while authorizing the payment.","Something went wrong while authorizing the payment."
+"Something went wrong while capturing the payment.","Something went wrong while capturing the payment."
+"The shopping cart contents and/or address has been changed.","The shopping cart contents and/or address has been changed."
+"This is an invalid amount for partial authorization.","This is an invalid amount for partial authorization."
+"Parent Authorize.Net transaction (ID %1) expired","Parent Authorize.Net transaction (ID %1) expired"
+"Something went wrong while voiding the payment.","Something went wrong while voiding the payment."
+"Something went wrong while refunding the payment.","Something went wrong while refunding the payment."
+"You have reached the maximum number of credit cards ' 'allowed to be used for the payment.","You have reached the maximum number of credit cards ' 'allowed to be used for the payment."
+"Something went wrong while authorizing the partial payment.","Something went wrong while authorizing the partial payment."
+"Something went wrong in the payment gateway.","Something went wrong in the payment gateway."
+"Gateway error: %1","Gateway error: %1"
+"Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s).","Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s)."
+"Payment updating error.","Fout bij het bijwerken van de betaling."
+"Authorize Only","Alleen authoriseren"
+"Authorize and Capture","Authoriseren en opnemen"
+"Invalid amount for capture.","Ongeldige aantal voor vangst."
+"Payment capturing error.","Fout in het ophalen van de betaling."
+"Invalid transaction ID.","Invalid transaction ID."
+"Payment voiding error.","Fout in het vernietigen van de betaling."
+"Invalid amount for refund.","Ongeldige aantal voor teruggave."
+"Payment refunding error.","Fout in het terugbetalen van de betaling."
+"The transaction was declined because the response hash validation failed.","The transaction was declined because the response hash validation failed."
+"This payment didn't work out because we can't find this order.","This payment didn't work out because we can't find this order."
+"There was a payment authorization error.","There was a payment authorization error."
+"This payment was not authorized because the transaction ID field is empty.","This payment was not authorized because the transaction ID field is empty."
+"Amount of %1 approved by payment gateway. Transaction ID: ""%2"".","Amount of %1 approved by payment gateway. Transaction ID: ""%2""."
+"Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again.","Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again."
+"Credit Card Type",Creditcardtype
+"Credit Card Number",Creditcardnummer
+"Expiration Date",vervaldatum
+"Card Verification Number","Kaart verificatie nummer"
+"Click ""Cancel"" to remove any pending status and release money already processed during this payment.","Click ""Cancel"" to remove any pending status and release money already processed during this payment."
+"Please enter a different credit card number to complete your purchase.","Please enter a different credit card number to complete your purchase."
+"Credit Card %1","Credit Card %1"
+"Credit Card Information","Creditcard informatie"
+"--Please Select--","--selecteer a.u.b.--"
+"Card Verification Number Visual Reference","Kaart verificatie nummer visuele referentie"
+"What is this?","Wat is dit?"
+"You'll be asked for your payment details before placing an order.","You'll be asked for your payment details before placing an order."
+"To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel.","To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel."
+Processing...,Processing...
+Enabled,Enabled
+"Sort Order","Sort Order"
+Title,Title
+"3D Secure Card Validation","3D Secure Card Validation"
+"New Order Status","New Order Status"
+"No confirmation","No confirmation"
+Authorize.net,Authorize.net
+"Credit Card Types","Credit Card Types"
+"Credit Card Verification","Credit Card Verification"
+"Email Customer","Email Customer"
+"API Login ID","API Login ID"
+"Merchant's Email","Merchant's Email"
+"Test Mode","Test Mode"
+Debug,Debug
+"Transaction Key","Transaction Key"
+"Payment Action","Payment Action"
+"Accepted Currency","Accepted Currency"
+"Payment from Applicable Countries","Payment from Applicable Countries"
+"Payment from Specific Countries","Payment from Specific Countries"
+"Minimum Order Total","Minimum Order Total"
+"Maximum Order Total","Maximum Order Total"
+"Allow Partial Authorization","Allow Partial Authorization"
+"3D Secure","3D Secure"
+"Severe 3D Secure Card Validation","Severe 3D Secure Card Validation"
+"Severe Validation Removes Chargeback Liability on Merchant","Severe Validation Removes Chargeback Liability on Merchant"
+"If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement.","If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement."
+"Authorize.net Direct Post","Authorize.net Direct Post"
+"Merchant MD5","Merchant MD5"
+"Gateway URL","Gateway URL"
diff --git a/app/code/Magento/Authorizenet/i18n/pt_BR.csv b/app/code/Magento/Authorizenet/i18n/pt_BR.csv
new file mode 100644
index 0000000000000000000000000000000000000000..5aa07e625d2adc568be404b5e49571982a9ac878
--- /dev/null
+++ b/app/code/Magento/Authorizenet/i18n/pt_BR.csv
@@ -0,0 +1,100 @@
+Cancel,Cancelar
+"You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding.","You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding."
+"Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way.","Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way."
+"We canceled your payment and released any money we were holding.","We canceled your payment and released any money we were holding."
+"You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction.","You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction."
+"Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents.","Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents."
+"Are you sure you want to cancel your payment? Click OK to cancel your payment and release the amount on hold. Click Cancel to enter another credit card and continue with your payment.","Tem certeza de que deseja cancelar o seu pagamento? Clique em OK para cancelar o seu pagamento e liberar o montante em espera. Clique em Cancelar para inserir outro cartão de crédito e continuar com o seu pagamento."
+"Processed Amount","Valor Processado"
+"Remaining Balance","Balanço Restante"
+"Order saving error: %1","Order saving error: %1"
+"Please choose a payment method.","Please choose a payment method."
+"You created the order.","You created the order."
+"Something went wrong canceling the transactions.","Something went wrong canceling the transactions."
+"There was an error canceling transactions. Please contact us or try again later.","Ocorreu um erro ao cancelar as transações. Por favor entre em contato conosco ou tente novamente mais tarde."
+"We couldn't process your order right now. Please try again later.","We couldn't process your order right now. Please try again later."
+"amount %1","amount %1"
+failed,fracassado
+successful,"bem sucedido"
+"Credit Card: xxxx-%1","Credit Card: xxxx-%1"
+"Authorize.Net Transaction ID %1","Authorize.Net Transaction ID %1"
+authorize,autorizar
+"authorize and capture","autorizar e capturar"
+capture,capturar
+refund,reembolso
+void,vazio
+"This is an invalid amount for authorization.","This is an invalid amount for authorization."
+"This is an invalid amount for capture.","This is an invalid amount for capture."
+"This is an invalid amount for refund.","This is an invalid amount for refund."
+"This is an invalid split tenderId ID.","This is an invalid split tenderId ID."
+"Something went wrong while canceling the payment.","Something went wrong while canceling the payment."
+"Something went wrong while authorizing the payment.","Something went wrong while authorizing the payment."
+"Something went wrong while capturing the payment.","Something went wrong while capturing the payment."
+"The shopping cart contents and/or address has been changed.","The shopping cart contents and/or address has been changed."
+"This is an invalid amount for partial authorization.","This is an invalid amount for partial authorization."
+"Parent Authorize.Net transaction (ID %1) expired","Parent Authorize.Net transaction (ID %1) expired"
+"Something went wrong while voiding the payment.","Something went wrong while voiding the payment."
+"Something went wrong while refunding the payment.","Something went wrong while refunding the payment."
+"You have reached the maximum number of credit cards ' 'allowed to be used for the payment.","You have reached the maximum number of credit cards ' 'allowed to be used for the payment."
+"Something went wrong while authorizing the partial payment.","Something went wrong while authorizing the partial payment."
+"Something went wrong in the payment gateway.","Something went wrong in the payment gateway."
+"Gateway error: %1","Gateway error: %1"
+"Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s).","Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s)."
+"Payment updating error.","Erro de atualização de pagamento."
+"Authorize Only","Somente Autorizar"
+"Authorize and Capture","Autorizar e Controlar"
+"Invalid amount for capture.","Valor inválido para captura."
+"Payment capturing error.","Erro de captura de pagamento."
+"Invalid transaction ID.","Invalid transaction ID."
+"Payment voiding error.","Erro de anulamento de pagamento."
+"Invalid amount for refund.","Valor inválido para reembolso."
+"Payment refunding error.","Erro de reembolso de pagamento."
+"The transaction was declined because the response hash validation failed.","The transaction was declined because the response hash validation failed."
+"This payment didn't work out because we can't find this order.","This payment didn't work out because we can't find this order."
+"There was a payment authorization error.","There was a payment authorization error."
+"This payment was not authorized because the transaction ID field is empty.","This payment was not authorized because the transaction ID field is empty."
+"Amount of %1 approved by payment gateway. Transaction ID: ""%2"".","Amount of %1 approved by payment gateway. Transaction ID: ""%2""."
+"Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again.","Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again."
+"Credit Card Type","Tipo de Cartão de Crédito"
+"Credit Card Number","Número do Cartão de Crédito"
+"Expiration Date","Data de Validade"
+"Card Verification Number","Número de Verificação do Cartão"
+"Click ""Cancel"" to remove any pending status and release money already processed during this payment.","Click ""Cancel"" to remove any pending status and release money already processed during this payment."
+"Please enter a different credit card number to complete your purchase.","Please enter a different credit card number to complete your purchase."
+"Credit Card %1","Credit Card %1"
+"Credit Card Information","Informações do Cartão de Crédito"
+"--Please Select--","--Por Favor, Escolha--"
+"Card Verification Number Visual Reference","Referência Visual de Número de Verificação do Cartão"
+"What is this?","O que é isso?"
+"You'll be asked for your payment details before placing an order.","You'll be asked for your payment details before placing an order."
+"To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel.","To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel."
+Processing...,Processing...
+Enabled,Enabled
+"Sort Order","Sort Order"
+Title,Title
+"3D Secure Card Validation","3D Secure Card Validation"
+"New Order Status","New Order Status"
+"No confirmation","No confirmation"
+Authorize.net,Authorize.net
+"Credit Card Types","Credit Card Types"
+"Credit Card Verification","Credit Card Verification"
+"Email Customer","Email Customer"
+"API Login ID","API Login ID"
+"Merchant's Email","Merchant's Email"
+"Test Mode","Test Mode"
+Debug,Debug
+"Transaction Key","Transaction Key"
+"Payment Action","Payment Action"
+"Accepted Currency","Accepted Currency"
+"Payment from Applicable Countries","Payment from Applicable Countries"
+"Payment from Specific Countries","Payment from Specific Countries"
+"Minimum Order Total","Minimum Order Total"
+"Maximum Order Total","Maximum Order Total"
+"Allow Partial Authorization","Allow Partial Authorization"
+"3D Secure","3D Secure"
+"Severe 3D Secure Card Validation","Severe 3D Secure Card Validation"
+"Severe Validation Removes Chargeback Liability on Merchant","Severe Validation Removes Chargeback Liability on Merchant"
+"If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement.","If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement."
+"Authorize.net Direct Post","Authorize.net Direct Post"
+"Merchant MD5","Merchant MD5"
+"Gateway URL","Gateway URL"
diff --git a/app/code/Magento/Authorizenet/i18n/zh_CN.csv b/app/code/Magento/Authorizenet/i18n/zh_CN.csv
new file mode 100644
index 0000000000000000000000000000000000000000..0847524628d66db1a8c847830d4a5143959c1f48
--- /dev/null
+++ b/app/code/Magento/Authorizenet/i18n/zh_CN.csv
@@ -0,0 +1,100 @@
+Cancel,取消
+"You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding.","You don't have enough on your credit card to pay for this purchase. To complete your purchase, click ""OK"" and add a credit card to use for the balance. Otherwise, you can cancel the purchase and release the partial payment we are holding."
+"Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way.","Your credit card has been declined. You can click OK to add another credit card to complete your purchase. Or you can cancel this credit transaction and pay a different way."
+"We canceled your payment and released any money we were holding.","We canceled your payment and released any money we were holding."
+"You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction.","You can't use any more credit cards for this payment, and you don't have enough to pay for this purchase. Sorry, but we'll have to cancel your transaction."
+"Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents.","Your order has not been placed, because the contents of the shopping cart and/or your address has been changed. Authorized amounts from your previous payment that were left pending are now released. Please go through the checkout process to purchase your cart contents."
+"Are you sure you want to cancel your payment? Click OK to cancel your payment and release the amount on hold. Click Cancel to enter another credit card and continue with your payment.",您是否确定要取消支付?单击确定可取消您的支付,并释放占用的额度。单击取消可输入其他信用卡,并继续进行支付。
+"Processed Amount",处理的额度
+"Remaining Balance",剩下的余额
+"Order saving error: %1","Order saving error: %1"
+"Please choose a payment method.","Please choose a payment method."
+"You created the order.","You created the order."
+"Something went wrong canceling the transactions.","Something went wrong canceling the transactions."
+"There was an error canceling transactions. Please contact us or try again later.",取消交易时遇到了错误。请联系我们或稍候重试。
+"We couldn't process your order right now. Please try again later.","We couldn't process your order right now. Please try again later."
+"amount %1","amount %1"
+failed,失败
+successful,成功
+"Credit Card: xxxx-%1","Credit Card: xxxx-%1"
+"Authorize.Net Transaction ID %1","Authorize.Net Transaction ID %1"
+authorize,授权
+"authorize and capture",授权和获取
+capture,获取
+refund,退款
+void,避免
+"This is an invalid amount for authorization.","This is an invalid amount for authorization."
+"This is an invalid amount for capture.","This is an invalid amount for capture."
+"This is an invalid amount for refund.","This is an invalid amount for refund."
+"This is an invalid split tenderId ID.","This is an invalid split tenderId ID."
+"Something went wrong while canceling the payment.","Something went wrong while canceling the payment."
+"Something went wrong while authorizing the payment.","Something went wrong while authorizing the payment."
+"Something went wrong while capturing the payment.","Something went wrong while capturing the payment."
+"The shopping cart contents and/or address has been changed.","The shopping cart contents and/or address has been changed."
+"This is an invalid amount for partial authorization.","This is an invalid amount for partial authorization."
+"Parent Authorize.Net transaction (ID %1) expired","Parent Authorize.Net transaction (ID %1) expired"
+"Something went wrong while voiding the payment.","Something went wrong while voiding the payment."
+"Something went wrong while refunding the payment.","Something went wrong while refunding the payment."
+"You have reached the maximum number of credit cards ' 'allowed to be used for the payment.","You have reached the maximum number of credit cards ' 'allowed to be used for the payment."
+"Something went wrong while authorizing the partial payment.","Something went wrong while authorizing the partial payment."
+"Something went wrong in the payment gateway.","Something went wrong in the payment gateway."
+"Gateway error: %1","Gateway error: %1"
+"Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s).","Gateway actions are locked because the gateway cannot complete ' 'one or more of the transactions. ' 'Please log in to your Authorize.Net account to manually resolve the issue(s)."
+"Payment updating error.",支付更新错误。
+"Authorize Only",仅供授权
+"Authorize and Capture",授权和捕获
+"Invalid amount for capture.",获取的额度无效。
+"Payment capturing error.",支付捕获出错。
+"Invalid transaction ID.","Invalid transaction ID."
+"Payment voiding error.",支付的作废出错。
+"Invalid amount for refund.",退款额度无效。
+"Payment refunding error.",支付的退款出错。
+"The transaction was declined because the response hash validation failed.","The transaction was declined because the response hash validation failed."
+"This payment didn't work out because we can't find this order.","This payment didn't work out because we can't find this order."
+"There was a payment authorization error.","There was a payment authorization error."
+"This payment was not authorized because the transaction ID field is empty.","This payment was not authorized because the transaction ID field is empty."
+"Amount of %1 approved by payment gateway. Transaction ID: ""%2"".","Amount of %1 approved by payment gateway. Transaction ID: ""%2""."
+"Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again.","Something went wrong: the paid amount doesn't match the order amount. Please correct this and try again."
+"Credit Card Type",信用卡类型
+"Credit Card Number",信用卡号码
+"Expiration Date",过期日期
+"Card Verification Number",卡片验证号码
+"Click ""Cancel"" to remove any pending status and release money already processed during this payment.","Click ""Cancel"" to remove any pending status and release money already processed during this payment."
+"Please enter a different credit card number to complete your purchase.","Please enter a different credit card number to complete your purchase."
+"Credit Card %1","Credit Card %1"
+"Credit Card Information",信用卡信息
+"--Please Select--","-- 请选择 --"
+"Card Verification Number Visual Reference","信用卡验证号码 视觉参考"
+"What is this?",这是什么?
+"You'll be asked for your payment details before placing an order.","You'll be asked for your payment details before placing an order."
+"To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel.","To cancel pending authorizations and release amounts that have already been processed during this payment, click Cancel."
+Processing...,Processing...
+Enabled,Enabled
+"Sort Order","Sort Order"
+Title,Title
+"3D Secure Card Validation","3D Secure Card Validation"
+"New Order Status","New Order Status"
+"No confirmation","No confirmation"
+Authorize.net,Authorize.net
+"Credit Card Types","Credit Card Types"
+"Credit Card Verification","Credit Card Verification"
+"Email Customer","Email Customer"
+"API Login ID","API Login ID"
+"Merchant's Email","Merchant's Email"
+"Test Mode","Test Mode"
+Debug,Debug
+"Transaction Key","Transaction Key"
+"Payment Action","Payment Action"
+"Accepted Currency","Accepted Currency"
+"Payment from Applicable Countries","Payment from Applicable Countries"
+"Payment from Specific Countries","Payment from Specific Countries"
+"Minimum Order Total","Minimum Order Total"
+"Maximum Order Total","Maximum Order Total"
+"Allow Partial Authorization","Allow Partial Authorization"
+"3D Secure","3D Secure"
+"Severe 3D Secure Card Validation","Severe 3D Secure Card Validation"
+"Severe Validation Removes Chargeback Liability on Merchant","Severe Validation Removes Chargeback Liability on Merchant"
+"If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement.","If you leave this empty, we'll use a default value. The custom URL may be provided by CardinalCommerce agreement."
+"Authorize.net Direct Post","Authorize.net Direct Post"
+"Merchant MD5","Merchant MD5"
+"Gateway URL","Gateway URL"
diff --git a/app/code/Magento/Authorizenet/view/adminhtml/layout/adminhtml_authorizenet_directpost_payment_redirect.xml b/app/code/Magento/Authorizenet/view/adminhtml/layout/adminhtml_authorizenet_directpost_payment_redirect.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d3f5ec48384034f36aa8c7efd3633a558306ad05
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/adminhtml/layout/adminhtml_authorizenet_directpost_payment_redirect.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd">
+    <container name="root" label="Root">
+        <block class="Magento\Authorizenet\Block\Transparent\Iframe" name="authorizenet_directpost_iframe" template="Magento_Authorizenet::directpost/iframe.phtml"/>
+    </container>
+</layout>
diff --git a/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_create_index.xml b/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_create_index.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e14a5a03af11b804644abacbdff9cd89f198d96e
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_create_index.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="order_create_billing_form">
+            <action method="setMethodFormTemplate">
+                <argument name="method" xsi:type="string">authorizenet_directpost</argument>
+                <argument name="template" xsi:type="string">Magento_Authorizenet::directpost/info.phtml</argument>
+            </action>
+        </referenceBlock>
+    </body>
+</page>
\ No newline at end of file
diff --git a/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_create_load_block_billing_method.xml b/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_create_load_block_billing_method.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b3451c3c683a9ca23aef5cdae81ca29a4f40f83e
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_create_load_block_billing_method.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="order.create.billing.method.form">
+            <action method="setMethodFormTemplate">
+                <argument name="method" xsi:type="string">authorizenet_directpost</argument>
+                <argument name="template" xsi:type="string">Magento_Authorizenet::directpost/info.phtml</argument>
+            </action>
+        </referenceBlock>
+    </body>
+</page>
\ No newline at end of file
diff --git a/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_view.xml b/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0c44217a8700e8a60aa1f1073c843d7698e1f5ce
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/adminhtml/layout/sales_order_view.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceContainer name="payment_additional_info">
+            <block class="Magento\Authorizenet\Block\Adminhtml\Order\View\Info\FraudDetails" name="authorizenet_fraud_details" template="Magento_Authorizenet::order/view/info/fraud_details.phtml" />
+        </referenceContainer>
+    </body>
+</page>
diff --git a/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/iframe.phtml b/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/iframe.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..23c1438d777bcde85fb5a5a6ed7b5e46e4ff7a6d
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/iframe.phtml
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+
+/**
+ * @var $block \Magento\Authorizenet\Block\Transparent\Iframe
+ */
+$params = $block->getParams();
+$helper = $block->getHelper('adminhtml');
+?>
+<html>
+    <head>
+        <script>
+        <?php if (isset($params['redirect'])): ?>
+            window.location="<?php echo $block->escapeUrl($params['redirect']) ?>";
+        <?php endif; ?>
+        <?php if (isset($params['redirect_parent'])): ?>
+            window.top.location="<?php echo $block->escapeUrl($params['redirect_parent']) ?>";
+        <?php endif; ?>
+        <?php if (isset($params['error_msg'])): ?>
+            window.top.directPostModel.showError(<?php echo json_encode((array)$params['error_msg']) ?>);
+            <?php if (isset($params['x_invoice_num'])): ?>
+                window.top.directPostModel.successUrl="<?php echo $helper->getSuccessOrderUrl($params) ?>";
+            <?php endif; ?>
+        <?php endif; ?>
+        </script>
+    </head>
+    <body></body>
+</html>
diff --git a/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml b/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..586d6ff403ebc616325ea6ac206ae963233cf3bb
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/adminhtml/templates/directpost/info.phtml
@@ -0,0 +1,119 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+
+/**
+ * @see \Magento\Authorizenet\Block\Directpost\Form
+ */
+?>
+<?php
+$_form = $block;
+$_code = $_form->getMethodCode();
+$_method = $_form->getMethod();
+$_controller = $block->getRequest()->getControllerName();
+$_orderUrl = $this->helper('Magento\Authorizenet\Helper\Backend\Data')->getPlaceOrderAdminUrl();
+?>
+<!-- IFRAME for request to our server -->
+<iframe id="order-directpost-iframe" allowtransparency="true" frameborder="0" name="iframeSubmitOrder" style="display:none;width:100%;background-color:transparent" src="<?php echo $block->getViewFileUrl('blank.html') ?>"></iframe>
+<!-- IFRAME for request to Authorize.net -->
+<iframe id="directpost-iframe" allowtransparency="true" frameborder="0"  name="iframeDirectPost" style="display:none;width:100%;background-color:transparent" src="<?php echo $block->getViewFileUrl('blank.html') ?>"></iframe>
+<fieldset class="admin__fieldset payment-method" id="payment_form_<?php echo $_code ?>" style="display:none;">
+    <div class="admin__field _required">
+        <label for="<?php echo $_code ?>_cc_type"
+               class="admin__field-label"><span><?php echo __('Credit Card Type') ?></span></label>
+        <div class="admin__field-control">
+            <select id="<?php echo $_code ?>_cc_type"
+                    name="payment[cc_type]"
+                    class="required-entry validate-cc-type-select admin__control-select">
+                <?php $_ccType = $_form->getInfoData('cc_type') ?>
+                <option value=""></option>
+                <?php foreach ($_form->getCcAvailableTypes() as $_typeCode => $_typeName): ?>
+                    <option value="<?php echo $_typeCode ?>"
+                            <?php if ($_typeCode == $_ccType): ?>selected="selected"<?php endif ?>><?php echo $_typeName ?></option>
+                <?php endforeach ?>
+            </select>
+        </div>
+    </div>
+    <div class="admin__field _required">
+        <label for="<?php echo $_code ?>_cc_number"
+               class="admin__field-label"><span><?php echo __('Credit Card Number') ?></span></label>
+
+        <div class="admin__field-control">
+            <input type="text" id="<?php echo $_code ?>_cc_number"
+                   name="payment[cc_number]"
+                   class="input-text required-entry validate-cc-number admin__control-text"
+                   value="<?php echo $block->getInfoData('cc_number') ?>"/>
+        </div>
+    </div>
+    <div class="admin__field _required">
+        <label for="<?php echo $_code ?>_expiration"
+               class="admin__field-label"><span><?php echo __('Expiration Date') ?></span></label>
+
+        <div class="admin__field-control">
+            <select id="<?php echo $_code ?>_expiration"
+                    name="payment[cc_exp_month]"
+                    class="validate-cc-exp required-entry admin__control-select admin__control-select-month">
+                <?php $_ccExpMonth = $_form->getInfoData('cc_exp_month') ?>
+                <?php foreach ($_form->getCcMonths() as $k => $v): ?>
+                    <option value="<?php echo $k ?>"
+                            <?php if ($k == $_ccExpMonth): ?>selected="selected"<?php endif ?>><?php echo $v ?></option>
+                <?php endforeach ?>
+            </select>
+            <?php $_ccExpYear = $_form->getInfoData('cc_exp_year') ?>
+            <select id="<?php echo $_code ?>_expiration_yr"
+                    name="payment[cc_exp_year]"
+                    class="required-entry admin__control-select admin__control-select-year">
+                <?php foreach ($_form->getCcYears() as $k => $v): ?>
+                    <option value="<?php echo $k ? $k : '' ?>"
+                            <?php if ($k == $_ccExpYear): ?>selected="selected"<?php endif ?>><?php echo $v ?></option>
+                <?php endforeach ?>
+            </select>
+        </div>
+    </div>
+    <?php if ($_form->hasVerification()): ?>
+    <div class="admin__field _required">
+        <label for="<?php echo $_code ?>_cc_cid"><span><?php echo __('Card Verification Number') ?></span></label>
+
+        <div class="admin__field-control">
+            <input type="text"
+                   class="required-entry input-text validate-cc-cvn admin__control-text"
+                   id="<?php echo $_code ?>_cc_cid" name="payment[cc_cid]"
+                   value="<?php echo $block->getInfoData('cc_cid') ?>"/>
+        </div>
+    </div>
+    <?php endif; ?>
+</fieldset>
+<script>
+    require([
+        'prototype',
+        'Magento_Sales/order/create/scripts',
+        "Magento_Sales/order/create/form",
+        'Magento_Authorizenet/js/direct-post'
+    ], function(){
+
+        /**
+         * Disable card server validation in admin
+         */
+        order.addExcludedPaymentMethod('<?php echo $_code ?>');
+
+        <?php if (!$block->isAjaxRequest()): ?>
+            document.observe('dom:loaded', function(){
+        <?php endif; ?>
+
+        directPostModel = new directPost(
+            '<?php echo $_code ?>',
+            'directpost-iframe',
+            '<?php echo $_controller ?>',
+            '<?php echo $_orderUrl ?>',
+            '<?php echo $_method->getCgiUrl() ?>',
+            '<?php echo $block->getUrl('*/*/save', ['_secure' => $block->getRequest()->isSecure()]) ?>');
+
+        <?php if (!$block->isAjaxRequest()): ?>
+            });
+        <?php endif; ?>
+    });
+</script>
diff --git a/app/code/Magento/Authorizenet/view/adminhtml/templates/order/view/info/fraud_details.phtml b/app/code/Magento/Authorizenet/view/adminhtml/templates/order/view/info/fraud_details.phtml
new file mode 100644
index 0000000000000000000000000000000000000000..90a39448fa2eac25190faa11be159c1b6b12bb97
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/adminhtml/templates/order/view/info/fraud_details.phtml
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+// @codingStandardsIgnoreFile
+?>
+
+<?php $payment = $block->getPayment() ?>
+<?php $fraudDetails = $payment->getAdditionalInformation('fraud_details') ?>
+
+<?php if (!empty($fraudDetails)): ?>
+    <div class="admin__page-section-item-title">
+        <span class="title"><?php echo __('Fraud Detection ') ?></span>
+    </div>
+
+    <div class="admin__page-section-item-content">
+        <div class="order-payment-additional">
+            <?php if(!empty($fraudDetails['fds_filter_action'])): ?>
+                <?php echo __('FDS Filter Action') ?>: <?php echo $fraudDetails['fds_filter_action'] ?></br>
+            <?php endif; ?>
+
+            <?php if(!empty($fraudDetails['avs_response'])): ?>
+                <?php echo __('AVS Response') ?>: <?php echo $fraudDetails['avs_response'] ?></br>
+            <?php endif; ?>
+
+            <?php if(!empty($fraudDetails['card_code_response'])): ?>
+                <?php echo __('Card Code Response') ?>: <?php echo $fraudDetails['card_code_response'] ?></br>
+            <?php endif; ?>
+
+            <?php if(!empty($fraudDetails['cavv_response']) || ($fraudDetails['cavv_response'] === 0)): ?>
+                <?php echo __('CAVV Response') ?>: <?php echo $fraudDetails['cavv_response'] ?></br>
+            <?php endif; ?>
+
+            <?php if(!empty($fraudDetails['fraud_filters'])): ?>
+                <b><?php echo __('Fraud Filters') ?>:</b></br>
+                <?php foreach($fraudDetails['fraud_filters'] as $filter): ?>
+                    <?php echo $filter['name'] ?>: <?php echo $filter['action'] ?></br>
+                <?php endforeach; ?>
+            <?php endif; ?>
+        </div>
+    </div>
+<?php endif; ?>
\ No newline at end of file
diff --git a/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js b/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js
new file mode 100644
index 0000000000000000000000000000000000000000..d6423db943e1eb5ad55bae6d7a3c61a8d27a6987
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js
@@ -0,0 +1,426 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+(function (factory) {
+    if (typeof define === 'function' && define.amd) {
+        define([
+            "jquery",
+            "mage/backend/validation",
+            "prototype"
+        ], factory);
+    } else {
+        factory(jQuery);
+    }
+}(function (jQuery) {
+
+window.directPost = Class.create();
+directPost.prototype = {
+    initialize : function(methodCode, iframeId, controller, orderSaveUrl, cgiUrl, nativeAction) {
+        var prepare = function (event, method) {
+            if (method === 'authorizenet_directpost') {
+                this.preparePayment();
+            }
+        };
+        this.iframeId = iframeId;
+        this.controller = controller;
+        this.orderSaveUrl = orderSaveUrl;
+        this.nativeAction = nativeAction;
+        this.cgiUrl = cgiUrl;
+        this.code = methodCode;
+        this.inputs = ['cc_type', 'cc_number', 'expiration', 'expiration_yr', 'cc_cid'];
+        this.headers = [];
+        this.isValid = true;
+        this.paymentRequestSent = false;
+        this.isResponse = false;
+        this.orderIncrementId = false;
+        this.successUrl = false;
+        this.hasError = false;
+        this.tmpForm = false;
+
+        this.onSaveOnepageOrderSuccess = this.saveOnepageOrderSuccess.bindAsEventListener(this);
+        this.onLoadIframe = this.loadIframe.bindAsEventListener(this);
+        this.onLoadOrderIframe = this.loadOrderIframe.bindAsEventListener(this);
+        this.onSubmitAdminOrder = this.submitAdminOrder.bindAsEventListener(this);
+
+        jQuery('#edit_form').on('changePaymentMethod', prepare.bind(this));
+
+        jQuery('#edit_form').trigger(
+            'changePaymentMethod',
+            [
+                jQuery('#edit_form').find(':radio[name="payment[method]"]:checked').val()
+            ]
+        );
+    },
+
+    validate : function() {
+        this.isValid = true;
+        this.inputs.each(function(elemIndex) {
+            if ($(this.code + '_' + elemIndex)) {
+                if (!jQuery.validator.validateElement($(this.code + '_' + elemIndex))) {
+                    this.isValid = false;
+                }
+            }
+        }, this);
+
+        return this.isValid;
+    },
+
+    changeInputOptions : function(param, value) {
+        this.inputs.each(function(elemIndex) {
+            if ($(this.code + '_' + elemIndex)) {
+                $(this.code + '_' + elemIndex).writeAttribute(param, value);
+            }
+        }, this);
+    },
+
+    preparePayment : function() {
+        this.changeInputOptions('autocomplete', 'off');
+        jQuery('#edit_form')
+            .off('submitOrder')
+            .on('submitOrder', this.submitAdminOrder.bind(this));
+        if ($(this.iframeId)) {
+            switch (this.controller) {
+                case 'onepage':
+                    this.headers = $$('#' + checkout.accordion.container.readAttribute('id') + ' .section');
+                    var button = $('review-buttons-container').down('button');
+                    button.writeAttribute('onclick', '');
+                    button.stopObserving('click');
+                    button.observe('click', function() {
+                        if ($(this.iframeId)) {
+                            if (this.validate()) {
+                                this.saveOnepageOrder();
+                            }
+                        } else {
+                            review.save();
+                        }
+                    }.bind(this));
+                    break;
+                case 'order_create':
+                case 'order_edit':
+                    // Temporary solution will be removed after refactoring Authorize.Net (sales) functionality
+                    jQuery('.scalable.save:not(disabled)').removeAttr('onclick');
+                    jQuery(document).off('click.directPost');
+                    jQuery(document).on(
+                        'click.directPost',
+                        '.scalable.save:not(disabled)',
+                        jQuery.proxy(this.onSubmitAdminOrder, this)
+                    );
+
+                    $('order-' + this.iframeId).observe('load', this.onLoadOrderIframe);
+                    break;
+            }
+
+            $(this.iframeId).observe('load', this.onLoadIframe);
+        }
+    },
+
+    loadIframe : function() {
+        if (this.paymentRequestSent) {
+            switch (this.controller) {
+                case 'onepage':
+                    this.paymentRequestSent = false;
+                    if (!this.hasError) {
+                        this.returnQuote();
+                    }
+                    break;
+                case 'order_edit':
+                case 'order_create':
+                    if (!this.orderRequestSent) {
+                        this.paymentRequestSent = false;
+                        if (!this.hasError) {
+                            this.returnQuote();
+                        } else {
+                            this.changeInputOptions('disabled', false);
+                            jQuery('body').trigger('processStop');
+                            enableElements('save');
+                        }
+                    }
+                    break;
+            }
+            if (this.tmpForm) {
+                document.body.removeChild(this.tmpForm);
+            }
+        }
+    },
+
+    loadOrderIframe : function() {
+        if (this.orderRequestSent) {
+            $(this.iframeId).hide();
+            var data = $('order-' + this.iframeId).contentWindow.document.body.getElementsByTagName('pre')[0].innerHTML;
+            this.saveAdminOrderSuccess(data);
+            this.orderRequestSent = false;
+        }
+    },
+
+    showError : function(msg) {
+        this.hasError = true;
+        if (this.controller == 'onepage') {
+            $(this.iframeId).hide();
+            this.resetLoadWaiting();
+        }
+        alert(msg);
+    },
+
+    returnQuote : function() {
+        var url = this.orderSaveUrl.replace('place', 'returnQuote');
+        new Ajax.Request(url, {
+            onSuccess : function(transport) {
+                try {
+                    response = eval('(' + transport.responseText + ')');
+                } catch (e) {
+                    response = {};
+                }
+                if (response.error_message) {
+                    alert(response.error_message);
+                }
+                $(this.iframeId).show();
+                switch (this.controller) {
+                    case 'onepage':
+                        this.resetLoadWaiting();
+                        break;
+                    case 'order_edit':
+                    case 'order_create':
+                        this.changeInputOptions('disabled', false);
+                        jQuery('body').trigger('processStop');
+                        enableElements('save');
+                        break;
+                }
+            }.bind(this)
+        });
+    },
+
+    setLoadWaiting : function() {
+        this.headers.each(function(header) {
+            header.removeClassName('allow');
+        });
+        checkout.setLoadWaiting('review');
+    },
+
+    resetLoadWaiting : function() {
+        this.headers.each(function(header) {
+            header.addClassName('allow');
+        });
+        checkout.setLoadWaiting(false);
+    },
+
+    saveOnepageOrder : function() {
+        this.hasError = false;
+        this.setLoadWaiting();
+        var params = Form.serialize(payment.form);
+        if (review.agreementsForm) {
+            params += '&' + Form.serialize(review.agreementsForm);
+        }
+        params += '&controller=' + this.controller;
+        new Ajax.Request(this.orderSaveUrl, {
+            method : 'post',
+            parameters : params,
+            onComplete : this.onSaveOnepageOrderSuccess,
+            onFailure : function(transport) {
+                this.resetLoadWaiting();
+                if (transport.status == 403) {
+                    checkout.ajaxFailure();
+                }
+            }
+        });
+    },
+
+    saveOnepageOrderSuccess : function(transport) {
+        if (transport.status == 403) {
+            checkout.ajaxFailure();
+        }
+        try {
+            response = eval('(' + transport.responseText + ')');
+        } catch (e) {
+            response = {};
+        }
+
+        if (response.success && response.directpost) {
+            this.orderIncrementId = response.directpost.fields.x_invoice_num;
+            var paymentData = {};
+            for ( var key in response.directpost.fields) {
+                paymentData[key] = response.directpost.fields[key];
+            }
+            var preparedData = this.preparePaymentRequest(paymentData);
+            this.sendPaymentRequest(preparedData);
+        } else {
+            var msg = response.error_messages;
+            if (typeof (msg) == 'object') {
+                msg = msg.join("\n");
+            }
+            if (msg) {
+                alert(msg);
+            }
+
+            if (response.update_section) {
+                $('checkout-' + response.update_section.name + '-load').replace(response.update_section.html);
+                response.update_section.html.evalScripts();
+            }
+
+            if (response.goto_section) {
+                checkout.gotoSection(response.goto_section);
+                checkout.reloadProgressBlock();
+            }
+        }
+    },
+
+    submitAdminOrder : function() {
+        // Temporary solution will be removed after refactoring Authorize.Net (sales) functionality
+        var editForm = jQuery('#edit_form');
+        if (editForm.valid()) {
+            // Temporary solution will be removed after refactoring Authorize.Net (sales) functionality
+            paymentMethodEl = editForm.find(':radio[name="payment[method]"]:checked');
+            this.hasError = false;
+            if (paymentMethodEl.val() == this.code) {
+                jQuery('body').trigger('processStart');
+                setLoaderPosition();
+                this.changeInputOptions('disabled', 'disabled');
+                this.paymentRequestSent = true;
+                this.orderRequestSent = true;
+                // Temporary solutions will be removed after refactoring Authorize.Net (sales) functionality
+                editForm.attr('action', this.orderSaveUrl);
+                editForm.attr('target',
+                        jQuery('#order-' + this.iframeId).attr('name'));
+                editForm.append(this.createHiddenElement('controller', this.controller));
+                disableElements('save');
+                // Temporary solutions will be removed after refactoring Authorize.Net (sales) functionality
+                order._realSubmit();
+            } else {
+                editForm.attr('action', this.nativeAction);
+                editForm.attr('target', '_top');
+                disableElements('save');
+                // Temporary solutions will be removed after refactoring Authorize.Net (sales) functionality
+                order._realSubmit();
+            }
+        }
+    },
+
+    recollectQuote : function() {
+        var area = [ 'sidebar', 'items', 'shipping_method', 'billing_method', 'totals', 'giftmessage' ];
+        area = order.prepareArea(area);
+        var url = order.loadBaseUrl + 'block/' + area;
+        var info = $('order-items_grid').select('input', 'select', 'textarea');
+        var data = {};
+        for ( var i = 0; i < info.length; i++) {
+            if (!info[i].disabled && (info[i].type != 'checkbox' || info[i].checked)) {
+                data[info[i].name] = info[i].getValue();
+            }
+        }
+        data.reset_shipping = true;
+        data.update_items = true;
+        if ($('coupons:code') && $F('coupons:code')) {
+            data['order[coupon][code]'] = $F('coupons:code');
+        }
+        data.json = true;
+        new Ajax.Request(url, {
+            parameters : data,
+            loaderArea : 'html-body',
+            onSuccess : function(transport) {
+                jQuery('#edit_form').submit();
+            }.bind(this)
+        });
+
+    },
+
+    saveAdminOrderSuccess : function(data) {
+        try {
+            response = eval('(' + data + ')');
+        } catch (e) {
+            response = {};
+        }
+
+        if (response.directpost) {
+            this.orderIncrementId = response.directpost.fields.x_invoice_num;
+            var paymentData = {};
+            for ( var key in response.directpost.fields) {
+                paymentData[key] = response.directpost.fields[key];
+            }
+            var preparedData = this.preparePaymentRequest(paymentData);
+            this.sendPaymentRequest(preparedData);
+        } else {
+            if (response.redirect) {
+                window.location = response.redirect;
+            }
+            if (response.error_messages) {
+                var msg = response.error_messages;
+                if (typeof (msg) == 'object') {
+                    msg = msg.join("\n");
+                }
+                if (msg) {
+                    alert(msg);
+                }
+            }
+        }
+    },
+
+    preparePaymentRequest : function(data) {
+        if ($(this.code + '_cc_cid')) {
+            data.x_card_code = $(this.code + '_cc_cid').value;
+        }
+        var year = $(this.code + '_expiration_yr').value;
+        if (year.length > 2) {
+            year = year.substring(2);
+        }
+        var month = parseInt($(this.code + '_expiration').value, 10);
+        if (month < 10) {
+            month = '0' + month;
+        }
+
+        data.x_exp_date = month + '/' + year;
+        data.x_card_num = $(this.code + '_cc_number').value;
+
+        return data;
+    },
+
+    sendPaymentRequest : function(preparedData) {
+        this.recreateIframe();
+        this.tmpForm = document.createElement('form');
+        this.tmpForm.style.display = 'none';
+        this.tmpForm.enctype = 'application/x-www-form-urlencoded';
+        this.tmpForm.method = 'POST';
+        document.body.appendChild(this.tmpForm);
+        this.tmpForm.action = this.cgiUrl;
+        this.tmpForm.target = $(this.iframeId).readAttribute('name');
+        this.tmpForm.setAttribute('target', $(this.iframeId).readAttribute('name'));
+
+        for ( var param in preparedData) {
+            this.tmpForm.appendChild(this.createHiddenElement(param, preparedData[param]));
+        }
+
+        this.paymentRequestSent = true;
+        this.tmpForm.submit();
+    },
+
+    createHiddenElement : function(name, value) {
+        var field;
+        if (isIE) {
+            field = document.createElement('input');
+            field.setAttribute('type', 'hidden');
+            field.setAttribute('name', name);
+            field.setAttribute('value', value);
+        } else {
+            field = document.createElement('input');
+            field.type = 'hidden';
+            field.name = name;
+            field.value = value;
+        }
+
+        return field;
+    },
+
+    recreateIframe : function() {
+        if ($(this.iframeId)) {
+            var nextElement = $(this.iframeId).next();
+            var src = $(this.iframeId).readAttribute('src');
+            var name = $(this.iframeId).readAttribute('name');
+            $(this.iframeId).stopObserving();
+            $(this.iframeId).remove();
+            var iframe = '<iframe id="' + this.iframeId +
+                '" allowtransparency="true" frameborder="0"  name="' + name +
+                '" style="display:none;width:100%;background-color:transparent" src="' + src + '" />';
+            Element.insert(nextElement, {'before':iframe});
+            $(this.iframeId).observe('load', this.onLoadIframe);
+        }
+    }
+};
+}));
\ No newline at end of file
diff --git a/app/code/Magento/Authorizenet/view/frontend/layout/authorizenet_directpost_payment_backendresponse.xml b/app/code/Magento/Authorizenet/view/frontend/layout/authorizenet_directpost_payment_backendresponse.xml
new file mode 100644
index 0000000000000000000000000000000000000000..affaef4af2b27ce3189fd1cf8a8ae16e16f499c9
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/frontend/layout/authorizenet_directpost_payment_backendresponse.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd">
+    <container name="root">
+        <block class="Magento\Payment\Block\Transparent\Iframe" name="authorizenet_directpost_iframe" template="Magento_Payment::transparent/iframe.phtml"/>
+    </container>
+</layout>
diff --git a/app/code/Magento/Authorizenet/view/frontend/layout/authorizenet_directpost_payment_redirect.xml b/app/code/Magento/Authorizenet/view/frontend/layout/authorizenet_directpost_payment_redirect.xml
new file mode 100644
index 0000000000000000000000000000000000000000..affaef4af2b27ce3189fd1cf8a8ae16e16f499c9
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/frontend/layout/authorizenet_directpost_payment_redirect.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd">
+    <container name="root">
+        <block class="Magento\Payment\Block\Transparent\Iframe" name="authorizenet_directpost_iframe" template="Magento_Payment::transparent/iframe.phtml"/>
+    </container>
+</layout>
diff --git a/app/code/Magento/Authorizenet/view/frontend/layout/authorizenet_directpost_payment_response.xml b/app/code/Magento/Authorizenet/view/frontend/layout/authorizenet_directpost_payment_response.xml
new file mode 100644
index 0000000000000000000000000000000000000000..affaef4af2b27ce3189fd1cf8a8ae16e16f499c9
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/frontend/layout/authorizenet_directpost_payment_response.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd">
+    <container name="root">
+        <block class="Magento\Payment\Block\Transparent\Iframe" name="authorizenet_directpost_iframe" template="Magento_Payment::transparent/iframe.phtml"/>
+    </container>
+</layout>
diff --git a/app/code/Magento/Authorizenet/view/frontend/layout/checkout_index_index.xml b/app/code/Magento/Authorizenet/view/frontend/layout/checkout_index_index.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c23121d30ce8e317dcb2054075501bd41a666c31
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/frontend/layout/checkout_index_index.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
+    <body>
+        <referenceBlock name="checkout.root">
+            <arguments>
+                <argument name="jsLayout" xsi:type="array">
+                    <item name="components" xsi:type="array">
+                        <item name="checkout" xsi:type="array">
+                            <item name="children" xsi:type="array">
+                                <item name="steps" xsi:type="array">
+                                    <item name="children" xsi:type="array">
+                                        <item name="billing-step" xsi:type="array">
+                                            <item name="component" xsi:type="string">uiComponent</item>
+                                            <item name="children" xsi:type="array">
+                                                <item name="payment" xsi:type="array">
+                                                    <item name="children" xsi:type="array">
+                                                        <item name="renders" xsi:type="array">
+                                                            <!-- merge payment method renders here -->
+                                                            <item name="children" xsi:type="array">
+                                                                <item name="authorizenet" xsi:type="array">
+                                                                    <item name="component" xsi:type="string">Magento_Authorizenet/js/view/payment/authorizenet</item>
+                                                                    <item name="methods" xsi:type="array">
+                                                                        <item name="authorizenet_directpost" xsi:type="array">
+                                                                            <item name="isBillingAddressRequired" xsi:type="boolean">true</item>
+                                                                        </item>
+                                                                    </item>
+                                                                </item>
+                                                            </item>
+                                                        </item>
+                                                    </item>
+                                                </item>
+                                            </item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                        </item>
+                    </item>
+                </argument>
+            </arguments>
+        </referenceBlock>
+    </body>
+</page>
\ No newline at end of file
diff --git a/app/code/Magento/Authorizenet/view/frontend/requirejs-config.js b/app/code/Magento/Authorizenet/view/frontend/requirejs-config.js
new file mode 100644
index 0000000000000000000000000000000000000000..0b6cd03c100c3dd5f7ccf0dbf9432eb1a5cfdd73
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/frontend/requirejs-config.js
@@ -0,0 +1,12 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+var config = {
+    map: {
+        '*': {
+            transparent: 'Magento_Payment/transparent'
+        }
+    }
+};
diff --git a/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/authorizenet.js b/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/authorizenet.js
new file mode 100644
index 0000000000000000000000000000000000000000..76bef231b5d0efb7bab07c82d91bc2ed41f7174a
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/authorizenet.js
@@ -0,0 +1,26 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'uiComponent',
+        'Magento_Checkout/js/model/payment/renderer-list'
+    ],
+    function (
+        Component,
+        rendererList
+    ) {
+        'use strict';
+        rendererList.push(
+            {
+                type: 'authorizenet_directpost',
+                component: 'Magento_Authorizenet/js/view/payment/method-renderer/authorizenet-directpost'
+            }
+        );
+        /** Add view logic here if needed */
+        return Component.extend({});
+    }
+);
\ No newline at end of file
diff --git a/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js b/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js
new file mode 100644
index 0000000000000000000000000000000000000000..5e56746fbe50a2476fc860c66b45c3c0003ac105
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/frontend/web/js/view/payment/method-renderer/authorizenet-directpost.js
@@ -0,0 +1,59 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+/*browser:true*/
+/*global define*/
+define(
+    [
+        'jquery',
+        'Magento_Payment/js/view/payment/iframe',
+        'Magento_Checkout/js/action/set-payment-information'
+    ],
+    function ($, Component, setPaymentInformationAction) {
+        'use strict';
+        return Component.extend({
+            defaults: {
+                template: 'Magento_Authorizenet/payment/authorizenet-directpost'
+            },
+            placeOrderHandler: null,
+            validateHandler: null,
+
+            setPlaceOrderHandler: function(handler) {
+                this.placeOrderHandler = handler;
+            },
+
+            setValidateHandler: function(handler) {
+                this.validateHandler = handler;
+            },
+
+            context: function() {
+                return this;
+            },
+
+            isShowLegend: function() {
+                return true;
+            },
+
+            getCode: function() {
+                return 'authorizenet_directpost';
+            },
+
+            isActive: function() {
+                return true;
+            },
+
+            placeOrder: function() {
+                var self = this;
+                if (this.validateHandler()) {
+                    this.isPlaceOrderActionAllowed(false);
+                    $.when(setPaymentInformationAction()).done(function() {
+                        self.placeOrderHandler();
+                    }).fail(function() {
+                        self.isPlaceOrderActionAllowed(true);
+                    });
+                }
+            }
+        });
+    }
+);
diff --git a/app/code/Magento/Authorizenet/view/frontend/web/template/payment/authorizenet-directpost.html b/app/code/Magento/Authorizenet/view/frontend/web/template/payment/authorizenet-directpost.html
new file mode 100644
index 0000000000000000000000000000000000000000..0ea2ebb85fe98034cba2fdc98a52e3c55d72eecc
--- /dev/null
+++ b/app/code/Magento/Authorizenet/view/frontend/web/template/payment/authorizenet-directpost.html
@@ -0,0 +1,70 @@
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<div class="payment-method" data-bind="css: {'_active': (getCode() == isChecked())}">
+    <div class="payment-method-title field choice">
+        <input type="radio"
+               name="payment[method]"
+               class="radio"
+               data-bind="attr: {'id': getCode()}, value: getCode(), checked: isChecked, click: selectPaymentMethod, visible: isRadioButtonVisible()" />
+        <label data-bind="attr: {'for': getCode()}" class="label">
+            <span data-bind="text: getTitle()"></span>
+        </label>
+    </div>
+    <div class="payment-method-content">
+        <div class="payment-method-billing-address">
+            <!-- ko foreach: $parent.getRegion(getBillingAddressFormName()) -->
+            <!-- ko template: getTemplate() --><!-- /ko -->
+            <!--/ko-->
+        </div>
+        <iframe width="0"
+                height="0"
+                data-bind="src: getSource(), attr: {id: getCode() + '-transparent-iframe', 'data-container': getCode() + '-transparent-iframe'}"
+                allowtransparency="true"
+                frameborder="0"
+                name="iframeTransparent"
+                style="display:none;width:100%;background-color:transparent">
+
+        </iframe>
+        <form class="form" id="co-transparent-form" action="#" method="post" data-bind="mageInit: {
+            'transparent':{
+                'context': context(),
+                'controller': getControllerName(),
+                'gateway': getCode(),
+                'orderSaveUrl':getPlaceOrderUrl(),
+                'cgiUrl': getCgiUrl(),
+                'dateDelim': getDateDelim(),
+                'cardFieldsMap': getCardFieldsMap(),
+                'nativeAction': getSaveOrderUrl()
+            }, 'validation':[]}">
+
+            <!-- ko template: 'Magento_Payment/payment/cc-form' --><!-- /ko -->
+
+            <div class="checkout-agreements-block">
+                <!-- ko foreach: $parent.getRegion('before-place-order') -->
+                    <!-- ko template: getTemplate() --><!-- /ko -->
+                <!--/ko-->
+            </div>
+
+            <div class="actions-toolbar">
+                <div class="primary">
+                    <button data-role="review-save"
+                            type="submit"
+                            data-bind="
+                            attr: {title: $t('Place order')},
+                            enable: (getCode() == isChecked()),
+                            click: placeOrder,
+                            css: {disabled: !isPlaceOrderActionAllowed()}
+                            "
+                            class="action primary checkout"
+                            disabled>
+                        <span data-bind="text: $t('Place order')"></span>
+                    </button>
+                </div>
+            </div>
+        </form>
+    </div>
+</div>
diff --git a/app/code/Magento/Captcha/Test/Unit/Model/Cart/ConfigPluginTest.php b/app/code/Magento/Captcha/Test/Unit/Model/Cart/ConfigPluginTest.php
index 2761a141c17682c89e126c07c3047b24f78da4fb..be94382ea2ab37ece92018a4738439fd998601d0 100644
--- a/app/code/Magento/Captcha/Test/Unit/Model/Cart/ConfigPluginTest.php
+++ b/app/code/Magento/Captcha/Test/Unit/Model/Cart/ConfigPluginTest.php
@@ -43,4 +43,4 @@ class ConfigPluginTest extends \PHPUnit_Framework_TestCase
 
         $this->assertEquals($expectedResult, $this->model->afterGetConfig($sidebarMock, $resultMock));
     }
-}
\ No newline at end of file
+}
diff --git a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
index 0f51c233b4946ece7747e1f7744593dffc46fdc2..02898a8e87fff11dbfb6607fd39224bcdf9d3395 100644
--- a/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
+++ b/app/code/Magento/Catalog/view/frontend/web/js/catalog-add-to-cart.js
@@ -4,8 +4,9 @@
  */
 define([
     'jquery',
+    'mage/translate',
     'jquery/ui'
-], function($) {
+], function($, $t) {
     "use strict";
 
     $.widget('mage.catalogAddToCart', {
@@ -16,7 +17,13 @@ define([
             bindSubmit: true,
             minicartSelector: '[data-block="minicart"]',
             messagesSelector: '[data-placeholder="messages"]',
-            productStatusSelector: '.stock.available'
+            productStatusSelector: '.stock.available',
+            addToCartButtonSelector: '.action.tocart',
+            addToCartButtonDisabledClass: 'disabled',
+            addToCartButtonTextWhileAdding: $t('Adding...'),
+            addToCartButtonTextAdded: $t('Added'),
+            addToCartButtonTextDefault: $t('Add to Cart')
+
         },
 
         _create: function() {
@@ -49,6 +56,9 @@ define([
 
         ajaxSubmit: function(form) {
             var self = this;
+            $(self.options.minicartSelector).trigger('contentLoading');
+            self.disableAddToCartButton(form);
+
             $.ajax({
                 url: form.attr('action'),
                 data: form.serialize(),
@@ -82,8 +92,30 @@ define([
                             .find('span')
                             .html(res.product.statusText);
                     }
+                    self.enableAddToCartButton(form);
                 }
             });
+        },
+
+        disableAddToCartButton: function(form) {
+            var addToCartButton = $(form).find(this.options.addToCartButtonSelector);
+            addToCartButton.addClass(this.options.addToCartButtonDisabledClass);
+            addToCartButton.attr('title', this.options.addToCartButtonTextWhileAdding);
+            addToCartButton.find('span').text(this.options.addToCartButtonTextWhileAdding);
+        },
+
+        enableAddToCartButton: function(form) {
+            var self = this,
+                addToCartButton = $(form).find(this.options.addToCartButtonSelector);
+
+            addToCartButton.find('span').text(this.options.addToCartButtonTextAdded);
+            addToCartButton.attr('title', this.options.addToCartButtonTextAdded);
+
+            setTimeout(function() {
+                addToCartButton.removeClass(self.options.addToCartButtonDisabledClass);
+                addToCartButton.find('span').text(self.options.addToCartButtonTextDefault);
+                addToCartButton.attr('title', self.options.addToCartButtonTextDefault);
+            }, 1000);
         }
     });
 
diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
index 87e3cb28ec78d1a76ba7610d7e252324a6d24a47..2c07db0239885e4db5118a56b38fed1b411eea64 100644
--- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
+++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
@@ -109,7 +109,6 @@ class ShippingInformationManagement implements \Magento\Checkout\Api\ShippingInf
         $this->validateQuote($quote);
 
         $saveInAddressBook = $address->getSaveInAddressBook() ? 1 : 0;
-        $sameAsBilling = $address->getSameAsBilling() ? 1 : 0;
         $customerAddressId = $address->getCustomerAddressId();
         $this->addressValidator->validate($address);
         $quote->setShippingAddress($address);
@@ -119,7 +118,7 @@ class ShippingInformationManagement implements \Magento\Checkout\Api\ShippingInf
             $addressData = $this->addressRepository->getById($customerAddressId);
             $address = $quote->getShippingAddress()->importCustomerAddressData($addressData);
         }
-        $address->setSameAsBilling($sameAsBilling);
+
         $address->setSaveInAddressBook($saveInAddressBook);
         $address->setCollectShippingRates(true);
 
@@ -169,9 +168,12 @@ class ShippingInformationManagement implements \Magento\Checkout\Api\ShippingInf
     }
 
     /**
+     * Validate quote
+     *
      * @param \Magento\Quote\Model\Quote $quote
      * @throws InputException
      * @throws NoSuchEntityException
+     * @return void
      */
     protected function validateQuote(\Magento\Quote\Model\Quote $quote)
     {
diff --git a/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml b/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml
index 6d08bcb4bbf500ef2f823c46e8074640099f07d6..6f05b3b6a4cb503f6a2d41087fa9cffa574da053 100644
--- a/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml
+++ b/app/code/Magento/Checkout/view/frontend/templates/cart/minicart.phtml
@@ -9,12 +9,12 @@
 /** @var $block \Magento\Checkout\Block\Cart\Sidebar */
 ?>
 
-<div data-block="minicart" class="minicart-wrapper" >
+<div data-block="minicart" class="minicart-wrapper">
     <a class="action showcart" href="<?php echo $block->getShoppingCartUrl(); ?>"
        data-bind="scope: 'minicart_content'">
         <span class="text"><?php echo __('My Cart'); ?></span>
         <span class="counter qty empty"
-              data-bind="css: { empty: cart().summary_count == 0 }">
+              data-bind="css: { empty: cart().summary_count == 0 }, blockLoader: isLoading">
             <span class="counter-number"><!-- ko text: cart().summary_count --><!-- /ko --></span>
             <span class="counter-label">
             <!-- ko if: cart().summary_count -->
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/select-billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/action/select-billing-address.js
index da290fc1aa214d38d38deb8ca5b68805e66962f5..478dc2f29e4b40b725f4d1067f3369af6260c1d7 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/action/select-billing-address.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/select-billing-address.js
@@ -5,12 +5,20 @@
 /*global define*/
 define(
     [
+        'jquery',
         '../model/quote'
     ],
-    function(quote) {
+    function($, quote) {
         "use strict";
         return function(billingAddress) {
-            quote.billingAddress(billingAddress);
+            var address = null;
+            if (billingAddress.getCacheKey() == quote.shippingAddress().getCacheKey()) {
+                address = $.extend({}, billingAddress);
+                address.save_in_address_book = false;
+            } else {
+                address = billingAddress;
+            }
+            quote.billingAddress(address);
         };
     }
 );
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-address.js b/app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-address.js
index a8d1e6d38be27d054ca80636f988009ff66e87fb..db5bd93b275a69fb0d8a8bfa2f99540315bbb8f4 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-address.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/action/select-shipping-address.js
@@ -4,11 +4,13 @@
  */
 /*global define*/
 define(
-    ['../model/quote',
-     'Magento_Checkout/js/model/shipping-rate-service'
+    [
+        '../model/quote',
+        'Magento_Checkout/js/model/shipping-rate-service',
+        'Magento_Checkout/js/action/select-billing-address'
     ],
-    function(quote, shippingRateService) {
-        "use strict";
+    function(quote, shippingRateService, selectBillingAddress) {
+        'use strict';
         quote.shippingAddress.subscribe(function () {
             shippingRateService.getRates(quote.shippingAddress())
         });
@@ -16,7 +18,7 @@ define(
             quote.shippingAddress(shippingAddress);
             //set billing address same as shipping by default if it is not empty
             if (shippingAddress.countryId != undefined && shippingAddress.canUseForBilling()) {
-                quote.billingAddress(shippingAddress);
+                selectBillingAddress(quote.shippingAddress());
             }
         };
     }
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js
index d6cef062b1d507b82fcc00b5ee99fbc128d533a5..f4c2213022caf49f888f5155a94e41a81948c83c 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/region-updater.js
@@ -194,7 +194,7 @@ define([
             if (this.options.isZipRequired) {
                 $.inArray(country, this.options.countriesWithOptionalZip) >= 0 ?
                     postcode.removeClass('required-entry').closest('.field').removeClass('required') :
-                    postcode.removeClass('required-entry').closest('.field').addClass('required');
+                    postcode.addClass('required-entry').closest('.field').addClass('required');
             }
 
             // Add defaultvalue attribute to state/province select element
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
index 5f93022da11a9089f3ef90ebef20ef2057529a56..a7242d44933b77fcb880f817a5917ccc10632c45 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
@@ -24,41 +24,41 @@ define([
         },
 
         _initContent: function() {
-            var self = this;
+            var self = this,
+                events = {};
 
             this.element.decorate('list', this.options.isRecursive);
 
-            $(this.options.button.close).click(function(event) {
+            events['click ' + this.options.button.close] = function(event) {
                 event.stopPropagation();
                 $(self.options.targetElement).dropdownDialog("close");
-            });
-
-            $(this.options.button.checkout).on('click', $.proxy(function() {
+            };
+            events['click ' + this.options.button.checkout] = $.proxy(function() {
                 var cart = customerData.get('cart'),
                     customer = customerData.get('customer');
 
                 if (customer() == false && !cart().isGuestCheckoutAllowed) {
                     authenticationPopup.showModal();
+
                     return false;
                 }
                 location.href = this.options.url.checkout;
-            }, this));
-
-            $(this.options.button.remove).click(function(event) {
+            }, this);
+            events['click ' + this.options.button.remove] =  function(event) {
                 event.stopPropagation();
                 if (confirm(self.options.confirmMessage)) {
-                    self._removeItem($(this));
+                    self._removeItem($(event.target));
                 }
-            });
-
-            $(this.options.item.qty).keyup(function() {
-                self._showItemButton($(this));
-            });
-            $(this.options.item.button).click(function(event) {
+            };
+            events['keyup ' + this.options.item.qty] = function(event) {
+                self._showItemButton($(event.target));
+            };
+            events['click ' + this.options.item.button] = function(event) {
                 event.stopPropagation();
-                self._updateItemQty($(this))
-            });
+                self._updateItemQty($(event.target));
+            };
 
+            this._on(this.element, events);
             this._calcHeight();
             this._isOverflowed();
         },
@@ -122,10 +122,8 @@ define([
          * Update content after update qty
          *
          * @param elem
-         * @param response
-         * @private
          */
-        _updateItemQtyAfter: function(elem, response) {
+        _updateItemQtyAfter: function(elem) {
             this._hideItemButton(elem);
         },
 
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js
index 945cd2802754e39b92161091615b8e09e3ad0e4e..95f20afa7264e5bfde04db6ed8c334e371b62c84 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/billing-address.js
@@ -50,10 +50,16 @@ define(
                         isAddressFormVisible: !customer.isLoggedIn() || addressOptions.length == 1,
                         isAddressSameAsShipping: false
                     });
+
                 quote.billingAddress.subscribe(function(newAddress) {
-                    this.isAddressSameAsShipping(newAddress == quote.shippingAddress() && !quote.isVirtual());
+                    this.isAddressSameAsShipping(
+                        newAddress != null
+                            && newAddress.getCacheKey() == quote.shippingAddress().getCacheKey()
+                            && !quote.isVirtual()
+                    );
                     this.isAddressDetailsVisible(true);
                 }, this);
+
                 return this;
             },
 
@@ -117,7 +123,9 @@ define(
                 if (quote.billingAddress()) {
                     // restore 'Same As Shipping' checkbox state
                     this.isAddressSameAsShipping(
-                        !quote.isVirtual() && (quote.shippingAddress() == quote.billingAddress())
+                        quote.billingAddress() != null
+                            && quote.billingAddress().getCacheKey() == quote.shippingAddress().getCacheKey()
+                            && !quote.isVirtual()
                     );
                     this.isAddressDetailsVisible(true);
                 }
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js
index 51e59d8ff6bb31bfb06222c8ef965cbdf19f835d..516d1e3b1c245d54ae5b7f4193e828a95da8aa89 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/minicart.js
@@ -7,21 +7,24 @@ define([
     'Magento_Customer/js/customer-data',
     'jquery',
     'ko',
-    'mage/url'
+    'mage/url',
+    'sidebar'
 ], function (Component, customerData, $, ko, url) {
     'use strict';
 
     var sidebarInitialized = false;
+    var addToCartCalls = 0;
     url.setBaseUrl(window.checkout.baseUrl);
 
     function initSidebar() {
         var minicart = $("[data-block='minicart']");
+
         minicart.trigger('contentUpdated');
         if (sidebarInitialized) {
             return false;
         }
         sidebarInitialized = true;
-        minicart.mage('sidebar', {
+        minicart.sidebar({
             "targetElement": "div.block.block-minicart",
             "url": {
                 "checkout": window.checkout.checkoutUrl,
@@ -57,19 +60,29 @@ define([
     return Component.extend({
         shoppingCartUrl: window.checkout.shoppingCartUrl,
         initialize: function () {
+            var self = this;
             this._super();
             this.cart = customerData.get('cart');
             this.cart.subscribe(function () {
+                addToCartCalls--;
+                this.isLoading(addToCartCalls > 0);
                 sidebarInitialized = false;
+            }, this);
+            $('[data-block="minicart"]').on('contentLoading', function(event) {
+                addToCartCalls++;
+                self.isLoading(true);
             });
         },
+        isLoading: ko.observable(false),
         initSidebar: ko.observable(initSidebar),
-        closeSidebar: function(element) {
+        closeSidebar: function() {
             var minicart = $('[data-block="minicart"]');
+
             minicart.on('click', '[data-action="close"]', function(event) {
                 event.stopPropagation();
                 minicart.find('[data-role="dropdownDialog"]').dropdownDialog("close");
             });
+
             return true;
         },
         getItemRenderer: function (productType) {
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/default.js b/app/code/Magento/Checkout/view/frontend/web/js/view/payment/default.js
index 29c225495711675e0aaa18582ca34b2e774cf420..aa7647e033b77ab5ac72bd4ef8a87eb6f75ba2c0 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/view/payment/default.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/view/payment/default.js
@@ -45,7 +45,10 @@ define(
             /**
              * Place order.
              */
-            placeOrder: function () {
+            placeOrder: function (data, event) {
+                if (event) {
+                    event.preventDefault();
+                }
                 var self = this,
                     placeOrder,
                     emailValidationResult = customer.isLoggedIn(),
diff --git a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php
index c1fbd62d212129341ce19c777d4c84033c6e2c9b..b884e625c1a7a91e302773fb520a8778182958a9 100644
--- a/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php
+++ b/app/code/Magento/Cms/Model/Wysiwyg/Images/Storage.php
@@ -185,63 +185,67 @@ class Storage extends \Magento\Framework\Object
     }
 
     /**
-     * Return one-level child directories for specified path
+     * Create sub directories if DB storage is used
      *
-     * @param string $path Parent directory path
-     * @return \Magento\Framework\Data\Collection\Filesystem
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     * @SuppressWarnings(PHPMD.NPathComplexity)
+     * @param string $path
+     * @return void
      */
-    public function getDirsCollection($path)
+    protected function createSubDirectories($path)
     {
         if ($this->_coreFileStorageDb->checkDbUsage()) {
             /** @var \Magento\MediaStorage\Model\File\Storage\Directory\Database $subDirectories */
             $subDirectories = $this->_directoryDatabaseFactory->create();
-            $subDirectories->getSubdirectories($path);
-            foreach ($subDirectories as $directory) {
+            $directories = $subDirectories->getSubdirectories($path);
+            foreach ($directories as $directory) {
                 $fullPath = rtrim($path, '/') . '/' . $directory['name'];
                 $this->_directory->create($fullPath);
             }
         }
+    }
 
+    /**
+     * Prepare and get conditions for exclude directories
+     *
+     * @return array
+     */
+    protected function getConditionsForExcludeDirs()
+    {
         $conditions = ['reg_exp' => [], 'plain' => []];
 
         if ($this->_dirs['exclude']) {
             foreach ($this->_dirs['exclude'] as $dir) {
-                $conditions[$dir->getAttribute('regexp') ? 'reg_exp' : 'plain'][$dir] = true;
+                $conditions[!empty($dir['regexp']) ? 'reg_exp' : 'plain'][$dir['name']] = true;
             }
         }
 
         // "include" section takes precedence and can revoke directory exclusion
         if ($this->_dirs['include']) {
             foreach ($this->_dirs['include'] as $dir) {
-                unset($conditions['regexp'][(string)$dir], $conditions['plain'][$dir]);
+                unset($conditions['reg_exp'][$dir['name']], $conditions['plain'][$dir['name']]);
             }
         }
 
+        return $conditions;
+    }
+
+    /**
+     * Remove excluded directories from collection
+     *
+     * @param \Magento\Framework\Data\Collection\Filesystem $collection
+     * @param array $conditions
+     * @return \Magento\Framework\Data\Collection\Filesystem
+     */
+    protected function removeItemFromCollection($collection, $conditions)
+    {
         $regExp = $conditions['reg_exp'] ? '~' . implode('|', array_keys($conditions['reg_exp'])) . '~i' : null;
-        $collection = $this->getCollection(
-            $path
-        )->setCollectDirs(
-            true
-        )->setCollectFiles(
-            false
-        )->setCollectRecursively(
-            false
-        );
         $storageRootLength = strlen($this->_cmsWysiwygImages->getStorageRoot());
 
         foreach ($collection as $key => $value) {
             $rootChildParts = explode('/', substr($value->getFilename(), $storageRootLength));
 
-            if (array_key_exists(
-                $rootChildParts[0],
-                $conditions['plain']
-            ) || $regExp && preg_match(
-                $regExp,
-                $value->getFilename()
-            )
-            ) {
+            if (array_key_exists($rootChildParts[1], $conditions['plain'])
+                || ($regExp && preg_match($regExp, $value->getFilename()))) {
+
                 $collection->removeItemByKey($key);
             }
         }
@@ -249,6 +253,26 @@ class Storage extends \Magento\Framework\Object
         return $collection;
     }
 
+    /**
+     * Return one-level child directories for specified path
+     *
+     * @param string $path Parent directory path
+     * @return \Magento\Framework\Data\Collection\Filesystem
+     */
+    public function getDirsCollection($path)
+    {
+        $this->createSubDirectories($path);
+
+        $collection = $this->getCollection($path)
+            ->setCollectDirs(true)
+            ->setCollectFiles(false)
+            ->setCollectRecursively(false);
+
+        $conditions = $this->getConditionsForExcludeDirs();
+
+        return $this->removeItemFromCollection($collection, $conditions);
+    }
+
     /**
      * Return files
      *
diff --git a/app/code/Magento/Cms/Setup/InstallData.php b/app/code/Magento/Cms/Setup/InstallData.php
index 726a8e45f01a369bf28833a02bd972ce67b5a857..e73fe3d3e6c0d2e498c6cf07bb6f8c4789987d90 100644
--- a/app/code/Magento/Cms/Setup/InstallData.php
+++ b/app/code/Magento/Cms/Setup/InstallData.php
@@ -111,13 +111,12 @@ class InstallData implements InstallDataInterface
         </span>
     </div>
     <p>
-        This privacy policy sets out how {{config path="general/store_information/name"}} uses and protects any
-        information that you give {{config path="general/store_information/name"}} when you use this website.
-        {{config path="general/store_information/name"}} is committed to ensuring that your privacy is protected.
-        Should we ask you to provide certain information by which you can be identified when using this website,
-        then you can be assured that it will only be used in accordance with this privacy statement.
-        {{config path="general/store_information/name"}} may change this policy from time to time by updating this page.
-        You should check this page from time to time to ensure that you are happy with any changes.
+        This privacy policy sets out how this website (hereafter "the Store") uses and protects any information that
+        you give the Store while using this website. The Store is committed to ensuring that your privacy is protected.
+        Should we ask you to provide certain information by which you can be identified when using this website, then
+        you can be assured that it will only be used in accordance with this privacy statement. The Store may change
+        this policy from time to time by updating this page. You should check this page from time to time to ensure
+        that you are happy with any changes.
     </p>
     <h2>What we collect</h2>
     <p>We may collect the following information:</p>
@@ -191,8 +190,7 @@ class InstallData implements InstallDataInterface
         </li>
         <li>
             if you have previously agreed to us using your personal information for direct marketing purposes,
-            you may change your mind at any time by writing to or emailing us at
-            {{config path="trans_email/ident_general/email"}}
+            you may change your mind at any time by letting us know using our Contact Us information
         </li>
     </ul>
     <p>
@@ -202,8 +200,8 @@ class InstallData implements InstallDataInterface
     </p>
     <p>
         You may request details of personal information which we hold about you under the Data Protection Act 1998.
-        A small fee will be payable. If you would like a copy of the information held on you please write to
-        {{config path="general/store_information/address"}}.
+        A small fee will be payable. If you would like a copy of the information held on you please email us this
+        request using our Contact Us information.
     </p>
     <p>
         If you believe that any information we are holding on you is incorrect or incomplete,
diff --git a/app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php b/app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php
index a24fae248edabe1f9b89dbe38fff026f542fc29a..f2a23dc16b8c25819223f1a0073a5e9bc8894369 100644
--- a/app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php
+++ b/app/code/Magento/Cms/Test/Unit/Model/Wysiwyg/Images/StorageTest.php
@@ -1,14 +1,17 @@
 <?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
 namespace Magento\Cms\Test\Unit\Model\Wysiwyg\Images;
 
 use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Cms\Model\Wysiwyg\Images\Storage\Collection as StorageCollection;
 
 /**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- *
  * @SuppressWarnings(PHPMD.LongVariable)
  * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.TooManyFields)
  */
 class StorageTest extends \PHPUnit_Framework_TestCase
 {
@@ -22,72 +25,87 @@ class StorageTest extends \PHPUnit_Framework_TestCase
     /**
      * @var \Magento\Cms\Model\Wysiwyg\Images\Storage
      */
-    protected $_model = null;
+    protected $imagesStorage;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_filesystemMock;
+    protected $filesystemMock;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_adapterFactoryMock;
+    protected $adapterFactoryMock;
 
     /**
      * @var \PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_imageHelperMock;
+    protected $imageHelperMock;
 
     /**
      * @var array()
      */
-    protected $_resizeParameters;
+    protected $resizeParameters;
 
     /**
      * @var \Magento\Cms\Model\Wysiwyg\Images\Storage\CollectionFactory|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_storageCollectionFactoryMock;
+    protected $storageCollectionFactoryMock;
+
+    /**
+     * @var \Magento\MediaStorage\Model\File\Storage\FileFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storageFileFactoryMock;
 
     /**
-     * @var \Magento\MediaStorage\Model\File\Storage\FileFactory|PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\MediaStorage\Model\File\Storage\DatabaseFactory|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_storageFileFactoryMock;
+    protected $storageDatabaseFactoryMock;
 
     /**
-     * @var \Magento\MediaStorage\Model\File\Storage\DatabaseFactory|PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\MediaStorage\Model\File\Storage\Directory\DatabaseFactory|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_storageDatabaseFactoryMock;
+    protected $directoryDatabaseFactoryMock;
 
     /**
-     * @var \Magento\MediaStorage\Model\File\Storage\Directory\DatabaseFactory|PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\MediaStorage\Model\File\Storage\Directory\Database|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_directoryDatabaseFactoryMock;
+    protected $directoryCollectionMock;
 
     /**
-     * @var \Magento\MediaStorage\Model\File\UploaderFactory|PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\MediaStorage\Model\File\UploaderFactory|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_uploaderFactoryMock;
+    protected $uploaderFactoryMock;
 
     /**
      * @var \Magento\Backend\Model\Session|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_sessionMock;
+    protected $sessionMock;
 
     /**
      * @var \Magento\Backend\Model\Url|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_backendUrlMock;
+    protected $backendUrlMock;
 
     /**
      * @var \Magento\Framework\Filesystem\Directory\Write|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_directoryMock;
+    protected $directoryMock;
 
     /**
      * @var \Magento\Framework\Filesystem\DriverInterface|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_driverMock;
+    protected $driverMock;
+
+    /**
+     * @var \Magento\MediaStorage\Helper\File\Storage\Database|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $coreFileStorageMock;
+
+    /**
+     * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectManagerHelper;
 
     /**
      * @return void
@@ -95,8 +113,8 @@ class StorageTest extends \PHPUnit_Framework_TestCase
      */
     protected function setUp()
     {
-        $this->_filesystemMock = $this->getMock('Magento\Framework\Filesystem', [], [], '', false);
-        $this->_driverMock = $this->getMockForAbstractClass(
+        $this->filesystemMock = $this->getMock('Magento\Framework\Filesystem', [], [], '', false);
+        $this->driverMock = $this->getMockForAbstractClass(
             'Magento\Framework\Filesystem\DriverInterface',
             [],
             '',
@@ -105,55 +123,55 @@ class StorageTest extends \PHPUnit_Framework_TestCase
             true,
             ['getRealPath']
         );
-        $this->_driverMock->expects($this->any())->method('getRealPath')->will($this->returnArgument(0));
+        $this->driverMock->expects($this->any())->method('getRealPath')->will($this->returnArgument(0));
 
-        $this->_directoryMock = $this->getMock(
+        $this->directoryMock = $this->getMock(
             'Magento\Framework\Filesystem\Directory\Write',
-            ['delete', 'getDriver'],
+            ['delete', 'getDriver', 'create'],
             [],
             '',
             false
         );
-        $this->_directoryMock->expects(
+        $this->directoryMock->expects(
             $this->any()
         )->method(
             'getDriver'
         )->will(
-            $this->returnValue($this->_driverMock)
+            $this->returnValue($this->driverMock)
         );
 
-        $this->_filesystemMock = $this->getMock(
+        $this->filesystemMock = $this->getMock(
             'Magento\Framework\Filesystem',
             ['getDirectoryWrite'],
             [],
             '',
             false
         );
-        $this->_filesystemMock->expects(
+        $this->filesystemMock->expects(
             $this->any()
         )->method(
             'getDirectoryWrite'
         )->with(
             DirectoryList::MEDIA
         )->will(
-            $this->returnValue($this->_directoryMock)
+            $this->returnValue($this->directoryMock)
         );
 
-        $this->_adapterFactoryMock = $this->getMock(
+        $this->adapterFactoryMock = $this->getMock(
             'Magento\Framework\Image\AdapterFactory',
             [],
             [],
             '',
             false
         );
-        $this->_imageHelperMock = $this->getMock(
+        $this->imageHelperMock = $this->getMock(
             'Magento\Cms\Helper\Wysiwyg\Images',
             ['getStorageRoot'],
             [],
             '',
             false
         );
-        $this->_imageHelperMock->expects(
+        $this->imageHelperMock->expects(
             $this->any()
         )->method(
             'getStorageRoot'
@@ -161,65 +179,76 @@ class StorageTest extends \PHPUnit_Framework_TestCase
             $this->returnValue(self::STORAGE_ROOT_DIR)
         );
 
-        $this->_resizeParameters = ['width' => 100, 'height' => 50];
+        $this->resizeParameters = ['width' => 100, 'height' => 50];
 
-        $this->_storageCollectionFactoryMock = $this->getMock(
+        $this->storageCollectionFactoryMock = $this->getMock(
             'Magento\Cms\Model\Wysiwyg\Images\Storage\CollectionFactory',
             ['create'],
             [],
             '',
             false
         );
-        $this->_storageFileFactoryMock = $this->getMock(
+        $this->storageFileFactoryMock = $this->getMock(
             'Magento\MediaStorage\Model\File\Storage\FileFactory',
             [],
             [],
             '',
             false
         );
-        $this->_storageDatabaseFactoryMock = $this->getMock(
+        $this->storageDatabaseFactoryMock = $this->getMock(
             'Magento\MediaStorage\Model\File\Storage\DatabaseFactory',
             [],
             [],
             '',
             false
         );
-        $this->_directoryDatabaseFactoryMock = $this->getMock(
+        $this->directoryDatabaseFactoryMock = $this->getMock(
             'Magento\MediaStorage\Model\File\Storage\Directory\DatabaseFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->directoryCollectionMock = $this->getMock(
+            'Magento\MediaStorage\Model\File\Storage\Directory\Database',
             [],
             [],
             '',
             false
         );
-        $this->_uploaderFactoryMock = $this->getMockBuilder('Magento\MediaStorage\Model\File\UploaderFactory')
+
+        $this->uploaderFactoryMock = $this->getMockBuilder('Magento\MediaStorage\Model\File\UploaderFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->sessionMock = $this->getMock('Magento\Backend\Model\Session', [], [], '', false);
+        $this->backendUrlMock = $this->getMock('Magento\Backend\Model\Url', [], [], '', false);
+
+        $this->coreFileStorageMock = $this->getMockBuilder('Magento\MediaStorage\Helper\File\Storage\Database')
             ->disableOriginalConstructor()
             ->getMock();
-        $this->_sessionMock = $this->getMock('Magento\Backend\Model\Session', [], [], '', false);
-        $this->_backendUrlMock = $this->getMock('Magento\Backend\Model\Url', [], [], '', false);
 
-        $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-        $this->_model = $objectManagerHelper->getObject(
+        $this->objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+
+        $this->imagesStorage = $this->objectManagerHelper->getObject(
             'Magento\Cms\Model\Wysiwyg\Images\Storage',
             [
-                'session' => $this->_sessionMock,
-                'backendUrl' => $this->_backendUrlMock,
-                'cmsWysiwygImages' => $this->_imageHelperMock,
-                'coreFileStorageDb' => $this->getMock(
-                    'Magento\MediaStorage\Helper\File\Storage\Database',
-                    [],
-                    [],
-                    '',
-                    false
-                ),
-                'filesystem' => $this->_filesystemMock,
-                'imageFactory' => $this->_adapterFactoryMock,
+                'session' => $this->sessionMock,
+                'backendUrl' => $this->backendUrlMock,
+                'cmsWysiwygImages' => $this->imageHelperMock,
+                'coreFileStorageDb' => $this->coreFileStorageMock,
+                'filesystem' => $this->filesystemMock,
+                'imageFactory' => $this->adapterFactoryMock,
                 'assetRepo' => $this->getMock('Magento\Framework\View\Asset\Repository', [], [], '', false),
-                'storageCollectionFactory' => $this->_storageCollectionFactoryMock,
-                'storageFileFactory' => $this->_storageFileFactoryMock,
-                'storageDatabaseFactory' => $this->_storageDatabaseFactoryMock,
-                'directoryDatabaseFactory' => $this->_directoryDatabaseFactoryMock,
-                'uploaderFactory' => $this->_uploaderFactoryMock,
-                'resizeParameters' => $this->_resizeParameters
+                'storageCollectionFactory' => $this->storageCollectionFactoryMock,
+                'storageFileFactory' => $this->storageFileFactoryMock,
+                'storageDatabaseFactory' => $this->storageDatabaseFactoryMock,
+                'directoryDatabaseFactory' => $this->directoryDatabaseFactoryMock,
+                'uploaderFactory' => $this->uploaderFactoryMock,
+                'resizeParameters' => $this->resizeParameters,
+                'dirs' => [
+                    'exclude' => [],
+                    'include' => []
+                ]
             ]
         );
     }
@@ -229,7 +258,7 @@ class StorageTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetResizeWidth()
     {
-        $this->assertEquals(100, $this->_model->getResizeWidth());
+        $this->assertEquals(100, $this->imagesStorage->getResizeWidth());
     }
 
     /**
@@ -237,7 +266,7 @@ class StorageTest extends \PHPUnit_Framework_TestCase
      */
     public function testGetResizeHeight()
     {
-        $this->assertEquals(50, $this->_model->getResizeHeight());
+        $this->assertEquals(50, $this->imagesStorage->getResizeHeight());
     }
 
     /**
@@ -249,7 +278,7 @@ class StorageTest extends \PHPUnit_Framework_TestCase
             '\Magento\Framework\Exception\LocalizedException',
             sprintf('Directory %s is not under storage root path.', self::INVALID_DIRECTORY_OVER_ROOT)
         );
-        $this->_model->deleteDirectory(self::INVALID_DIRECTORY_OVER_ROOT);
+        $this->imagesStorage->deleteDirectory(self::INVALID_DIRECTORY_OVER_ROOT);
     }
 
     /**
@@ -261,6 +290,167 @@ class StorageTest extends \PHPUnit_Framework_TestCase
             '\Magento\Framework\Exception\LocalizedException',
             sprintf('We can\'t delete root directory %s right now.', self::STORAGE_ROOT_DIR)
         );
-        $this->_model->deleteDirectory(self::STORAGE_ROOT_DIR);
+        $this->imagesStorage->deleteDirectory(self::STORAGE_ROOT_DIR);
+    }
+
+    public function testGetDirsCollectionCreateSubDirectories()
+    {
+        $directoryName = 'test1';
+
+        $this->coreFileStorageMock->expects($this->once())
+            ->method('checkDbUsage')
+            ->willReturn(true);
+
+        $this->directoryCollectionMock->expects($this->once())
+            ->method('getSubdirectories')
+            ->with(self::STORAGE_ROOT_DIR)
+            ->willReturn([['name' => $directoryName]]);
+
+        $this->directoryDatabaseFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($this->directoryCollectionMock);
+
+        $this->directoryMock->expects($this->once())
+            ->method('create')
+            ->with(rtrim(self::STORAGE_ROOT_DIR, '/') . '/' . $directoryName);
+
+        $this->generalTestGetDirsCollection(self::STORAGE_ROOT_DIR);
+    }
+
+    /**
+     * @param array $exclude
+     * @param array $include
+     * @param array $fileNames
+     * @param array $expectedRemoveKeys
+     * @dataProvider dirsCollectionDataProvider
+     */
+    public function testGetDirsCollection($exclude, $include, $fileNames, $expectedRemoveKeys)
+    {
+        $this->imagesStorage = $this->objectManagerHelper->getObject(
+            'Magento\Cms\Model\Wysiwyg\Images\Storage',
+            [
+                'session' => $this->sessionMock,
+                'backendUrl' => $this->backendUrlMock,
+                'cmsWysiwygImages' => $this->imageHelperMock,
+                'coreFileStorageDb' => $this->coreFileStorageMock,
+                'filesystem' => $this->filesystemMock,
+                'imageFactory' => $this->adapterFactoryMock,
+                'assetRepo' => $this->getMock('Magento\Framework\View\Asset\Repository', [], [], '', false),
+                'storageCollectionFactory' => $this->storageCollectionFactoryMock,
+                'storageFileFactory' => $this->storageFileFactoryMock,
+                'storageDatabaseFactory' => $this->storageDatabaseFactoryMock,
+                'directoryDatabaseFactory' => $this->directoryDatabaseFactoryMock,
+                'uploaderFactory' => $this->uploaderFactoryMock,
+                'resizeParameters' => $this->resizeParameters,
+                'dirs' => [
+                    'exclude' => $exclude,
+                    'include' => $include
+                ]
+            ]
+        );
+
+        $collection = [];
+        foreach ($fileNames as $filename) {
+            /** @var \Magento\Framework\Object|\PHPUnit_Framework_MockObject_MockObject $objectMock */
+            $objectMock = $this->getMock('Magento\Framework\Object', ['getFilename'], [], '', false);
+            $objectMock->expects($this->any())
+                ->method('getFilename')
+                ->willReturn(self::STORAGE_ROOT_DIR . $filename);
+            $collection[] = $objectMock;
+        }
+
+        $this->generalTestGetDirsCollection(self::STORAGE_ROOT_DIR, $collection, $expectedRemoveKeys);
+    }
+
+    /**
+     * @return array
+     */
+    public function dirsCollectionDataProvider()
+    {
+        return [
+            [
+                'exclude' => [
+                    ['name' => 'dress']
+                ],
+                'include' => [],
+                'filenames' => [],
+                'expectRemoveKeys' => []
+            ],
+            [
+                'exclude' => [],
+                'include' => [],
+                'filenames' => [
+                    '/dress',
+                ],
+                'expectRemoveKeys' => []
+            ],
+            [
+                'exclude' => [
+                    ['name' => 'dress']
+                ],
+                'include' => [],
+                'filenames' => [
+                    '/collection',
+                ],
+                'expectRemoveKeys' => []
+            ],
+            [
+                'exclude' => [
+                    ['name' => 'gear', 'regexp' => 1],
+                    ['name' => 'home', 'regexp' => 1],
+                    ['name' => 'collection'],
+                    ['name' => 'dress']
+                ],
+                'include' => [
+                    ['name' => 'home', 'regexp' => 1],
+                    ['name' => 'collection']
+                ],
+                'filenames' => [
+                    '/dress',
+                    '/collection',
+                    '/gear'
+                ],
+                'expectRemoveKeys' => [[0], [2]]
+            ]
+        ];
+    }
+
+    /**
+     * General conditions for testGetDirsCollection tests
+     *
+     * @param string $path
+     * @param array $collectionArray
+     * @param array $expectedRemoveKeys
+     */
+    protected function generalTestGetDirsCollection($path, $collectionArray = [], $expectedRemoveKeys = [])
+    {
+        /** @var StorageCollection|\PHPUnit_Framework_MockObject_MockObject $storageCollectionMock */
+        $storageCollectionMock = $this->getMockBuilder('Magento\Cms\Model\Wysiwyg\Images\Storage\Collection')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $storageCollectionMock->expects($this->once())
+            ->method('setCollectDirs')
+            ->with(true)
+            ->willReturnSelf();
+        $storageCollectionMock->expects($this->once())
+            ->method('setCollectFiles')
+            ->with(false)
+            ->willReturnSelf();
+        $storageCollectionMock->expects($this->once())
+            ->method('setCollectRecursively')
+            ->with(false)
+            ->willReturnSelf();
+        $storageCollectionMock->expects($this->once())
+            ->method('getIterator')
+            ->willReturn(new \ArrayIterator($collectionArray));
+        $storageCollectionInvMock = $storageCollectionMock->expects($this->exactly(sizeof($expectedRemoveKeys)))
+            ->method('removeItemByKey');
+        call_user_func_array([$storageCollectionInvMock, 'withConsecutive'], $expectedRemoveKeys);
+
+        $this->storageCollectionFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($storageCollectionMock);
+
+        $this->imagesStorage->getDirsCollection($path);
     }
 }
diff --git a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php
index c28a8d4d07093cbd44506b57a0688615e18e78fe..b5b914db4cf5b1aa9d3756f2bbfa33784b71fb53 100644
--- a/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php
+++ b/app/code/Magento/Cms/Ui/Component/Listing/Column/PageActions.php
@@ -26,6 +26,11 @@ class PageActions extends Column
     /** @var UrlInterface */
     protected $urlBuilder;
 
+    /**
+     * @var string
+     */
+    private $editUrl;
+
     /**
      * @param ContextInterface $context
      * @param UiComponentFactory $uiComponentFactory
@@ -33,6 +38,7 @@ class PageActions extends Column
      * @param UrlInterface $urlBuilder
      * @param array $components
      * @param array $data
+     * @param string $editUrl
      */
     public function __construct(
         ContextInterface $context,
@@ -40,10 +46,12 @@ class PageActions extends Column
         UrlBuilder $actionUrlBuilder,
         UrlInterface $urlBuilder,
         array $components = [],
-        array $data = []
+        array $data = [],
+        $editUrl = self::CMS_URL_PATH_EDIT
     ) {
         $this->urlBuilder = $urlBuilder;
         $this->actionUrlBuilder = $actionUrlBuilder;
+        $this->editUrl = $editUrl;
         parent::__construct($context, $uiComponentFactory, $components, $data);
     }
 
@@ -60,7 +68,7 @@ class PageActions extends Column
                 $name = $this->getData('name');
                 if (isset($item['page_id'])) {
                     $item[$name]['edit'] = [
-                        'href' => $this->urlBuilder->getUrl(self::CMS_URL_PATH_EDIT, ['page_id' => $item['page_id']]),
+                        'href' => $this->urlBuilder->getUrl($this->editUrl, ['page_id' => $item['page_id']]),
                         'label' => __('Edit')
                     ];
                     $item[$name]['delete'] = [
diff --git a/app/code/Magento/Cookie/View/frontend/templates/html/notices.phtml b/app/code/Magento/Cookie/View/frontend/templates/html/notices.phtml
index ded203df87220221407350e11475cf1d3a347f55..e22d0fa8f092f8b090222d015cf36015a9bd80ad 100644
--- a/app/code/Magento/Cookie/View/frontend/templates/html/notices.phtml
+++ b/app/code/Magento/Cookie/View/frontend/templates/html/notices.phtml
@@ -28,7 +28,7 @@
                 "cookieNotices": {
                     "cookieAllowButtonSelector": "#btn-cookie-allow",
                     "cookieName": "<?php echo \Magento\Cookie\Helper\Cookie::IS_USER_ALLOWED_SAVE_COOKIE ?>",
-                    "cookieValue": "<?php echo $this->helper('Magento\Cookie\Helper\Cookie')->getAcceptedSaveCookiesWebsiteIds() ?>",
+                    "cookieValue": <?php echo $this->helper('Magento\Cookie\Helper\Cookie')->getAcceptedSaveCookiesWebsiteIds() ?>,
                     "cookieLifetime": <?php echo $this->helper('Magento\Cookie\Helper\Cookie')->getCookieRestrictionLifetime()?>,
                     "noCookiesUrl": "<?php echo $block->getUrl('cookie/index/noCookies') ?>"
                 }
diff --git a/app/code/Magento/Customer/view/frontend/web/js/model/customer/address.js b/app/code/Magento/Customer/view/frontend/web/js/model/customer/address.js
index c3f656411450d8f6a9603d7688a93d5e8f788fd7..b10800641c443d9078eeb273f3757eb95aba745b 100644
--- a/app/code/Magento/Customer/view/frontend/web/js/model/customer/address.js
+++ b/app/code/Magento/Customer/view/frontend/web/js/model/customer/address.js
@@ -47,6 +47,9 @@ define([], function() {
             getKey: function() {
                 return this.getType() + this.customerAddressId;
             },
+            getCacheKey: function() {
+                return this.getKey();
+            },
             isEditable: function() {
                 return false;
             },
diff --git a/app/code/Magento/Customer/view/frontend/web/template/customer-email.html b/app/code/Magento/Customer/view/frontend/web/template/customer-email.html
index 558bb0a5b4d2e4a44daddefc803db0f27ec76f35..a2159cc764d2a6955f2fe8b79935f6a8253f163c 100644
--- a/app/code/Magento/Customer/view/frontend/web/template/customer-email.html
+++ b/app/code/Magento/Customer/view/frontend/web/template/customer-email.html
@@ -25,7 +25,7 @@
                        data-validate="{required:true, 'validate-email':true}"
                        id="customer-email" />
                 <!-- ko template: 'ui/form/element/helper/tooltip' --><!-- /ko -->
-                <span class="note"><!-- ko text: $t("You can create an account after checkout.")--><!-- /ko --></span>
+                <span class="note" data-bind="fadeVisible: isPasswordVisible() == false"><!-- ko text: $t("You can create an account after checkout.")--><!-- /ko --></span>
             </div>
         </div>
 
diff --git a/app/code/Magento/Payment/Model/Checks/CanUseForCountry.php b/app/code/Magento/Payment/Model/Checks/CanUseForCountry.php
index 46e129662cc7859f315e00ab6207e12ceee599ba..749093370682541e2455a67b16ac8bed700937ad 100644
--- a/app/code/Magento/Payment/Model/Checks/CanUseForCountry.php
+++ b/app/code/Magento/Payment/Model/Checks/CanUseForCountry.php
@@ -7,9 +7,23 @@ namespace Magento\Payment\Model\Checks;
 
 use Magento\Payment\Model\MethodInterface;
 use Magento\Quote\Model\Quote;
+use Magento\Payment\Model\Checks\CanUseForCountry\CountryProvider;
 
 class CanUseForCountry implements SpecificationInterface
 {
+    /**
+     * @var CountryProvider
+     */
+    protected $countryProvider;
+
+    /**
+     * @param CountryProvider $countryProvider
+     */
+    public function __construct(CountryProvider $countryProvider)
+    {
+        $this->countryProvider = $countryProvider;
+    }
+
     /**
      * Check whether payment method is applicable to quote
      * @param MethodInterface $paymentMethod
@@ -18,6 +32,6 @@ class CanUseForCountry implements SpecificationInterface
      */
     public function isApplicable(MethodInterface $paymentMethod, Quote $quote)
     {
-        return $paymentMethod->canUseForCountry($quote->getBillingAddress()->getCountry());
+        return $paymentMethod->canUseForCountry($this->countryProvider->getCountry($quote));
     }
 }
diff --git a/app/code/Magento/Payment/Model/Checks/CanUseForCountry/CountryProvider.php b/app/code/Magento/Payment/Model/Checks/CanUseForCountry/CountryProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..8bbdbef28307a9d0a8fd6ae8ef5d2f14808ed5a0
--- /dev/null
+++ b/app/code/Magento/Payment/Model/Checks/CanUseForCountry/CountryProvider.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Model\Checks\CanUseForCountry;
+
+use Magento\Quote\Model\Quote;
+use Magento\Directory\Helper\Data as DirectoryHelper;
+
+class CountryProvider
+{
+    /**
+     * @var DirectoryHelper
+     */
+    protected $directoryHelper;
+
+    /**
+     * @param DirectoryHelper $directoryHelper
+     */
+    public function __construct(DirectoryHelper $directoryHelper)
+    {
+        $this->directoryHelper = $directoryHelper;
+    }
+
+    /**
+     * Get payment country
+     *
+     * @param Quote $quote
+     * @return int
+     */
+    public function getCountry(Quote $quote)
+    {
+        return $quote->isVirtual()
+            ? $this->directoryHelper->getDefaultCountry()
+            : $quote->getShippingAddress()->getCountry();
+    }
+}
diff --git a/app/code/Magento/Payment/Model/Method/Adapter.php b/app/code/Magento/Payment/Model/Method/Adapter.php
index 314a03d51550fedde3cd9b9e8c795eb25b4f5061..ac3a5c96e630aca09b3891f13fe04286473bb932 100644
--- a/app/code/Magento/Payment/Model/Method/Adapter.php
+++ b/app/code/Magento/Payment/Model/Method/Adapter.php
@@ -366,6 +366,7 @@ class Adapter implements MethodInterface
             $payment,
             ['amount' => $amount]
         );
+
         return $this;
     }
 
@@ -379,6 +380,7 @@ class Adapter implements MethodInterface
             $payment,
             ['amount' => $amount]
         );
+
         return $this;
     }
 
@@ -406,6 +408,7 @@ class Adapter implements MethodInterface
             $payment,
             ['amount' => $amount]
         );
+
         return $this;
     }
 
@@ -418,6 +421,7 @@ class Adapter implements MethodInterface
             'cancel',
             $payment
         );
+
         return $this;
     }
 
@@ -430,6 +434,7 @@ class Adapter implements MethodInterface
             'void',
             $payment
         );
+
         return $this;
     }
 
@@ -442,6 +447,7 @@ class Adapter implements MethodInterface
             'accept_payment',
             $payment
         );
+
         return $this;
     }
 
@@ -454,7 +460,8 @@ class Adapter implements MethodInterface
             'deny_payment',
             $payment
         );
-        return false;
+
+        return $this;
     }
 
     /**
diff --git a/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountry/CountryProviderTest.php b/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountry/CountryProviderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..13f1ad7d41451b30dc1e7c5a5fb8afab37d755e2
--- /dev/null
+++ b/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountry/CountryProviderTest.php
@@ -0,0 +1,46 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Test\Unit\Model\Checks\CanUseForCountry;
+
+class CountryProviderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Payment\Model\Checks\CanUseForCountry\CountryProvider
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $directoryMock;
+
+    public function setUp()
+    {
+        $this->directoryMock = $this->getMock('Magento\Directory\Helper\Data', [], [], '', false, false);
+        $this->model = new \Magento\Payment\Model\Checks\CanUseForCountry\CountryProvider($this->directoryMock);
+    }
+
+    public function testGetCountryForNonVirtualQuote()
+    {
+        $quoteMock = $this->getMock('Magento\Quote\Model\Quote', [], [], '', false, false);
+        $quoteMock->expects($this->once())->method('isVirtual')->willReturn(false);
+        $addressMock = $this->getMock('Magento\Quote\Model\Quote\Address', [], [], '', false, false);
+        $addressMock->expects($this->once())->method('getCountry')->will($this->returnValue(1));
+        $quoteMock->expects($this->once())->method('getShippingAddress')->will($this->returnValue($addressMock));
+        $this->assertEquals(1, $this->model->getCountry($quoteMock));
+    }
+
+    public function testGetCountryForVirtualQuote()
+    {
+        $quoteMock = $this->getMock('Magento\Quote\Model\Quote', [], [], '', false, false);
+        $quoteMock->expects($this->once())->method('isVirtual')->willReturn(true);
+        $addressMock = $this->getMock('Magento\Quote\Model\Quote\Address', [], [], '', false, false);
+        $addressMock->expects($this->never())->method('getCountry');
+        $quoteMock->expects($this->never())->method('getShippingAddress');
+        $this->directoryMock->expects($this->once())->method('getDefaultCountry')->willReturn(10);
+        $this->assertEquals(10, $this->model->getCountry($quoteMock));
+    }
+}
diff --git a/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountryTest.php b/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountryTest.php
index c9f1407a98349f0e0ab3efc8f91895d60916ef3a..2df67ab234dd370438d7e419d529a18711ad1518 100644
--- a/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountryTest.php
+++ b/app/code/Magento/Payment/Test/Unit/Model/Checks/CanUseForCountryTest.php
@@ -15,6 +15,11 @@ class CanUseForCountryTest extends \PHPUnit_Framework_TestCase
      */
     const EXPECTED_COUNTRY_ID = 1;
 
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $countryProvider;
+
     /**
      * @var CanUseForCountry
      */
@@ -22,7 +27,15 @@ class CanUseForCountryTest extends \PHPUnit_Framework_TestCase
 
     public function setUp()
     {
-        $this->_model = new CanUseForCountry();
+        $this->countryProvider = $this->getMock(
+            'Magento\Payment\Model\Checks\CanUseForCountry\CountryProvider',
+            [],
+            [],
+            '',
+            false,
+            false
+        );
+        $this->_model = new CanUseForCountry($this->countryProvider);
     }
 
     /**
@@ -34,13 +47,6 @@ class CanUseForCountryTest extends \PHPUnit_Framework_TestCase
         $quoteMock = $this->getMockBuilder('Magento\Quote\Model\Quote')->disableOriginalConstructor()->setMethods(
             []
         )->getMock();
-        $billingAddressMock = $this->getMockBuilder(
-            'Magento\Quote\Model\Quote\Address'
-        )->disableOriginalConstructor()->setMethods([])->getMock();
-        $billingAddressMock->expects($this->once())->method('getCountry')->will(
-            $this->returnValue(self::EXPECTED_COUNTRY_ID)
-        );
-        $quoteMock->expects($this->once())->method('getBillingAddress')->will($this->returnValue($billingAddressMock));
 
         $paymentMethod = $this->getMockBuilder(
             '\Magento\Payment\Model\MethodInterface'
@@ -48,6 +54,7 @@ class CanUseForCountryTest extends \PHPUnit_Framework_TestCase
         $paymentMethod->expects($this->once())->method('canUseForCountry')->with(
             self::EXPECTED_COUNTRY_ID
         )->will($this->returnValue($expectation));
+        $this->countryProvider->expects($this->once())->method('getCountry')->willReturn(self::EXPECTED_COUNTRY_ID);
 
         $this->assertEquals($expectation, $this->_model->isApplicable($paymentMethod, $quoteMock));
     }
diff --git a/app/code/Magento/Payment/composer.json b/app/code/Magento/Payment/composer.json
index 4f7a7f707bb8238f6619148cbeb112e5c90fb37f..b72ba192b4d49878924b8ce91a221228f2f2d199 100644
--- a/app/code/Magento/Payment/composer.json
+++ b/app/code/Magento/Payment/composer.json
@@ -8,6 +8,7 @@
         "magento/module-sales": "0.74.0-beta16",
         "magento/module-checkout": "0.74.0-beta16",
         "magento/module-quote": "0.74.0-beta16",
+        "magento/module-directory": "0.74.0-beta16",
         "magento/framework": "0.74.0-beta16",
         "magento/magento-composer-installer": "*"
     },
diff --git a/app/code/Magento/Payment/view/frontend/web/template/payment/cc-form.html b/app/code/Magento/Payment/view/frontend/web/template/payment/cc-form.html
index eb7865ddf83c8151653159b59d8c3c725a4d65b8..0b7e69fa0bd0acb5bcbdc48eabf1633cfdb325c1 100644
--- a/app/code/Magento/Payment/view/frontend/web/template/payment/cc-form.html
+++ b/app/code/Magento/Payment/view/frontend/web/template/payment/cc-form.html
@@ -31,10 +31,12 @@
                 <!--/ko-->
             </ul>
             <input type="hidden"
-                   name="payment[cc_number]"
+                   name="payment[cc_type]"
                    class="input-text"
                    value=""
-                   data-bind="attr: {id: getCode() + '_cc_type'}, value: creditCardType">
+                   data-bind="attr: {id: getCode() + '_cc_type', 'data-container': getCode() + '-cc-type'},
+                   value: creditCardType
+                   ">
         </div>
     </div>
     <div class="field number required">
@@ -42,8 +44,9 @@
             <span><!-- ko text: $t('Credit Card Number')--><!-- /ko --></span>
         </label>
         <div class="control">
-            <input type="text" name="payment[cc_number]" class="input-text" value=""
+            <input type="number" name="payment[cc_number]" class="input-text" value=""
                    data-bind="attr: {
+                                    autocomplete: off,
                                     id: getCode() + '_cc_number',
                                     title: $t('Credit Card Number'),
                                     'data-container': getCode() + '-cc-number',
@@ -96,7 +99,7 @@
             <span><!-- ko text: $t('Card Verification Number')--><!-- /ko --></span>
         </label>
         <div class="control _with-tooltip">
-            <input type="text" class="input-text cvv" name="payment[cc_cid]" value=""
+            <input type="number" autocomplete="off" class="input-text cvv" name="payment[cc_cid]" value=""
                    data-bind="attr: {id: getCode() + '_cc_cid', title: $t('Card Verification Number'), 'data-container': getCode() + '-cc-cvv', 'data-validate': JSON.stringify({'required-number':true, 'validate-card-cvv':'#' + getCode() + '_cc_type'})},
                              enable: isActive($parents),
                              value: creditCardVerificationNumber"/>
@@ -122,7 +125,7 @@
                     <span><!-- ko text: $t('Issue Number')--><!-- /ko --></span>
                 </label>
                 <div class="control">
-                    <input type="text" name="payment[cc_ss_issue]"
+                    <input type="number" name="payment[cc_ss_issue]"
                            value=""
                            class="input-text cvv"
                            data-bind="attr: {id: getCode() + '_cc_issue', title: $t('Issue Number'), 'data-container': getCode() + '-cc-issue', 'data-validate': JSON.stringify({'validate-cc-ukss':true})}, enable: isActive($parents)"/>
diff --git a/app/code/Magento/Payment/view/frontend/web/template/payment/iframe.html b/app/code/Magento/Payment/view/frontend/web/template/payment/iframe.html
index 9e4d53bda7384775fecdc37eeecb63ba90664972..b9abaa6694130fb7fdd959b431f45965d9c2a5ec 100644
--- a/app/code/Magento/Payment/view/frontend/web/template/payment/iframe.html
+++ b/app/code/Magento/Payment/view/frontend/web/template/payment/iframe.html
@@ -6,7 +6,7 @@
 -->
 <!-- IFRAME for request to Payment Gateway -->
 <iframe width="0" height="0" data-bind="src: getSource(), attr: {id: getCode() + '-transparent-iframe', 'data-container': getCode() + '-transparent-iframe'}" allowtransparency="true" frameborder="0"  name="iframeTransparent" style="display:none;width:100%;background-color:transparent"></iframe>
-<form class="form" id="co-transparent-form" action="#" method="post" data-bind="mageInit: {
+<form class="form" id="co-transparent-form" autocomplete="off" action="#" method="post" data-bind="mageInit: {
     'transparent':{
         'controller': getControllerName(),
         'gateway': getCode(),
diff --git a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_au.xml b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_au.xml
index 0fefc6f00ca0b50521d94fbcc59897336a5456d6..5ea58d76f2d6720e8975f0add49abe86c63ce558 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_au.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_au.xml
@@ -34,6 +34,11 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="paypal_payflowpro_au">paypal_payflowpro_au</argument>
+                <argument name="payments_pro_hosted_solution_au">payments_pro_hosted_solution_au</argument>
+                <argument name="express_checkout_other">express_checkout_other</argument>
+            </rule>
         </relation>
     </payment>
     <!--PayPal Payflow Pro-->
@@ -56,10 +61,13 @@
         <relation target="payments_pro_hosted_solution_au">
             <rule type="disable" event="activate"/>
         </relation>
-
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+                <argument name="payments_pro_hosted_solution_au">payments_pro_hosted_solution_au</argument>
+            </rule>
         </relation>
     </payment>
     <!--PayPal Website Payments Pro Hosted Solution-->
@@ -85,6 +93,10 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+                <argument name="paypal_payflowpro_au">paypal_payflowpro_au</argument>
+            </rule>
         </relation>
     </payment>
     <!--PayPal Express Checkout-->
@@ -106,6 +118,9 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
 </rules>
diff --git a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_ca.xml b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_ca.xml
index bd67d95f017727359da724caa5a93e46bf102191..767235735a54e190420b96330fa38cc2280a76fa 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_ca.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_ca.xml
@@ -38,6 +38,12 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wpp_ca">wpp_ca</argument>
+                <argument name="paypal_payflowpro_ca">paypal_payflowpro_ca</argument>
+                <argument name="payflow_link_ca">payflow_link_ca</argument>
+                <argument name="express_checkout_other">express_checkout_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Website Payments Pro -->
@@ -67,6 +73,11 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+                <argument name="paypal_payflowpro_ca">paypal_payflowpro_ca</argument>
+                <argument name="payflow_link_ca">payflow_link_ca</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Payflow Pro -->
@@ -96,6 +107,11 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+                <argument name="wpp_ca">wpp_ca</argument>
+                <argument name="payflow_link_ca">payflow_link_ca</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Payflow Link (Includes Express Checkout) -->
@@ -132,7 +148,6 @@
             <rule type="paypal/express/unlock-configuration" event="deactivate">
                 <argument name="payflow_link_ca">payflow_link_ca</argument>
             </rule>
-            <rule type="paypal/express/mark-enable" event=":load"/>
             <rule type="paypal/express/lock-configuration-conditional" event=":load"/>
         </relation>
         <relation target=":self">
@@ -141,6 +156,12 @@
             <rule type="payflow/express/enable" event="activate"/>
             <rule type="payflow/express/disable" event="deactivate"/>
             <rule type="payflow/express/lock-conditional" event=":load"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+                <argument name="wpp_ca">wpp_ca</argument>
+                <argument name="paypal_payflowpro_ca">paypal_payflowpro_ca</argument>
+                <argument name="express_checkout_other">express_checkout_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Express Checkout -->
@@ -165,6 +186,10 @@
                 <argument name="wps_other">wps_other</argument>
                 <argument name="payflow_link_ca">payflow_link_ca</argument>
             </rule>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+                <argument name="payflow_link_ca">payflow_link_ca</argument>
+            </rule>
         </relation>
     </payment>
 </rules>
diff --git a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_es.xml b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_es.xml
index 9e4434c3c584dda6ad1b5053eb12bb3d8b7e7191..ceac68e6c89efbb0d650a98eebc769b12dbf0303 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_es.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_es.xml
@@ -26,6 +26,9 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Website Payments Standard -->
@@ -51,6 +54,10 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="payments_pro_hosted_solution_es">payments_pro_hosted_solution_es</argument>
+                <argument name="express_checkout_other">express_checkout_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Express Checkout -->
@@ -74,6 +81,9 @@
             <rule type="paypal/express/mark-disable" event="deactivate">
                 <argument name="wps_other">wps_other</argument>
             </rule>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
 </rules>
diff --git a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_fr.xml b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_fr.xml
index 5204c9570db234d4018a01b241704b35a4235e40..a1ccc8f5f657be767c8273cfbe41f8ab7a4e461a 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_fr.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_fr.xml
@@ -26,6 +26,9 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Website Payments Standard -->
@@ -51,6 +54,10 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="payments_pro_hosted_solution_fr">payments_pro_hosted_solution_fr</argument>
+                <argument name="express_checkout_other">express_checkout_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Express Checkout -->
@@ -74,6 +81,9 @@
             <rule type="paypal/express/mark-disable" event="deactivate">
                 <argument name="wps_other">wps_other</argument>
             </rule>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
 </rules>
diff --git a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_gb.xml b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_gb.xml
index 25c760205e22be35073bb7e258914a45bc4e9e0d..6045bddce2e3962ed57d1d020bbc170553276997 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_gb.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_gb.xml
@@ -26,6 +26,9 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_express">wps_express</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Website Payments Standard -->
@@ -51,6 +54,10 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="payments_pro_hosted_solution_with_express_checkout">payments_pro_hosted_solution_with_express_checkout</argument>
+                <argument name="express_checkout_us">express_checkout_us</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Express Checkout -->
@@ -74,6 +81,9 @@
             <rule type="paypal/express/mark-disable" event="deactivate">
                 <argument name="wps_express">wps_express</argument>
             </rule>
+            <rule type="conflict" event=":load">
+                <argument name="wps_express">wps_express</argument>
+            </rule>
         </relation>
     </payment>
 </rules>
diff --git a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_hk.xml b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_hk.xml
index 50fe9895b02a989aa98cb894e4617aa19e5c1c5b..974bcf8bfe756044d991285252960b873eeda6a4 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_hk.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_hk.xml
@@ -26,6 +26,9 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Website Payments Standard -->
@@ -51,6 +54,10 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="payments_pro_hosted_solution_hk">payments_pro_hosted_solution_hk</argument>
+                <argument name="express_checkout_other">express_checkout_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Express Checkout -->
@@ -74,6 +81,9 @@
             <rule type="paypal/express/mark-disable" event="deactivate">
                 <argument name="wps_other">wps_other</argument>
             </rule>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
 </rules>
diff --git a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_it.xml b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_it.xml
index 072bc09da5c1bfb58bac66e4e05a556bf6a922b8..4d88054b781efde268e9a86ee66b015fe74da04d 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_it.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_it.xml
@@ -26,6 +26,9 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Website Payments Standard -->
@@ -51,6 +54,10 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="payments_pro_hosted_solution_it">payments_pro_hosted_solution_it</argument>
+                <argument name="express_checkout_other">express_checkout_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Express Checkout -->
@@ -74,6 +81,9 @@
             <rule type="paypal/express/mark-disable" event="deactivate">
                 <argument name="wps_other">wps_other</argument>
             </rule>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
 </rules>
diff --git a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_jp.xml b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_jp.xml
index 14f709d67fe4e3665226ceb9760e3dbcd1652174..ac502c272186d20a9df4a64a25a90bd653fed02b 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_jp.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_jp.xml
@@ -26,6 +26,9 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Website Payments Standard -->
@@ -51,6 +54,10 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="payments_pro_hosted_solution_jp">payments_pro_hosted_solution_jp</argument>
+                <argument name="express_checkout_other">express_checkout_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Express Checkout -->
@@ -74,6 +81,9 @@
             <rule type="paypal/express/mark-disable" event="deactivate">
                 <argument name="wps_other">wps_other</argument>
             </rule>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
 </rules>
diff --git a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_nz.xml b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_nz.xml
index f5fcb5062ac6619d564b4d37a5f46986479e58de..4c0f0af0a8eccfa9eee6a8120f496a69d60297b6 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_nz.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_nz.xml
@@ -26,6 +26,9 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Website Payments Standard -->
@@ -51,6 +54,10 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="paypal_payflowpro_nz">paypal_payflowpro_nz</argument>
+                <argument name="express_checkout_other">express_checkout_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Express Checkout -->
@@ -74,6 +81,9 @@
             <rule type="paypal/express/mark-disable" event="deactivate">
                 <argument name="wps_other">wps_other</argument>
             </rule>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
 </rules>
diff --git a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_other.xml b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_other.xml
index 65d8256652cdd1470c09d601877e7a1a15f65b3c..e5b0f41cc5fab6a71e8ae8dee086135b5e3bdb5d 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_other.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_other.xml
@@ -26,6 +26,9 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="express_checkout_other">express_checkout_other</argument>
+            </rule>
         </relation>
     </payment>
     <!-- Express Checkout -->
@@ -47,6 +50,9 @@
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="simple/disable" event="deactivate"/>
+            <rule type="conflict" event=":load">
+                <argument name="wps_other">wps_other</argument>
+            </rule>
         </relation>
     </payment>
 </rules>
diff --git a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_us.xml b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_us.xml
index b1b5a896b33e5165166b87fd5edd76ad969222c4..8a8ea7c31cb1a225de0e972749d4b75f8da85da4 100644
--- a/app/code/Magento/Paypal/etc/adminhtml/rules/payment_us.xml
+++ b/app/code/Magento/Paypal/etc/adminhtml/rules/payment_us.xml
@@ -69,6 +69,13 @@
             <rule type="payflow/bml/disable" event="deactivate"/>
             <rule type="payflow/express/disable-conditional" event=":load"/>
             <rule type="payflow/bml/disable-conditional" event=":load"/>
+            <rule type="conflict" event=":load">
+                <argument name="wpp_usuk">wpp_usuk</argument>
+                <argument name="wps_express">wps_express</argument>
+                <argument name="paypal_payflowpro_with_express_checkout">paypal_payflowpro_with_express_checkout</argument>
+                <argument name="payflow_link_us">payflow_link_us</argument>
+                <argument name="express_checkout_us">express_checkout_us</argument>
+            </rule>
         </relation>
     </payment>
     <!-- PayPal Payments Pro (Includes Express Checkout) -->
@@ -133,6 +140,13 @@
             <rule type="payflow/bml/disable" event="deactivate"/>
             <rule type="payflow/express/disable-conditional" event=":load"/>
             <rule type="payflow/bml/disable-conditional" event=":load"/>
+            <rule type="conflict" event=":load">
+                <argument name="payflow_advanced">payflow_advanced</argument>
+                <argument name="wps_express">wps_express</argument>
+                <argument name="paypal_payflowpro_with_express_checkout">paypal_payflowpro_with_express_checkout</argument>
+                <argument name="payflow_link_us">payflow_link_us</argument>
+                <argument name="express_checkout_us">express_checkout_us</argument>
+            </rule>
         </relation>
     </payment>
     <!-- PayPal Payments Standard -->
@@ -173,6 +187,13 @@
             <rule type="simple/disable" event="deactivate"/>
             <rule type="paypal/bml/disable" event="deactivate"/>
             <rule type="paypal/bml/disable-conditional" event=":load"/>
+            <rule type="conflict" event=":load">
+                <argument name="payflow_advanced">payflow_advanced</argument>
+                <argument name="wpp_usuk">wpp_usuk</argument>
+                <argument name="paypal_payflowpro_with_express_checkout">paypal_payflowpro_with_express_checkout</argument>
+                <argument name="payflow_link_us">payflow_link_us</argument>
+                <argument name="express_checkout_us">express_checkout_us</argument>
+            </rule>
         </relation>
     </payment>
     <!-- PayPal Payflow Pro (Includes Express Checkout) -->
@@ -237,6 +258,13 @@
             <rule type="payflow/bml/disable" event="deactivate"/>
             <rule type="payflow/express/disable-conditional" event=":load"/>
             <rule type="payflow/bml/disable-conditional" event=":load"/>
+            <rule type="conflict" event=":load">
+                <argument name="payflow_advanced">payflow_advanced</argument>
+                <argument name="wpp_usuk">wpp_usuk</argument>
+                <argument name="wps_express">wps_express</argument>
+                <argument name="payflow_link_us">payflow_link_us</argument>
+                <argument name="express_checkout_us">express_checkout_us</argument>
+            </rule>
         </relation>
     </payment>
     <!-- PayPal Payflow Link (Includes Express Checkout) -->
@@ -285,14 +313,12 @@
                 <argument name="wpp_usuk">wpp_usuk</argument>
                 <argument name="paypal_payflowpro_with_express_checkout">paypal_payflowpro_with_express_checkout</argument>
             </rule>
-            <rule type="paypal/express/mark-enable" event=":load"/>
             <rule type="paypal/express/lock-configuration-conditional" event=":load"/>
         </relation>
         <relation target=":self">
             <rule type="simple/mark-enable" event="activate"/>
             <rule type="payflow/express/enable" event="activate"/>
             <rule type="payflow/bml/enable" event="activate"/>
-
             <rule type="simple/disable" event="deactivate"/>
             <rule type="payflow/express/enable-conditional" event="deactivate">
                 <argument name="payflow_advanced">payflow_advanced</argument>
@@ -304,12 +330,17 @@
                 <argument name="wpp_usuk">wpp_usuk</argument>
                 <argument name="paypal_payflowpro_with_express_checkout">paypal_payflowpro_with_express_checkout</argument>
             </rule>
-
             <rule type="payflow/bml/disable-conditional-express" event="deactivate-express"/>
             <rule type="payflow/bml/enable" event="activate-express"/>
-
             <rule type="payflow/express/lock-conditional" event=":load"/>
             <rule type="payflow/bml/lock-conditional" event=":load"/>
+            <rule type="conflict" event=":load">
+                <argument name="payflow_advanced">payflow_advanced</argument>
+                <argument name="wpp_usuk">wpp_usuk</argument>
+                <argument name="wps_express">wps_express</argument>
+                <argument name="paypal_payflowpro_with_express_checkout">paypal_payflowpro_with_express_checkout</argument>
+                <argument name="express_checkout_us">express_checkout_us</argument>
+            </rule>
         </relation>
     </payment>
     <!-- PayPal Express Checkout -->
@@ -340,6 +371,13 @@
                 <argument name="payflow_link_us">payflow_link_us</argument>
             </rule>
             <rule type="paypal/bml/disable-conditional" event=":load"/>
+            <rule type="conflict" event=":load">
+                <argument name="payflow_advanced">payflow_advanced</argument>
+                <argument name="wpp_usuk">wpp_usuk</argument>
+                <argument name="wps_express">wps_express</argument>
+                <argument name="paypal_payflowpro_with_express_checkout">paypal_payflowpro_with_express_checkout</argument>
+                <argument name="payflow_link_us">payflow_link_us</argument>
+            </rule>
         </relation>
     </payment>
 </rules>
diff --git a/app/code/Magento/Paypal/view/adminhtml/web/js/rules/conflict.js b/app/code/Magento/Paypal/view/adminhtml/web/js/rules/conflict.js
new file mode 100644
index 0000000000000000000000000000000000000000..783c841a05c7e4d1e1f11f0b1e8b1d78784d0059
--- /dev/null
+++ b/app/code/Magento/Paypal/view/adminhtml/web/js/rules/conflict.js
@@ -0,0 +1,30 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+(function() {
+    var executed = false;
+    define([], function () {
+        "use strict";
+        return function ($target, $owner, data) {
+            if ($owner.find(data.enableButton).val() == 1) {
+                var isDisabled = true;
+
+                _.every(data.argument, function (name) {
+                    if (data.solutionsElements[name]
+                        && data.solutionsElements[name].find(data.enableButton).val() == 1
+                    ) {
+                        isDisabled = false;
+                        return isDisabled;
+                    }
+                    return isDisabled;
+                }, this);
+
+                if (!isDisabled && !executed) {
+                    executed = true;
+                    alert("The following error(s) occured:\n\rSome PayPal solutions conflict.\n\rPlease re-enable the previously enabled payment solutions.");
+                }
+            }
+        };
+    });
+})();
diff --git a/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/iframe-methods.js b/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/iframe-methods.js
index 1a76848002e7df1bcb59f97336bec7159744150b..a3c7eaa215389926832e1d38573ef340aebdf2cc 100644
--- a/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/iframe-methods.js
+++ b/app/code/Magento/Paypal/view/frontend/web/js/view/payment/method-renderer/iframe-methods.js
@@ -28,8 +28,14 @@ define(
              * Places order in pending payment status.
              */
             placePendingPaymentOrder: function () {
-                this.placeOrder(false);
-                this.isInAction(true);
+                if (this.placeOrder()) {
+                    this.isInAction(true);
+                    // capture all click events
+                    document.addEventListener('click', function(event) {
+                        event.stopImmediatePropagation();
+                        event.preventDefault();
+                    }, true);
+                }
             }
         });
     }
diff --git a/app/code/Magento/Quote/Model/Quote/Item/Processor.php b/app/code/Magento/Quote/Model/Quote/Item/Processor.php
index 9c0894a785ef5b343be81f6d03b95e221bb6139e..ad17f5a8ea5be4e4571d9ae9136742a1665e09b2 100644
--- a/app/code/Magento/Quote/Model/Quote/Item/Processor.php
+++ b/app/code/Magento/Quote/Model/Quote/Item/Processor.php
@@ -94,7 +94,7 @@ class Processor
         /**
          * We specify qty after we know about parent (for stock)
          */
-        if ($request->getResetCount()) {
+        if ($request->getResetCount() && !$candidate->getStickWithinParent() && $item->getId() == $request->getId()) {
             $item->setData(CartItemInterface::KEY_QTY, 0);
         }
         $item->addQty($candidate->getCartQty());
diff --git a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/ProcessorTest.php b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/ProcessorTest.php
index b27d2ca465a3ed917f61c7973ae980f9619ada18..84864eab6296e38a55b1fe3cb0c56987c27d140f 100644
--- a/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/ProcessorTest.php
+++ b/app/code/Magento/Quote/Test/Unit/Model/Quote/Item/ProcessorTest.php
@@ -72,7 +72,16 @@ class ProcessorTest extends \PHPUnit_Framework_TestCase
 
         $this->itemMock = $this->getMock(
             'Magento\Quote\Model\Quote\Item',
-            ['getId', 'setOptions', '__wakeup', 'setProduct', 'addQty', 'setCustomPrice', 'setOriginalCustomPrice'],
+            [
+                'getId',
+                'setOptions',
+                '__wakeup',
+                'setProduct',
+                'addQty',
+                'setCustomPrice',
+                'setOriginalCustomPrice',
+                'setData'
+            ],
             [],
             '',
             false
@@ -109,7 +118,7 @@ class ProcessorTest extends \PHPUnit_Framework_TestCase
 
         $this->productMock = $this->getMock(
             'Magento\Catalog\Model\Product',
-            ['getCustomOptions', '__wakeup', 'getParentProductId', 'getCartQty'],
+            ['getCustomOptions', '__wakeup', 'getParentProductId', 'getCartQty', 'getStickWithinParent'],
             [],
             '',
             false
@@ -148,8 +157,12 @@ class ProcessorTest extends \PHPUnit_Framework_TestCase
             ->will($this->returnValue($itemId));
         $this->itemMock->expects($this->any())
             ->method('setData')
-            ->with($this->equalTo('qty'), $this->equalTo(0));
-
+            ->willReturnMap(
+                [
+                    ['store_id', $storeId],
+                    ['qty', 0],
+                ]
+            );
 
         $this->storeMock->expects($this->any())
             ->method('getId')
@@ -177,7 +190,6 @@ class ProcessorTest extends \PHPUnit_Framework_TestCase
             ->method('getParentProductId')
             ->will($this->returnValue(true));
 
-
         $this->itemMock->expects($this->never())->method('setOptions');
         $this->itemMock->expects($this->never())->method('setProduct');
 
@@ -185,7 +197,13 @@ class ProcessorTest extends \PHPUnit_Framework_TestCase
             ->method('getId')
             ->will($this->returnValue($itemId));
 
-        $this->itemMock->expects($this->never())->method('setData');
+        $this->itemMock->expects($this->any())
+            ->method('setData')
+            ->willReturnMap(
+                [
+                    ['store_id', $storeId],
+                ]
+            );
 
         $this->storeMock->expects($this->any())
             ->method('getId')
@@ -222,7 +240,13 @@ class ProcessorTest extends \PHPUnit_Framework_TestCase
             ->method('getId')
             ->will($this->returnValue($itemId));
 
-        $this->itemMock->expects($this->never())->method('setData');
+        $this->itemMock->expects($this->any())
+            ->method('setData')
+            ->willReturnMap(
+                [
+                    ['store_id', $storeId],
+                ]
+            );
 
         $this->storeMock->expects($this->any())
             ->method('getId')
@@ -238,58 +262,171 @@ class ProcessorTest extends \PHPUnit_Framework_TestCase
     {
         $qty = 3000000000;
         $customPrice = 400000000;
+        $itemId = 1;
+        $requestItemId = 1;
 
         $this->productMock->expects($this->any())
             ->method('getCartQty')
             ->will($this->returnValue($qty));
+        $this->productMock->expects($this->any())
+            ->method('getStickWithinParent')
+            ->will($this->returnValue(false));
 
-        $this->itemMock->expects($this->any())
+        $this->itemMock->expects($this->once())
             ->method('addQty')
             ->with($qty);
+        $this->itemMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($itemId));
+        $this->itemMock->expects($this->never())
+            ->method('setData');
 
         $this->objectMock->expects($this->any())
             ->method('getCustomPrice')
             ->will($this->returnValue($customPrice));
+        $this->objectMock->expects($this->any())
+            ->method('getResetCount')
+            ->will($this->returnValue(false));
+        $this->objectMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($requestItemId));
+
+        $this->itemMock->expects($this->once())
+            ->method('setCustomPrice')
+            ->will($this->returnValue($customPrice));
+        $this->itemMock->expects($this->once())
+            ->method('setOriginalCustomPrice')
+            ->will($this->returnValue($customPrice));
 
+        $this->processor->prepare($this->itemMock, $this->objectMock, $this->productMock);
+    }
+
+    public function testPrepareWithResetCountAndStick()
+    {
+        $qty = 3000000000;
+        $customPrice = 400000000;
+        $itemId = 1;
+        $requestItemId = 1;
+
+        $this->productMock->expects($this->any())
+            ->method('getCartQty')
+            ->will($this->returnValue($qty));
+        $this->productMock->expects($this->any())
+            ->method('getStickWithinParent')
+            ->will($this->returnValue(true));
+
+        $this->itemMock->expects($this->once())
+            ->method('addQty')
+            ->with($qty);
         $this->itemMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($itemId));
+        $this->itemMock->expects($this->never())
+            ->method('setData');
+
+        $this->objectMock->expects($this->any())
+            ->method('getCustomPrice')
+            ->will($this->returnValue($customPrice));
+        $this->objectMock->expects($this->any())
+            ->method('getResetCount')
+            ->will($this->returnValue(true));
+        $this->objectMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($requestItemId));
+
+        $this->itemMock->expects($this->once())
             ->method('setCustomPrice')
             ->will($this->returnValue($customPrice));
+        $this->itemMock->expects($this->once())
+            ->method('setOriginalCustomPrice')
+            ->will($this->returnValue($customPrice));
+
+        $this->processor->prepare($this->itemMock, $this->objectMock, $this->productMock);
+    }
+
+    public function testPrepareWithResetCountAndNotStickAndOtherItemId()
+    {
+        $qty = 3000000000;
+        $customPrice = 400000000;
+        $itemId = 1;
+        $requestItemId = 2;
+
+        $this->productMock->expects($this->any())
+            ->method('getCartQty')
+            ->will($this->returnValue($qty));
+        $this->productMock->expects($this->any())
+            ->method('getStickWithinParent')
+            ->will($this->returnValue(false));
+
+        $this->itemMock->expects($this->once())
+            ->method('addQty')
+            ->with($qty);
         $this->itemMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($itemId));
+        $this->itemMock->expects($this->never())
+            ->method('setData');
+
+        $this->objectMock->expects($this->any())
+            ->method('getCustomPrice')
+            ->will($this->returnValue($customPrice));
+        $this->objectMock->expects($this->any())
+            ->method('getResetCount')
+            ->will($this->returnValue(true));
+        $this->objectMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($requestItemId));
+
+        $this->itemMock->expects($this->once())
+            ->method('setCustomPrice')
+            ->will($this->returnValue($customPrice));
+        $this->itemMock->expects($this->once())
             ->method('setOriginalCustomPrice')
             ->will($this->returnValue($customPrice));
 
         $this->processor->prepare($this->itemMock, $this->objectMock, $this->productMock);
     }
 
-    public function testPrepareResetCount()
+    public function testPrepareWithResetCountAndNotStickAndSameItemId()
     {
         $qty = 3000000000;
         $customPrice = 400000000;
+        $itemId = 1;
+        $requestItemId = 1;
 
         $this->objectMock->expects($this->any())
             ->method('getResetCount')
             ->will($this->returnValue(true));
 
         $this->itemMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($itemId));
+        $this->itemMock->expects($this->once())
             ->method('setData')
             ->with(CartItemInterface::KEY_QTY, 0);
 
         $this->productMock->expects($this->any())
             ->method('getCartQty')
             ->will($this->returnValue($qty));
+        $this->productMock->expects($this->any())
+            ->method('getStickWithinParent')
+            ->will($this->returnValue(false));
 
-        $this->itemMock->expects($this->any())
+        $this->itemMock->expects($this->once())
             ->method('addQty')
             ->with($qty);
 
         $this->objectMock->expects($this->any())
             ->method('getCustomPrice')
             ->will($this->returnValue($customPrice));
+        $this->objectMock->expects($this->any())
+            ->method('getId')
+            ->will($this->returnValue($requestItemId));
 
-        $this->itemMock->expects($this->any())
+        $this->itemMock->expects($this->once())
             ->method('setCustomPrice')
             ->will($this->returnValue($customPrice));
-        $this->itemMock->expects($this->any())
+        $this->itemMock->expects($this->once())
             ->method('setOriginalCustomPrice')
             ->will($this->returnValue($customPrice));
 
diff --git a/app/code/Magento/Reports/Model/Event/Observer.php b/app/code/Magento/Reports/Model/Event/Observer.php
index cde42e07e9f5923a1752f8ad1e833f009dce37f3..560e58b337bf69b22b44f09abeae86b60357dba6 100644
--- a/app/code/Magento/Reports/Model/Event/Observer.php
+++ b/app/code/Magento/Reports/Model/Event/Observer.php
@@ -151,7 +151,7 @@ class Observer
         $productId = $observer->getEvent()->getProduct()->getId();
 
         $viewData['product_id'] = $productId;
-
+        $viewData['store_id']   = $this->_storeManager->getStore()->getId();
         if ($this->_customerSession->isLoggedIn()) {
             $viewData['customer_id'] = $this->_customerSession->getCustomerId();
         } else {
diff --git a/app/code/Magento/Reports/Test/Unit/Model/Event/ObserverTest.php b/app/code/Magento/Reports/Test/Unit/Model/Event/ObserverTest.php
index 7e53522ac6680d17587318727bf538a6bebbdd0e..f1ecde466b1d9438c59ee0f41603407504db91bd 100644
--- a/app/code/Magento/Reports/Test/Unit/Model/Event/ObserverTest.php
+++ b/app/code/Magento/Reports/Test/Unit/Model/Event/ObserverTest.php
@@ -85,7 +85,6 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
 
         /** @var \Magento\Store\Model\StoreManagerInterface|\PHPUnit_Framework_MockObject_MockObject $storeManager */
         $storeManager = $this->getMock('Magento\Store\Model\StoreManagerInterface');
-
         $this->storeMock = $this->getMockBuilder('\Magento\Store\Model\Store')
             ->disableOriginalConstructor()->getMock();
 
@@ -128,7 +127,8 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
         $storeId = 1;
         $expectedViewedData = [
             'product_id' => $productId,
-            'customer_id' => $customerId
+            'customer_id' => $customerId,
+            'store_id' => $storeId,
         ];
 
         $expectedEventData = [
@@ -160,7 +160,8 @@ class ObserverTest extends \PHPUnit_Framework_TestCase
         $storeId = 1;
         $expectedViewedData = [
             'product_id' => $productId,
-            'visitor_id' => $visitorId
+            'visitor_id' => $visitorId,
+            'store_id' => $storeId,
         ];
 
         $expectedEventData = [
diff --git a/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php b/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php
index 5373f40402736e30b617017e230aad9e391caba0..1b5c239c17835b786b6a1b8b8909453417f7be87 100644
--- a/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php
+++ b/app/code/Magento/Sales/Controller/Adminhtml/Order/ReviewPayment.php
@@ -34,16 +34,23 @@ class ReviewPayment extends \Magento\Sales\Controller\Adminhtml\Order
                         break;
                     case 'update':
                         $order->getPayment()->update();
-                        $message = __('The payment update has been made.');
+                        if ($order->getPayment()->getIsTransactionApproved()) {
+                            $message = __('Transaction has been approved.');
+                        } else if ($order->getPayment()->getIsTransactionDenied()) {
+                            $message = __('Transaction has been voided/declined.');
+                        } else {
+                            $message = __('There is no update for the transaction.');
+                        }
                         break;
                     default:
                         throw new \Exception(sprintf('Action "%s" is not supported.', $action));
                 }
                 $order->save();
                 $this->messageManager->addSuccess($message);
+            } else {
+                $resultRedirect->setPath('sales/*/');
+                return $resultRedirect;
             }
-            $resultRedirect->setPath('sales/*/');
-            return $resultRedirect;
         } catch (\Magento\Framework\Exception\LocalizedException $e) {
             $this->messageManager->addError($e->getMessage());
         } catch (\Exception $e) {
diff --git a/app/code/Magento/Sales/Model/Order.php b/app/code/Magento/Sales/Model/Order.php
old mode 100644
new mode 100755
index 902d0719ee99723301c41fbc6012133cfe47121d..d843ae55ec914c73b45e9f681717178a4578c81a
--- a/app/code/Magento/Sales/Model/Order.php
+++ b/app/code/Magento/Sales/Model/Order.php
@@ -1067,6 +1067,17 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface
         return $this;
     }
 
+    /**
+     * Is order status in DB "Fraud detected"
+     *
+     * @return bool
+     */
+    public function isFraudDetected()
+    {
+        return $this->getOrigData(self::STATE) == self::STATE_PAYMENT_REVIEW
+            && $this->getOrigData(self::STATUS) == self::STATUS_FRAUD;
+    }
+
     /**
      * Prepare order totals to cancellation
      *
@@ -1074,10 +1085,11 @@ class Order extends AbstractModel implements EntityInterface, OrderInterface
      * @param bool $graceful
      * @return $this
      * @throws \Magento\Framework\Exception\LocalizedException
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      */
     public function registerCancellation($comment = '', $graceful = true)
     {
-        if ($this->canCancel() || $this->isPaymentReview()) {
+        if ($this->canCancel() || $this->isPaymentReview() || $this->isFraudDetected()) {
             $state = self::STATE_CANCELED;
             foreach ($this->getAllItems() as $item) {
                 if ($state != self::STATE_PROCESSING && $item->getQtyToRefund()) {
diff --git a/app/code/Magento/Sales/Model/Order/Config.php b/app/code/Magento/Sales/Model/Order/Config.php
old mode 100644
new mode 100755
index aa34d1b3d2f80480d42bb27101cfb918804c53c3..6f638d146a34e3ef6e17eeba1c80ae9dc52489cc
--- a/app/code/Magento/Sales/Model/Order/Config.php
+++ b/app/code/Magento/Sales/Model/Order/Config.php
@@ -37,18 +37,35 @@ class Config
      */
     protected $orderStatusCollectionFactory;
 
+    /**
+     * @var \Magento\Framework\App\State
+     */
+    protected $state;
+
+    /**
+     * @var array
+     */
+    protected $maskStatusesMapping = [
+        \Magento\Framework\App\Area::AREA_FRONTEND => [
+            \Magento\Sales\Model\Order::STATUS_FRAUD => \Magento\Sales\Model\Order::STATE_PROCESSING
+        ]
+    ];
+
     /**
      * Constructor
      *
      * @param \Magento\Sales\Model\Order\StatusFactory $orderStatusFactory
      * @param \Magento\Sales\Model\Resource\Order\Status\CollectionFactory $orderStatusCollectionFactory
+     * @param \Magento\Framework\App\State $state
      */
     public function __construct(
         \Magento\Sales\Model\Order\StatusFactory $orderStatusFactory,
-        \Magento\Sales\Model\Resource\Order\Status\CollectionFactory $orderStatusCollectionFactory
+        \Magento\Sales\Model\Resource\Order\Status\CollectionFactory $orderStatusCollectionFactory,
+        \Magento\Framework\App\State $state
     ) {
         $this->orderStatusFactory = $orderStatusFactory;
         $this->orderStatusCollectionFactory = $orderStatusCollectionFactory;
+        $this->state = $state;
     }
 
     /**
@@ -101,10 +118,26 @@ class Config
      */
     public function getStatusLabel($code)
     {
+        $code = $this->maskStatusForArea($this->state->getAreaCode(), $code);
         $status = $this->orderStatusFactory->create()->load($code);
         return $status->getStoreLabel();
     }
 
+    /**
+     * Mask status for order for specified area
+     *
+     * @param string $area
+     * @param string $code
+     * @return string
+     */
+    protected function maskStatusForArea($area, $code)
+    {
+        if (isset($this->maskStatusesMapping[$area][$code])) {
+            return $this->maskStatusesMapping[$area][$code];
+        }
+        return $code;
+    }
+
     /**
      * State label getter
      *
diff --git a/app/code/Magento/Sales/Model/Order/Payment.php b/app/code/Magento/Sales/Model/Order/Payment.php
old mode 100644
new mode 100755
index 269f9e0187798ed74eb919d31c88b6aada5a6bd5..ef13f325fcec26516c4900af9a524b49cfc32490
--- a/app/code/Magento/Sales/Model/Order/Payment.php
+++ b/app/code/Magento/Sales/Model/Order/Payment.php
@@ -310,11 +310,14 @@ class Payment extends Info implements OrderPaymentInterface
                 $orderState = $order->getState() ? $order->getState() : $orderState;
                 $orderStatus = $order->getStatus() ? $order->getStatus() : $orderStatus;
             }
+        } else {
+            $order->setState($orderState)
+                ->setStatus($orderStatus);
         }
 
         $isCustomerNotified = $isCustomerNotified ?: $order->getCustomerNoteNotify();
 
-        if (!in_array($orderStatus, $order->getConfig()->getStateStatuses($orderState))) {
+        if (!array_key_exists($orderStatus, $order->getConfig()->getStateStatuses($orderState))) {
             $orderStatus = $order->getConfig()->getStateDefaultStatus($orderState);
         }
 
@@ -347,12 +350,12 @@ class Payment extends Info implements OrderPaymentInterface
                 break;
             case ($message):
             case ($originalOrderState && $message):
-            case ($originalOrderState != $orderState):
-            case ($originalOrderStatus != $orderStatus):
-                $order->setState($orderState)
-                    ->setStatus($orderStatus)
-                    ->addStatusHistoryComment($message)
-                    ->setIsCustomerNotified($isCustomerNotified);
+                if ($originalOrderState != $orderState || $originalOrderStatus != $orderStatus) {
+                    $order->setState($orderState)
+                        ->setStatus($orderStatus)
+                        ->addStatusHistoryComment($message)
+                        ->setIsCustomerNotified($isCustomerNotified);
+                }
                 break;
             default:
                 break;
@@ -407,6 +410,9 @@ class Payment extends Info implements OrderPaymentInterface
         if (is_null($invoice)) {
             $invoice = $this->_invoice();
             $this->setCreatedInvoice($invoice);
+            if ($this->getIsFraudDetected()) {
+                $this->getOrder()->setStatus(Order::STATUS_FRAUD);
+            }
             return $this;
         }
         $amountToCapture = $this->_formatAmount($invoice->getBaseGrandTotal());
@@ -444,7 +450,7 @@ class Payment extends Info implements OrderPaymentInterface
             );
         }
         $status = false;
-        if (!$invoice->getIsPaid() && !$this->getIsTransactionPending()) {
+        if (!$invoice->getIsPaid()) {
             // attempt to capture: this can trigger "is_transaction_pending"
             $method = $this->getMethodInstance();
             $method->setStore(
@@ -1014,9 +1020,15 @@ class Payment extends Info implements OrderPaymentInterface
     {
         $transactionId = $isOnline ? $this->getLastTransId() : $this->getTransactionId();
 
-        $result = $isOnline ?
-            $this->getMethodInstance()->setStore($this->getOrder()->getStoreId())->denyPayment($this) :
-            (bool)$this->getNotificationResult();
+        if ($isOnline) {
+            /** @var \Magento\Payment\Model\Method\AbstractMethod $method */
+            $method = $this->getMethodInstance();
+            $method->setStore($this->getOrder()->getStoreId());
+
+            $result = $method->denyPayment($this);
+        } else {
+            $result = (bool)$this->getNotificationResult();
+        }
 
         if ($result) {
             $invoice = $this->_getInvoiceForTransactionId($transactionId);
@@ -1241,7 +1253,7 @@ class Payment extends Info implements OrderPaymentInterface
             );
         } else {
             if ($this->getIsFraudDetected()) {
-                $state = Order::STATE_PAYMENT_REVIEW;
+                $state = Order::STATE_PROCESSING;
                 $message = __(
                     'Order is suspended as its authorizing amount %1 is suspected to be fraudulent.',
                     $this->_formatPrice($amount, $this->getCurrencyCode())
@@ -1525,7 +1537,10 @@ class Payment extends Info implements OrderPaymentInterface
     {
         $preparedMessage = $this->getPreparedMessage();
         if ($preparedMessage) {
-            if (is_string($preparedMessage)) {
+            if (
+                is_string($preparedMessage)
+                || $preparedMessage instanceof \Magento\Framework\Phrase
+            ) {
                 return $preparedMessage . ' ' . $messagePrependTo;
             } elseif (is_object(
                     $preparedMessage
diff --git a/app/code/Magento/Sales/Setup/InstallData.php b/app/code/Magento/Sales/Setup/InstallData.php
index 0c19a25a166708cb5576ca45e9ae8e79961f0ab6..2dac7727cef40f91779350184308b1bbf82379ac 100644
--- a/app/code/Magento/Sales/Setup/InstallData.php
+++ b/app/code/Magento/Sales/Setup/InstallData.php
@@ -101,7 +101,7 @@ class InstallData implements InstallDataInterface
             ],
             'processing' => [
                 'label' => __('Processing'),
-                'statuses' => ['processing' => ['default' => '1']],
+                'statuses' => ['processing' => ['default' => '1'], 'fraud' => []],
                 'visible_on_front' => true,
             ],
             'complete' => [
diff --git a/app/code/Magento/Sales/Setup/InstallSchema.php b/app/code/Magento/Sales/Setup/InstallSchema.php
index a46e9c09e84a1b9b2e640d57860745c4b2e41a71..edc0cf10a36e942cae238556aa7fa0872c177cc3 100644
--- a/app/code/Magento/Sales/Setup/InstallSchema.php
+++ b/app/code/Magento/Sales/Setup/InstallSchema.php
@@ -1893,7 +1893,7 @@ class InstallSchema implements InstallSchemaInterface
         )->addColumn(
             'cc_last_4',
             \Magento\Framework\DB\Ddl\Table::TYPE_TEXT,
-            4,
+            100,
             [],
             'Cc Last 4'
         )->addColumn(
diff --git a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/ReviewPaymentTest.php b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/ReviewPaymentTest.php
old mode 100644
new mode 100755
index b2d3cd81597345f3163dfa3ae21a9342806828af..1f53e7b02b5979a38f5aa1706af57ceabaa73efa
--- a/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/ReviewPaymentTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Controller/Adminhtml/Order/ReviewPaymentTest.php
@@ -77,7 +77,7 @@ class ReviewPaymentTest extends \PHPUnit_Framework_TestCase
 
         $this->paymentMock = $this->getMock(
             'Magento\Sales\Model\Order\Payment',
-            ['update'],
+            ['update', 'getIsTransactionApproved'],
             [],
             '',
             false
@@ -143,15 +143,18 @@ class ReviewPaymentTest extends \PHPUnit_Framework_TestCase
 
         $this->orderMock->expects($this->once())->method('load')->with($orderId)->willReturn($this->orderMock);
         $this->orderMock->expects($this->any())->method('getId')->willReturn($orderId);
-        $this->orderMock->expects($this->once())->method('getPayment')->willReturn($this->paymentMock);
+        $this->orderMock->expects($this->any())->method('getPayment')->willReturn($this->paymentMock);
         $this->orderMock->expects($this->once())->method('save')->willReturnSelf();
 
-        $this->messageManagerMock->expects($this->once())->method('addSuccess')
-            ->with('The payment update has been made.');
-
-        $this->resultRedirectMock->expects($this->once())->method('setPath')->with('sales/*/')->willReturnSelf();
-
         $this->paymentMock->expects($this->once())->method('update');
+        $this->paymentMock->expects($this->any())->method('getIsTransactionApproved')->willReturn(true);
+        
+        $this->messageManagerMock->expects($this->once())->method('addSuccess');
+
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('sales/order/view')
+            ->willReturnSelf();
 
         $result = $this->reviewPayment->execute();
         $this->assertEquals($this->resultRedirectMock, $result);
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/ConfigTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/ConfigTest.php
old mode 100644
new mode 100755
index 19dc8e6fce76fceddb6a0411fd35c140faa1fdd8..0cfd5e052ef0ea4f61fe2b396d6fbe19543272d1
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/ConfigTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/ConfigTest.php
@@ -33,7 +33,14 @@ class ConfigTest extends \PHPUnit_Framework_TestCase
             false,
             false
         );
-        $this->salesConfig = new Config($orderStatusFactory, $this->orderStatusCollectionFactoryMock);
+        $this->salesConfig = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))
+            ->getObject(
+                'Magento\Sales\Model\Order\Config',
+                [
+                    'orderStatusFactory' => $orderStatusFactory,
+                    'orderStatusCollectionFactory' => $this->orderStatusCollectionFactoryMock
+                ]
+            );
     }
 
     public function testGetInvisibleOnFrontStatuses()
diff --git a/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php b/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php
old mode 100644
new mode 100755
index a4f473ef75b3f5259d0a4252b7c44e85c4c2a847..2612afa5dd8dd4717367639427060134bb87bcba
--- a/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php
+++ b/app/code/Magento/Sales/Test/Unit/Model/Order/PaymentTest.php
@@ -133,7 +133,8 @@ class PaymentTest extends \PHPUnit_Framework_TestCase
                     'denyPayment',
                     'fetchTransactionInfo',
                     'canCapture',
-                    'canRefund'
+                    'canRefund',
+                    'canOrder',
                 ]
             )
             ->getMock();
@@ -254,8 +255,12 @@ class PaymentTest extends \PHPUnit_Framework_TestCase
             ->method('getMethodInstance')
             ->will($this->returnValue($this->paymentMethodMock));
 
-        $this->mockGetDefaultStatus(Order::STATE_NEW, $newOrderStatus, ['first', 'second']);
+        $this->paymentMethodMock->expects($this->any())
+            ->method('getConfigData')
+            ->with('order_status', null)
+            ->willReturn($newOrderStatus);
 
+        $this->mockGetDefaultStatus(Order::STATE_NEW, $newOrderStatus, ['first', 'second']);
         $this->assertOrderUpdated(Order::STATE_NEW, $newOrderStatus);
 
         $this->paymentMethodMock->expects($this->once())
@@ -365,7 +370,7 @@ class PaymentTest extends \PHPUnit_Framework_TestCase
             ->method('getBaseCurrency')
             ->willReturn($baseCurrencyMock);
 
-        $this->assertOrderUpdated(Order::STATE_PAYMENT_REVIEW, Order::STATUS_FRAUD, $message);
+        $this->assertOrderUpdated(Order::STATE_PROCESSING, Order::STATUS_FRAUD, $message);
 
         $this->paymentMethodMock->expects($this->once())
             ->method('authorize')
diff --git a/app/code/Magento/Sales/etc/di.xml b/app/code/Magento/Sales/etc/di.xml
old mode 100644
new mode 100755
index 28ea25b9dcf30f4db415e56c8f90753867ff14be..8b0d60ea3c63cf9cfcc05fd415a49e7c1e3cb356
--- a/app/code/Magento/Sales/etc/di.xml
+++ b/app/code/Magento/Sales/etc/di.xml
@@ -268,4 +268,9 @@
             <argument name="entityRelationComposite" xsi:type="object">CreditmemoRelationsComposite</argument>
         </arguments>
     </type>
+    <type name="Magento\Sales\Model\Order\Config">
+        <arguments>
+            <argument name="state" xsi:type="object">Magento\Framework\App\State\Proxy</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_view.xml b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_view.xml
index 19260c6cf0849dd9c89287a9291eed94c459d08a..f0c99ecaf4464a39c7e2b1263325e8fd8a6f13d1 100644
--- a/app/code/Magento/Sales/view/adminhtml/layout/sales_order_view.xml
+++ b/app/code/Magento/Sales/view/adminhtml/layout/sales_order_view.xml
@@ -31,6 +31,8 @@
                         <block class="Magento\Sales\Block\Adminhtml\Items\Column\Name" name="column_name" template="items/column/name.phtml" group="column"/>
                         <block class="Magento\Framework\View\Element\Text\ListText" name="order_item_extra_info"/>
                     </block>
+
+                    <container name="payment_additional_info" htmlTag="div" htmlClass="order-payment-additional" />
                     <block class="Magento\Sales\Block\Adminhtml\Order\Payment" name="order_payment"/>
                     <block class="Magento\Sales\Block\Adminhtml\Order\View\History" name="order_history" template="order/view/history.phtml"/>
                     <block class="Magento\Backend\Block\Template" name="gift_options" template="Magento_Sales::order/giftoptions.phtml">
diff --git a/app/code/Magento/Sales/view/adminhtml/templates/order/view/tab/info.phtml b/app/code/Magento/Sales/view/adminhtml/templates/order/view/tab/info.phtml
index 3a8b3cf29d08482c4f2568b89b482292ffbdab41..b4dbc4a8426d92c579ba4a2ec0a752a54ce66c7f 100644
--- a/app/code/Magento/Sales/view/adminhtml/templates/order/view/tab/info.phtml
+++ b/app/code/Magento/Sales/view/adminhtml/templates/order/view/tab/info.phtml
@@ -30,7 +30,10 @@
             <div class="admin__page-section-item-content">
                 <div class="order-payment-method-title"><?php echo $block->getPaymentHtml() ?></div>
                 <div class="order-payment-currency"><?php echo __('The order was placed using %1.', $_order->getOrderCurrencyCode()) ?></div>
-                <div class="order-payment-additional"><?php echo $block->getChildHtml('order_payment_additional'); ?></div>
+                <div class="order-payment-additional">
+                    <?php echo $block->getChildHtml('order_payment_additional'); ?>
+                    <?php echo $block->getChildHtml('payment_additional_info'); ?>
+                </div>
             </div>
         </div>
         <?php echo $block->getChildHtml('order_shipping_view') ?>
diff --git a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php
old mode 100644
new mode 100755
index ed0bab0aec2ea260f851808fcdaee177d67d4d60..2f28cf9818308b3e176783004e84ad1b91bd8a83
--- a/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php
+++ b/app/code/Magento/Sitemap/Controller/Adminhtml/Sitemap/Save.php
@@ -1,6 +1,5 @@
 <?php
 /**
- *
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
@@ -8,102 +7,149 @@ namespace Magento\Sitemap\Controller\Adminhtml\Sitemap;
 
 use Magento\Backend\App\Action;
 use Magento\Framework\App\Filesystem\DirectoryList;
+use Magento\Framework\Controller;
 
 class Save extends \Magento\Sitemap\Controller\Adminhtml\Sitemap
 {
     /**
-     * Save action
+     * Validate path for generation
      *
-     * @return void
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+     * @param array $data
+     * @return bool
+     * @throws \Exception
      */
-    public function execute()
+    protected function validatePath(array $data)
     {
-        // check if data sent
-        $data = $this->getRequest()->getPostValue();
-        if ($data) {
-            // init model and set data
-            /** @var \Magento\Sitemap\Model\Sitemap $model */
-            $model = $this->_objectManager->create('Magento\Sitemap\Model\Sitemap');
-
-            //validate path to generate
-            if (!empty($data['sitemap_filename']) && !empty($data['sitemap_path'])) {
-                $data['sitemap_path'] = '/' . ltrim($data['sitemap_path'], '/');
-                $path = rtrim($data['sitemap_path'], '\\/') . '/' . $data['sitemap_filename'];
-                /** @var $validator \Magento\MediaStorage\Model\File\Validator\AvailablePath */
-                $validator = $this->_objectManager->create('Magento\MediaStorage\Model\File\Validator\AvailablePath');
-                /** @var $helper \Magento\Sitemap\Helper\Data */
-                $helper = $this->_objectManager->get('Magento\Sitemap\Helper\Data');
-                $validator->setPaths($helper->getValidPaths());
-                if (!$validator->isValid($path)) {
-                    foreach ($validator->getMessages() as $message) {
-                        $this->messageManager->addError($message);
-                    }
-                    // save data in session
-                    $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data);
-                    // redirect to edit form
-                    $this->_redirect(
-                        'adminhtml/*/edit',
-                        ['sitemap_id' => $this->getRequest()->getParam('sitemap_id')]
-                    );
-                    return;
+        if (!empty($data['sitemap_filename']) && !empty($data['sitemap_path'])) {
+            $data['sitemap_path'] = '/' . ltrim($data['sitemap_path'], '/');
+            $path = rtrim($data['sitemap_path'], '\\/') . '/' . $data['sitemap_filename'];
+            /** @var $validator \Magento\MediaStorage\Model\File\Validator\AvailablePath */
+            $validator = $this->_objectManager->create('Magento\MediaStorage\Model\File\Validator\AvailablePath');
+            /** @var $helper \Magento\Sitemap\Helper\Data */
+            $helper = $this->_objectManager->get('Magento\Sitemap\Helper\Data');
+            $validator->setPaths($helper->getValidPaths());
+            if (!$validator->isValid($path)) {
+                foreach ($validator->getMessages() as $message) {
+                    $this->messageManager->addError($message);
                 }
+                // save data in session
+                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data);
+                // redirect to edit form
+                return false;
             }
+        }
+        return true;
+    }
 
-            /** @var \Magento\Framework\Filesystem\Directory\Write $directory */
-            $directory = $this->_objectManager->get(
-                'Magento\Framework\Filesystem'
-            )->getDirectoryWrite(
-                DirectoryList::ROOT
-            );
+    /**
+     * Clear sitemap
+     *
+     * @param \Magento\Sitemap\Model\Sitemap $model
+     * @return void
+     */
+    protected function clearSiteMap(\Magento\Sitemap\Model\Sitemap $model)
+    {
+        /** @var \Magento\Framework\Filesystem\Directory\Write $directory */
+        $directory = $this->_objectManager->get('Magento\Framework\Filesystem')
+            ->getDirectoryWrite(DirectoryList::ROOT);
 
-            if ($this->getRequest()->getParam('sitemap_id')) {
-                $model->load($this->getRequest()->getParam('sitemap_id'));
-                $fileName = $model->getSitemapFilename();
+        if ($this->getRequest()->getParam('sitemap_id')) {
+            $model->load($this->getRequest()->getParam('sitemap_id'));
+            $fileName = $model->getSitemapFilename();
 
-                $path = $model->getSitemapPath() . '/' . $fileName;
-                if ($fileName && $directory->isFile($path)) {
-                    $directory->delete($path);
-                }
+            $path = $model->getSitemapPath() . '/' . $fileName;
+            if ($fileName && $directory->isFile($path)) {
+                $directory->delete($path);
             }
+        }
+    }
 
-            $model->setData($data);
+    /**
+     * Save data
+     *
+     * @param array $data
+     * @return string|bool
+     */
+    protected function saveData($data)
+    {
+        // init model and set data
+        /** @var \Magento\Sitemap\Model\Sitemap $model */
+        $model = $this->_objectManager->create('Magento\Sitemap\Model\Sitemap');
+        $this->clearSiteMap($model);
+        $model->setData($data);
 
-            // try to save it
-            try {
-                // save the data
-                $model->save();
-                // display success message
-                $this->messageManager->addSuccess(__('You saved the sitemap.'));
-                // clear previously saved data from session
-                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false);
+        // try to save it
+        try {
+            // save the data
+            $model->save();
+            // display success message
+            $this->messageManager->addSuccess(__('You saved the sitemap.'));
+            // clear previously saved data from session
+            $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData(false);
+            return $model->getId();
+        } catch (\Exception $e) {
+            // display error message
+            $this->messageManager->addError($e->getMessage());
+            // save data in session
+            $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data);
+        }
+        return false;
+    }
 
-                // check if 'Save and Continue'
-                if ($this->getRequest()->getParam('back')) {
-                    $this->_redirect('adminhtml/*/edit', ['sitemap_id' => $model->getId()]);
-                    return;
-                }
-                // go to grid or forward to generate action
-                if ($this->getRequest()->getParam('generate')) {
-                    $this->getRequest()->setParam('sitemap_id', $model->getId());
-                    $this->_forward('generate');
-                    return;
-                }
-                $this->_redirect('adminhtml/*/');
-                return;
-            } catch (\Exception $e) {
-                // display error message
-                $this->messageManager->addError($e->getMessage());
-                // save data in session
-                $this->_objectManager->get('Magento\Backend\Model\Session')->setFormData($data);
-                // redirect to edit form
-                $this->_redirect(
+    /**
+     * Get result after saving data
+     *
+     * @param string|bool $id
+     * @return \Magento\Framework\Controller\ResultInterface
+     */
+    protected function getResult($id)
+    {
+        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(Controller\ResultFactory::TYPE_REDIRECT);
+        if ($id) {
+            // check if 'Save and Continue'
+            if ($this->getRequest()->getParam('back')) {
+                $resultRedirect->setPath('adminhtml/*/edit', ['sitemap_id' => $id]);
+                return $resultRedirect;
+            }
+            // go to grid or forward to generate action
+            if ($this->getRequest()->getParam('generate')) {
+                $this->getRequest()->setParam('sitemap_id', $id);
+                return $this->resultFactory->create(Controller\ResultFactory::TYPE_FORWARD)
+                    ->forward('generate');
+            }
+            $resultRedirect->setPath('adminhtml/*/');
+            return $resultRedirect;
+        }
+        $resultRedirect->setPath(
+            'adminhtml/*/edit',
+            ['sitemap_id' => $this->getRequest()->getParam('sitemap_id')]
+        );
+        return $resultRedirect;
+    }
+
+    /**
+     * Save action
+     *
+     * @return \Magento\Backend\Model\View\Result\Redirect
+     */
+    public function execute()
+    {
+        // check if data sent
+        $data = $this->getRequest()->getPostValue();
+        /** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
+        $resultRedirect = $this->resultFactory->create(Controller\ResultFactory::TYPE_REDIRECT);
+        if ($data) {
+            if (!$this->validatePath($data)) {
+                $resultRedirect->setPath(
                     'adminhtml/*/edit',
                     ['sitemap_id' => $this->getRequest()->getParam('sitemap_id')]
                 );
-                return;
+                return $resultRedirect;
             }
+            return $this->getResult($this->saveData($data));
         }
-        $this->_redirect('adminhtml/*/');
+        $resultRedirect->setPath('adminhtml/*/');
+        return $resultRedirect;
     }
 }
diff --git a/app/code/Magento/Sitemap/Test/Unit/Controller/Adminhtml/Sitemap/SaveTest.php b/app/code/Magento/Sitemap/Test/Unit/Controller/Adminhtml/Sitemap/SaveTest.php
new file mode 100755
index 0000000000000000000000000000000000000000..e067bf2059814fdeadbd0719adda36117dfcdac0
--- /dev/null
+++ b/app/code/Magento/Sitemap/Test/Unit/Controller/Adminhtml/Sitemap/SaveTest.php
@@ -0,0 +1,171 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Sitemap\Test\Unit\Controller\Adminhtml\Sitemap;
+
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
+use Magento\Framework\Controller\ResultFactory;
+
+class SaveTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Sitemap\Controller\Adminhtml\Sitemap\Save
+     */
+    protected $saveController;
+
+    /**
+     * @var \Magento\Backend\App\Action\Context
+     */
+    protected $context;
+
+    /**
+     * @var \Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+     */
+    protected $objectManagerHelper;
+
+    /**
+     * @var \Magento\Framework\HTTP\PhpEnvironment\Request|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $requestMock;
+
+    /**
+     * @var \Magento\Framework\Controller\ResultFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultFactoryMock;
+
+    /**
+     * @var \Magento\Backend\Model\View\Result\Redirect|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $resultRedirectMock;
+
+    /**
+     * @var \Magento\Framework\ObjectManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $objectManagerMock;
+
+    /**
+     * @var \Magento\Framework\Message\ManagerInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $messageManagerMock;
+
+    protected function setUp()
+    {
+        $this->requestMock = $this->getMockBuilder('Magento\Framework\App\RequestInterface')
+            ->disableOriginalConstructor()
+            ->setMethods(['getPostValue'])
+            ->getMockForAbstractClass();
+        $this->resultRedirectMock = $this->getMockBuilder('Magento\Backend\Model\View\Result\Redirect')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->resultFactoryMock = $this->getMockBuilder('Magento\Framework\Controller\ResultFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->objectManagerMock = $this->getMockBuilder('Magento\Framework\ObjectManagerInterface')
+            ->getMock();
+        $this->messageManagerMock = $this->getMockBuilder('Magento\Framework\Message\ManagerInterface')
+            ->getMock();
+
+        $this->resultFactoryMock->expects($this->once())
+            ->method('create')
+            ->with(ResultFactory::TYPE_REDIRECT)
+            ->willReturn($this->resultRedirectMock);
+
+        $this->objectManagerHelper = new ObjectManagerHelper($this);
+        $this->context = $this->objectManagerHelper->getObject(
+            'Magento\Backend\App\Action\Context',
+            [
+                'resultFactory' => $this->resultFactoryMock,
+                'request' => $this->requestMock,
+                'messageManager' => $this->messageManagerMock,
+                'objectManager' => $this->objectManagerMock
+            ]
+        );
+        $this->saveController = $this->objectManagerHelper->getObject(
+            'Magento\Sitemap\Controller\Adminhtml\Sitemap\Save',
+            [
+                'context' => $this->context
+            ]
+        );
+    }
+
+    public function testSaveEmptyDataShouldRedirectToDefault()
+    {
+        $this->requestMock->expects($this->once())
+            ->method('getPostValue')
+            ->willReturn([]);
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('adminhtml/*/')
+            ->willReturnSelf();
+
+        $this->assertSame($this->resultRedirectMock, $this->saveController->execute());
+    }
+
+    public function testTryToSaveInvalidDataShouldFailWithErrors()
+    {
+        $validatorClass = 'Magento\MediaStorage\Model\File\Validator\AvailablePath';
+        $helperClass = 'Magento\Sitemap\Helper\Data';
+        $validPaths = [];
+        $messages = ['message1', 'message2'];
+        $sessionClass = 'Magento\Backend\Model\Session';
+        $data = ['sitemap_filename' => 'sitemap_filename', 'sitemap_path' => '/sitemap_path'];
+        $siteMapId = 1;
+
+        $this->requestMock->expects($this->once())
+            ->method('getPostValue')
+            ->willReturn($data);
+        $this->requestMock->expects($this->once())
+            ->method('getParam')
+            ->with('sitemap_id')
+            ->willReturn($siteMapId);
+
+        $validator = $this->getMock($validatorClass, [], [], '', false);
+        $validator->expects($this->once())
+            ->method('setPaths')
+            ->with($validPaths)
+            ->willReturnSelf();
+        $validator->expects($this->once())
+            ->method('isValid')
+            ->with('/sitemap_path/sitemap_filename')
+            ->willReturn(false);
+        $validator->expects($this->once())
+            ->method('getMessages')
+            ->willReturn($messages);
+
+        $helper = $this->getMock($helperClass, [], [], '', false);
+        $helper->expects($this->once())
+            ->method('getValidPaths')
+            ->willReturn($validPaths);
+
+        $session = $this->getMock($sessionClass, ['setFormData'], [], '', false);
+        $session->expects($this->once())
+            ->method('setFormData')
+            ->with($data)
+            ->willReturnSelf();
+
+        $this->objectManagerMock->expects($this->once())
+            ->method('create')
+            ->with($validatorClass)
+            ->willReturn($validator);
+        $this->objectManagerMock->expects($this->any())
+            ->method('get')
+            ->willReturnMap([[$helperClass, $helper], [$sessionClass, $session]]);
+
+        $this->messageManagerMock->expects($this->at(0))
+            ->method('addError')
+            ->withConsecutive(
+                [$messages[0]],
+                [$messages[1]]
+            )
+            ->willReturnSelf();
+
+        $this->resultRedirectMock->expects($this->once())
+            ->method('setPath')
+            ->with('adminhtml/*/edit', ['sitemap_id' => $siteMapId])
+            ->willReturnSelf();
+
+        $this->assertSame($this->resultRedirectMock, $this->saveController->execute());
+    }
+}
diff --git a/app/code/Magento/Tax/Model/Calculation/Rate/Converter.php b/app/code/Magento/Tax/Model/Calculation/Rate/Converter.php
index 5fd8da907a5d8b81a297511758895d0dfa2156bd..b7dc4920d15cc99192f1a5bcc9ee1388980947d8 100644
--- a/app/code/Magento/Tax/Model/Calculation/Rate/Converter.php
+++ b/app/code/Magento/Tax/Model/Calculation/Rate/Converter.php
@@ -74,6 +74,10 @@ class Converter
             'zip_is_range' => $returnNumericLogic?0:false,
         ];
 
+        if ($taxRateFormData['tax_region_id'] === '0') {
+            $taxRateFormData['tax_region_id'] = '';
+        }
+
         if ($taxRate->getZipFrom() && $taxRate->getZipTo()) {
             $taxRateFormData['zip_is_range'] = $returnNumericLogic?1:true;
             $taxRateFormData['zip_from'] = $taxRate->getZipFrom();
diff --git a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js
index 0cc7098574c9d120f5235644bdf74ded7d9c82b2..81603bc35d9018fcc5c60c7be9f7496a8b010385 100644
--- a/app/code/Magento/Theme/view/adminhtml/requirejs-config.js
+++ b/app/code/Magento/Theme/view/adminhtml/requirejs-config.js
@@ -11,6 +11,9 @@ var config = {
         "extjs/ext-tree-checkbox": [
             "extjs/ext-tree",
             "extjs/defaults"
+        ],
+        "jquery/editableMultiselect/js/jquery.editable": [
+            "jquery"
         ]
     },
     "bundles": {
diff --git a/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php b/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php
index 6893905b14938d6e9f4906cb9c205c8563c43244..cc956ad07c5c55b55fe7a16b4d744bfea3413d18 100644
--- a/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php
+++ b/app/code/Magento/Ui/Controller/Adminhtml/AbstractAction.php
@@ -56,4 +56,12 @@ abstract class AbstractAction extends Action implements UiActionInterface
     {
         return $this->_request->getParam('component');
     }
+
+    /**
+     * @return bool
+     */
+    protected function _isAllowed()
+    {
+        return true;
+    }
 }
diff --git a/app/code/Magento/Widget/Block/Adminhtml/Widget.php b/app/code/Magento/Widget/Block/Adminhtml/Widget.php
index 645be47b201151c1677318e54621c2db6c77b8d4..cd9e5b51a8a7797c2473d4cc673e759612b5e22f 100644
--- a/app/code/Magento/Widget/Block/Adminhtml/Widget.php
+++ b/app/code/Magento/Widget/Block/Adminhtml/Widget.php
@@ -34,6 +34,7 @@ class Widget extends \Magento\Backend\Block\Widget\Form\Container
         $this->buttonList->update('save', 'id', 'insert_button');
         $this->buttonList->update('save', 'onclick', 'wWidget.insertWidget()');
         $this->buttonList->update('save', 'region', 'footer');
+        $this->buttonList->update('save', 'data_attribute', []);
 
         $this->_formScripts[] = 'require(["mage/adminhtml/wysiwyg/widget"], function(){wWidget = new WysiwygWidget.Widget(' .
             '"widget_options_form", "select_widget_type", "widget_options", "' .
diff --git a/app/code/Magento/Widget/Model/NamespaceResolver.php b/app/code/Magento/Widget/Model/NamespaceResolver.php
index f4e035bdea589a6d61f7a5fda4ca643c1e93930f..c458bc795c61f1ad12af243b01de5ce337118292 100644
--- a/app/code/Magento/Widget/Model/NamespaceResolver.php
+++ b/app/code/Magento/Widget/Model/NamespaceResolver.php
@@ -12,19 +12,19 @@ class NamespaceResolver
      *
      * @var array
      */
-    protected $_moduleNamespaces;
+    protected $moduleNamespaces;
 
     /**
      * @var \Magento\Framework\Module\ModuleListInterface
      */
-    protected $_moduleList;
+    protected $moduleList;
 
     /**
      * @param \Magento\Framework\Module\ModuleListInterface $moduleList
      */
     public function __construct(\Magento\Framework\Module\ModuleListInterface $moduleList)
     {
-        $this->_moduleList = $moduleList;
+        $this->moduleList = $moduleList;
     }
 
     /**
@@ -34,28 +34,15 @@ class NamespaceResolver
      * @param string $name
      * @param bool $asFullModuleName
      * @return string
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     public function determineOmittedNamespace($name, $asFullModuleName = false)
     {
-        if (null === $this->_moduleNamespaces) {
-            $this->_moduleNamespaces = [];
-            foreach ($this->_moduleList->getNames() as $moduleName) {
-                $module = strtolower($moduleName);
-                $this->_moduleNamespaces[substr($module, 0, strpos($module, '_'))][$module] = $moduleName;
-            }
-        }
-
-        $explodeString = strpos(
-            $name,
-            '\\'
-        ) === false ? '_' : '\\';
-        $name = explode($explodeString, strtolower($name));
+        $this->prepareModuleNamespaces();
+        $name = $this->prepareName($name);
 
         $partsNum = count($name);
         $defaultNamespaceFlag = false;
-        foreach ($this->_moduleNamespaces as $namespaceName => $namespace) {
+        foreach ($this->moduleNamespaces as $namespaceName => $namespace) {
             // assume the namespace is omitted (default namespace only, which comes first)
             if ($defaultNamespaceFlag === false) {
                 $defaultNamespaceFlag = true;
@@ -74,4 +61,32 @@ class NamespaceResolver
         }
         return '';
     }
+
+    /**
+     * Prepare module namespaces
+     *
+     * @return void
+     */
+    protected function prepareModuleNamespaces()
+    {
+        if (null === $this->moduleNamespaces) {
+            $this->moduleNamespaces = [];
+            foreach ($this->moduleList->getNames() as $moduleName) {
+                $module = strtolower($moduleName);
+                $this->moduleNamespaces[substr($module, 0, strpos($module, '_'))][$module] = $moduleName;
+            }
+        }
+    }
+
+    /**
+     * Prepare name
+     *
+     * @param string $name
+     * @return array
+     */
+    protected function prepareName($name)
+    {
+        $explodeString = strpos($name, '\\') === false ? '_' : '\\';
+        return explode($explodeString, strtolower($name));
+    }
 }
diff --git a/app/code/Magento/Widget/Model/Widget.php b/app/code/Magento/Widget/Model/Widget.php
index 8dcdc466ebb6870ecf20bcbc603c17bece868341..9ac4133834602fec95dbb0415cb2a311c15f15b5 100644
--- a/app/code/Magento/Widget/Model/Widget.php
+++ b/app/code/Magento/Widget/Model/Widget.php
@@ -3,9 +3,6 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
-// @codingStandardsIgnoreFile
-
 namespace Magento\Widget\Model;
 
 /**
@@ -16,39 +13,37 @@ class Widget
     /**
      * @var \Magento\Widget\Model\Config\Data
      */
-    protected $_dataStorage;
+    protected $dataStorage;
 
     /**
      * @var \Magento\Framework\App\Cache\Type\Config
      */
-    protected $_configCacheType;
+    protected $configCacheType;
 
     /**
      * @var \Magento\Framework\View\Asset\Repository
      */
-    protected $_assetRepo;
+    protected $assetRepo;
 
     /**
      * @var \Magento\Framework\View\Asset\Source
      */
-    protected $_assetSource;
+    protected $assetSource;
 
     /**
      * @var \Magento\Framework\View\FileSystem
      */
-    protected $_viewFileSystem;
+    protected $viewFileSystem;
 
     /**
-     * Core data
-     *
      * @var \Magento\Framework\Escaper
      */
-    protected $_escaper;
+    protected $escaper;
 
     /**
      * @var array
      */
-    protected $_widgetsArray = [];
+    protected $widgetsArray = [];
 
     /**
      * @var \Magento\Widget\Helper\Conditions
@@ -71,11 +66,11 @@ class Widget
         \Magento\Framework\View\FileSystem $viewFileSystem,
         \Magento\Widget\Helper\Conditions $conditionsHelper
     ) {
-        $this->_escaper = $escaper;
-        $this->_dataStorage = $dataStorage;
-        $this->_assetRepo = $assetRepo;
-        $this->_assetSource = $assetSource;
-        $this->_viewFileSystem = $viewFileSystem;
+        $this->escaper = $escaper;
+        $this->dataStorage = $dataStorage;
+        $this->assetRepo = $assetRepo;
+        $this->assetSource = $assetSource;
+        $this->viewFileSystem = $viewFileSystem;
         $this->conditionsHelper = $conditionsHelper;
     }
 
@@ -118,8 +113,6 @@ class Widget
      *
      * @param string $type Widget type
      * @return \Magento\Framework\Object
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     public function getConfigAsObject($type)
     {
@@ -129,54 +122,92 @@ class Widget
         if ($widget === null) {
             return $object;
         }
-        $widget = $this->_getAsCanonicalArray($widget);
+        $widget = $this->getAsCanonicalArray($widget);
 
         // Save all nodes to object data
         $object->setType($type);
         $object->setData($widget);
 
         // Correct widget parameters and convert its data to objects
+        $newParams = $this->prepareWidgetParameters($object);
+        $object->setData('parameters', $newParams);
+
+        return $object;
+    }
+
+    /**
+     * Prepare widget parameters
+     *
+     * @param \Magento\Framework\Object $object
+     * @return array
+     */
+    protected function prepareWidgetParameters(\Magento\Framework\Object $object)
+    {
         $params = $object->getData('parameters');
         $newParams = [];
         if (is_array($params)) {
             $sortOrder = 0;
             foreach ($params as $key => $data) {
                 if (is_array($data)) {
-                    $data['key'] = $key;
-                    $data['sort_order'] = isset($data['sort_order']) ? (int)$data['sort_order'] : $sortOrder;
-
-                    // prepare values (for drop-dawns) specified directly in configuration
-                    $values = [];
-                    if (isset($data['values']) && is_array($data['values'])) {
-                        foreach ($data['values'] as $value) {
-                            if (isset($value['label']) && isset($value['value'])) {
-                                $values[] = $value;
-                            }
-                        }
-                    }
-                    $data['values'] = $values;
-
-                    // prepare helper block object
-                    if (isset($data['helper_block'])) {
-                        $helper = new \Magento\Framework\Object();
-                        if (isset($data['helper_block']['data']) && is_array($data['helper_block']['data'])) {
-                            $helper->addData($data['helper_block']['data']);
-                        }
-                        if (isset($data['helper_block']['type'])) {
-                            $helper->setType($data['helper_block']['type']);
-                        }
-                        $data['helper_block'] = $helper;
-                    }
+                    $data = $this->prepareDropDownValues($data, $key, $sortOrder);
+                    $data = $this->prepareHelperBlock($data);
 
                     $newParams[$key] = new \Magento\Framework\Object($data);
                     $sortOrder++;
                 }
             }
         }
-        uasort($newParams, [$this, '_sortParameters']);
-        $object->setData('parameters', $newParams);
+        uasort($newParams, [$this, 'sortParameters']);
 
-        return $object;
+        return $newParams;
+    }
+
+    /**
+     * Prepare drop-down values
+     *
+     * @param array $data
+     * @param string $key
+     * @param int $sortOrder
+     * @return array
+     */
+    protected function prepareDropDownValues(array $data, $key, $sortOrder)
+    {
+        $data['key'] = $key;
+        $data['sort_order'] = isset($data['sort_order']) ? (int)$data['sort_order'] : $sortOrder;
+
+        $values = [];
+        if (isset($data['values']) && is_array($data['values'])) {
+            foreach ($data['values'] as $value) {
+                if (isset($value['label']) && isset($value['value'])) {
+                    $values[] = $value;
+                }
+            }
+        }
+        $data['values'] = $values;
+
+        return $data;
+    }
+
+    /**
+     * Prepare helper block
+     *
+     * @param array $data
+     * @return array
+     */
+    protected function prepareHelperBlock(array $data)
+    {
+        if (isset($data['helper_block'])) {
+            $helper = new \Magento\Framework\Object();
+            if (isset($data['helper_block']['data']) && is_array($data['helper_block']['data'])) {
+                $helper->addData($data['helper_block']['data']);
+            }
+            if (isset($data['helper_block']['type'])) {
+                $helper->setType($data['helper_block']['type']);
+            }
+            $data['helper_block'] = $helper;
+        }
+
+        return $data;
     }
 
     /**
@@ -188,7 +219,7 @@ class Widget
      */
     public function getWidgets($filters = [])
     {
-        $widgets = $this->_dataStorage->get();
+        $widgets = $this->dataStorage->get();
         $result = $widgets;
 
         // filter widgets by params
@@ -219,7 +250,7 @@ class Widget
      */
     public function getWidgetsArray($filters = [])
     {
-        if (empty($this->_widgetsArray)) {
+        if (empty($this->widgetsArray)) {
             $result = [];
             foreach ($this->getWidgets($filters) as $code => $widget) {
                 $result[$widget['name']] = [
@@ -229,10 +260,10 @@ class Widget
                     'description' => __((string)$widget['description']),
                 ];
             }
-            usort($result, [$this, "_sortWidgets"]);
-            $this->_widgetsArray = $result;
+            usort($result, [$this, "sortWidgets"]);
+            $this->widgetsArray = $result;
         }
-        return $this->_widgetsArray;
+        return $this->widgetsArray;
     }
 
     /**
@@ -274,9 +305,9 @@ class Widget
 
         $html = sprintf(
             '<img id="%s" src="%s" title="%s">',
-            $this->_idEncode($directive),
+            $this->idEncode($directive),
             $this->getPlaceholderImageUrl($type),
-            $this->_escaper->escapeUrl($directive)
+            $this->escaper->escapeUrl($directive)
         );
         return $html;
     }
@@ -295,13 +326,13 @@ class Widget
             $placeholder = (string)$widget['placeholder_image'];
         }
         if ($placeholder) {
-            $asset = $this->_assetRepo->createAsset($placeholder);
-            $placeholder = $this->_assetSource->getFile($asset);
+            $asset = $this->assetRepo->createAsset($placeholder);
+            $placeholder = $this->assetSource->getFile($asset);
             if ($placeholder) {
                 return $asset->getUrl();
             }
         }
-        return $this->_assetRepo->getUrl('Magento_Widget::placeholder.gif');
+        return $this->assetRepo->getUrl('Magento_Widget::placeholder.gif');
     }
 
     /**
@@ -328,12 +359,12 @@ class Widget
     }
 
     /**
-     * Remove attributes from widget array so that emulates how \Magento\Framework\Simplexml\Element::asCanonicalArray works
+     * Remove attributes from widget array and emulate work of \Magento\Framework\Simplexml\Element::asCanonicalArray
      *
      * @param array $inputArray
      * @return array
      */
-    protected function _getAsCanonicalArray($inputArray)
+    protected function getAsCanonicalArray($inputArray)
     {
         if (array_key_exists('@', $inputArray)) {
             unset($inputArray['@']);
@@ -342,7 +373,7 @@ class Widget
             if (!is_array($value)) {
                 continue;
             }
-            $inputArray[$key] = $this->_getAsCanonicalArray($value);
+            $inputArray[$key] = $this->getAsCanonicalArray($value);
         }
         return $inputArray;
     }
@@ -353,7 +384,7 @@ class Widget
      * @param string $string
      * @return string
      */
-    protected function _idEncode($string)
+    protected function idEncode($string)
     {
         return strtr(base64_encode($string), '+/=', ':_-');
     }
@@ -365,7 +396,7 @@ class Widget
      * @param array $secondElement
      * @return bool
      */
-    protected function _sortWidgets($firstElement, $secondElement)
+    protected function sortWidgets($firstElement, $secondElement)
     {
         return strcmp($firstElement["name"], $secondElement["name"]);
     }
@@ -377,7 +408,7 @@ class Widget
      * @param \Magento\Framework\Object $secondElement
      * @return int
      */
-    protected function _sortParameters($firstElement, $secondElement)
+    protected function sortParameters($firstElement, $secondElement)
     {
         $aOrder = (int)$firstElement->getData('sort_order');
         $bOrder = (int)$secondElement->getData('sort_order');
diff --git a/app/code/Magento/Widget/Test/Unit/Model/NamespaceResolverTest.php b/app/code/Magento/Widget/Test/Unit/Model/NamespaceResolverTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1e9552c058be42d307da333719488b3228e9d89a
--- /dev/null
+++ b/app/code/Magento/Widget/Test/Unit/Model/NamespaceResolverTest.php
@@ -0,0 +1,99 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Widget\Test\Unit\Model;
+
+class NamespaceResolverTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Widget\Model\NamespaceResolver
+     */
+    protected $namespaceResolver;
+
+    /**
+     * @var \Magento\Framework\Module\ModuleListInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $moduleListMock;
+
+    public function setUp()
+    {
+        $objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
+        $this->moduleListMock = $this->getMockBuilder('Magento\Framework\Module\ModuleListInterface')
+            ->getMockForAbstractClass();
+
+        $this->namespaceResolver = $objectManager->getObject(
+            'Magento\Widget\Model\NamespaceResolver',
+            [
+                'moduleList' => $this->moduleListMock
+            ]
+        );
+    }
+
+    /**
+     * @param string $namespace
+     * @param array $modules
+     * @param string $expected
+     * @param bool $asFullModuleName
+     *
+     * @dataProvider determineOmittedNamespaceDataProvider
+     */
+    public function testDetermineOmittedNamespace($namespace, $modules, $expected, $asFullModuleName)
+    {
+        $this->moduleListMock->expects($this->once())
+            ->method('getNames')
+            ->willReturn($modules);
+
+        $this->assertSame(
+            $expected,
+            $this->namespaceResolver->determineOmittedNamespace($namespace, $asFullModuleName)
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function determineOmittedNamespaceDataProvider()
+    {
+        return[
+            [
+                'namespace' => 'Magento\Widget\Test\Unit\Model\NamespaceResolverTest',
+                'modules' => ['Magento_Cms', 'Magento_Catalog', 'Magento_Sales', 'Magento_Widget'],
+                'expected' => 'Magento_Widget',
+                'asFullModuleName' => true
+            ],
+            [
+                'namespace' => 'Magento\Widget\Test\Unit\Model\NamespaceResolverTest',
+                'modules' => ['Magento_Cms', 'Magento_Catalog', 'Magento_Sales', 'Magento_Widget'],
+                'expected' => 'magento_widget',
+                'asFullModuleName' => false
+            ],
+            [
+                'namespace' => 'Widget\Test\Unit\Model\NamespaceResolverTest',
+                'modules' => ['Magento_Cms', 'Magento_Catalog', 'Magento_Sales', 'Magento_Widget'],
+                'expected' => 'Magento_Widget',
+                'asFullModuleName' => true
+
+            ],
+            [
+                'namespace' => 'Widget\Test\Unit\Model\NamespaceResolverTest',
+                'modules' => ['Magento_Cms', 'Magento_Catalog', 'Magento_Sales', 'Magento_Widget'],
+                'expected' => 'widget',
+                'asFullModuleName' => false
+            ],
+            [
+                'namespace' => 'Unit\Model\NamespaceResolverTest',
+                'modules' => ['Magento_Cms', 'Magento_Catalog', 'Magento_Sales', 'Magento_Widget'],
+                'expected' => '',
+                'asFullModuleName' => true
+            ],
+            [
+                'namespace' => 'Unit\Model\NamespaceResolverTest',
+                'modules' => ['Magento_Cms', 'Magento_Catalog', 'Magento_Sales', 'Magento_Widget'],
+                'expected' => '',
+                'asFullModuleName' => false
+            ],
+        ];
+    }
+}
diff --git a/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php b/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php
index dfbbc341d9b37c7d19b0986251e9a0b2c6f06c37..dffc3bf38ace272348b3a86e027f18fd526b83d4 100644
--- a/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php
+++ b/app/code/Magento/Widget/Test/Unit/Model/WidgetTest.php
@@ -8,33 +8,34 @@ namespace Magento\Widget\Test\Unit\Model;
 class WidgetTest extends \PHPUnit_Framework_TestCase
 {
     /**
-     * @var \Magento\Widget\Model\Config\Data|PHPUnit_Framework_MockObject_MockObject
+     * @var \Magento\Widget\Model\Config\Data|\PHPUnit_Framework_MockObject_MockObject
      */
-    protected $_storage;
+    protected $dataStorageMock;
 
     /**
      * @var \Magento\Widget\Model\Widget
      */
-    protected $_model;
+    protected $widget;
 
     public function setUp()
     {
-        $this->_storage = $this->getMockBuilder(
-            'Magento\Widget\Model\Config\Data'
-        )->disableOriginalConstructor()->getMock();
+        $this->dataStorageMock = $this->getMockBuilder('Magento\Widget\Model\Config\Data')
+            ->disableOriginalConstructor()
+            ->getMock();
         $objectManagerHelper = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);
-        $objectManagerHelper->getObject('Magento\Widget\Model\Widget', ['dataStorage' => $this->_storage]);
-        $this->_model = $objectManagerHelper->getObject(
+        $this->widget = $objectManagerHelper->getObject(
             'Magento\Widget\Model\Widget',
-            ['dataStorage' => $this->_storage]
+            ['dataStorage' => $this->dataStorageMock]
         );
     }
 
     public function testGetWidgets()
     {
         $expected = ['val1', 'val2'];
-        $this->_storage->expects($this->once())->method('get')->will($this->returnValue($expected));
-        $result = $this->_model->getWidgets();
+        $this->dataStorageMock->expects($this->once())
+            ->method('get')
+            ->willReturn($expected);
+        $result = $this->widget->getWidgets();
         $this->assertEquals($expected, $result);
     }
 
@@ -42,8 +43,10 @@ class WidgetTest extends \PHPUnit_Framework_TestCase
     {
         $configFile = __DIR__ . '/_files/mappedConfigArrayAll.php';
         $widgets = include $configFile;
-        $this->_storage->expects($this->once())->method('get')->will($this->returnValue($widgets));
-        $result = $this->_model->getWidgets(['name' => 'CMS Page Link', 'description' => 'Link to a CMS Page']);
+        $this->dataStorageMock->expects($this->once())
+            ->method('get')
+            ->willReturn($widgets);
+        $result = $this->widget->getWidgets(['name' => 'CMS Page Link', 'description' => 'Link to a CMS Page']);
         $configFileOne = __DIR__ . '/_files/mappedConfigArray1.php';
         $expected = ['cms_page_link' => include $configFileOne];
         $this->assertEquals($expected, $result);
@@ -53,8 +56,10 @@ class WidgetTest extends \PHPUnit_Framework_TestCase
     {
         $configFile = __DIR__ . '/_files/mappedConfigArrayAll.php';
         $widgets = include $configFile;
-        $this->_storage->expects($this->once())->method('get')->will($this->returnValue($widgets));
-        $result = $this->_model->getWidgets(['name' => 'unknown', 'description' => 'unknown']);
+        $this->dataStorageMock->expects($this->once())
+            ->method('get')
+            ->willReturn($widgets);
+        $result = $this->widget->getWidgets(['name' => 'unknown', 'description' => 'unknown']);
         $expected = [];
         $this->assertEquals($expected, $result);
     }
@@ -63,16 +68,63 @@ class WidgetTest extends \PHPUnit_Framework_TestCase
     {
         $widgetOne = ['@' => ['type' => 'type1']];
         $widgets = ['widget1' => $widgetOne];
-        $this->_storage->expects($this->any())->method('get')->will($this->returnValue($widgets));
-        $this->assertEquals($widgetOne, $this->_model->getWidgetByClassType('type1'));
-        $this->assertNull($this->_model->getWidgetByClassType('type2'));
+        $this->dataStorageMock->expects($this->any())
+            ->method('get')
+            ->willReturn($widgets);
+        $this->assertEquals($widgetOne, $this->widget->getWidgetByClassType('type1'));
+        $this->assertNull($this->widget->getWidgetByClassType('type2'));
     }
 
     public function testGetWidgetDeclarationTypeWithBackslashes()
     {
         $this->assertContains(
             'Magento\\\\Widget\\\\Backslashed\\\\ClassName',
-            $this->_model->getWidgetDeclaration('Magento\Widget\Backslashed\ClassName')
+            $this->widget->getWidgetDeclaration('Magento\Widget\Backslashed\ClassName')
         );
     }
+
+    public function testGetConfigAsObject()
+    {
+        $configFile = __DIR__ . '/_files/mappedConfigArrayAll.php';
+        $widgets = include $configFile;
+        $this->dataStorageMock->expects($this->once())
+            ->method('get')
+            ->willReturn($widgets);
+
+        $resultObject = $this->widget->getConfigAsObject('Magento\Cms\Block\Widget\Page\Link');
+        $this->assertInstanceOf('Magento\Framework\Object', $resultObject);
+
+        $this->assertSame('CMS Page Link', $resultObject->getName());
+        $this->assertSame('Link to a CMS Page', $resultObject->getDescription());
+        $this->assertSame('1', $resultObject->getIsEmailCompatible());
+        $this->assertSame('Magento_Cms::images/widget_page_link.png', $resultObject->getPlaceholderImage());
+
+        $resultParameters = $resultObject->getParameters();
+        $this->assertInstanceOf('Magento\Framework\Object', $resultParameters['page_id' ]);
+        $this->assertInstanceOf('Magento\Framework\Object', $resultParameters['anchor_text']);
+        $this->assertInstanceOf('Magento\Framework\Object', $resultParameters['template']);
+
+        $supportedContainersExpected = [
+            '0' => [
+                'container_name' => 'left',
+                'template' => ['default' => 'default', 'names_only' => 'link_inline'],
+            ],
+            '1' => [
+                'container_name' => 'content',
+                'template' => ['grid' => 'default', 'list' => 'list']
+            ],
+        ];
+        $this->assertSame($supportedContainersExpected, $resultObject->getSupportedContainers());
+    }
+
+    public function testGetConfigAsObjectWidgetNoFound()
+    {
+        $this->dataStorageMock->expects($this->once())
+            ->method('get')
+            ->willReturn([]);
+
+        $resultObject = $this->widget->getConfigAsObject('Magento\Cms\Block\Widget\Page\Link');
+        $this->assertInstanceOf('Magento\Framework\Object', $resultObject);
+        $this->assertSame([], $resultObject->getData());
+    }
 }
diff --git a/composer.json b/composer.json
index 7a915ce16b3e8f2e702b8073befc5f5e20eeef22..be59f9bb947b1d972fcb638e5ae906266254c8c9 100644
--- a/composer.json
+++ b/composer.json
@@ -65,6 +65,7 @@
         "magento/module-admin-notification": "self.version",
         "magento/module-advanced-pricing-import-export": "self.version",
         "magento/module-authorization": "self.version",
+        "magento/module-authorizenet": "self.version",
         "magento/module-backend": "self.version",
         "magento/module-backup": "self.version",
         "magento/module-bundle": "self.version",
diff --git a/composer.lock b/composer.lock
index 4f974ab2e194e8469ef3ff204250ab9831855c8c..09e5c89e602382d4ebb8782a04379bb05da9520c 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "1260ae319e263c7debd87fb523d59246",
+    "hash": "3f06baff4c9942141e3922ea9d66fee7",
     "packages": [
         {
             "name": "composer/composer",
diff --git a/dev/tests/functional/tests/app/Magento/Authorizenet/Test/Block/Authorizenet/Form/Cc.php b/dev/tests/functional/tests/app/Magento/Authorizenet/Test/Block/Authorizenet/Form/Cc.php
new file mode 100644
index 0000000000000000000000000000000000000000..7b109b8947ea479eaf395413d9ead332867f0f5e
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Authorizenet/Test/Block/Authorizenet/Form/Cc.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Authorizenet\Test\Block\Authorizenet\Form;
+
+use Magento\Payment\Test\Block\Form\Cc as CreditCard;
+
+/**
+ * Class Cc
+ * Form for filling credit card data for Authorize.Net payment method
+ */
+class Cc extends CreditCard
+{
+    //
+}
diff --git a/dev/tests/functional/tests/app/Magento/Authorizenet/Test/Block/Authorizenet/Form/Cc.xml b/dev/tests/functional/tests/app/Magento/Authorizenet/Test/Block/Authorizenet/Form/Cc.xml
new file mode 100644
index 0000000000000000000000000000000000000000..338d574835d67b6605d1364ec507c0da20cd835a
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Authorizenet/Test/Block/Authorizenet/Form/Cc.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<mapping strict="1">
+    <wrapper>payment</wrapper>
+    <fields>
+        <cc_type>
+            <input>select</input>
+        </cc_type>
+        <cc_number />
+        <cc_exp_month>
+            <input>select</input>
+        </cc_exp_month>
+        <cc_exp_year>
+            <input>select</input>
+        </cc_exp_year>
+        <cc_cid />
+    </fields>
+</mapping>
diff --git a/dev/tests/functional/tests/app/Magento/Authorizenet/Test/Repository/ConfigData.xml b/dev/tests/functional/tests/app/Magento/Authorizenet/Test/Repository/ConfigData.xml
new file mode 100644
index 0000000000000000000000000000000000000000..de7d54e27bb1832e21e740767d3224aaf646d131
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Authorizenet/Test/Repository/ConfigData.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd">
+    <repository class="Magento\Config\Test\Repository\ConfigData">
+        <dataset name="authorizenet">
+            <field name="payment/authorizenet/active" xsi:type="array">
+                <item name="scope" xsi:type="string">payment</item>
+                <item name="scope_id" xsi:type="number">1</item>
+                <item name="label" xsi:type="string">Yes</item>
+                <item name="value" xsi:type="number">1</item>
+            </field>
+            <field name="payment/authorizenet/login" xsi:type="array">
+                <item name="scope" xsi:type="string">payment</item>
+                <item name="scope_id" xsi:type="number">1</item>
+                <item name="label" xsi:type="string"/>
+                <item name="value" xsi:type="string">PAYMENT_AUTHORIZENET_LOGIN</item>
+            </field>
+            <field name="payment/authorizenet/trans_key" xsi:type="array">
+                <item name="scope" xsi:type="string">payment</item>
+                <item name="scope_id" xsi:type="number">1</item>
+                <item name="label" xsi:type="string"/>
+                <item name="value" xsi:type="string">PAYMENT_AUTHORIZENET_TRANS_KEY</item>
+            </field>
+            <field name="payment/authorizenet/test" xsi:type="array">
+                <item name="scope" xsi:type="string">payment</item>
+                <item name="scope_id" xsi:type="number">1</item>
+                <item name="label" xsi:type="string">No</item>
+                <item name="value" xsi:type="number">0</item>
+            </field>
+            <field name="payment/authorizenet/cgi_url" xsi:type="array">
+                <item name="scope" xsi:type="string">payment</item>
+                <item name="scope_id" xsi:type="number">1</item>
+                <item name="label" xsi:type="string"/>
+                <item name="value" xsi:type="string">https://test.authorize.net/gateway/transact.dll</item>
+            </field>
+            <field name="payment/authorizenet/debug" xsi:type="array">
+                <item name="scope" xsi:type="string">payment</item>
+                <item name="scope_id" xsi:type="number">1</item>
+                <item name="label" xsi:type="string">Yes</item>
+                <item name="value" xsi:type="number">1</item>
+            </field>
+            <field name="payment/authorizenet/useccv" xsi:type="array">
+                <item name="scope" xsi:type="string">payment</item>
+                <item name="scope_id" xsi:type="number">1</item>
+                <item name="label" xsi:type="string">Yes</item>
+                <item name="value" xsi:type="number">1</item>
+            </field>
+        </dataset>
+        <dataset name="authorizenet_rollback">
+            <field name="payment/authorizenet/active" xsi:type="array">
+                <item name="scope" xsi:type="string">payment</item>
+                <item name="scope_id" xsi:type="number">1</item>
+                <item name="label" xsi:type="string">Yes</item>
+                <item name="value" xsi:type="number">0</item>
+            </field>
+        </dataset>
+    </repository>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Authorizenet/Test/Repository/CreditCard.xml b/dev/tests/functional/tests/app/Magento/Authorizenet/Test/Repository/CreditCard.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8e2b942b48d1f766e5b6bf9a82d0f5a68f84639c
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Authorizenet/Test/Repository/CreditCard.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/Magento/Mtf/Repository/etc/repository.xsd">
+    <repository class="Magento\Payment\Test\Repository\CreditCard">
+        <dataset name="visa_authorizenet">
+            <field name="cc_type" xsi:type="string">Visa</field>
+            <field name="cc_number" xsi:type="string">4007000000027</field>
+            <field name="cc_exp_month" xsi:type="string">01 - January</field>
+            <field name="cc_exp_year" xsi:type="string">2016</field>
+            <field name="cc_cid" xsi:type="string">123</field>
+        </dataset>
+    </repository>
+</config>
diff --git a/dev/tests/functional/tests/app/Magento/Authorizenet/Test/TestCase/OnePageCheckoutTest.xml b/dev/tests/functional/tests/app/Magento/Authorizenet/Test/TestCase/OnePageCheckoutTest.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7adf887baa967267ee63cf94dd55eb057a1acc51
--- /dev/null
+++ b/dev/tests/functional/tests/app/Magento/Authorizenet/Test/TestCase/OnePageCheckoutTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+ -->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../vendor/magento/mtf/etc/variations.xsd">
+    <testCase name="Magento\Checkout\Test\TestCase\OnePageCheckoutTest">
+        <variation name="OnePageCheckoutTestVariation17">
+            <data name="description" xsi:type="string">MAGETWO-12832 - Check Out as a Guest with Authorize.Net and Offline Shipping method</data>
+            <data name="products" xsi:type="string">catalogProductSimple::product_10_dollar, configurableProduct::with_one_option, bundleProduct::bundle_fixed_100_dollar_product</data>
+            <data name="taxRule" xsi:type="string">us_ca_ny_rule</data>
+            <data name="customer/dataSet" xsi:type="string">default</data>
+            <data name="billingAddress/dataSet" xsi:type="string">US_address_1</data>
+            <data name="checkoutMethod" xsi:type="string">guest</data>
+            <data name="shipping/shipping_service" xsi:type="string">Flat Rate</data>
+            <data name="shipping/shipping_method" xsi:type="string">Fixed</data>
+            <data name="prices" xsi:type="array">
+                <item name="grandTotal" xsi:type="string">156.81</item>
+            </data>
+            <data name="payment/method" xsi:type="string">authorizenet</data>
+            <data name="creditCard/dataSet" xsi:type="string">visa_default</data>
+            <data name="configData" xsi:type="string">authorizenet</data>
+            <data name="tag" xsi:type="string">test_type:3rd_party_test</data>
+            <constraint name="Magento\Checkout\Test\Constraint\AssertOrderSuccessPlacedMessage"/>
+            <constraint name="Magento\Sales\Test\Constraint\AssertOrderGrandTotal"/>
+            <constraint name="Magento\Sales\Test\Constraint\AssertOrderCommentsHistory"/>
+        </variation>
+    </testCase>
+</config>
diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/PlaceTest.php b/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/PlaceTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..85b6564400494dbe437a8170d74c4426db8e6928
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/PlaceTest.php
@@ -0,0 +1,139 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+/**
+ * Class PlaceTest
+ */
+class PlaceTest extends \Magento\TestFramework\TestCase\AbstractBackendController
+{
+    /**
+     * Test requestToAuthorizenetData returning
+     */
+    public function testExecuteAuthorizenetDataReturning()
+    {
+        $requestToAuthorizenetData = ['Authorizenet' => 'data'];
+
+        $this->getRequest()->setParam('payment', ['method' => 'authorizenet_directpost']);
+        $this->getRequest()->setParam('controller', 'order_create');
+        $orderCreateMock = $this->getOrderCreateMock($requestToAuthorizenetData);
+        $directpostMock =  $this->getMockBuilder('Magento\Authorizenet\Model\Directpost')
+            ->setMethods(['getCode'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $directpostMock->expects($this->once())
+            ->method('getCode')
+            ->willReturn('authorizenet_directpost');
+        $jsonHelper = $this->_objectManager->get('Magento\Framework\Json\Helper\Data');
+        $objectManagerMock =  $this->getMockBuilder('Magento\Framework\ObjectManagerInterface')
+            ->setMethods(['create', 'get'])
+            ->getMockForAbstractClass();
+        $objectManagerMock->expects($this->atLeastOnce())
+            ->method('create')
+            ->with('Magento\Authorizenet\Model\Directpost')
+            ->willReturn($directpostMock);
+        $authorizenetSessionMock = $this->getMockBuilder('Magento\Authorizenet\Model\Directpost')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $urlMock = $this->getMockBuilder('Magento\Backend\Model\UrlInterface')
+            ->getMockForAbstractClass();
+        $objectManagerMock->expects($this->atLeastOnce())
+            ->method('get')
+            ->willReturnMap([
+                ['Magento\Sales\Model\AdminOrder\Create', $orderCreateMock],
+                ['Magento\Framework\Json\Helper\Data', $jsonHelper],
+                ['Magento\Authorizenet\Model\Directpost\Session', $authorizenetSessionMock],
+                ['Magento\Backend\Model\UrlInterface', $urlMock],
+            ]);
+
+        $context = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\Backend\App\Action\Context',
+            [
+                'objectManager' => $objectManagerMock
+            ]
+        );
+
+        $controller = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
+            'Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment\PlaceTesting',
+            ['context' => $context]
+        );
+        $controller->execute();
+        $this->assertContains(json_encode($requestToAuthorizenetData), $this->getResponse()->getBody());
+    }
+
+    /**
+     * @param array $requestToAuthorizenetData
+     * @return \PHPUnit_Framework_MockObject_MockObject
+     */
+    private function getOrderCreateMock($requestToAuthorizenetData)
+    {
+        $methodInstanceMock =  $this->getMockBuilder('Magento\Authorizenet\Model\Directpost')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $directpostRequestMock = $this->getMockBuilder('Magento\Authorizenet\Model\Directpost\Request')
+            ->setMethods(['getData'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $directpostRequestMock->expects($this->once())
+            ->method('getData')
+            ->willReturn($requestToAuthorizenetData);
+        $methodInstanceMock->expects($this->once())
+            ->method('generateRequestFromOrder')
+            ->willReturn($directpostRequestMock);
+        $paymentMock = $this->getMockBuilder('Magento\Quote\Model\Quote\Payment')
+            ->setMethods(['getMethod', 'getMethodInstance'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $paymentMock->expects($this->once())
+            ->method('getMethod')
+            ->willReturn('authorizenet_directpost');
+        $paymentMock->expects($this->once())
+            ->method('getMethodInstance')
+            ->willReturn($methodInstanceMock);
+        $quoteMock = $this->getMockBuilder('Magento\Quote\Model\Quote')
+            ->setMethods(['getPayment', 'getStoreId'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $quoteMock->expects($this->any())
+            ->method('getPayment')
+            ->willReturn($paymentMock);
+        $orderMock = $this->getMockBuilder('Magento\Sales\Model\Order')
+            ->setMethods(['getPayment'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $orderMock->expects($this->any())
+            ->method('getPayment')
+            ->willReturn($paymentMock);
+        $sessionQuoteMock = $this->getMockBuilder('Magento\Backend\Model\Session\Quote')
+            ->setMethods(['getOrder'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $sessionQuoteMock->expects($this->once())
+            ->method('getOrder')
+            ->willReturn($orderMock);
+        $orderCreateMock = $this->getMockBuilder('Magento\Sales\Model\AdminOrder\Create')
+            ->setMethods(['getQuote', 'getSession', 'setIsValidate', 'importPostData', 'createOrder', 'setPaymentData'])
+            ->disableOriginalConstructor()
+            ->getMock();
+        $orderCreateMock->expects($this->any())
+            ->method('getQuote')
+            ->willReturn($quoteMock);
+        $orderCreateMock->expects($this->once())
+            ->method('getSession')
+            ->willReturn($sessionQuoteMock);
+        $orderCreateMock->expects($this->once())
+            ->method('setIsValidate')
+            ->willReturnSelf();
+        $orderCreateMock->expects($this->once())
+            ->method('importPostData')
+            ->willReturnSelf();
+        $orderCreateMock->expects($this->once())
+            ->method('createOrder')
+            ->willReturn($orderMock);
+
+        return $orderCreateMock;
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/PlaceTesting.php b/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/PlaceTesting.php
new file mode 100644
index 0000000000000000000000000000000000000000..cb9712d5fa5d5b8302dea58db147939151ddd16f
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Adminhtml/Authorizenet/Directpost/Payment/PlaceTesting.php
@@ -0,0 +1,21 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Directpost\Payment;
+
+/**
+ * Class PlaceTesting extended test class, used to substitute calls to parent methods
+ */
+class PlaceTesting extends Place
+{
+    /**
+     * {@inheritdoc}
+     * This method tested in Magento\Sales\Controller\Adminhtml\Order\CreateTest
+     */
+    protected function _processActionData($action = null)
+    {
+        //
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Directpost/PaymentTest.php b/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Directpost/PaymentTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..68bc0704f44ec5f2b5e7f4ed200ff0c3e40d9f8a
--- /dev/null
+++ b/dev/tests/integration/testsuite/Magento/Authorizenet/Controller/Directpost/PaymentTest.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Authorizenet\Controller\Directpost;
+
+/**
+ * Class PaymentTest
+ */
+class PaymentTest extends \Magento\TestFramework\TestCase\AbstractController
+{
+    public function testResponseActionValidationFailed()
+    {
+        $this->getRequest()->setPostValue('controller_action_name', 'onepage');
+        $this->dispatch('authorizenet/directpost_payment/response');
+        // @codingStandardsIgnoreStart
+        $this->assertContains(
+            'authorizenet/directpost_payment/redirect/success/0/error_msg/The transaction was'
+            . ' declined because the response hash validation failed.',
+            // @codingStandardsIgnoreEnd
+            $this->getResponse()->getBody()
+        );
+    }
+
+    public function testRedirectActionErrorMessage()
+    {
+        $this->getRequest()->setParam('success', '0');
+        $this->getRequest()->setParam('error_msg', 'Error message');
+        $this->dispatch('authorizenet/directpost_payment/redirect');
+        $this->assertContains('alert("Error message");', $this->getResponse()->getBody());
+    }
+
+    public function testBackendResponseActionOrderSuccess()
+    {
+        $xNum = 1;
+        $this->getRequest()->setPostValue('x_invoice_num', $xNum);
+        $this->dispatch('authorizenet/directpost_payment/backendresponse');
+        $this->assertContains(
+            '/sales/order/view/',
+            $this->getResponse()->getBody()
+        );
+    }
+
+    public function testBackendResponseActionValidationFailed()
+    {
+        $this->getRequest()->setPostValue('controller_action_name', 'action_name');
+        $this->dispatch('authorizenet/directpost_payment/backendresponse');
+        // @codingStandardsIgnoreStart
+        $this->assertContains(
+            'authorizenet_directpost_payment/redirect/success/0/error_msg/The transaction was declined'
+            . ' because the response hash validation failed./controller_action_name/action_name/',
+            // @codingStandardsIgnoreEnd
+            $this->getResponse()->getBody()
+        );
+    }
+}
diff --git a/dev/tests/integration/testsuite/Magento/Checkout/Controller/OnepageTest.php b/dev/tests/integration/testsuite/Magento/Checkout/Controller/OnepageTest.php
deleted file mode 100644
index 567ad6ec03b1444b0393669a88aa8c43c328f108..0000000000000000000000000000000000000000
--- a/dev/tests/integration/testsuite/Magento/Checkout/Controller/OnepageTest.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Checkout\Controller;
-
-/**
- * @magentoDataFixture Magento/Sales/_files/quote.php
- */
-class OnepageTest extends \Magento\TestFramework\TestCase\AbstractController
-{
-    protected function setUp()
-    {
-        parent::setUp();
-        $quote = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create('Magento\Quote\Model\Quote');
-        $quote->load('test01', 'reserved_order_id');
-        \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            'Magento\Checkout\Model\Session'
-        )->setQuoteId(
-            $quote->getId()
-        );
-    }
-
-    public function testSaveOrderActionWithoutFormKey()
-    {
-        $this->dispatch('checkout/onepage/saveOrder');
-        $this->assertRedirect($this->stringContains('checkout/onepage'));
-    }
-
-    public function testSaveOrderActionWithFormKey()
-    {
-        $formKey = $this->_objectManager->get('Magento\Framework\Data\Form\FormKey');
-        $this->getRequest()->setParam('form_key', $formKey->getFormKey());
-        $this->dispatch('checkout/onepage/saveOrder');
-        $html = $this->getResponse()->getBody();
-        $this->assertEquals(
-            '{"success":false,"error":true,"error_messages":"Please specify a shipping method."}',
-            $html,
-            $html
-        );
-    }
-}
diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/core.txt b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/core.txt
index 9210d15d05df6a7a82ce4f6c5f1b312bf54ccf01..15ba997298fe0f932500ae2134a029295007691a 100644
--- a/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/core.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/blacklist/core.txt
@@ -1,3 +1,4 @@
+app/code/Magento/Authorizenet/view/adminhtml/web/js/direct-post.js
 app/code/Magento/Captcha/view/frontend/web/onepage.js
 app/code/Magento/Catalog/view/adminhtml/web/catalog/category/edit.js
 app/code/Magento/Catalog/view/adminhtml/web/catalog/product.js
diff --git a/dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/core.txt b/dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/core.txt
index 92cc3827467b323172d10eced73799e93eb44983..1476776c1ebbc3bf19e14ffc2a9dd930ba2c17c6 100644
--- a/dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/core.txt
+++ b/dev/tests/static/testsuite/Magento/Test/Js/_files/whitelist/core.txt
@@ -1,3 +1,4 @@
+app/code/Magento/Authorizenet
 app/code/Magento/Bundle
 app/code/Magento/Captcha
 app/code/Magento/Catalog
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
index 7ce0fd78153f3064133fdd0cbddd129899aa8944..f028b38b2d9883c105928c6a0cdb6fa451504b7f 100755
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
@@ -3671,6 +3671,31 @@ return [
     ['Magento\Framework\View\Element\UiComponent\JsConfigInterface'],
     ['Magento\GiftMessage\Model\Plugin\TotalsDataProcessorPlugin'],
     ['Magento\Catalog\Model\Product\Attribute\Backend\Startdate', 'Magento\Catalog\Model\Attribute\Backend\Startdate'],
+    ['Magento\Authorizenet\Block\Authorizenet\Form\Cc'],
+    ['Magento\Authorizenet\Block\Authorizenet\Info\Cc'],
+    ['Magento\Authorizenet\Controller\Adminhtml\Authorizenet\Payment\Cancel'],
+    ['Magento\Authorizenet\Controller\Authorizenet\Payment\Cancel'],
+    [
+        'Magento\Authorizenet\Model\Authorizenet\Source\Cctype',
+        'Magento\Authorizenet\Model\Source\Cctype'
+    ],
+    [
+        'Magento\Authorizenet\Model\Authorizenet\Source\PaymentAction',
+        'Magento\Authorizenet\Model\Source\PaymentAction'
+    ],
+    ['Magento\Authorizenet\Model\Authorizenet\Cards'],
+    [
+        'Magento\Authorizenet\Model\Authorizenet\Debug',
+        'Magento\Authorizenet\Model\Debug'
+    ],
+    [
+        'Magento\Authorizenet\Model\Resource\Authorizenet\Debug\Collection',
+        'Magento\Authorizenet\Model\Resource\Debug\Collection'
+    ],
+    [
+        'Magento\Authorizenet\Model\Resource\Authorizenet\Debug',
+        'Magento\Authorizenet\Model\Resource\Debug'
+    ],
     ['Magento\GoogleShopping\Block\SiteVerification'],
     ['Magento\GoogleShopping\Block\Adminhtml\Items\Renderer\Id'],
     ['Magento\GoogleShopping\Block\Adminhtml\Items\Item'],
@@ -3760,5 +3785,5 @@ return [
     ['Magento\GoogleShopping\Test\Unit\Model\ConfigTest'],
     ['Magento\GoogleShopping\Test\Unit\Model\MassOperationsTest'],
     ['Magento\GoogleShopping\Test\Unit\Model\ObserverTest'],
-    ['Magento\GoogleShopping\Test\Unit\Model\ServiceTest'],
+    ['Magento\GoogleShopping\Test\Unit\Model\ServiceTest']
 ];
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
index e34b61b5912bffd84268469a4679bacd7a0bf729..6c288cf82cef94af2644159f620b683995307159 100644
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_methods.php
@@ -2277,5 +2277,28 @@ return [
     ['_getCentinelVpasLabel', 'Magento\Paypal\Model\Info'],
     ['_getCentinelEciLabel', 'Magento\Paypal\Model\Info'],
     ['_getPayPalPayflowPro3dSecure', 'Magento\Config\Test\Repository\Config'],
-    ['_getPayPalPaymentsPro3dSecure', 'Magento\Config\Test\Repository\Config']
+    ['_getPayPalPaymentsPro3dSecure', 'Magento\Config\Test\Repository\Config'],
+    ['addAdditionalFieldsToResponseFrontend', 'Magento\Authorizenet\Model\Directpost\Observer'],
+    ['_getAuthorizeNet3dSecure', 'Magento\Config\Test\Repository\Config'],
+    [
+        'getRelyUrl',
+        'Magento\Authorizenet\Helper\Backend\Data',
+        'Magento\Authorizenet\Helper\Backend\Data::getRelayUrl()'
+    ],
+    [
+        'getRelyUrl',
+        'Magento\Authorizenet\Helper\Data',
+        'Magento\Authorizenet\Helper\Data::getRelayUrl()'
+    ],
+    ['setPartialAuthorizationLastActionState', 'Magento\Authorizenet\Model\Authorizenet'],
+    ['getPartialAuthorizationLastActionState', 'Magento\Authorizenet\Model\Authorizenet'],
+    ['unsetPartialAuthorizationLastActionState', 'Magento\Authorizenet\Model\Authorizenet'],
+    ['cancelPartialAuthorization', 'Magento\Authorizenet\Model\Authorizenet'],
+    ['getCardsStorage', 'Magento\Authorizenet\Model\Authorizenet'],
+    ['isPartialAuthorization', 'Magento\Authorizenet\Model\Authorizenet'],
+    [
+        'setHelper',
+        'Magento\Authorizenet\Model\Directpost',
+        'Magento\Authorizenet\Model\Directpost::setDataHelper()'
+    ]
 ];
diff --git a/lib/internal/Magento/Framework/App/Http.php b/lib/internal/Magento/Framework/App/Http.php
index 755131e2309d36bd3af5c3cd9dbeb52e6a1d9468..897985cc0982b52298fed8665e9ba7ac518b347e 100644
--- a/lib/internal/Magento/Framework/App/Http.php
+++ b/lib/internal/Magento/Framework/App/Http.php
@@ -113,7 +113,7 @@ class Http implements \Magento\Framework\AppInterface
         /** @var \Magento\Framework\App\FrontControllerInterface $frontController */
         $frontController = $this->_objectManager->get('Magento\Framework\App\FrontControllerInterface');
         $result = $frontController->dispatch($this->_request);
-        // TODO: Temporary solution till all controllers are returned not ResultInterface (MAGETWO-28359)
+        // TODO: Temporary solution until all controllers return ResultInterface (MAGETWO-28359)
         if ($result instanceof ResultInterface) {
             $this->registry->register('use_page_cache_plugin', true, true);
             $result->renderResult($this->_response);
diff --git a/lib/internal/Magento/Framework/Cache/Core.php b/lib/internal/Magento/Framework/Cache/Core.php
index 3fde67c05b317fff0db72f189f16e4a82b211821..6ed73bd93a2e1b28a1437b7ab9833a53fa8c5704 100644
--- a/lib/internal/Magento/Framework/Cache/Core.php
+++ b/lib/internal/Magento/Framework/Cache/Core.php
@@ -29,6 +29,7 @@ class Core extends \Zend_Cache_Core
     protected function _id($cacheId)
     {
         if ($cacheId !== null) {
+            $cacheId = str_replace('.', '__', $cacheId); //reduce collision chances
             $cacheId = preg_replace('/([^a-zA-Z0-9_]{1,1})/', '_', $cacheId);
             if (isset($this->_options['cache_id_prefix'])) {
                 $cacheId = $this->_options['cache_id_prefix'] . $cacheId;
diff --git a/lib/web/mage/apply/main.js b/lib/web/mage/apply/main.js
index 37a12873c3335e7cb2a3afee00770ec5ce5effdd..55166b089fd6c3602e0acd3d1c3f59beb4ec18bb 100644
--- a/lib/web/mage/apply/main.js
+++ b/lib/web/mage/apply/main.js
@@ -67,8 +67,7 @@ define([
                 .map(getData)
                 .concat(virtuals)
                 .forEach(function (itemContainer) {
-                    var configStack,
-                        element = itemContainer.el;
+                    var element = itemContainer.el;
 
                     _.each(itemContainer.data, function (obj, key) {
                             if (obj.mixins) {
@@ -78,10 +77,10 @@ define([
                                     }
 
                                     delete obj.mixins;
-                                    _.each(itemContainer.data, init.bind(null, element));
-                                })
+                                    init.call(null, element, obj, key);
+                                });
                             } else {
-                                _.each(itemContainer.data, init.bind(null, element));
+                                init.call(null, element, obj, key);
                             }
 
                         }
diff --git a/setup/pub/magento/setup/readiness-check.js b/setup/pub/magento/setup/readiness-check.js
index fa6da9344a549ffe0fe5a228630c8b27507ef26e..840fe52343831da06dbbe76b9d3892753485b5ef 100644
--- a/setup/pub/magento/setup/readiness-check.js
+++ b/setup/pub/magento/setup/readiness-check.js
@@ -23,6 +23,13 @@ angular.module('readiness-check', [])
         $rootScope.checkingInProgress = function() {
             return $scope.progressCounter > 0;
         };
+        $scope.requestFailedHandler = function(obj) {
+            obj.processed = true;
+            obj.isRequestError = true;
+            $scope.hasErrors = true;
+            $rootScope.hasErrors = true;
+            $scope.stopProgress();
+        };
 
         $scope.completed = false;
         $scope.hasErrors = false;
@@ -30,22 +37,26 @@ angular.module('readiness-check', [])
         $scope.version = {
             visible: false,
             processed: false,
-            expanded: false
+            expanded: false,
+            isRequestError: false
         };
         $scope.settings = {
             visible: false,
             processed: false,
-            expanded: false
+            expanded: false,
+            isRequestError: false
         };
         $scope.extensions = {
             visible: false,
             processed: false,
-            expanded: false
+            expanded: false,
+            isRequestError: false
         };
         $scope.permissions = {
             visible: false,
             processed: false,
-            expanded: false
+            expanded: false,
+            isRequestError: false
         };
 
         $scope.items = {
@@ -60,6 +71,9 @@ angular.module('readiness-check', [])
                     angular.extend($scope.version, data);
                     $scope.updateOnProcessed($scope.version.responseType);
                     $scope.stopProgress();
+                },
+                fail: function() {
+                    $scope.requestFailedHandler($scope.version);
                 }
             },
             'php-settings': {
@@ -73,6 +87,9 @@ angular.module('readiness-check', [])
                     angular.extend($scope.settings, data);
                     $scope.updateOnProcessed($scope.settings.responseType);
                     $scope.stopProgress();
+                },
+                fail: function() {
+                    $scope.requestFailedHandler($scope.settings);
                 }
             },
             'php-extensions': {
@@ -86,6 +103,9 @@ angular.module('readiness-check', [])
                     angular.extend($scope.extensions, data);
                     $scope.updateOnProcessed($scope.extensions.responseType);
                     $scope.stopProgress();
+                },
+                fail: function() {
+                    $scope.requestFailedHandler($scope.extensions);
                 }
             },
             'file-permissions': {
@@ -99,12 +119,16 @@ angular.module('readiness-check', [])
                     angular.extend($scope.permissions, data);
                     $scope.updateOnProcessed($scope.permissions.responseType);
                     $scope.stopProgress();
+                },
+                fail: function() {
+                    $scope.requestFailedHandler($scope.permissions);
                 }
             }
         };
 
         $scope.isCompleted = function() {
             return $scope.version.processed
+                && $scope.settings.processed
                 && $scope.extensions.processed
                 && $scope.permissions.processed;
         };
@@ -133,8 +157,11 @@ angular.module('readiness-check', [])
         };
 
         $scope.query = function(item) {
-            return $http.get(item.url)
-                .success(function(data) { item.process(data) });
+            return $http.get(item.url, {timeout: 3000})
+                .success(function(data) { item.process(data) })
+                .error(function(data, status) {
+                    item.fail();
+                });
         };
 
         $scope.progress = function() {
diff --git a/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php b/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php
index 5eeae872008f86a29acaf448df70222e314ecd95..4e1f95f5056a35e31481e3c32beab386b801537b 100644
--- a/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php
+++ b/setup/src/Magento/Setup/Console/Command/InstallStoreConfigurationCommand.php
@@ -178,6 +178,9 @@ class InstallStoreConfigurationCommand extends AbstractSetupCommand
             switch ($key) {
                 case StoreConfigurationDataMapper::KEY_BASE_URL:
                     /** @var Validator $url */
+                    if (strcmp($value, '{{base_url}}') == 0) {
+                        break;
+                    }
                     $url = $this->objectManager->get('Magento\Framework\Url\Validator');
                     if (!$url->isValid($value)) {
                         $errorMsgs = $url->getMessages();
diff --git a/setup/src/Magento/Setup/Fixtures/FixtureModel.php b/setup/src/Magento/Setup/Fixtures/FixtureModel.php
index f414e1a2884b3ba4180f322dc156265535ab8dba..a51eb57d44e42b5107cee8a0b776f6b071441170 100644
--- a/setup/src/Magento/Setup/Fixtures/FixtureModel.php
+++ b/setup/src/Magento/Setup/Fixtures/FixtureModel.php
@@ -105,11 +105,6 @@ class FixtureModel
      */
     public function loadFixtures()
     {
-        if (!is_readable(__DIR__)) {
-            throw new \Exception(
-                'Fixtures set directory `' . __DIR__ . '` is not readable or does not exists.'
-            );
-        }
         $files = glob(__DIR__ . DIRECTORY_SEPARATOR . self::FIXTURE_PATTERN);
 
         foreach ($files as $file) {
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/CartPriceRulesFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/CartPriceRulesFixtureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..fc6914f44ad5a5c553bc2604857c802a005312be
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/CartPriceRulesFixtureTest.php
@@ -0,0 +1,144 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use \Magento\Setup\Fixtures\CartPriceRulesFixture;
+
+class CartPriceRulesFixtureTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel
+     */
+    private $fixtureModelMock;
+
+    /**
+     * @var \Magento\Setup\Fixtures\CartPriceRulesFixture
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->fixtureModelMock = $this->getMock('\Magento\Setup\Fixtures\FixtureModel', [], [], '', false);
+
+        $this->model = new CartPriceRulesFixture($this->fixtureModelMock);
+    }
+
+    public function testExecute()
+    {
+        $storeMock = $this->getMock('\Magento\Store\Model\Store', [], [], '', false);
+        $storeMock->expects($this->once())
+            ->method('getRootCategoryId')
+            ->will($this->returnValue(2));
+
+        $websiteMock = $this->getMock('\Magento\Store\Model\Website', [], [], '', false);
+        $websiteMock->expects($this->once())
+            ->method('getGroups')
+            ->will($this->returnValue([$storeMock]));
+        $websiteMock->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue('website_id'));
+
+        $contextMock = $this->getMock('\Magento\Framework\Model\Resource\Db\Context', [], [], '', false);
+        $abstractDbMock = $this->getMockForAbstractClass(
+            '\Magento\Framework\Model\Resource\Db\AbstractDb',
+            [$contextMock],
+            '',
+            true,
+            true,
+            true,
+            ['getAllChildren']
+        );
+        $abstractDbMock->expects($this->once())
+            ->method('getAllChildren')
+            ->will($this->returnValue([1]));
+
+        $storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+        $storeManagerMock->expects($this->once())
+            ->method('getWebsites')
+            ->will($this->returnValue([$websiteMock]));
+
+        $categoryMock = $this->getMock('Magento\Catalog\Model\Category', [], [], '', false);
+        $categoryMock->expects($this->once())
+            ->method('getResource')
+            ->will($this->returnValue($abstractDbMock));
+        $categoryMock->expects($this->once())
+            ->method('getPath')
+            ->will($this->returnValue('path/to/file'));
+        $categoryMock->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue('category_id'));
+
+        $modelMock = $this->getMock('\Magento\SalesRule\Model\Rule', [], [], '', false);
+        $modelMock->expects($this->once())
+            ->method('getIdFieldName')
+            ->will($this->returnValue('Field Id Name'));
+
+        $objectValueMap = [
+            ['Magento\SalesRule\Model\Rule', $modelMock],
+            ['Magento\Catalog\Model\Category', $categoryMock]
+        ];
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($storeManagerMock));
+        $objectManagerMock->expects($this->exactly(2))
+            ->method('get')
+            ->will($this->returnValueMap($objectValueMap));
+
+        $valueMap = [
+            ['cart_price_rules', 0, 1],
+            ['cart_price_rules_floor', 3, 3]
+        ];
+
+        $this->fixtureModelMock
+            ->expects($this->exactly(2))
+            ->method('getValue')
+            ->will($this->returnValueMap($valueMap));
+        $this->fixtureModelMock
+            ->expects($this->exactly(3))
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+
+        $this->model->execute();
+    }
+
+    public function testNoFixtureConfigValue()
+    {
+        $ruleMock = $this->getMock('\Magento\SalesRule\Model\Rule', [], [], '', false);
+        $ruleMock->expects($this->never())->method('save');
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->never())
+            ->method('get')
+            ->with($this->equalTo('Magento\SalesRule\Model\Rule'))
+            ->willReturn($ruleMock);
+
+        $this->fixtureModelMock
+            ->expects($this->never())
+            ->method('getObjectManager')
+            ->willReturn($objectManagerMock);
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(false);
+
+        $this->model->execute();
+    }
+
+    public function testGetActionTitle()
+    {
+        $this->assertSame('Generating Cart Price Rules', $this->model->getActionTitle());
+    }
+
+    public function testIntroduceParamLabels()
+    {
+        $this->assertSame([
+            'cart_price_rules' => 'Cart Price Rules'
+        ], $this->model->introduceParamLabels());
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/CatalogPriceRulesFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/CatalogPriceRulesFixtureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..be8a7f156a43cf6aab89603b6058e557c5eddb74
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/CatalogPriceRulesFixtureTest.php
@@ -0,0 +1,139 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use \Magento\Setup\Fixtures\CatalogPriceRulesFixture;
+
+class CatalogPriceRulesFixtureTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel
+     */
+    private $fixtureModelMock;
+
+    /**
+     * @var \Magento\Setup\Fixtures\CatalogPriceRulesFixture
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->fixtureModelMock = $this->getMock('\Magento\Setup\Fixtures\FixtureModel', [], [], '', false);
+
+        $this->model = new CatalogPriceRulesFixture($this->fixtureModelMock);
+    }
+
+    public function testExecute()
+    {
+        $storeMock = $this->getMock('\Magento\Store\Model\Store', [], [], '', false);
+        $storeMock->expects($this->once())
+            ->method('getRootCategoryId')
+            ->will($this->returnValue(2));
+
+        $websiteMock = $this->getMock('\Magento\Store\Model\Website', [], [], '', false);
+        $websiteMock->expects($this->once())
+            ->method('getGroups')
+            ->will($this->returnValue([$storeMock]));
+        $websiteMock->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue('website_id'));
+
+        $storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+        $storeManagerMock->expects($this->once())
+            ->method('getWebsites')
+            ->will($this->returnValue([$websiteMock]));
+
+        $contextMock = $this->getMock('\Magento\Framework\Model\Resource\Db\Context', [], [], '', false);
+        $abstractDbMock = $this->getMockForAbstractClass(
+            '\Magento\Framework\Model\Resource\Db\AbstractDb',
+            [$contextMock],
+            '',
+            true,
+            true,
+            true,
+            ['getAllChildren']
+        );
+        $abstractDbMock->expects($this->once())
+            ->method('getAllChildren')
+            ->will($this->returnValue([1]));
+
+        $categoryMock = $this->getMock('Magento\Catalog\Model\Category', [], [], '', false);
+        $categoryMock->expects($this->once())
+            ->method('getResource')
+            ->will($this->returnValue($abstractDbMock));
+        $categoryMock->expects($this->once())
+            ->method('getPath')
+            ->will($this->returnValue('path/to/file'));
+        $categoryMock->expects($this->once())
+            ->method('getId')
+            ->will($this->returnValue('category_id'));
+
+        $modelMock = $this->getMock('Magento\CatalogRule\Model\Rule', [], [], '', false);
+        $modelMock->expects($this->once())
+            ->method('getIdFieldName')
+            ->will($this->returnValue('Field Id Name'));
+
+        $valueMap = [
+            ['Magento\CatalogRule\Model\Rule', $modelMock],
+            ['Magento\Catalog\Model\Category', $categoryMock]
+        ];
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->once())
+            ->method('create')
+            ->will($this->returnValue($storeManagerMock));
+        $objectManagerMock->expects($this->exactly(2))
+            ->method('get')
+            ->will($this->returnValueMap($valueMap));
+
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->will($this->returnValue(1));
+        $this->fixtureModelMock
+            ->expects($this->exactly(3))
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+
+        $this->model->execute();
+    }
+
+    public function testNoFixtureConfigValue()
+    {
+        $ruleMock = $this->getMock('\Magento\SalesRule\Model\Rule', [], [], '', false);
+        $ruleMock->expects($this->never())->method('save');
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->never())
+            ->method('get')
+            ->with($this->equalTo('Magento\SalesRule\Model\Rule'))
+            ->willReturn($ruleMock);
+
+        $this->fixtureModelMock
+            ->expects($this->never())
+            ->method('getObjectManager')
+            ->willReturn($objectManagerMock);
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(false);
+
+        $this->model->execute();
+    }
+
+    public function testGetActionTitle()
+    {
+        $this->assertSame('Generating catalog price rules', $this->model->getActionTitle());
+    }
+
+    public function testIntroduceParamLabels()
+    {
+        $this->assertSame([
+            'catalog_price_rules' => 'Catalog Price Rules'
+        ], $this->model->introduceParamLabels());
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/CategoriesFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/CategoriesFixtureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..30d4bb4e8737ccde819f95fb56f3dd843e55018d
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/CategoriesFixtureTest.php
@@ -0,0 +1,156 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use \Magento\Setup\Fixtures\CategoriesFixture;
+
+class CategoriesFixtureTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel
+     */
+    private $fixtureModelMock;
+
+    /**
+     * @var \Magento\Setup\Fixtures\CategoriesFixture
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->fixtureModelMock = $this->getMock('\Magento\Setup\Fixtures\FixtureModel', [], [], '', false);
+
+        $this->model = new CategoriesFixture($this->fixtureModelMock);
+    }
+    public function testExecute()
+    {
+        $categoryMock = $this->getMock(
+            '\Magento\Catalog\Model\Category',
+            [
+                'getName',
+                'setId',
+                'setUrlKey',
+                'setUrlPath',
+                'setName',
+                'setParentId',
+                'setPath',
+                'setLevel',
+                'setAvailableSortBy',
+                'setDefaultSortBy',
+                'setIsActive',
+                'save'
+            ],
+            [],
+            '',
+            false
+        );
+        $categoryMock->expects($this->once())
+            ->method('getName')
+            ->will($this->returnValue('category_name'));
+        $categoryMock->expects($this->once())
+            ->method('setId')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setUrlKey')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setUrlPath')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setName')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setParentId')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setPath')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setLevel')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setAvailableSortBy')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setDefaultSortBy')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setIsActive')
+            ->willReturnSelf();
+
+        $groupMock = $this->getMock('\Magento\Store\Model\Group', [], [], '', false);
+        $groupMock->expects($this->once())
+            ->method('getRootCategoryId')
+            ->will($this->returnValue('root_category_id'));
+
+        $storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+        $storeManagerMock->expects($this->once())
+            ->method('getGroups')
+            ->will($this->returnValue([$groupMock]));
+
+        $objectValueMock = [
+            ['Magento\Store\Model\StoreManager', [], $storeManagerMock],
+            ['Magento\Catalog\Model\Category', [], $categoryMock]
+        ];
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->exactly(2))
+            ->method('create')
+            ->will($this->returnValueMap($objectValueMock));
+
+        $valueMap = [
+            ['categories', 0, 1],
+            ['categories_nesting_level', 3, 3]
+        ];
+
+        $this->fixtureModelMock
+            ->expects($this->exactly(2))
+            ->method('getValue')
+            ->will($this->returnValueMap($valueMap));
+        $this->fixtureModelMock
+            ->expects($this->exactly(2))
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+
+        $this->model->execute();
+    }
+
+    public function testNoFixtureConfigValue()
+    {
+        $categoryMock = $this->getMock('\Magento\Catalog\Model\Category', [], [], '', false);
+        $categoryMock->expects($this->never())->method('save');
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->never())
+            ->method('create')
+            ->with($this->equalTo('Magento\Catalog\Model\Category'))
+            ->willReturn($categoryMock);
+
+        $this->fixtureModelMock
+            ->expects($this->never())
+            ->method('getObjectManager')
+            ->willReturn($objectManagerMock);
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(false);
+
+        $this->model->execute();
+    }
+
+    public function testGetActionTitle()
+    {
+        $this->assertSame('Generating categories', $this->model->getActionTitle());
+    }
+
+    public function testIntroduceParamLabels()
+    {
+        $this->assertSame([
+            'categories' => 'Categories'
+        ], $this->model->introduceParamLabels());
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigsApplyFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigsApplyFixtureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..93d56f2742b640de90469d69a37f701f8f3311b3
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigsApplyFixtureTest.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use \Magento\Setup\Fixtures\ConfigsApplyFixture;
+
+class ConfigsApplyFixtureTest extends \PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel
+     */
+    private $fixtureModelMock;
+
+    /**
+     * @var \Magento\Setup\Fixtures\ConfigsApplyFixture
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->fixtureModelMock = $this->getMock('\Magento\Setup\Fixtures\FixtureModel', [], [], '', false);
+
+        $this->model = new ConfigsApplyFixture($this->fixtureModelMock);
+    }
+    public function testExecute()
+    {
+        $cacheMock = $this->getMock('\Magento\Framework\App\Cache', [], [], '', false);
+
+        $valueMock = $this->getMock('\Magento\Framework\App\Config', [], [], '', false);
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->once())
+            ->method('get')
+            ->will($this->returnValue($cacheMock));
+
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->will($this->returnValue(['config' => $valueMock]));
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+
+        $this->model->execute();
+    }
+
+    public function testNoFixtureConfigValue()
+    {
+        $configMock = $this->getMock('\Magento\Framework\App\Config\ValueInterface', [], [], '', false);
+        $configMock->expects($this->never())->method('save');
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->never())
+            ->method('create')
+            ->willReturn($configMock);
+
+        $this->fixtureModelMock
+            ->expects($this->never())
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(false);
+
+        $this->model->execute();
+    }
+
+    public function testGetActionTitle()
+    {
+        $this->assertSame('Config Changes', $this->model->getActionTitle());
+    }
+
+    public function testIntroduceParamLabels()
+    {
+        $this->assertSame([], $this->model->introduceParamLabels());
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigurableProductsFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigurableProductsFixtureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..f0cd86010b2376c252eff4233f4ce0d2c5df4ca1
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/ConfigurableProductsFixtureTest.php
@@ -0,0 +1,144 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use \Magento\Setup\Fixtures\ConfigurableProductsFixture;
+
+class ConfigurableProductsFixtureTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel
+     */
+    private $fixtureModelMock;
+
+    /**
+     * @var \Magento\Setup\Fixtures\ConfigurableProductsFixture
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->fixtureModelMock = $this->getMock('\Magento\Setup\Fixtures\FixtureModel', [], [], '', false);
+
+        $this->model = new ConfigurableProductsFixture($this->fixtureModelMock);
+    }
+
+    public function testExecute()
+    {
+        $importMock = $this->getMock('\Magento\ImportExport\Model\Import', [], [], '', false);
+
+        $contextMock = $this->getMock('\Magento\Framework\Model\Resource\Db\Context', [], [], '', false);
+        $abstractDbMock = $this->getMockForAbstractClass(
+            '\Magento\Framework\Model\Resource\Db\AbstractDb',
+            [$contextMock],
+            '',
+            true,
+            true,
+            true,
+            ['getAllChildren']
+        );
+        $abstractDbMock->expects($this->once())
+            ->method('getAllChildren')
+            ->will($this->returnValue([1]));
+
+        $categoryMock = $this->getMock('Magento\Catalog\Model\Category', [], [], '', false);
+        $categoryMock->expects($this->once())
+            ->method('getResource')
+            ->will($this->returnValue($abstractDbMock));
+        $categoryMock->expects($this->exactly(3))
+            ->method('getName')
+            ->will($this->returnValue('category_name'));
+        $categoryMock->expects($this->once())
+            ->method('getPath')
+            ->will($this->returnValue('path/to/category'));
+        $categoryMock->expects($this->exactly(4))
+            ->method('load')
+            ->willReturnSelf();
+
+        $storeMock = $this->getMock('\Magento\Store\Model\Store', [], [], '', false);
+        $storeMock->expects($this->once())
+            ->method('getRootCategoryId')
+            ->will($this->returnValue([2]));
+
+        $websiteMock = $this->getMock('\Magento\Store\Model\Website', [], [], '', false);
+        $websiteMock->expects($this->once())
+            ->method('getCode')
+            ->will($this->returnValue('website_code'));
+        $websiteMock->expects($this->once())
+            ->method('getGroups')
+            ->will($this->returnValue([$storeMock]));
+
+        $storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+        $storeManagerMock->expects($this->once())
+            ->method('getWebsites')
+            ->will($this->returnValue([$websiteMock]));
+
+        $valueMap = [
+            [
+                'Magento\ImportExport\Model\Import',
+                ['data' => ['entity' => 'catalog_product', 'behavior' => 'append']],
+                $importMock
+            ],
+            ['Magento\Store\Model\StoreManager', [], $storeManagerMock]
+        ];
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->exactly(2))
+            ->method('create')
+            ->will($this->returnValueMap($valueMap));
+        $objectManagerMock->expects($this->once())
+            ->method('get')
+            ->will($this->returnValue($categoryMock));
+
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->will($this->returnValue(1));
+        $this->fixtureModelMock
+            ->expects($this->exactly(3))
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+
+        $this->model->execute();
+    }
+
+    public function testNoFixtureConfigValue()
+    {
+        $importMock = $this->getMock('\Magento\ImportExport\Model\Import', [], [], '', false);
+        $importMock->expects($this->never())->method('validateSource');
+        $importMock->expects($this->never())->method('importSource');
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->never())
+            ->method('create')
+            ->with($this->equalTo('Magento\ImportExport\Model\Import'))
+            ->willReturn($importMock);
+
+        $this->fixtureModelMock
+            ->expects($this->never())
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(false);
+
+        $this->model->execute();
+    }
+
+    public function testGetActionTitle()
+    {
+        $this->assertSame('Generating configurable products', $this->model->getActionTitle());
+    }
+
+    public function testIntroduceParamLabels()
+    {
+        $this->assertSame([
+            'configurable_products' => 'Configurable products'
+        ], $this->model->introduceParamLabels());
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/CustomersFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/CustomersFixtureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6761be9e0dbd50cf1e75d751a9a0868b0c1e1c6c
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/CustomersFixtureTest.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use \Magento\Setup\Fixtures\CustomersFixture;
+
+class CustomersFixtureTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel
+     */
+    private $fixtureModelMock;
+
+    /**
+     * @var \Magento\Setup\Fixtures\CustomersFixture
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->fixtureModelMock = $this->getMock('\Magento\Setup\Fixtures\FixtureModel', [], [], '', false);
+
+        $this->model = new CustomersFixture($this->fixtureModelMock);
+    }
+
+    public function testExecute()
+    {
+        $importMock = $this->getMock('\Magento\ImportExport\Model\Import', [], [], '', false);
+
+        $storeMock = $this->getMock('\Magento\Store\Model\Store', [], [], '', false);
+        $storeMock->expects($this->once())
+            ->method('getCode')
+            ->will($this->returnValue('store_code'));
+
+        $websiteMock = $this->getMock('\Magento\Store\Model\Website', [], [], '', false);
+        $websiteMock->expects($this->once())
+            ->method('getCode')
+            ->will($this->returnValue('website_code'));
+
+        $storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+        $storeManagerMock->expects($this->once())
+            ->method('getDefaultStoreView')
+            ->will($this->returnValue($storeMock));
+        $storeManagerMock->expects($this->once())
+            ->method('getWebsites')
+            ->will($this->returnValue([$websiteMock]));
+
+        $valueMap = [
+            [
+                'Magento\ImportExport\Model\Import',
+                ['data' => ['entity' => 'customer_composite', 'behavior' => 'append']],
+                $importMock
+            ],
+            ['Magento\Store\Model\StoreManager', [], $storeManagerMock]
+        ];
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->exactly(2))
+            ->method('create')
+            ->will($this->returnValueMap($valueMap));
+
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->will($this->returnValue(1));
+        $this->fixtureModelMock
+            ->expects($this->exactly(2))
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+
+        $this->model->execute();
+    }
+
+    public function testNoFixtureConfigValue()
+    {
+        $importMock = $this->getMock('\Magento\ImportExport\Model\Import', [], [], '', false);
+        $importMock->expects($this->never())->method('validateSource');
+        $importMock->expects($this->never())->method('importSource');
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->never())
+            ->method('create')
+            ->with($this->equalTo('Magento\ImportExport\Model\Import'))
+            ->willReturn($importMock);
+
+        $this->fixtureModelMock
+            ->expects($this->never())
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(false);
+
+        $this->model->execute();
+    }
+
+    public function testGetActionTitle()
+    {
+        $this->assertSame('Generating customers', $this->model->getActionTitle());
+    }
+
+    public function testIntroduceParamLabels()
+    {
+        $this->assertSame([
+            'customers' => 'Customers'
+        ], $this->model->introduceParamLabels());
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/EavVariationsFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/EavVariationsFixtureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..3e8e08002842f2dd053477aca718a30a775fbd06
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/EavVariationsFixtureTest.php
@@ -0,0 +1,126 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use Magento\Catalog\Model\Indexer\Product\Eav;
+use \Magento\Setup\Fixtures\EavVariationsFixture;
+
+class EavVariationsFixtureTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel
+     */
+    private $fixtureModelMock;
+
+    /**
+     * @var \Magento\Setup\Fixtures\EavVariationsFixture
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->fixtureModelMock = $this->getMock('\Magento\Setup\Fixtures\FixtureModel', [], [], '', false);
+
+        $this->model = new EavVariationsFixture($this->fixtureModelMock);
+    }
+
+    public function testExecute()
+    {
+        $attributeMock = $this->getMock(
+            'Magento\Catalog\Model\Resource\Eav\Attribute',
+            [
+                'setAttributeSetId',
+                'setAttributeGroupId',
+                'save'
+            ],
+            [],
+            '',
+            false
+        );
+        $attributeMock->expects($this->exactly(2))
+            ->method('setAttributeSetId')
+            ->willReturnSelf();
+        $attributeMock->expects($this->once())
+            ->method('setAttributeGroupId')
+            ->willReturnSelf();
+
+        $storeMock = $this->getMock('\Magento\Store\Model\Store', [], [], '', false);
+
+        $storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+        $storeManagerMock->expects($this->once())
+            ->method('getStores')
+            ->will($this->returnValue([$storeMock]));
+
+        $setMock = $this->getMock('Magento\Eav\Model\Entity\Attribute\Set', [], [], '', false);
+        $setMock->expects($this->once())
+            ->method('getDefaultGroupId')
+            ->will($this->returnValue(2));
+
+        $cacheMock = $this->getMock('Magento\Framework\App\CacheInterface', [], [], '', false);
+
+        $valueMap = [
+            ['Magento\Catalog\Model\Resource\Eav\Attribute', [], $attributeMock],
+            ['Magento\Store\Model\StoreManager', [], $storeManagerMock],
+            ['Magento\Eav\Model\Entity\Attribute\Set', $setMock],
+            ['Magento\Framework\App\CacheInterface', $cacheMock]
+        ];
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->exactly(2))
+            ->method('create')
+            ->will($this->returnValueMap($valueMap));
+        $objectManagerMock->expects($this->exactly(2))
+            ->method('get')
+            ->will($this->returnValueMap($valueMap));
+
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->will($this->returnValue(1));
+        $this->fixtureModelMock
+            ->expects($this->exactly(4))
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+
+        $this->model->execute();
+    }
+
+    public function testNoFixtureConfigValue()
+    {
+        $attributeMock = $this->getMock('Magento\Catalog\Model\Resource\Eav\Attribute', [], [], '', false);
+        $attributeMock->expects($this->never())->method('save');
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->never())
+            ->method('create')
+            ->with($this->equalTo('Magento\Catalog\Model\Resource\Eav\Attribute'))
+            ->willReturn($attributeMock);
+
+        $this->fixtureModelMock
+            ->expects($this->never())
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(false);
+
+        $this->model->execute();
+    }
+
+    public function testGetActionTitle()
+    {
+        $eavVariationsFixture = new EavVariationsFixture($this->fixtureModelMock);
+        $this->assertSame('Generating configurable EAV variations', $eavVariationsFixture->getActionTitle());
+    }
+
+    public function testIntroduceParamLabels()
+    {
+        $eavVariationsFixture = new EavVariationsFixture($this->fixtureModelMock);
+        $this->assertSame([], $eavVariationsFixture->introduceParamLabels());
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/FixtureModelTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/FixtureModelTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..4ac088271bfad8621e6ab40d6558071a01e4ca49
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/FixtureModelTest.php
@@ -0,0 +1,95 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use \Magento\Setup\Fixtures\FixtureModel;
+
+class FixtureModelTest extends \PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @var \Magento\Setup\Fixtures\FixtureModel
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $reindexCommandMock = $this->getMock(
+            '\Magento\Indexer\Console\Command\IndexerReindexCommand',
+            [],
+            [],
+            '',
+            false
+        );
+        $fileParserMock = $this->getMock('\Magento\Framework\XML\Parser', [], [], '', false);
+
+        $this->model = new FixtureModel($reindexCommandMock, $fileParserMock);
+    }
+
+    public function testGetObjectManager()
+    {
+        $this->assertInstanceOf('Magento\Framework\ObjectManager\ObjectManager', $this->model->getObjectManager());
+    }
+
+    public function testReindex()
+    {
+        $outputMock = $this->getMock('\Symfony\Component\Console\Output\OutputInterface', [], [], '', false);
+        $this->model->reindex($outputMock);
+    }
+
+    /**
+     * @expectedException \Exception
+     * @expectedExceptionMessage Profile configuration file `exception.file` is not readable or does not exists.
+     */
+    public function testLoadConfigException()
+    {
+        $this->model->loadConfig('exception.file');
+    }
+
+    public function testLoadConfig()
+    {
+        $reindexCommandMock = $this->getMock(
+            '\Magento\Indexer\Console\Command\IndexerReindexCommand',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $fileParserMock = $this->getMock('\Magento\Framework\XML\Parser', [], [], '', false);
+        $fileParserMock->expects($this->once())
+            ->method('load')
+            ->willReturnSelf();
+
+        $this->model = new FixtureModel($reindexCommandMock, $fileParserMock);
+        $this->model->loadConfig('config.file');
+    }
+
+    public function testGetValue()
+    {
+        $this->assertSame(null, $this->model->getValue('null_key'));
+    }
+}
+
+namespace Magento\Setup\Fixtures;
+
+/**
+ * Overriding the built-in PHP function since it cannot be mocked->
+ *
+ * The method is used in FixtureModel. loadConfig in an if statement. By overriding this method we are able to test
+ * both of the possible cases based on the return value of is_readable.
+ *
+ * @param string $filename
+ * @return bool
+ */
+function is_readable($filename)
+{
+    if (strpos($filename, 'exception') !== false) {
+        return false;
+    }
+    return true;
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/IndexersStatesApplyFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/IndexersStatesApplyFixtureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..6d31626bc37333aae5a80ecd4b39b440f9204d2c
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/IndexersStatesApplyFixtureTest.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use \Magento\Setup\Fixtures\IndexersStatesApplyFixture;
+
+class IndexersStatesApplyFixtureTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel
+     */
+    private $fixtureModelMock;
+
+    /**
+     * @var \Magento\Setup\Fixtures\IndexersStatesApplyFixture
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->fixtureModelMock = $this->getMock('\Magento\Setup\Fixtures\FixtureModel', [], [], '', false);
+
+        $this->model = new IndexersStatesApplyFixture($this->fixtureModelMock);
+    }
+
+    public function testExecute()
+    {
+        $cacheInterfaceMock = $this->getMock('Magento\Framework\App\CacheInterface', [], [], '', false);
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->once())
+            ->method('get')
+            ->willReturn($cacheInterfaceMock);
+
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn([
+                'indexer' => ['id' => 1]
+            ]);
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getObjectManager')
+            ->willReturn($objectManagerMock);
+
+        $this->model->execute();
+    }
+
+    public function testNoFixtureConfigValue()
+    {
+        $cacheInterfaceMock = $this->getMock('Magento\Framework\App\CacheInterface', [], [], '', false);
+        $cacheInterfaceMock->expects($this->never())->method('clean');
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->never())
+            ->method('get')
+            ->willReturn($cacheInterfaceMock);
+
+        $this->fixtureModelMock
+            ->expects($this->never())
+            ->method('getObjectManager')
+            ->willReturn($objectManagerMock);
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(false);
+
+        $this->model->execute();
+    }
+
+    public function testGetActionTitle()
+    {
+        $this->assertSame('Indexers Mode Changes', $this->model->getActionTitle());
+    }
+
+    public function testIntroduceParamLabels()
+    {
+        $this->assertSame([], $this->model->introduceParamLabels());
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/OrdersFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/OrdersFixtureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..2775d218af70ed7c5bb856733b0dc71d3a444dea
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/OrdersFixtureTest.php
@@ -0,0 +1,262 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use \Magento\Setup\Fixtures\OrdersFixture;
+
+class OrdersFixtureTest extends \PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel
+     */
+    private $fixtureModelMock;
+
+    /**
+     * @var \Magento\Setup\Fixtures\OrdersFixture
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->fixtureModelMock = $this->getMock('\Magento\Setup\Fixtures\FixtureModel', [], [], '', false);
+
+        $this->model = new OrdersFixture($this->fixtureModelMock);
+    }
+
+    /**
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testExecute()
+    {
+        $mockObjectNames = [
+            'Magento\Quote\Model\Resource\Quote',
+            'Magento\Quote\Model\Resource\Quote\Address',
+            'Magento\Quote\Model\Resource\Quote\Item',
+            'Magento\Quote\Model\Resource\Quote\Item\Option',
+            'Magento\Quote\Model\Resource\Quote\Payment',
+            'Magento\Quote\Model\Resource\Quote\Address\Rate',
+            'Magento\Reports\Model\Resource\Event',
+            'Magento\Sales\Model\Resource\Order',
+            'Magento\Sales\Model\Resource\Order\Grid',
+            'Magento\Sales\Model\Resource\Order\Item',
+            'Magento\Sales\Model\Resource\Order\Payment',
+            'Magento\Sales\Model\Resource\Order\Status\History',
+            '\Magento\Eav\Model\Resource\Entity\Store'
+        ];
+        $mockObjects = [];
+
+        foreach ($mockObjectNames as $mockObjectName) {
+            $mockObject = $this->getMock($mockObjectName, [], [], '', false);
+            $path = explode('\\', $mockObjectName);
+            $name = array_pop($path);
+            if (strcasecmp($mockObjectName, 'Magento\Sales\Model\Resource\Order') == 0) {
+                $mockObject->expects($this->exactly(2))
+                    ->method('getTable')
+                    ->willReturn(strtolower($name) . '_table_name');
+            } else {
+                $mockObject->expects($this->once())
+                    ->method('getTable')
+                    ->willReturn(strtolower($name) . '_table_name');
+            }
+            $mockObjects[] = [$mockObjectName, $mockObject];
+        }
+
+        $adapterInterfaceMock = $this->getMockForAbstractClass(
+            '\Magento\Framework\DB\Adapter\AdapterInterface',
+            [],
+            '',
+            true,
+            true,
+            true,
+            []
+        );
+        $adapterInterfaceMock->expects($this->exactly(14))
+            ->method('getTableName')
+            ->willReturn('table_name');
+
+        $resourceMock = $this->getMock('Magento\Framework\App\Resource', [], [], '', false);
+        $resourceMock->expects($this->exactly(15))
+            ->method('getConnection')
+            ->willReturn($adapterInterfaceMock);
+
+        $websiteMock = $this->getMock('\Magento\Store\Model\Website', ['getId', 'getName'], [], '', false);
+        $websiteMock->expects($this->once())
+            ->method('getId')
+            ->willReturn('website_id');
+        $websiteMock->expects($this->once())
+            ->method('getName')
+            ->willReturn('website_name');
+
+        $groupMock = $this->getMock('\Magento\Store\Model\Group', ['getName'], [], '', false);
+        $groupMock->expects($this->once())
+            ->method('getName')
+            ->willReturn('group_name');
+
+        $storeMock = $this->getMock(
+            '\Magento\Store\Model\Store',
+            [
+                'getStoreId',
+                'getWebsite',
+                'getGroup',
+                'getName',
+                'getRootCategoryId'
+            ],
+            [],
+            '',
+            false
+        );
+        $storeMock->expects($this->once())
+            ->method('getStoreId')
+            ->willReturn(1);
+        $storeMock->expects($this->exactly(2))
+            ->method('getWebsite')
+            ->willReturn($websiteMock);
+        $storeMock->expects($this->once())
+            ->method('getGroup')
+            ->willReturn($groupMock);
+        $storeMock->expects($this->once())
+            ->method('getName')
+            ->willReturn('store_name');
+        $storeMock->expects($this->once())
+            ->method('getRootCategoryId')
+            ->willReturn(1);
+
+        $storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+        $storeManagerMock->expects($this->once())
+            ->method('getStores')
+            ->willReturn([$storeMock]);
+
+        $contextMock = $this->getMock('\Magento\Framework\Model\Resource\Db\Context', [], [], '', false);
+        $abstractDbMock = $this->getMockForAbstractClass(
+            '\Magento\Framework\Model\Resource\Db\AbstractDb',
+            [$contextMock],
+            '',
+            true,
+            true,
+            true,
+            ['getAllChildren']
+        );
+        $abstractDbMock->expects($this->once())
+            ->method('getAllChildren')
+            ->will($this->returnValue([1]));
+
+        $categoryMock = $this->getMock('Magento\Catalog\Model\Category', [], [], '', false);
+        $categoryMock->expects($this->once())
+            ->method('getResource')
+            ->willReturn($abstractDbMock);
+        $categoryMock->expects($this->once())
+            ->method('getPath')
+            ->willReturn('path/to/category');
+        $categoryMock->expects($this->exactly(2))
+            ->method('getName')
+            ->willReturn('category_name');
+        $categoryMock->expects($this->exactly(5))
+            ->method('load')
+            ->willReturnSelf();
+
+        $productMock = $this->getMock('\Magento\Catalog\Model\Product', ['load', 'getSku', 'getName'], [], '', false);
+        $productMock->expects($this->exactly(2))
+            ->method('load')
+            ->willReturnSelf();
+        $productMock->expects($this->exactly(2))
+            ->method('getSku')
+            ->willReturn('product_sku');
+        $productMock->expects($this->exactly(2))
+            ->method('getName')
+            ->willReturn('product_name');
+
+        $selectMock = $this->getMock('\Magento\Framework\DB\Select', [], [], '', false);
+
+        $collectionMock = $this->getMock('\Magento\Catalog\Model\Resource\Product\Collection', [], [], '', false);
+        $collectionMock->expects($this->once())
+            ->method('getSelect')
+            ->willReturn($selectMock);
+        $collectionMock->expects($this->once())
+            ->method('getAllIds')
+            ->willReturn([1, 1]);
+
+        array_push(
+            $mockObjects,
+            ['Magento\Store\Model\StoreManager', [], $storeManagerMock],
+            ['Magento\Catalog\Model\Category', $categoryMock],
+            ['Magento\Catalog\Model\Product', $productMock],
+            ['Magento\Framework\App\Resource', $resourceMock],
+            ['Magento\Catalog\Model\Resource\Product\Collection', [], $collectionMock]
+        );
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->exactly(32))
+            ->method('get')
+            ->will($this->returnValueMap($mockObjects));
+        $objectManagerMock->expects($this->exactly(2))
+            ->method('create')
+            ->will($this->returnValueMap($mockObjects));
+
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(1);
+        $this->fixtureModelMock
+            ->expects($this->exactly(34))
+            ->method('getObjectManager')
+            ->willReturn($objectManagerMock);
+
+        $this->model->execute();
+    }
+
+    public function testNoFixtureConfigValue()
+    {
+        $adapterInterfaceMock = $this->getMockForAbstractClass(
+            '\Magento\Framework\DB\Adapter\AdapterInterface',
+            [],
+            '',
+            true,
+            true,
+            true,
+            []
+        );
+        $adapterInterfaceMock->expects($this->never())
+            ->method('query');
+
+        $resourceMock = $this->getMock('Magento\Framework\App\Resource', [], [], '', false);
+        $resourceMock->expects($this->never())
+            ->method('getConnection')
+            ->with($this->equalTo('write'))
+            ->willReturn($adapterInterfaceMock);
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->never())
+            ->method('get')
+            ->with($this->equalTo('Magento\Framework\App\Resource'))
+            ->willReturn($resourceMock);
+
+        $this->fixtureModelMock
+            ->expects($this->never())
+            ->method('getObjectManagerMock')
+            ->willReturn($objectManagerMock);
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(false);
+
+        $this->model->execute();
+    }
+
+    public function testGetActionTitle()
+    {
+        $this->assertSame('Generating orders', $this->model->getActionTitle());
+    }
+
+    public function testIntroduceParamLabels()
+    {
+        $this->assertSame([
+            'orders'     => 'Orders'
+        ], $this->model->introduceParamLabels());
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/SimpleProductsFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/SimpleProductsFixtureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..497a60768893c929aeea1f9584a00ec7f7da8b49
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/SimpleProductsFixtureTest.php
@@ -0,0 +1,144 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use \Magento\Setup\Fixtures\SimpleProductsFixture;
+
+class SimpleProductsFixtureTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel
+     */
+    private $fixtureModelMock;
+
+    /**
+     * @var \Magento\Setup\Fixtures\SimpleProductsFixture
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->fixtureModelMock = $this->getMock('\Magento\Setup\Fixtures\FixtureModel', [], [], '', false);
+
+        $this->model = new SimpleProductsFixture($this->fixtureModelMock);
+    }
+
+    public function testExecute()
+    {
+        $storeMock = $this->getMock('\Magento\Store\Model\Store', [], [], '', false);
+        $storeMock->expects($this->once())
+            ->method('getRootCategoryId')
+            ->willReturn(1);
+
+        $websiteMock = $this->getMock('\Magento\Store\Model\Website', [], [], '', false);
+        $websiteMock->expects($this->once())
+            ->method('getCode')
+            ->willReturn('website_code');
+        $websiteMock->expects($this->once())
+            ->method('getGroups')
+            ->willReturn([$storeMock]);
+
+        $storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+        $storeManagerMock->expects($this->once())
+            ->method('getWebsites')
+            ->willReturn([$websiteMock]);
+
+        $importMock = $this->getMock('\Magento\ImportExport\Model\Import', [], [], '', false);
+
+        $contextMock = $this->getMock('\Magento\Framework\Model\Resource\Db\Context', [], [], '', false);
+        $abstractDbMock = $this->getMockForAbstractClass(
+            '\Magento\Framework\Model\Resource\Db\AbstractDb',
+            [$contextMock],
+            '',
+            true,
+            true,
+            true,
+            ['getAllChildren']
+        );
+        $abstractDbMock->expects($this->once())
+            ->method('getAllChildren')
+            ->will($this->returnValue([1]));
+
+        $categoryMock = $this->getMock('Magento\Catalog\Model\Category', [], [], '', false);
+        $categoryMock->expects($this->once())
+            ->method('getResource')
+            ->willReturn($abstractDbMock);
+        $categoryMock->expects($this->once())
+            ->method('getPath')
+            ->willReturn('path/to/category');
+        $categoryMock->expects($this->exactly(5))
+            ->method('load')
+            ->willReturnSelf();
+        $categoryMock->expects($this->exactly(3))
+            ->method('getName')
+            ->willReturn('category_name');
+
+        $valueMap = [
+            [
+                'Magento\ImportExport\Model\Import',
+                ['data' => ['entity' => 'catalog_product', 'behavior' => 'append']],
+                $importMock
+            ],
+            ['Magento\Store\Model\StoreManager', [], $storeManagerMock]
+        ];
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->exactly(2))
+            ->method('create')
+            ->will($this->returnValueMap($valueMap));
+        $objectManagerMock->expects($this->once())
+            ->method('get')
+            ->willReturn($categoryMock);
+
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(1);
+        $this->fixtureModelMock
+            ->expects($this->exactly(3))
+            ->method('getObjectManager')
+            ->willReturn($objectManagerMock);
+
+        $this->model->execute();
+    }
+
+    public function testNoFixtureConfigValue()
+    {
+        $importMock = $this->getMock('\Magento\ImportExport\Model\Import', [], [], '', false);
+        $importMock->expects($this->never())->method('validateSource');
+        $importMock->expects($this->never())->method('importSource');
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->never())
+            ->method('create')
+            ->with($this->equalTo('Magento\ImportExport\Model\Import'))
+            ->willReturn($importMock);
+
+        $this->fixtureModelMock
+            ->expects($this->never())
+            ->method('getObjectManager')
+            ->will($this->returnValue($objectManagerMock));
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(false);
+
+        $this->model->execute();
+    }
+
+    public function testGetActionTitle()
+    {
+        $this->assertSame('Generating simple products', $this->model->getActionTitle());
+    }
+
+    public function testIntroduceParamLabels()
+    {
+        $this->assertSame([
+            'simple_products' => 'Simple products'
+        ], $this->model->introduceParamLabels());
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/StoresFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/StoresFixtureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..07cd715489eab46621edfc68ae1a332c5678d5d3
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/StoresFixtureTest.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use \Magento\Setup\Fixtures\StoresFixture;
+
+class StoresFixtureTest extends \PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel
+     */
+    private $fixtureModelMock;
+
+    /**
+     * @var \Magento\Setup\Fixtures\StoresFixture
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->fixtureModelMock = $this->getMock('\Magento\Setup\Fixtures\FixtureModel', [], [], '', false);
+
+        $this->model = new StoresFixture($this->fixtureModelMock);
+    }
+
+    /**
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+     */
+    public function testExecute()
+    {
+        $websiteMock = $this->getMock('\Magento\Store\Model\Website', [], [], '', false);
+        $websiteMock->expects($this->exactly(2))
+            ->method('getId')
+            ->willReturn('website_id');
+        $websiteMock->expects($this->once())
+            ->method('save');
+
+        $groupMock = $this->getMock('\Magento\Store\Model\Group', [], [], '', false);
+        $groupMock->expects($this->exactly(2))
+            ->method('getId')
+            ->willReturn('group_id');
+        $groupMock->expects($this->once())
+            ->method('save');
+
+        $storeMock = $this->getMock('\Magento\Store\Model\Store', [], [], '', false);
+        $storeMock->expects($this->once())
+            ->method('getRootCategoryId')
+            ->willReturn(1);
+        $storeMock->expects($this->once())
+            ->method('getId')
+            ->willReturn('store_id');
+        $storeMock->expects($this->once())
+            ->method('save');
+
+        $storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+        $storeManagerMock->expects($this->once())
+            ->method('getWebsite')
+            ->willReturn($websiteMock);
+        $storeManagerMock->expects($this->once())
+            ->method('getGroup')
+            ->willReturn($groupMock);
+        $storeManagerMock->expects($this->once())
+            ->method('getDefaultStoreView')
+            ->willReturn($storeMock);
+        $storeManagerMock->expects($this->once())
+            ->method('getStore')
+            ->willReturn($storeMock);
+
+        $categoryMock = $this->getMock(
+            'Magento\Catalog\Model\Category',
+            [
+                'setId',
+                'setName',
+                'setPath',
+                'setLevel',
+                'setAvailableSortBy',
+                'setDefaultSortBy',
+                'setIsActive',
+                'getId',
+                'save'
+            ],
+            [],
+            '',
+            false
+        );
+        $categoryMock->expects($this->once())
+            ->method('setId')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setName')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setPath')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setLevel')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setAvailableSortBy')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setDefaultSortBy')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('setIsActive')
+            ->willReturnSelf();
+        $categoryMock->expects($this->once())
+            ->method('getId')
+            ->willReturn('category_id');
+
+        $valueMap = [
+            ['Magento\Store\Model\StoreManager', [], $storeManagerMock],
+            ['Magento\Catalog\Model\Category', [], $categoryMock]
+        ];
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->exactly(2))
+            ->method('create')
+            ->will($this->returnValueMap($valueMap));
+
+        $this->fixtureModelMock
+            ->expects($this->exactly(3))
+            ->method('getValue')
+            ->will($this->returnValue(1));
+        $this->fixtureModelMock
+            ->expects($this->exactly(2))
+            ->method('getObjectManager')
+            ->willReturn($objectManagerMock);
+
+        $this->model->execute();
+    }
+
+    public function testNoFixtureConfigValue()
+    {
+        $storeMock = $this->getMock('\Magento\Store\Model\Store', [], [], '', false);
+        $storeMock->expects($this->never())->method('save');
+
+        $storeManagerMock = $this->getMock('Magento\Store\Model\StoreManager', [], [], '', false);
+        $storeManagerMock->expects($this->never())
+            ->method('getDefaultStoreView')
+            ->willReturn($storeMock);
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->never())
+            ->method('create')
+            ->with($this->equalTo('Magento\Store\Model\StoreManager'))
+            ->willReturn($storeManagerMock);
+
+        $this->fixtureModelMock
+            ->expects($this->never())
+            ->method('getObjectManager')
+            ->willReturn($objectManagerMock);
+        $this->fixtureModelMock
+            ->expects($this->exactly(3))
+            ->method('getValue')
+            ->willReturn(false);
+
+        $this->model->execute();
+    }
+
+    public function testGetActionTitle()
+    {
+        $this->assertSame('Generating websites, stores and store views', $this->model->getActionTitle());
+    }
+
+    public function testIntroduceParamLabels()
+    {
+        $this->assertSame([
+            'websites' => 'Websites',
+            'store_groups' => 'Store Groups',
+            'store_views' => 'Store Views'
+        ], $this->model->introduceParamLabels());
+    }
+}
diff --git a/setup/src/Magento/Setup/Test/Unit/Fixtures/TaxRatesFixtureTest.php b/setup/src/Magento/Setup/Test/Unit/Fixtures/TaxRatesFixtureTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b7547afbd5e8da7897b0cef455b1581dfcccb23
--- /dev/null
+++ b/setup/src/Magento/Setup/Test/Unit/Fixtures/TaxRatesFixtureTest.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\Setup\Test\Unit\Fixtures;
+
+use \Magento\Setup\Fixtures\TaxRatesFixture;
+
+class TaxRatesFixtureTest extends \PHPUnit_Framework_TestCase
+{
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\Setup\Fixtures\FixtureModel
+     */
+    private $fixtureModelMock;
+
+    /**
+     * @var \Magento\Setup\Fixtures\TaxRatesFixture
+     */
+    private $model;
+
+    public function setUp()
+    {
+        $this->fixtureModelMock = $this->getMock('\Magento\Setup\Fixtures\FixtureModel', [], [], '', false);
+
+        $this->model = new TaxRatesFixture($this->fixtureModelMock);
+    }
+
+    public function testExecute()
+    {
+        $rateMock = $this->getMock('Magento\Tax\Model\Calculation\Rate', ['setId', 'delete'], [], '', false);
+
+        $collectionMock = $this->getMock('Magento\Tax\Model\Resource\Calculation\Rate\Collection', [], [], '', false);
+        $collectionMock->expects($this->once())
+            ->method('getAllIds')
+            ->willReturn([1]);
+
+        $csvImportHandlerMock = $this->getMock(
+            'Magento\TaxImportExport\Model\Rate\CsvImportHandler',
+            [],
+            [],
+            '',
+            false
+        );
+
+        $valueMap = [
+            ['Magento\Tax\Model\Calculation\Rate', $rateMock],
+            ['Magento\Tax\Model\Resource\Calculation\Rate\Collection', $collectionMock]
+        ];
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->exactly(2))
+            ->method('get')
+            ->will($this->returnValueMap($valueMap));
+        $objectManagerMock->expects($this->once())
+            ->method('create')
+            ->willReturn($csvImportHandlerMock);
+
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn('taxRates.file');
+        $this->fixtureModelMock
+            ->expects($this->exactly(3))
+            ->method('getObjectManager')
+            ->willReturn($objectManagerMock);
+
+        $this->model->execute();
+    }
+
+    public function testNoFixtureConfigValue()
+    {
+        $csvImportHandlerMock = $this->getMock(
+            'Magento\TaxImportExport\Model\Rate\CsvImportHandler',
+            [],
+            [],
+            '',
+            false
+        );
+        $csvImportHandlerMock->expects($this->never())->method('importFromCsvFile');
+
+        $objectManagerMock = $this->getMock('Magento\Framework\ObjectManager\ObjectManager', [], [], '', false);
+        $objectManagerMock->expects($this->never())
+            ->method('create')
+            ->willReturn($csvImportHandlerMock);
+
+        $this->fixtureModelMock
+            ->expects($this->never())
+            ->method('getObjectManager')
+            ->willReturn($objectManagerMock);
+        $this->fixtureModelMock
+            ->expects($this->once())
+            ->method('getValue')
+            ->willReturn(false);
+
+        $this->model->execute();
+    }
+
+    public function testGetActionTitle()
+    {
+        $this->assertSame('Generating tax rates', $this->model->getActionTitle());
+    }
+
+    public function testIntroduceParamLabels()
+    {
+        $this->assertSame([], $this->model->introduceParamLabels());
+    }
+}
diff --git a/setup/view/magento/setup/readiness-check/progress.phtml b/setup/view/magento/setup/readiness-check/progress.phtml
index 38f17626b0349c1eddfcbc73bfddf60b814ebff8..ae1f6acaa1dd9db427e595b9230c9a84908350a1 100644
--- a/setup/view/magento/setup/readiness-check/progress.phtml
+++ b/setup/view/magento/setup/readiness-check/progress.phtml
@@ -67,17 +67,22 @@
 
             <div class="readiness-check-content">
                 <h3 class="readiness-check-title">PHP Version Check</h3>
-                <p>
-                    Your PHP version is {{version.data.current}}. The required PHP version is {{version.data.required}}.
-                    <a href="#php-version" ng-click="updateOnExpand(version)">
-                        <span ng-hide="version.expanded">Show detail</span>
-                        <span ng-show="version.expanded">Hide detail</span>
-                    </a>
-                </p>
-                <p ng-show="version.expanded">
-                    Download and install PHP version {{version.data.required}} from <a href="http://www.php.net" target="_blank">www.php.net</a> using this <a href="http://www.php.net/docs.php" target="_blank">PHP Documentation</a>.
-                </p>
-                <p ng-show="version.expanded">If you need more help please call your hosting provider.</p>
+                <div ng-show="version.isRequestError">
+                    <p>Server failed to respond. Please try again.</p>
+                </div>
+                <div ng-hide="version.isRequestError">
+                    <p>
+                        Your PHP version is {{version.data.current}}. The required PHP version is {{version.data.required}}.
+                        <a href="#php-version" ng-click="updateOnExpand(version)">
+                            <span ng-hide="version.expanded">Show detail</span>
+                            <span ng-show="version.expanded">Hide detail</span>
+                        </a>
+                    </p>
+                    <p ng-show="version.expanded">
+                        Download and install PHP version {{version.data.required}} from <a href="http://www.php.net" target="_blank">www.php.net</a> using this <a href="http://www.php.net/docs.php" target="_blank">PHP Documentation</a>.
+                    </p>
+                    <p ng-show="version.expanded">If you need more help please call your hosting provider.</p>
+                </div>
             </div>
 
         </div>
@@ -110,17 +115,22 @@
         <div class="readiness-check-item" ng-switch-default ng-init="updateOnError(settings)">
 
             <span class="readiness-check-icon icon-failed-round"></span>
-            <h3 class="readiness-check-title">PHP Settings Check</h3>
+            <div class="readiness-check-content">
+                <h3 class="readiness-check-title">PHP Settings Check</h3>
 
-            <div ng-repeat="setting in settings.data">
-                <div ng-show="setting.error && setting.helpUrl" class="rediness-check-side">
-                    <p class="side-title">Need Help?</p>
-                    <a href="{{setting.helpUrl}}" target="_blank">PHP Documentation</a>
+                <div ng-show="settings.isRequestError">
+                    <p>Server failed to respond. Please try again.</p>
                 </div>
-                <div ng-show="setting.error" class="readiness-check-content">
-                    <p>
-                        {{setting.message}}
-                    </p>
+                <div ng-hide="settings.isRequestError" ng-repeat="setting in settings.data">
+                    <div ng-show="setting.error && setting.helpUrl" class="rediness-check-side">
+                        <p class="side-title">Need Help?</p>
+                        <a href="{{setting.helpUrl}}" target="_blank">PHP Documentation</a>
+                    </div>
+                    <div ng-show="setting.error">
+                        <p>
+                            {{setting.message}}
+                        </p>
+                    </div>
                 </div>
             </div>
         </div>
@@ -178,32 +188,37 @@
 
                 <div class="readiness-check-content">
                     <h3 class="readiness-check-title">PHP Extensions Check</h3>
-                    <p>
-                        {{extensions.data.missing.length}} missing PHP extensions.
-                        <a href="#php-extensions" ng-click="updateOnExpand(extensions)">
-                            <span ng-hide="extensions.expanded">Show detail</span>
-                            <span ng-show="extensions.expanded">Hide detail</span>
-                        </a>
-                    </p>
-                    <p>
-                        The best way to resolve this is to install the correct missing extensions. The exact fix depends on our server, your host, and other system variables.
-                        <br>
-                        Our <a href="http://devdocs.magento.com/guides/v1.0/install-gde/system-requirements.html" target="_blank">PHP Extension Help</a> can get you started.
-                    </p>
-                    <p>
-                        If you need more help, please call your hosting provider.
-                    </p>
-                    <ul class="list" ng-show="extensions.expanded">
-                        <li
-                            class="list-item-icon"
-                            ng-repeat="name in extensions.data.required"
-                            ng-switch="extensions.data.missing.indexOf(name) >= 0"
-                            >
-                            <span ng-switch-when="true" class="icon-failed"></span>
-                            <span ng-switch-default class="icon-success"></span>
-                            PHP Extension {{name}}.
-                        </li>
-                    </ul>
+                    <div ng-show="extensions.isRequestError">
+                        <p>Server failed to respond. Please try again.</p>
+                    </div>
+                    <div ng-hide="extensions.isRequestError">
+                        <p>
+                            {{extensions.data.missing.length}} missing PHP extensions.
+                            <a href="#php-extensions" ng-click="updateOnExpand(extensions)">
+                                <span ng-hide="extensions.expanded">Show detail</span>
+                                <span ng-show="extensions.expanded">Hide detail</span>
+                            </a>
+                        </p>
+                        <p>
+                            The best way to resolve this is to install the correct missing extensions. The exact fix depends on our server, your host, and other system variables.
+                            <br>
+                            Our <a href="http://devdocs.magento.com/guides/v1.0/install-gde/system-requirements.html" target="_blank">PHP Extension Help</a> can get you started.
+                        </p>
+                        <p>
+                            If you need more help, please call your hosting provider.
+                        </p>
+                        <ul class="list" ng-show="extensions.expanded">
+                            <li
+                                class="list-item-icon"
+                                ng-repeat="name in extensions.data.required"
+                                ng-switch="extensions.data.missing.indexOf(name) >= 0"
+                                >
+                                <span ng-switch-when="true" class="icon-failed"></span>
+                                <span ng-switch-default class="icon-success"></span>
+                                PHP Extension {{name}}.
+                            </li>
+                        </ul>
+                    </div>
                 </div>
 
             </div>
@@ -256,32 +271,37 @@
             <div class="readiness-check-content">
 
                 <h3 class="readiness-check-title">File Permission Check</h3>
-                <p>
-                    {{permissions.data.required.length - permissions.data.current.length}} file permission not met.
-                    <a href="#php-permissions" ng-click="updateOnExpand(permissions)">
-                        <span ng-hide="permissions.expanded">Show detail</span>
-                        <span ng-show="permissions.expanded">Hide detail</span>
-                    </a>
-                </p>
-                <p>
-                    The best way to resolve this is to allow write permissions for the following Magento directories. The exact fix depends on your server, your host, and other system variables.
-                    <br>
-                    Our <a href="http://devdocs.magento.com/guides/v1.0/install-gde/install/composer-clone.html#instgde-prereq-compose-access" target="_blank">File Permission Help</a> can get you started.
-                </p>
-                <p>
-                    If you need more help, please call your hosting provider.
-                </p>
+                <div ng-show="permissions.isRequestError">
+                    <p>Server failed to respond. Please try again.</p>
+                </div>
+                <div ng-hide="permissions.isRequestError">
+                    <p>
+                        {{permissions.data.required.length - permissions.data.current.length}} file permission not met.
+                        <a href="#php-permissions" ng-click="updateOnExpand(permissions)">
+                            <span ng-hide="permissions.expanded">Show detail</span>
+                            <span ng-show="permissions.expanded">Hide detail</span>
+                        </a>
+                    </p>
+                    <p>
+                        The best way to resolve this is to allow write permissions for the following Magento directories. The exact fix depends on your server, your host, and other system variables.
+                        <br>
+                        Our <a href="http://devdocs.magento.com/guides/v1.0/install-gde/install/composer-clone.html#instgde-prereq-compose-access" target="_blank">File Permission Help</a> can get you started.
+                    </p>
+                    <p>
+                        If you need more help, please call your hosting provider.
+                    </p>
 
-                <ul class="list" ng-show="permissions.expanded">
-                    <li
-                        class="list-item-icon"
-                        ng-repeat="name in permissions.data.required"
-                        ng-switch="hasItem(permissions.data.current, name)">
-                        <span ng-switch-when="true" class="icon-success"></span>
-                        <span ng-switch-default class="icon-failed"></span>
-                        <span>"{{name}}" writable directory permission.</span>
-                    </li>
-                </ul>
+                    <ul class="list" ng-show="permissions.expanded">
+                        <li
+                            class="list-item-icon"
+                            ng-repeat="name in permissions.data.required"
+                            ng-switch="hasItem(permissions.data.current, name)">
+                            <span ng-switch-when="true" class="icon-success"></span>
+                            <span ng-switch-default class="icon-failed"></span>
+                            <span>"{{name}}" writable directory permission.</span>
+                        </li>
+                    </ul>
+                </div>
 
             </div>