├── etc
├── db_schema.xml
├── adminhtml
│ ├── routes.xml
│ └── system.xml
├── frontend
│ ├── routes.xml
│ └── di.xml
├── events.xml
├── module.xml
├── csp_whitelist.xml
├── di.xml
└── config.xml
├── composer.json
├── view
├── adminhtml
│ ├── web
│ │ ├── css
│ │ │ └── system-config.css
│ │ └── js
│ │ │ └── lib
│ │ │ └── connect.js
│ ├── requirejs-config.js
│ ├── layout
│ │ └── adminhtml_system_config_edit.xml
│ └── templates
│ │ └── connect
│ │ └── widget.phtml
└── frontend
│ ├── web
│ ├── css
│ │ └── main.css
│ ├── js
│ │ ├── view
│ │ │ └── payment
│ │ │ │ ├── xpayments-cloud.js
│ │ │ │ └── method-renderer
│ │ │ │ └── xpayments-cloud.js
│ │ ├── base.js
│ │ └── lib
│ │ │ └── widget.js
│ └── template
│ │ └── payment
│ │ └── form.html
│ ├── requirejs-config.js
│ └── layout
│ └── checkout_index_index.xml
├── registration.php
├── Observer
└── Payment
│ └── DataAssignObserver.php
├── Transport
├── DataObject.php
├── WidgetSettings.php
└── ConnectSettings.php
├── Logger
├── Handler.php
└── Logger.php
├── Block
├── Payment
│ └── Info.php
├── System
│ └── Config
│ │ └── CloudIframe.php
└── Adminhtml
│ └── Connect
│ └── Widget.php
├── Helper
├── Client.php
├── Address.php
└── Cart.php
├── Model
├── Order
│ └── Payment.php
└── Payment
│ └── Method
│ └── XPaymentsCloud.php
├── Controller
└── Adminhtml
│ └── System
│ └── Config
│ └── Save.php
├── README.md
├── Setup
└── Patch
│ └── Data
│ └── AddXPaymentsCustomerIDAttribute.php
└── Ui
└── XPaymentsCloud
└── ConfigProvider.php
/etc/db_schema.xml:
--------------------------------------------------------------------------------
1 |
3 |
7 |
8 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "cdev/x-payments-cloud",
3 | "description": "PCI level 1 certified & PSD2/SCA ready all-in-one secure credit card processing solution for web shops X-Payments takes the PCI DSS burden off your shoulders.",
4 | "type": "magento2-module",
5 | "version": "100.4.1",
6 | "license": [
7 | "OSL-3.0",
8 | "AFL-3.0"
9 | ],
10 | "minimum-stability": "dev",
11 | "require": {
12 | "php": "~7.4.0||~8.1.0",
13 | "magento/module-payment": "100.4.*",
14 | "magento/module-checkout": "100.4.*",
15 | "magento/module-sales": "103.0.*",
16 | "xpayments/cloud-sdk-php": "~0.2.0"
17 | },
18 | "autoload": {
19 | "files": [ "registration.php" ],
20 | "psr-4": {
21 | "CDev\\XPaymentsCloud\\": ""
22 | }
23 | },
24 | "repositories": [
25 | {
26 | "type": "git",
27 | "url": "https://github.com/xpayments/m2-cloud"
28 | }
29 | ]
30 | }
31 |
--------------------------------------------------------------------------------
/view/adminhtml/web/css/system-config.css:
--------------------------------------------------------------------------------
1 | /**
2 | vim: set ts=4 sw=4 sts=4 et:
3 | * X-Payments Cloud Settings
4 | *
5 | * NOTICE OF LICENSE
6 | *
7 | * This source file is subject to the Open Software License (OSL 3.0)
8 | * that is bundled with this package in the file LICENSE.txt.
9 | * It is also available through the world-wide-web at this URL:
10 | * http://opensource.org/licenses/osl-3.0.php
11 | * If you did not receive a copy of the license and are unable to
12 | * obtain it through the world-wide-web, please send an email
13 | * to license@magentocommerce.com so we can send you a copy immediately.
14 | *
15 | * @author Qualiteam Software
16 | * @category CDev
17 | * @package CDev_XPaymentsCloud
18 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
19 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20 | */
21 |
22 | #xpayments-iframe-container iframe {
23 | border: 0;
24 | }
25 |
--------------------------------------------------------------------------------
/view/adminhtml/requirejs-config.js:
--------------------------------------------------------------------------------
1 | // vim: set ts=2 sw=2 sts=2 et:
2 | /**
3 | * Magento
4 | *
5 | * NOTICE OF LICENSE
6 | *
7 | * This source file is subject to the Open Software License (OSL 3.0)
8 | * that is bundled with this package in the file LICENSE.txt.
9 | * It is also available through the world-wide-web at this URL:
10 | * http://opensource.org/licenses/osl-3.0.php
11 | * If you did not receive a copy of the license and are unable to
12 | * obtain it through the world-wide-web, please send an email
13 | * to license@magentocommerce.com so we can send you a copy immediately.
14 | *
15 | * @author Qualiteam Software
16 | * @category CDev
17 | * @package CDev_XPaymentsCloud
18 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
19 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20 | */
21 |
22 | var config = {
23 | paths: {
24 | 'xpayments/lib/connect': 'CDev_XPaymentsCloud/js/lib/connect',
25 | },
26 | };
27 |
28 |
--------------------------------------------------------------------------------
/registration.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | \Magento\Framework\Component\ComponentRegistrar::register(
24 | \Magento\Framework\Component\ComponentRegistrar::MODULE,
25 | 'CDev_XPaymentsCloud',
26 | __DIR__
27 | );
28 |
--------------------------------------------------------------------------------
/view/frontend/web/css/main.css:
--------------------------------------------------------------------------------
1 | /**
2 | vim: set ts=4 sw=4 sts=4 et:
3 | * Checkout page
4 | *
5 | * NOTICE OF LICENSE
6 | *
7 | * This source file is subject to the Open Software License (OSL 3.0)
8 | * that is bundled with this package in the file LICENSE.txt.
9 | * It is also available through the world-wide-web at this URL:
10 | * http://opensource.org/licenses/osl-3.0.php
11 | * If you did not receive a copy of the license and are unable to
12 | * obtain it through the world-wide-web, please send an email
13 | * to license@magentocommerce.com so we can send you a copy immediately.
14 | *
15 | * @author Qualiteam Software
16 | * @category CDev
17 | * @package CDev_XPaymentsCloud
18 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
19 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20 | */
21 |
22 | @supports (-webkit-appearance: -apple-pay-button) {
23 | .apple-pay-button {
24 | -webkit-appearance: -apple-pay-button;
25 | overflow: hidden;
26 | color: transparent !important;
27 | }
28 | .apple-pay-button span {
29 | visibility: hidden;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/view/adminhtml/layout/adminhtml_system_config_edit.xml:
--------------------------------------------------------------------------------
1 |
2 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/etc/adminhtml/routes.xml:
--------------------------------------------------------------------------------
1 |
2 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/etc/frontend/routes.xml:
--------------------------------------------------------------------------------
1 |
2 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/etc/events.xml:
--------------------------------------------------------------------------------
1 |
2 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/view/frontend/requirejs-config.js:
--------------------------------------------------------------------------------
1 | // vim: set ts=2 sw=2 sts=2 et:
2 | /**
3 | * Magento
4 | *
5 | * NOTICE OF LICENSE
6 | *
7 | * This source file is subject to the Open Software License (OSL 3.0)
8 | * that is bundled with this package in the file LICENSE.txt.
9 | * It is also available through the world-wide-web at this URL:
10 | * http://opensource.org/licenses/osl-3.0.php
11 | * If you did not receive a copy of the license and are unable to
12 | * obtain it through the world-wide-web, please send an email
13 | * to license@magentocommerce.com so we can send you a copy immediately.
14 | *
15 | * @author Qualiteam Software
16 | * @category CDev
17 | * @package CDev_XPaymentsCloud
18 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
19 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20 | */
21 |
22 | var config = {
23 | paths: {
24 | 'xpayments/lib/widget': 'CDev_XPaymentsCloud/js/lib/widget',
25 | 'xpayments/base': 'CDev_XPaymentsCloud/js/base',
26 | },
27 | shim: {
28 | 'xpayments/base': ['prototype', 'xpayments/lib/widget'],
29 | 'CDev_XPaymentsCloud/js/view/payment/xpayments-cloud': ['xpayments/base'],
30 | },
31 | deps: ['xpayments/lib/widget']
32 | };
33 |
--------------------------------------------------------------------------------
/etc/module.xml:
--------------------------------------------------------------------------------
1 |
2 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/etc/csp_whitelist.xml:
--------------------------------------------------------------------------------
1 |
2 |
24 |
25 |
26 |
27 |
28 | connect.xpayments.com
29 | *.xpayments.com
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/view/frontend/web/js/view/payment/xpayments-cloud.js:
--------------------------------------------------------------------------------
1 | // vim: set ts=2 sw=2 sts=2 et:
2 | /**
3 | * Magento
4 | *
5 | * NOTICE OF LICENSE
6 | *
7 | * This source file is subject to the Open Software License (OSL 3.0)
8 | * that is bundled with this package in the file LICENSE.txt.
9 | * It is also available through the world-wide-web at this URL:
10 | * http://opensource.org/licenses/osl-3.0.php
11 | * If you did not receive a copy of the license and are unable to
12 | * obtain it through the world-wide-web, please send an email
13 | * to license@magentocommerce.com so we can send you a copy immediately.
14 | *
15 | * @author Qualiteam Software
16 | * @category CDev
17 | * @package CDev_XPaymentsCloud
18 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
19 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20 | */
21 | define(
22 | [
23 | 'uiComponent',
24 | 'Magento_Checkout/js/model/payment/renderer-list',
25 | ],
26 | function (
27 | Component,
28 | rendererList
29 | ) {
30 | 'use strict';
31 |
32 | rendererList.push(
33 | {
34 | type: 'xpayments_cloud',
35 | component: 'CDev_XPaymentsCloud/js/view/payment/method-renderer/xpayments-cloud',
36 | }
37 | );
38 |
39 | return Component.extend({});
40 | }
41 | );
42 |
--------------------------------------------------------------------------------
/etc/frontend/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
24 |
25 |
26 |
27 |
28 | - CDev\XPaymentsCloud\Ui\XPaymentsCloud\ConfigProvider
29 |
30 |
31 |
32 |
33 |
34 |
35 | - 1
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/Observer/Payment/DataAssignObserver.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Observer\Payment;
24 |
25 | /**
26 | * Data assign observer for X-Payments Cloud payment method
27 | */
28 | class DataAssignObserver extends \Magento\Payment\Observer\AbstractDataAssignObserver
29 | {
30 | /**
31 | * Assign data
32 | *
33 | * @param \Magento\Framework\Event\Observer $observer
34 | *
35 | * @return void
36 | */
37 | public function execute(\Magento\Framework\Event\Observer $observer)
38 | {
39 | $method = $this->readMethodArgument($observer);
40 | $data = $this->readDataArgument($observer);
41 |
42 | $additionalData = $data->getData(\Magento\Quote\Api\Data\PaymentInterface::KEY_ADDITIONAL_DATA);
43 |
44 | if (!empty($additionalData['xpayments_token'])) {
45 | $paymentInfo = $method->getInfoInstance();
46 | $paymentInfo->setAdditionalInformation('xpayments_token', $additionalData['xpayments_token']);
47 | }
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/Transport/DataObject.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Transport;
24 |
25 | /**
26 | * Base data-object class for transport
27 | */
28 | abstract class DataObject extends \Magento\Framework\DataObject
29 | {
30 | /**
31 | * Tiny function to enhance functionality of ucwords
32 | * Will capitalize first letters and convert separators if needed
33 | * Doesn't exist in Magento 2 unfortunately
34 | *
35 | * @param string $str
36 | * @param string $destSep
37 | * @param string $srcSep
38 | *
39 | * @return string
40 | */
41 | protected function ucWords($str, $destSep = '_', $srcSep = '_')
42 | {
43 | return str_replace(' ', $destSep, ucwords(str_replace($srcSep, ' ', $str)));
44 | }
45 |
46 | /**
47 | * Converts field names for setters and geters
48 | * (Do not use underscopes, actually, keep orig names)
49 | *
50 | * @param string $name
51 | *
52 | * @return string
53 | */
54 | protected function _underscore($name)
55 | {
56 | return lcfirst($name);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Logger/Handler.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Logger;
24 |
25 | /**
26 | * Logger handler
27 | */
28 | class Handler extends \Magento\Framework\Logger\Handler\Base
29 | {
30 | /**
31 | * Log file name
32 | */
33 | protected const XPAYMENTS_LOG_FILE = '/var/log/xpayments-cloud-%s.log';
34 |
35 | /**
36 | * Constructor
37 | *
38 | * @param \Magento\Framework\Filesystem\DriverInterface $filesystem
39 | * @param \Magento\Framework\Stdlib\DateTime\DateTime $date
40 | * @param string $filePath
41 | * @param string $fileName
42 | *
43 | * @return void
44 | *
45 | * @SuppressWarnings(MEQP2.Classes.ConstructorOperations.CustomOperationsFound)
46 | * @codingStandardsIgnoreStart
47 | */
48 | public function __construct(
49 | \Magento\Framework\Filesystem\DriverInterface $filesystem,
50 | \Magento\Framework\Stdlib\DateTime\DateTime $date,
51 | $filePath = null,
52 | $fileName = null
53 | ) {
54 |
55 | $this->fileName = sprintf(self::XPAYMENTS_LOG_FILE, $date->date('Y-m'));
56 |
57 | parent::__construct($filesystem, $filePath, $fileName);
58 | }
59 | }
60 |
61 |
--------------------------------------------------------------------------------
/etc/di.xml:
--------------------------------------------------------------------------------
1 |
2 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | CDev\XPaymentsCloud\Model\Payment\Method\XPaymentsCloud::CODE
31 |
32 |
33 |
34 |
35 |
36 |
37 | Magento\Framework\Filesystem\Driver\File
38 |
39 |
40 |
41 |
42 | xpcLogger
43 |
44 | - CDev\XPaymentsCloud\Logger\Handler
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
24 |
25 |
26 |
27 |
28 |
29 | 0
30 | 0
31 | CDev\XPaymentsCloud\Model\Payment\Method\XPaymentsCloud
32 | pending_payment
33 | authorize_capture
34 | Credit or Debit Card
35 | USD
36 | 1
37 | 1
38 | 1
39 | 1
40 | 1
41 | 1
42 | 1
43 | 0
44 | 1
45 | cc_last_4,cc_first6,xpayments_customer_id
46 | cc_first6,xpayments_customer_id
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/view/frontend/web/template/payment/form.html:
--------------------------------------------------------------------------------
1 |
23 |
24 |
25 |
29 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/Block/Payment/Info.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Block\Payment;
24 |
25 | /**
26 | * Payment info block
27 | */
28 | class Info extends \Magento\Payment\Block\ConfigurableInfo
29 | {
30 | /**
31 | * Name of the X-Payments card field
32 | */
33 | protected const XPAYMENTS_CARD = 'xpayments_card';
34 |
35 | /**
36 | * Placeholder for hidden numbers in card number
37 | */
38 | protected const PLACEHOLDER = '•';
39 |
40 | /**
41 | * Returns label
42 | *
43 | * @param string $field
44 | *
45 | * @return \Magento\Framework\Phrase
46 | */
47 | protected function getLabel($field)
48 | {
49 | if (self::XPAYMENTS_CARD == $field) {
50 | $field = 'Payment Card';
51 | }
52 |
53 | return parent::getLabel($field);
54 | }
55 |
56 | /**
57 | * Prepare payment information
58 | *
59 | * @param \Magento\Framework\DataObject|array|null $transport
60 | *
61 | * @return \Magento\Framework\DataObject
62 | */
63 | protected function _prepareSpecificInformation($transport = null)
64 | {
65 | $transport = parent::_prepareSpecificInformation($transport);
66 |
67 | $payment = $this->getInfo();
68 |
69 | $first6 = $payment->getCcFirst6() ?: str_repeat(self::PLACEHOLDER, 6);
70 |
71 | $middleLength = ('AMEX' === $payment->getCcType()) ? 5 : 6;
72 | $middle = str_repeat(self::PLACEHOLDER, $middleLength);
73 |
74 | $card = sprintf(
75 | '[%s] %s%s%s (%s/%s)',
76 | $payment->getCcType(),
77 | $first6, $middle, $payment->getCcLast4(),
78 | $payment->getCcExpMonth(), $payment->getCcExpYear()
79 | );
80 |
81 | $this->setDataToTransfer(
82 | $transport,
83 | self::XPAYMENTS_CARD,
84 | $card
85 | );
86 |
87 | return $transport;
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/Block/System/Config/CloudIframe.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Block\System\Config;
24 |
25 | /**
26 | * X-Payments Cloud configuration iframe
27 | */
28 | class CloudIframe extends \Magento\Config\Block\System\Config\Form\Field
29 | {
30 | /**
31 | * Layout
32 | *
33 | * @var \Magento\Framework\View\LayoutInterface
34 | */
35 | protected $layout;
36 |
37 | /**
38 | * Constructor
39 | *
40 | * @param \Magento\Backend\Block\Template\Context $context
41 | * @param \Magento\Framework\View\LayoutInterface $layout
42 | * @param array $data
43 | *
44 | * @return void
45 | */
46 | public function __construct(
47 | \Magento\Backend\Block\Template\Context $context,
48 | \Magento\Framework\View\LayoutInterface $layout,
49 | array $data = array()
50 | ) {
51 | $this->layout = $layout;
52 | parent::__construct($context);
53 | }
54 |
55 | /**
56 | * Retrieve HTML markup for given form element
57 | *
58 | * @param \Magento\Framework\Data\Form\Element\AbstractElement $element
59 | *
60 | * @return string
61 | */
62 | public function render(\Magento\Framework\Data\Form\Element\AbstractElement $element)
63 | {
64 | $html = $this->layout
65 | ->createBlock(\CDev\XPaymentsCloud\Block\Adminhtml\Connect\Widget::class)
66 | ->toHtml();
67 |
68 | return $this->_decorateRowHtml($element, $html);
69 | }
70 |
71 | /**
72 | * Decorate field row html
73 | *
74 | * @param \Magento\Framework\Data\Form\Element\AbstractElement $element
75 | * @param string $html
76 | *
77 | * @return string
78 | */
79 | protected function _decorateRowHtml(
80 | \Magento\Framework\Data\Form\Element\AbstractElement $element,
81 | $html
82 | ) {
83 | $html = sprintf('%s | ', $html);
84 |
85 | return parent::_decorateRowHtml($element, $html);
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/Helper/Client.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Helper;
24 |
25 | /**
26 | * Helper for X-Payments SDK Client
27 | */
28 | class Client extends \Magento\Framework\App\Helper\AbstractHelper
29 | {
30 | /**
31 | * X-Payments SDK Client
32 | *
33 | * @var \XPaymentsCloud\Client
34 | */
35 | protected $client = null;
36 |
37 | /**
38 | * Scope config
39 | *
40 | * @var \Magento\Framework\App\Config\ScopeConfigInterface
41 | */
42 | protected $scopeConfig = null;
43 |
44 | /**
45 | * Logger
46 | *
47 | * @var \CDev\XPaymentsCloud\Logger\Logger
48 | */
49 | protected $xpaymentsLogger = null;
50 |
51 | /**
52 | * Constructor
53 | *
54 | * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
55 | * @param \CDev\XPaymentsCloud\Logger\Logger $xpaymentsLogger
56 | *
57 | * @return void
58 | */
59 | public function __construct(
60 | \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
61 | \CDev\XPaymentsCloud\Logger\Logger $xpaymentsLogger
62 | ) {
63 | $this->scopeConfig = $scopeConfig;
64 | }
65 |
66 | /**
67 | * Get SDK Client
68 | *
69 | * @return \XPaymentsCloud\Client
70 | */
71 | public function getClient()
72 | {
73 | if (null === $this->client) {
74 |
75 | $this->client = false;
76 |
77 | try {
78 |
79 | $this->client = new \XPaymentsCloud\Client(
80 | $this->scopeConfig->getValue('payment/xpayments_cloud/account'),
81 | $this->scopeConfig->getValue('payment/xpayments_cloud/api_key'),
82 | $this->scopeConfig->getValue('payment/xpayments_cloud/secret_key')
83 | );
84 |
85 | } catch (\Exception $exception) {
86 |
87 | $message = $this->xpaymentsLogger->processException($exception);
88 |
89 | throw new \Magento\Framework\Exception\LocalizedException(__($message));
90 | }
91 | }
92 |
93 | return $this->client;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/Model/Order/Payment.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Model\Order;
24 |
25 | /**
26 | * Auth/Capture/Sale logic
27 | */
28 | class Payment extends \Magento\Sales\Model\Order\Payment
29 | {
30 | /**
31 | * Check if it was a Sale action
32 | *
33 | * @return bool
34 | */
35 | protected function isSaleAction()
36 | {
37 | $transId = $this->getOrder()->getPayment()->getLastTransId();
38 |
39 | return 'sale' == substr($transId, -4);
40 | }
41 |
42 | /**
43 | * Implement Auth/Capture/Sale logic
44 | * This method is called for all actions for authorize_capture Payment Action:
45 | * - authorize only
46 | * - authorize and capture (sale)
47 | * - capture (after initial auth)
48 | *
49 | * @param \Magento\Sales\Api\Data\InvoiceInterface $invoice
50 | *
51 | * @return \Magento\Sales\Api\Data\OrderPaymentInterface
52 | */
53 | public function capture($invoice = null)
54 | {
55 | $order = $this->getOrder();
56 |
57 | if ('xpayments_cloud' !== $order->getPayment()->getMethodInstance()->getCode()) {
58 | return parent::capture($invoice);
59 | }
60 |
61 | if (!$order->getState()) {
62 |
63 | // Order is just created
64 | // Execute 'pay' API action
65 |
66 | $this->authorize(true, $order->getBaseTotalDue());
67 | $this->setAmountAuthorized($order->getTotalDue());
68 |
69 | if ($this->isSaleAction()) {
70 |
71 | // This was a Sale action
72 | // So create Invoice and mark it as Paid
73 |
74 | $invoice = $this->getOrder()->prepareInvoice();
75 | $invoice->register();
76 | $invoice->setTransactionId($this->getOrder()->getPayment()->getLastTransId());
77 | $invoice->pay();
78 |
79 | $this->getOrder()->addRelatedObject($invoice);
80 | }
81 |
82 | } elseif (null === $invoice) {
83 |
84 | // Order State is 'processing' or similar
85 | // Execute 'capture online' operation via Invoice creation
86 |
87 | $invoice = $this->_invoice();
88 | $this->setCreatedInvoice($invoice);
89 |
90 | } else {
91 |
92 | // Execute 'capture' API action
93 |
94 | parent::capture($invoice);
95 | }
96 |
97 | return $this;
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/Transport/WidgetSettings.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Transport;
24 |
25 | /**
26 | * Transport for widget settings
27 | */
28 | class WidgetSettings extends DataObject
29 | {
30 | /**
31 | * X-Payments cart helper
32 | *
33 | * @var \CDev\XPaymentsCloud\Helper\Cart
34 | */
35 | protected $cartHelper = null;
36 |
37 | /**
38 | * Constructor
39 | *
40 | * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
41 | * @param \Magento\Store\Model\StoreManagerInterface $storeManager
42 | * @param \CDev\XPaymentsCloud\Helper\Cart $cartHelper
43 | *
44 | * @return \Magento\Framework\DataObject
45 | */
46 | public function __construct(
47 | \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
48 | \Magento\Store\Model\StoreManagerInterface $storeManager,
49 | \CDev\XPaymentsCloud\Helper\Cart $cartHelper
50 | ) {
51 |
52 | $this->cartHelper = $cartHelper;
53 |
54 | $data = array(
55 | 'account' => $scopeConfig->getValue('payment/xpayments_cloud/account'),
56 | 'widgetKey' => $scopeConfig->getValue('payment/xpayments_cloud/widget_key'),
57 | 'devUrl' => (string)$scopeConfig->getValue('payment/xpayments_cloud/dev_url'),
58 | 'container' => '#xpayments-iframe-container',
59 | 'tokenInputId' => 'xpayments-token',
60 | 'language' => 'en',
61 | 'customerId' => '',
62 | 'autoload' => false,
63 | 'autoSubmit' => false,
64 | 'debug' => (bool)$scopeConfig->getValue('payment/xpayments_cloud/debug'),
65 | 'order' => array(
66 | 'currency' => $storeManager->getStore()->getCurrentCurrency()->getCode(),
67 | ),
68 | 'company' => array(
69 | 'name' => $scopeConfig->getValue('general/store_information/name'),
70 | 'countryCode' => $scopeConfig->getValue('general/country/default'),
71 | ),
72 | );
73 |
74 | return $this->setData($data);
75 | }
76 |
77 | /**
78 | * Set order total
79 | *
80 | * @param float|string $value
81 | *
82 | * @return \Magento\Framework\DataObject
83 | */
84 | public function setTotal($value)
85 | {
86 | $order = $this->getOrder();
87 |
88 | $order['total'] = $this->cartHelper->preparePrice($value);
89 |
90 | return $this->setOrder($order);
91 | }
92 |
93 | /**
94 | * Set tokenize card flag
95 | *
96 | * @param bool $value
97 | *
98 | * @return \Magento\Framework\DataObject
99 | */
100 | public function setTokenizeCard($value)
101 | {
102 | $order = $this->getOrder();
103 |
104 | $order['tokenizeCard'] = (bool)$value;
105 |
106 | return $this->setOrder($order);
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/Block/Adminhtml/Connect/Widget.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Block\Adminhtml\Connect;
24 |
25 | /**
26 | * X-Payments Cloud Connect Widget
27 | */
28 | class Widget extends \Magento\Backend\Block\Template
29 | {
30 | /**
31 | * Scope config
32 | *
33 | * @var \Magento\Framework\App\Config\ScopeConfigInterface
34 | */
35 | protected $scopeConfig = null;
36 |
37 | /**
38 | * Request
39 | *
40 | * @var \Magento\Framework\App\RequestInterface
41 | */
42 | protected $request = null;
43 |
44 | /**
45 | * Store Manager
46 | *
47 | * @var \Magento\Store\Model\StoreManagerInterface
48 | */
49 | protected $storeManager = null;
50 |
51 | /**
52 | * Backend URL builder
53 | *
54 | * @var \Magento\Backend\Model\UrlInterface
55 | */
56 | protected $backendUrl = null;
57 |
58 | /**
59 | * PayPal Structure Plugin
60 | *
61 | * @var \Magento\Paypal\Model\Config\StructurePlugin
62 | */
63 | protected $paypalStructure;
64 |
65 | /**
66 | * Constructor
67 | *
68 | * @param \Magento\Backend\Block\Template\Context $context
69 | * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
70 | * @param \Magento\Framework\App\RequestInterface $request
71 | * @param \Magento\Store\Model\StoreManagerInterface $storeManager
72 | * @param \Magento\Backend\Model\UrlInterface $backendUrl
73 | * @param \Magento\Paypal\Model\Config\StructurePlugin $paypalStructure
74 | * @param array $data
75 | *
76 | * @return void
77 | */
78 | public function __construct(
79 | \Magento\Backend\Block\Template\Context $context,
80 | \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
81 | \Magento\Framework\App\RequestInterface $request,
82 | \Magento\Store\Model\StoreManagerInterface $storeManager,
83 | \Magento\Backend\Model\UrlInterface $backendUrl,
84 | \Magento\Paypal\Model\Config\StructurePlugin $paypalStructure,
85 | array $data = array()
86 | ) {
87 | $this->_template = 'connect/widget.phtml';
88 |
89 | $this->scopeConfig = $scopeConfig;
90 | $this->request = $request;
91 | $this->storeManager = $storeManager;
92 | $this->backendUrl = $backendUrl;
93 | $this->paypalStructure = $paypalStructure;
94 |
95 | parent::__construct($context, $data);
96 | }
97 |
98 | /**
99 | * Get hash of widget settings
100 | *
101 | * @return \CDev\XPaymentsCloud\Transport\ConnectSettings
102 | */
103 | public function getConnectWidgetSettings()
104 | {
105 | return new \CDev\XPaymentsCloud\Transport\ConnectSettings(
106 | $this->scopeConfig,
107 | $this->request,
108 | $this->storeManager,
109 | $this->backendUrl,
110 | $this->paypalStructure
111 | );
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/Controller/Adminhtml/System/Config/Save.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Controller\Adminhtml\System\Config;
24 |
25 | /**
26 | * Save X-Payments Cloud connect settings
27 | */
28 | class Save extends \Magento\Config\Controller\Adminhtml\System\Config\Save
29 | {
30 | /**
31 | * Resource config
32 | *
33 | * @var \Magento\Config\Model\ResourceModel\Config
34 | */
35 | protected $resourceConfig = null;
36 |
37 | /**
38 | * Tiny function to enhance functionality of ucwords
39 | * Will capitalize first letters and convert separators if needed
40 | * Doesn't exist in Magento 2 unfortunately
41 | *
42 | * @param string $str
43 | * @param string $destSep
44 | * @param string $srcSep
45 | *
46 | * @return string
47 | */
48 | protected function ucWords($str, $destSep = '_', $srcSep = '_')
49 | {
50 | return str_replace(' ', $destSep, ucwords(str_replace($srcSep, ' ', $str)));
51 | }
52 |
53 | /**
54 | * @param \Magento\Backend\App\Action\Context $context
55 | * @param \Magento\Config\Model\Config\Structure $configStructure
56 | * @param \Magento\Config\Controller\Adminhtml\System\ConfigSectionChecker $sectionChecker
57 | * @param \Magento\Config\Model\Config\Factory $configFactory
58 | * @param \Magento\Framework\Cache\FrontendInterface $cache
59 | * @param \Magento\Framework\Stdlib\StringUtils $string
60 | * @param \Magento\Config\Model\ResourceModel\Config $resourceConfig
61 | */
62 | public function __construct(
63 | \Magento\Backend\App\Action\Context $context,
64 | \Magento\Config\Model\Config\Structure $configStructure,
65 | \Magento\Config\Controller\Adminhtml\System\ConfigSectionChecker $sectionChecker,
66 | \Magento\Config\Model\Config\Factory $configFactory,
67 | \Magento\Framework\Cache\FrontendInterface $cache,
68 | \Magento\Framework\Stdlib\StringUtils $string,
69 | \Magento\Config\Model\ResourceModel\Config $resourceConfig
70 | ) {
71 | parent::__construct($context, $configStructure, $sectionChecker, $configFactory, $cache, $string);
72 | $this->resourceConfig = $resourceConfig;
73 | }
74 |
75 | /**
76 | * Save configuration
77 | *
78 | * @return void
79 | */
80 | public function execute()
81 | {
82 | $fields = array(
83 | 'account',
84 | 'api_key',
85 | 'secret_key',
86 | 'widget_key',
87 | 'quick_access_key',
88 | );
89 |
90 | $data = $this->getRequest()->getPost();
91 |
92 | foreach ($fields as $field) {
93 |
94 | $path = 'payment/xpayments_cloud/' . $field;
95 |
96 | $key = lcfirst($this->ucWords($field, ''));
97 |
98 | $value = isset($data[$key]) ? $data[$key] : '';
99 |
100 | $this->resourceConfig->saveConfig(
101 | $path,
102 | $value
103 | );
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # X-Payments Cloud connector for Magento 2
2 | This extension connects your Magento 2 store with X-Payments Cloud - a PSD2/SCA ready PCI Level 1 certified credit card processing app which allows you to store customers’ credit card information and still be compliant with PCI security mandates.
3 |
4 | The credit card form can be embedded right into checkout page, so your customers won’t leave your site to complete an order.
5 |
6 | ### Installation
7 | Via composer:
8 | ```sh
9 | composer.phar require cdev/x-payments-cloud
10 | bin/magento module:enable CDev_XPaymentsCloud
11 | bin/magento setup:di:compile
12 | bin/magento setup:static-content:deploy -f
13 | ```
14 | Or copy these files into the `/app/code/CDev/XPaymentsCloud/` directory and run:
15 | ```sh
16 | bin/magento setup:upgrade
17 | bin/magento module:enable CDev_XPaymentsCloud
18 | bin/magento setup:di:compile
19 | bin/magento setup:static-content:deploy -f
20 | ```
21 | ### Configuration
22 | First, you shuld create the X-Payments Cloud account.
23 | - Navigate **Stores -> Configuration -> Sales -> Payment Methods**
24 | - Expand the **X-Payments Cloud** section
25 | - Start the signup process to create an X-Payments Cloud account and follow the Wizard instructions
26 | - In the end you will be prompted to set a password. Then complete 2-step user authentication setup for your account
27 |
28 | Now X-Payments Cloud payment method is available at checkout in demo mode. Just don't forget to enable it.
29 | To proceed with accepting real payments get back to the X-Payments Cloud payment method configuration and:
30 | - Select the necessary payment gateway from the **Add payment configuration** list
31 | - Enter you gateway credentials and adjust the necessary settings specific to this payment gateway
32 |
33 | Refer to the manual for the detailed instructions: https://www.x-payments.com/wp-content/uploads/help_uploads/Using-X-Payments-Cloud-with-Magento-2.pdf
34 |
35 |
36 | ### Supported payment gateways
37 | X-Payments Cloud supports more than 60 [payment gateway integrations](https://www.x-payments.com/help/XP_Cloud:Supported_payment_gateways): ANZ eGate, American Express Web-Services API Integration, Authorize.Net, Bambora (Beanstream), Beanstream (legacy API), Bendigo Bank, BillriantPay, BluePay, BlueSnap Payment API (XML), Braintree, BluePay Canada (Caledon), Cardinal Commerce Centinel, Chase Paymentech, CommWeb - Commonwealth Bank, BAC Credomatic, CyberSource - SOAP Toolkit API, X-Payments Demo Pay, X-Payments Demo Pay 3-D Secure, DIBS, DirectOne - Direct Interface, eProcessing Network - Transparent Database Engine, SecurePay Australia, Moneris eSELECTplus, Elavon (Realex API), ePDQ MPI XML (Phased out), eWAY Rapid - Direct Connection, eWay Realtime Payments XML, Sparrow (5th Dimension Gateway), First Data Payeezy Gateway (ex- Global Gateway e4), Global Iris, Global Payments, GoEmerchant - XML Gateway API, HeidelPay, Innovative Gateway, iTransact XML, Payment XP (Meritus) Web Host, NAB - National Australia Bank, NMI (Network Merchants Inc.), Netbilling - Direct Mode, Netevia, Ingenico ePayments (Ogone e-Commerce), PayGate South Africa, Payflow Pro, PayPal REST API, PayPal Payments Pro (PayPal API), PayPal Payments Pro (Payflow API), PSiGate XML API, QuantumGateway - XML Requester, Intuit QuickBooks Payments, QuickPay, Worldpay Corporate Gateway - Direct Model, Global Payments (ex. Realex), Opayo Direct (ex. Sage Pay Go - Direct Interface), Paya (ex. Sage Payments US), Simplify Commerce by MasterCard, SkipJack, Suncorp, TranSafe, powered by Monetra, 2Checkout, USA ePay - Transaction Gateway API, Elavon Converge (ex VirtualMerchant), WebXpress, Worldpay Total US, Worldpay US (Lynk Systems).
38 |
39 | ### Supported Fraud-screening services:
40 | - Kount
41 | - NoFraud
42 | - Signifyd
43 |
44 | ### Refference
45 | - [X-Payments Cloud API](https://xpayments.stoplight.io/docs/server-side-api/)
46 | - [X-Payments Cloud PHP SDK](https://github.com/xpayments/cloud-sdk-php)
47 |
48 | ### Support
49 | If you have any questions please free to [contact us](https://www.x-payments.com/contact-us).
50 |
--------------------------------------------------------------------------------
/view/frontend/layout/checkout_index_index.xml:
--------------------------------------------------------------------------------
1 |
2 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | -
33 |
-
34 |
-
35 |
-
36 |
-
37 |
-
38 |
- uiComponent
39 | -
40 |
-
41 |
-
42 |
-
43 |
44 |
-
45 |
-
46 |
- CDev_XPaymentsCloud/js/view/payment/xpayments-cloud
47 | -
48 |
-
49 |
- true
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/Logger/Logger.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Logger;
24 |
25 | /**
26 | * Logger
27 | */
28 | class Logger extends \Monolog\Logger
29 | {
30 | /**
31 | * Store manager
32 | *
33 | * @var \Magento\Store\Model\StoreManagerInterface
34 | */
35 | protected $storeManager = null;
36 |
37 | /**
38 | * Current URL
39 | *
40 | * @var string
41 | */
42 | protected $url = null;
43 |
44 | /**
45 | * Constructor
46 | *
47 | * @param string $name
48 | * @param \Magento\Store\Model\StoreManagerInterface $storeManager
49 | * @param HandlerInterface[] $handlers
50 | * @param callable[] $processors
51 | *
52 | * @return void
53 | */
54 | public function __construct(
55 | $name,
56 | \Magento\Store\Model\StoreManagerInterface $storeManager,
57 | array $handlers = array(),
58 | array $processors = array()
59 | ) {
60 |
61 | $this->storeManager = $storeManager;
62 |
63 | parent::__construct($name, $handlers, $processors);
64 | }
65 |
66 | /**
67 | * Process exception
68 | *
69 | * @param \Exception $exception
70 | * @param string $title
71 | * @param bool $trace Include backtrace or not
72 | *
73 | * @return string
74 | */
75 | public function processException(\Exception $exception, $title = false, $trace = false)
76 | {
77 | if (
78 | method_exists($exception, 'getPublicMessage')
79 | && $exception->getPublicMessage()
80 | ) {
81 | $message = $exception->getPublicMessage();
82 | } else {
83 | $message = $exception->getMessage();
84 | }
85 |
86 | $data = array();
87 |
88 | if (!empty($title)) {
89 | $data[] = $message;
90 | } else {
91 | $title = $message;
92 | }
93 |
94 | $data[] = get_class($exception);
95 |
96 | $data = implode(PHP_EOL, $data);
97 |
98 | $this->writeLog($title, $data, $trace);
99 |
100 | return $message;
101 | }
102 |
103 | /**
104 | * Get current URL
105 | *
106 | * @return string
107 | */
108 | protected function getUrl()
109 | {
110 | if (null === $this->url) {
111 |
112 | // Remove session key from URL
113 | $this->url = preg_replace(
114 | array('/\/key\/\w+\//', '/\?.*$/'),
115 | array('/', ''),
116 | $this->storeManager->getStore()->getCurrentUrl()
117 | );
118 | }
119 |
120 | return $this->url;
121 | }
122 |
123 | /**
124 | * Write log record
125 | *
126 | * @param string $title Log title
127 | * @param mixed $data Data to log
128 | * @param bool $trace Include backtrace or not
129 | *
130 | * @return bool Whether the record has been processed
131 | */
132 | public function writeLog($title, $data = '', $trace = false)
133 | {
134 | if (!is_string($data)) {
135 | $data = var_export($data, true);
136 | }
137 |
138 | $message = $title . PHP_EOL
139 | . date('Y-m-d H:i:s') . PHP_EOL
140 | . $data . PHP_EOL
141 | . $this->getUrl() . PHP_EOL;
142 |
143 | if ($trace) {
144 | $message .= '--------------------------' . PHP_EOL
145 | . \Magento\Framework\Debug::backtrace(true, false, false)
146 | . PHP_EOL;
147 | }
148 |
149 | return $this->debug($message);
150 | }
151 | }
152 |
--------------------------------------------------------------------------------
/Setup/Patch/Data/AddXPaymentsCustomerIDAttribute.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 | declare(strict_types=1);
23 |
24 | namespace CDev\XPaymentsCloud\Setup\Patch\Data;
25 |
26 | /**
27 | * Add EAV attribute for X-Payments Customer ID
28 | */
29 | class AddXPaymentsCustomerIDAttribute implements \Magento\Framework\Setup\Patch\DataPatchInterface
30 | {
31 | /**
32 | * @var ModuleDataSetupInterface $moduleDataSetup
33 | */
34 | private $moduleDataSetup;
35 |
36 | /**
37 | * Customer setup factory
38 | *
39 | * @var \Magento\Customer\Setup\CustomerSetupFactory $customerSetupFactory
40 | */
41 | protected $customerSetupFactory = null;
42 |
43 | /**
44 | * Attribute set factory
45 | *
46 | * @var \Magento\Eav\Model\Entity\Attribute\SetFactory
47 | */
48 | private $attributeSetFactory = null;
49 |
50 | /**
51 | * Constructor
52 | *
53 | * @param \Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup
54 | * @param \Magento\Customer\Setup\CustomerSetupFactory $customerSetupFactory
55 | * @param \Magento\Eav\Model\Entity\Attribute\SetFactory $attributeSetFactory
56 | *
57 | * @return void
58 | */
59 | public function __construct(
60 | \Magento\Framework\Setup\ModuleDataSetupInterface $moduleDataSetup,
61 | \Magento\Customer\Setup\CustomerSetupFactory $customerSetupFactory,
62 | \Magento\Eav\Model\Entity\Attribute\SetFactory $attributeSetFactory
63 | ) {
64 | $this->moduleDataSetup = $moduleDataSetup;
65 |
66 | $this->customerSetupFactory = $customerSetupFactory;
67 | $this->attributeSetFactory = $attributeSetFactory;
68 | }
69 |
70 | /**
71 | * Do Upgrade
72 | *
73 | * @return void
74 | */
75 | public function apply()
76 | {
77 | $customerSetup = $this->customerSetupFactory->create(array('setup' => $this->moduleDataSetup));
78 |
79 | $customerEntity = $customerSetup->getEavConfig()->getEntityType('customer');
80 | $attributeSetId = $customerEntity->getDefaultAttributeSetId();
81 |
82 | $attributeSet = $this->attributeSetFactory->create();
83 | $attributeGroupId = $attributeSet->getDefaultGroupId($attributeSetId);
84 |
85 | $customerSetup->addAttribute(
86 | \Magento\Customer\Model\Customer::ENTITY,
87 | 'xpayments_customer_id',
88 | array(
89 | 'type' => 'varchar',
90 | 'label' => 'X-Payments Cloud customer ID',
91 | 'input' => 'text',
92 | 'required' => false,
93 | 'visible' => false,
94 | 'user_defined' => true,
95 | 'sort_order' => 1000,
96 | 'position' => 1000,
97 | 'system' => 0,
98 | )
99 | );
100 |
101 | $attribute = $customerSetup->getEavConfig()
102 | ->getAttribute(
103 | \Magento\Customer\Model\Customer::ENTITY,
104 | 'xpayments_customer_id'
105 | )->addData(
106 | array(
107 | 'attribute_set_id' => $attributeSetId,
108 | 'attribute_group_id' => $attributeGroupId,
109 | )
110 | );
111 |
112 | $attribute->save();
113 | }
114 |
115 | /**
116 | * @inheritdoc
117 | */
118 | public function getAliases()
119 | {
120 | return array();
121 | }
122 |
123 | /**
124 | * @inheritdoc
125 | */
126 | public static function getDependencies()
127 | {
128 | return array();
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/view/adminhtml/templates/connect/widget.phtml:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 | ?>
23 |
28 |
29 |
30 |
31 |
154 |
--------------------------------------------------------------------------------
/Ui/XPaymentsCloud/ConfigProvider.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Ui\XPaymentsCloud;
24 |
25 | /**
26 | * Configuration provider for XPC method at checkout
27 | */
28 | class ConfigProvider implements \Magento\Checkout\Model\ConfigProviderInterface
29 | {
30 | /**
31 | * Payment method object
32 | *
33 | * @var \Magento\Payment\Model\MethodInterface
34 | */
35 | protected $method = null;
36 |
37 | /**
38 | * Scope config
39 | *
40 | * @var \Magento\Framework\App\Config\ScopeConfigInterface
41 | */
42 | protected $scopeConfig = null;
43 |
44 | /**
45 | * Store manager
46 | *
47 | * @var \Magento\Store\Model\StoreManagerInterface
48 | */
49 | protected $storeManager = null;
50 |
51 | /**
52 | * X-Payments cart helper
53 | *
54 | * @var \CDev\XPaymentsCloud\Helper\Cart
55 | */
56 | protected $cartHelper = null;
57 |
58 | /**
59 | * Customer session
60 | *
61 | * @var \Magento\Customer\Model\Session
62 | */
63 | protected $customerSession = null;
64 |
65 | /**
66 | * Checkout session
67 | *
68 | * @var \Magento\Checkout\Model\Session
69 | */
70 | protected $checkoutSession = null;
71 |
72 | /**
73 | * Constructor
74 | *
75 | * @param \Magento\Payment\Helper\Data $paymentHelper
76 | * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
77 | * @param \Magento\Store\Model\StoreManagerInterface $storeManager
78 | * @param \CDev\XPaymentsCloud\Helper\Cart $cartHelper
79 | * @param \Magento\Customer\Model\Session $customerSession
80 | * @param \Magento\Checkout\Model\Session $checkoutSession
81 | *
82 | * @return void
83 | */
84 | public function __construct(
85 | \Magento\Payment\Helper\Data $paymentHelper,
86 | \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
87 | \Magento\Store\Model\StoreManagerInterface $storeManager,
88 | \CDev\XPaymentsCloud\Helper\Cart $cartHelper,
89 | \Magento\Customer\Model\Session $customerSession,
90 | \Magento\Checkout\Model\Session $checkoutSession
91 | ) {
92 |
93 | $this->method = $paymentHelper->getMethodInstance(
94 | \CDev\XPaymentsCloud\Model\Payment\Method\XPaymentsCloud::CODE
95 | );
96 |
97 | $this->scopeConfig = $scopeConfig;
98 | $this->storeManager = $storeManager;
99 |
100 | $this->cartHelper = $cartHelper;
101 |
102 | $this->customerSession = $customerSession;
103 | $this->checkoutSession = $checkoutSession;
104 | }
105 |
106 | /**
107 | * Get X-Payments Customer ID
108 | *
109 | * @return string
110 | */
111 | protected function getXpaymentsCustomerId()
112 | {
113 | $xpaymentsCustomerId = '';
114 |
115 | if ($this->customerSession->isLoggedIn()) {
116 |
117 | $xpaymentsCustomerId = (string)$this->customerSession
118 | ->getCustomer()
119 | ->getXpaymentsCustomerId();
120 | }
121 |
122 | return $xpaymentsCustomerId;
123 | }
124 |
125 | /**
126 | * Retrieve assoc array of checkout configuration
127 | *
128 | * @return array
129 | */
130 | public function getConfig()
131 | {
132 | $total = $this->checkoutSession->getQuote()
133 | ->getGrandTotal();
134 |
135 | $showSaveCard = $this->customerSession->isLoggedIn();
136 |
137 | $settings = new \CDev\XPaymentsCloud\Transport\WidgetSettings(
138 | $this->scopeConfig,
139 | $this->storeManager,
140 | $this->cartHelper
141 | );
142 |
143 | $settings->setShowSaveCard($showSaveCard)
144 | ->setTokenizeCard(false)
145 | ->setAutoSubmit(false)
146 | ->setCustomerId($this->getXpaymentsCustomerId())
147 | ->setForm('#co-payment-form')
148 | ->setTokenInputName('payment[xpayments_token]')
149 | ->setTotal($total);
150 |
151 | return array(
152 | 'payment' => array(
153 | $this->method::CODE => $settings->getData()
154 | ),
155 | );
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/view/frontend/web/js/view/payment/method-renderer/xpayments-cloud.js:
--------------------------------------------------------------------------------
1 | // vim: set ts=2 sw=2 sts=2 et:
2 | /**
3 | * Magento
4 | *
5 | * NOTICE OF LICENSE
6 | *
7 | * This source file is subject to the Open Software License (OSL 3.0)
8 | * that is bundled with this package in the file LICENSE.txt.
9 | * It is also available through the world-wide-web at this URL:
10 | * http://opensource.org/licenses/osl-3.0.php
11 | * If you did not receive a copy of the license and are unable to
12 | * obtain it through the world-wide-web, please send an email
13 | * to license@magentocommerce.com so we can send you a copy immediately.
14 | *
15 | * @author Qualiteam Software
16 | * @category CDev
17 | * @package CDev_XPaymentsCloud
18 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
19 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20 | */
21 | define(
22 | [
23 | 'Magento_Checkout/js/view/payment/default',
24 | 'Magento_Checkout/js/checkout-data',
25 | ],
26 | function (Component, checkoutData) {
27 | 'use strict';
28 |
29 | return Component.extend({
30 |
31 | /**
32 | * Component defaults
33 | */
34 | defaults: {
35 | template: 'CDev_XPaymentsCloud/payment/form',
36 | },
37 |
38 | /**
39 | * Get payment method code
40 | *
41 | * @return string
42 | */
43 | getCode: function() {
44 | return 'xpayments_cloud';
45 | },
46 |
47 | /**
48 | * Check if payment method is active
49 | *
50 | * @return bool
51 | */
52 | isActive: function() {
53 |
54 | var active = (this.getCode() === this.isChecked());
55 |
56 | window.xpayments.onSwitchPaymentMethod();
57 |
58 | return active;
59 | },
60 |
61 | /**
62 | * Initialize payment method
63 | *
64 | * @return void
65 | */
66 | initialize: function()
67 | {
68 | this._super();
69 |
70 | var self = this;
71 |
72 | /**
73 | * Check if X-Payments Cloud is currently selected payment method
74 | *
75 | * @return bool
76 | */
77 | XPayments.prototype.isCurrent = function () {
78 | return 'undefined' != typeof checkoutData
79 | && (
80 | 'xpayments_cloud' == checkoutData.getSelectedPaymentMethod()
81 | || (
82 | jQuery('#xpayments_cloud').next('label').is(':visible')
83 | && jQuery('#xpayments_cloud').get(0).checked
84 | )
85 | );
86 | }
87 |
88 | /**
89 | * Toggle Apple Pay button
90 | *
91 | * @return bool
92 | */
93 | XPayments.prototype.toggleApplePayButton = function (isApple) {
94 | $('xpayments-place-order').toggleClassName('apple-pay-button', isApple);
95 | }
96 |
97 | /**
98 | * On success event
99 | *
100 | * @return void
101 | */
102 | XPayments.prototype.onSuccess = XPayments.prototype.onSuccess.wrap(
103 | function (parentMethod, params) {
104 |
105 | self.xpaymentsToken = params.token;
106 |
107 | parentMethod(params);
108 | }
109 | );
110 |
111 | window.xpayments = new XPayments(window.checkoutConfig.payment.xpayments_cloud);
112 |
113 | window.xpayments.load();
114 | },
115 |
116 | /**
117 | * Get payment method data which is send to controller after order is submitted
118 | *
119 | * @return JSON
120 | */
121 | getData: function()
122 | {
123 | return {
124 | method: this.item.method,
125 | additional_data: {
126 | xpayments_token: this.xpaymentsToken,
127 | }
128 | };
129 | },
130 |
131 | /**
132 | * Place order
133 | *
134 | * @return bool
135 | */
136 | placeOrder: function ()
137 | {
138 | window.xpayments.onSubmitPayment(this._super.bind(this));
139 | },
140 |
141 | /**
142 | * Place order fail
143 | *
144 | * @return void
145 | */
146 | placeOrderFail: function ()
147 | {
148 | window.xpayments.onSwitchPaymentMethod();
149 | },
150 |
151 | /**
152 | * Get place order deferred object
153 | *
154 | * @return {*}
155 | */
156 | getPlaceOrderDeferredObject: function()
157 | {
158 | return this._super().fail(this.placeOrderFail);
159 | },
160 | });
161 | }
162 | );
163 |
--------------------------------------------------------------------------------
/view/adminhtml/web/js/lib/connect.js:
--------------------------------------------------------------------------------
1 | /*
2 | * X-Payments Cloud SDK - Connect Widget
3 | */
4 |
5 | function XPaymentsConnect(elmSelector, quickAccessKey, handlers) {
6 | this.serverDomain = 'xpayments.com';
7 | this.messageNamespace = 'xpayments.connect.';
8 |
9 | this.previousHeight = -1;
10 |
11 | this.config = {
12 | debug: false,
13 | account: '',
14 | container: '',
15 | topElement: '',
16 | referrerUrl: document.location.href,
17 | applePayOnly: false,
18 | quickAccessKey: ''
19 | }
20 |
21 | this.handlers = {};
22 |
23 | this.bindedListener = false;
24 |
25 | }
26 |
27 | XPaymentsConnect.prototype.init = function(settings)
28 | {
29 | for (var key in settings) {
30 | if ('undefined' !== typeof this.config[key]) {
31 | this.config[key] = settings[key];
32 | }
33 | }
34 |
35 | // Set default handlers
36 | this.on('alert', function(params) {
37 | window.alert(params.message);
38 | }).on('config', function() {
39 | console.error('X-Payments Widget is not configured properly!');
40 | });
41 |
42 | this.bindedListener = this.messageListener.bind(this);
43 | window.addEventListener('message', this.bindedListener);
44 |
45 | return this;
46 | }
47 |
48 | XPaymentsConnect.prototype.getContainerElm = function()
49 | {
50 | return this.safeQuerySelector(this.config.container);
51 | }
52 |
53 | XPaymentsConnect.prototype.getIframeId = function()
54 | {
55 | return 'xpayments-connect';
56 | }
57 |
58 | XPaymentsConnect.prototype.getIframeElm = function()
59 | {
60 | return document.getElementById(this.getIframeId());
61 | }
62 |
63 | XPaymentsConnect.prototype.safeQuerySelector = function(selector)
64 | {
65 | var elm = false;
66 | if (selector) {
67 | elm = document.querySelector(selector);
68 | }
69 | return elm;
70 | }
71 |
72 | XPaymentsConnect.prototype.resize = function(height)
73 | {
74 | var elm = this.getIframeElm();
75 | if (elm) {
76 | this.previousHeight = elm.style.height;
77 | elm.style.height = height + 'px';
78 | }
79 | }
80 |
81 | XPaymentsConnect.prototype.load = function()
82 | {
83 | var containerElm = this.getContainerElm();
84 | if (!containerElm) {
85 | return this;
86 | }
87 |
88 | var elm = document.createElement('iframe');
89 | elm.id = this.getIframeId();
90 | elm.style.width = '100%';
91 | elm.style.height = '0';
92 | elm.style.overflow = 'hidden';
93 | elm.setAttribute('scrolling', 'no')
94 | containerElm.appendChild(elm);
95 |
96 | elm.src = this.getRedirectUrl();
97 |
98 | }
99 |
100 | XPaymentsConnect.prototype.getRedirectUrl = function()
101 | {
102 | return 'https://' + this.getServerHost() + '/' +
103 | '?ref=' + encodeURIComponent(this.config.referrerUrl) +
104 | '&account=' + encodeURIComponent(this.config.account) +
105 | '&apple_pay=' + (this.config.applePayOnly ? 'Y' : 'N') +
106 | '&quickaccess=' + encodeURIComponent(this.config.quickAccessKey);
107 | }
108 |
109 | XPaymentsConnect.prototype.on = function(event, handler)
110 | {
111 | this.handlers[event] = handler.bind(this);
112 | return this;
113 | }
114 |
115 | XPaymentsConnect.prototype.trigger = function(event, params)
116 | {
117 | if ('function' === typeof this.handlers[event]) {
118 | this.handlers[event](params);
119 | }
120 | return this;
121 | }
122 |
123 | XPaymentsConnect.prototype.getServerHost = function()
124 | {
125 | return 'connect.' + this.serverDomain;
126 | }
127 |
128 | XPaymentsConnect.prototype.messageListener = function(event)
129 | {
130 | if (window.JSON) {
131 | var msg = false;
132 |
133 | try {
134 | msg = window.JSON.parse(event.data);
135 | } catch (e) {
136 | // Skip invalid messages
137 | }
138 |
139 | if (msg && msg.event && 0 === msg.event.indexOf(this.messageNamespace)) {
140 | this.log('X-Payments Event: ' + msg.event + "\n" + window.JSON.stringify(msg.params));
141 |
142 | var eventType = msg.event.substr(this.messageNamespace.length);
143 |
144 | if ('loaded' === eventType) {
145 | if (-1 !== this.previousHeight) {
146 | var topElm = (this.config.topElement)
147 | ? this.safeQuerySelector(this.config.topElement)
148 | : this.getContainerElm();
149 | if (topElm) {
150 | topElm.scrollIntoView(true);
151 | }
152 | }
153 | this.resize(msg.params.height);
154 | } else if ('resize' === eventType) {
155 | this.resize(msg.params.height);
156 | } else if ('alert' === eventType) {
157 | msg.params.message = msg.params.message.replace(/<\/?[^>]+>/gi, '');
158 | }
159 |
160 | this.trigger(eventType, msg.params);
161 | }
162 | }
163 | }
164 |
165 | XPaymentsConnect.prototype.postMessage = function(message)
166 | {
167 | var elm = this.getIframeElm();
168 | if (
169 | window.postMessage
170 | && window.JSON
171 | && elm
172 | && elm.contentWindow
173 | ) {
174 | this.log('Sent to X-Payments: ' + message.event + "\n" + window.JSON.stringify(message.params));
175 | elm.contentWindow.postMessage(window.JSON.stringify(message), '*');
176 | } else {
177 | this.log('Error sending message - iframe wasn\'t initialized!');
178 | }
179 | }
180 |
181 | XPaymentsConnect.prototype.log = function(msg) {
182 | if (this.config.debug) {
183 | console.log(msg);
184 | }
185 | }
--------------------------------------------------------------------------------
/Helper/Address.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Helper;
24 |
25 | /**
26 | * Helper for address
27 | */
28 | class Address extends \Magento\Framework\App\Helper\AbstractHelper
29 | {
30 | /**
31 | * Placeholder for empty email (something which will pass X-Payments validation)
32 | */
33 | protected const EMPTY_USER_EMAIL = 'user@example.com';
34 |
35 | /**
36 | * Placeholder for not available cart data
37 | */
38 | protected const NOT_AVAILABLE = 'N/A';
39 |
40 | /**
41 | * Billing and shipping address names
42 | */
43 | protected const BILLING_ADDRESS = 'Billing';
44 | protected const SHIPPING_ADDRESS = 'Shipping';
45 |
46 | /**
47 | * Address Repository
48 | *
49 | * @var \Magento\Customer\Api\AddressRepositoryInterface
50 | */
51 | protected $addressRepository = null;
52 |
53 | /**
54 | * Region factory
55 | *
56 | * @var \Magento\Directory\Model\RegionFactory
57 | */
58 | protected $regionFactory = null;
59 |
60 | /**
61 | * Constructor
62 | *
63 | * @param \Magento\Customer\Api\AddressRepositoryInterface $addressRepository
64 | * @param \Magento\Directory\Model\RegionFactory $regionFactory
65 | *
66 | * @return void
67 | */
68 | public function __construct(
69 | \Magento\Customer\Api\AddressRepositoryInterface $addressRepository,
70 | \Magento\Directory\Model\RegionFactory $regionFactory
71 | ) {
72 |
73 | $this->addressRepository = $addressRepository;
74 | $this->regionFactory = $regionFactory;
75 | }
76 |
77 | /**
78 | * Prepare state
79 | *
80 | * @param array $data Address data
81 | *
82 | * @return string
83 | */
84 | private function prepareState($data)
85 | {
86 | $state = self::NOT_AVAILABLE;
87 |
88 | if (!empty($data['region_id'])) {
89 |
90 | $region = $this->regionFactory->create()->load($data['region_id']);
91 |
92 | if (
93 | $region
94 | && $region->getCode()
95 | ) {
96 | $state = $region->getCode();
97 | }
98 | }
99 |
100 | return $state;
101 | }
102 |
103 | /**
104 | * Prepare street (Address lines 1 and 2)
105 | *
106 | * @param array $data Address data
107 | *
108 | * @return string
109 | */
110 | private function prepareStreet($data)
111 | {
112 | $street = self::NOT_AVAILABLE;
113 |
114 | if (!empty($data['street'])) {
115 |
116 | $street = $data['street'];
117 |
118 | if (is_array($street)) {
119 | $street = array_filter($street);
120 | $street = implode("\n", $street);
121 | }
122 | }
123 |
124 | return $street;
125 | }
126 |
127 | /**
128 | * Prepare address hash
129 | *
130 | * @param \Magento\Sales\Api\Data\OrderInterface $order Order
131 | * @param string $type Address type, Billing or Shipping
132 | *
133 | * @return array
134 | */
135 | protected function prepareAddress(\Magento\Sales\Api\Data\OrderInterface $order, $type = self::BILLING_ADDRESS)
136 | {
137 | $method = 'get' . $type . 'Address';
138 |
139 | $data = $order->$method()->getData();
140 |
141 | if (!empty($data['email'])) {
142 | $email = $data['email'];
143 | } elseif ($order->getCustomerEmail()) {
144 | $email = $order->getCustomerEmail();
145 | } else {
146 | $email = self::EMPTY_USER_EMAIL;
147 | }
148 |
149 | $address = array(
150 | 'firstname' => !empty($data['firstname']) ? $data['firstname'] : self::NOT_AVAILABLE,
151 | 'lastname' => !empty($data['lastname']) ? $data['lastname'] : self::NOT_AVAILABLE,
152 | 'address' => $this->prepareStreet($data),
153 | 'city' => !empty($data['city']) ? $data['city'] : self::NOT_AVAILABLE,
154 | 'state' => $this->prepareState($data),
155 | 'country' => !empty($data['country_id']) ? $data['country_id'] : 'XX', // WA fix for MySQL 5.7 with strict mode
156 | 'zipcode' => !empty($data['postcode']) ? $data['postcode'] : self::NOT_AVAILABLE,
157 | 'phone' => !empty($data['telephone']) ? $data['telephone'] : '',
158 | 'company' => '',
159 | 'email' => $email,
160 | );
161 |
162 | return $address;
163 | }
164 |
165 | /**
166 | * Prepare billing address
167 | *
168 | * @param \Magento\Sales\Api\Data\OrderInterface $order
169 | *
170 | * @return array
171 | */
172 | public function prepareBillingAddress(\Magento\Sales\Api\Data\OrderInterface $order)
173 | {
174 | return $this->prepareAddress($order, self::BILLING_ADDRESS);
175 | }
176 |
177 | /**
178 | * Prepare shipping address
179 | *
180 | * @param \Magento\Sales\Api\Data\OrderInterface $order
181 | *
182 | * @return array
183 | */
184 | public function prepareShippingAddress(\Magento\Sales\Api\Data\OrderInterface $order)
185 | {
186 | return $this->prepareAddress($order, self::SHIPPING_ADDRESS);
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/Transport/ConnectSettings.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Transport;
24 |
25 | /**
26 | * Transport for connect settings
27 | */
28 | class ConnectSettings extends DataObject
29 | {
30 | /**
31 | * Request
32 | *
33 | * @var \Magento\Framework\App\RequestInterface
34 | */
35 | protected $request = null;
36 |
37 | /**
38 | * Store Manager
39 | *
40 | * @var \Magento\Store\Model\StoreManagerInterface
41 | */
42 | protected $storeManager = null;
43 |
44 | /**
45 | * Scope Config
46 | *
47 | * @var \Magento\Framework\App\Config\ScopeConfigInterface
48 | */
49 | protected $scopeConfig = null;
50 |
51 | /**
52 | * Backend URL builder
53 | *
54 | * @var \Magento\Backend\Model\UrlInterface
55 | */
56 | protected $backendUrl = null;
57 |
58 | /**
59 | * PayPal Structure Plugin
60 | *
61 | * @var \Magento\Paypal\Model\Config\StructurePlugin
62 | */
63 | protected $paypalStructure = null;
64 |
65 | /**
66 | * Section ID
67 | *
68 | * @var string
69 | */
70 | protected $sectionId = null;
71 |
72 | /**
73 | * Constructor
74 | *
75 | * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
76 | * @param \Magento\Framework\App\RequestInterface $request
77 | * @param \Magento\Store\Model\StoreManagerInterface $storeManager
78 | * @param \Magento\Backend\Model\UrlInterface $backendUrl
79 | * @param \Magento\Paypal\Model\Config\StructurePlugin $paypalStructure
80 | *
81 | * @return \Magento\Framework\DataObject
82 | */
83 | public function __construct(
84 | \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
85 | \Magento\Framework\App\RequestInterface $request,
86 | \Magento\Store\Model\StoreManagerInterface $storeManager,
87 | \Magento\Backend\Model\UrlInterface $backendUrl,
88 | \Magento\Paypal\Model\Config\StructurePlugin $paypalStructure
89 | ) {
90 | $this->request = $request;
91 | $this->storeManager = $storeManager;
92 | $this->backendUrl = $backendUrl;
93 | $this->scopeConfig = $scopeConfig;
94 | $this->paypalStructure = $paypalStructure;
95 |
96 | $data = array(
97 | 'account' => $scopeConfig->getValue('payment/xpayments_cloud/account'),
98 | 'quickAccessKey' => $scopeConfig->getValue('payment/xpayments_cloud/quick_access_key'),
99 | 'devUrl' => (string)$scopeConfig->getValue('payment/xpayments_cloud/dev_url'),
100 | 'topElement' => '',
101 | 'container' => '#xpayments-iframe-container',
102 | 'sectionId' => $this->getSectionId(),
103 | 'loaded' => false,
104 | 'referrerUrl' => $this->storeManager->getStore()->getBaseUrl(),
105 | 'saveUrl' => $this->getSaveUrl(),
106 | 'configMap' => $this->getConfigMap(),
107 | 'debug' => (bool)$scopeConfig->getValue('payment/xpayments_cloud/debug'),
108 | );
109 |
110 | return $this->setData($data);
111 | }
112 |
113 | /**
114 | * Get map of the configuration fields: {
115 | * field: payment_us_xpayments_cloud_connection_some_option
116 | * param: someOption
117 | * }
118 | *
119 | * @return array
120 | */
121 | protected function getConfigMap()
122 | {
123 | $fields = array(
124 | 'account',
125 | 'api_key',
126 | 'secret_key',
127 | 'widget_key',
128 | 'quick_access_key',
129 | );
130 |
131 | $map = array();
132 |
133 | foreach ($fields as $field) {
134 |
135 | $map[] = array(
136 | 'field' => $this->getSectionId() . '_connection_' . $field,
137 | 'param' => lcfirst($this->ucWords($field, '')),
138 | );
139 | }
140 |
141 | return $map;
142 | }
143 |
144 | /**
145 | * Get X-Payments Config save URL
146 | *
147 | * @return string
148 | */
149 | protected function getSaveUrl()
150 | {
151 | $params = array(
152 | 'section' => 'payment',
153 | );
154 |
155 | if ($this->request->getParam('website')) {
156 | $params['website'] = $this->request->getParam('website');
157 | }
158 |
159 | if ($this->request->getParam('store')) {
160 | $params['store'] = $this->request->getParam('store');
161 | }
162 |
163 | return $this->backendUrl->getUrl('xpayments_cloud/system_config/save', $params);
164 | }
165 |
166 | /**
167 | * Get ID of section
168 | *
169 | * @return string
170 | */
171 | protected function getSectionId()
172 | {
173 | if (null !== $this->sectionId) {
174 | return $this->sectionId;
175 | }
176 |
177 | if ($this->request->getParam('paypal_country')) {
178 | $merchantCountry = $this->request->getParam('paypal_country');
179 | } elseif ($this->scopeConfig->getValue('paypal/general/merchant_country')) {
180 | $merchantCountry = $this->scopeConfig->getValue('paypal/general/merchant_country');
181 | } elseif ($this->scopeConfig->getValue('general/country/default')) {
182 | $merchantCountry = $this->scopeConfig->getValue('general/country/default');
183 | } else {
184 | $merchantCountry = 'US';
185 | }
186 |
187 | $merchantCountry = 'payment_' . strtolower($merchantCountry);
188 |
189 | $paypalCountries = $this->paypalStructure->getPaypalConfigCountries();
190 |
191 | if (!in_array($merchantCountry, $paypalCountries)) {
192 | $merchantCountry = 'payment_other';
193 | }
194 |
195 | $this->sectionId = $merchantCountry . '_xpayments_cloud';
196 |
197 | return $this->sectionId;
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/Helper/Cart.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Helper;
24 |
25 | /**
26 | * Helper for cart
27 | */
28 | class Cart extends \Magento\Framework\App\Helper\AbstractHelper
29 | {
30 | /**
31 | * Default string length
32 | */
33 | protected const DEFAULT_STRING_LENGTH = 255;
34 |
35 | /**
36 | * Store information
37 | *
38 | * @var \Magento\Store\Model\Information
39 | */
40 | private $storeInfo = null;
41 |
42 | /**
43 | * Store manager
44 | *
45 | * @var \Magento\Store\Model\StoreManagerInterface
46 | */
47 | private $storeManager = null;
48 |
49 | /**
50 | * Scope config
51 | *
52 | * @var \Magento\Framework\App\Config\ScopeConfigInterface
53 | */
54 | protected $scopeConfig = null;
55 |
56 | /**
57 | * Helper for address
58 | *
59 | * @var \CDev\XPaymentsCloud\Helper\Address
60 | */
61 | protected $addressHelper = null;
62 |
63 | /**
64 | * Constructor
65 | *
66 | * @param \Magento\Store\Model\Information $storeInfo
67 | * @param \Magento\Store\Model\StoreManagerInterface $storeManager
68 | * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
69 | * @param \CDev\XPaymentsCloud\Helper\Address $addressHelper
70 | *
71 | * @return void
72 | */
73 | public function __construct(
74 | \Magento\Store\Model\Information $storeInfo,
75 | \Magento\Store\Model\StoreManagerInterface $storeManager,
76 | \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
77 | \CDev\XPaymentsCloud\Helper\Address $addressHelper
78 | ) {
79 | $this->storeInfo = $storeInfo;
80 | $this->storeManager = $storeManager;
81 | $this->scopeConfig = $scopeConfig;
82 |
83 | $this->addressHelper = $addressHelper;
84 | }
85 |
86 | /**
87 | * Format price in 1234.56 format
88 | *
89 | * @param mixed $price
90 | *
91 | * @return string
92 | */
93 | public function preparePrice($price)
94 | {
95 | return number_format($price, 2, '.', '');
96 | }
97 |
98 | /**
99 | * Convert passed value to a string of limited length
100 | *
101 | * @param mixed $value
102 | * @param int $length
103 | *
104 | * @return string
105 | */
106 | protected function prepareString($value, $length = self::DEFAULT_STRING_LENGTH)
107 | {
108 | return substr((string)$value, 0, $length);
109 | }
110 |
111 | /**
112 | * Check if quantity is positive integer
113 | *
114 | * @param int|float|string $quantity Quantity
115 | *
116 | * @return bool
117 | */
118 | protected function isNaturalNumber($quantity)
119 | {
120 | return (int)$quantity == $quantity
121 | && (int)$quantity > 0;
122 | }
123 |
124 | /**
125 | * Prepare items from quote for initial payment request
126 | *
127 | * @param \Magento\Sales\Api\Data\OrderInterface $order
128 | *
129 | * @return array
130 | */
131 | protected function prepareItems(\Magento\Sales\Api\Data\OrderInterface $order)
132 | {
133 | $items = array();
134 |
135 | foreach ($order->getAllVisibleItems() as $item) {
136 |
137 | if (\Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE == $item->getProductType()) {
138 | continue;
139 | }
140 |
141 | $name = $item->getName();
142 | $sku = $item->getSku();
143 | $quantity = $item->getQtyOrdered();
144 |
145 | if ($item->getParentItem()) {
146 | $currentItem = $item->getParentItem();
147 | } else {
148 | $currentItem = $item;
149 | }
150 |
151 | $quantity = $item->getQtyOrdered();
152 |
153 | if ($this->isNaturalNumber($quantity)) {
154 |
155 | $price = $currentItem->getPrice();
156 | $quantity = (int)$quantity;
157 |
158 | } else {
159 |
160 | $name = sprintf('%s (x%s)', $name, round($quantity, 2));
161 | $quantity = 1;
162 | $price = $currentItem->getBaseRowTotal();
163 | }
164 |
165 | $items[] = array(
166 | 'quantity' => $quantity,
167 | 'name' => $this->prepareString($name),
168 | 'sku' => $this->prepareString($sku),
169 | 'price' => $this->preparePrice($price),
170 | );
171 | }
172 |
173 | return $items;
174 | }
175 |
176 | /**
177 | * Prepare cart for initial payment request
178 | *
179 | * @param \Magento\Sales\Api\Data\OrderInterface $order
180 | *
181 | * @return array
182 | */
183 | public function prepareCart(\Magento\Sales\Api\Data\OrderInterface $order)
184 | {
185 | $description = 'Order #' . $order->getIncrementId();
186 |
187 | $billingAddress = $this->addressHelper->prepareBillingAddress($order);
188 |
189 | if ($order->getShippingAddress()) {
190 | $shippingAddress = $this->addressHelper->prepareShippingAddress($order);
191 | } else {
192 | // For downloadable products
193 | $shippingAddress = $billingAddress;
194 | }
195 |
196 | $cart = array(
197 | 'login' => $order->getCustomerEmail(),
198 | 'billingAddress' => $billingAddress,
199 | 'shippingAddress' => $shippingAddress,
200 | 'items' => $this->prepareItems($order),
201 | 'currency' => $order->getBaseCurrencyCode(),
202 | 'shippingCost' => $this->preparePrice($order->getShippingAmount()),
203 | 'taxCost' => $this->preparePrice($order->getTaxAmount()),
204 | 'discount' => $this->preparePrice($order->getDiscountAmount()),
205 | 'totalCost' => $this->preparePrice($order->getGrandTotal()),
206 | 'description' => $description,
207 | 'merchantEmail' => $this->scopeConfig->getValue('trans_email/ident_sales/email'),
208 | );
209 |
210 | return $cart;
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/view/frontend/web/js/base.js:
--------------------------------------------------------------------------------
1 | // vim: set ts=2 sw=2 sts=2 et:
2 | /**
3 | * Magento
4 | *
5 | * NOTICE OF LICENSE
6 | *
7 | * This source file is subject to the Open Software License (OSL 3.0)
8 | * that is bundled with this package in the file LICENSE.txt.
9 | * It is also available through the world-wide-web at this URL:
10 | * http://opensource.org/licenses/osl-3.0.php
11 | * If you did not receive a copy of the license and are unable to
12 | * obtain it through the world-wide-web, please send an email
13 | * to license@magentocommerce.com so we can send you a copy immediately.
14 | *
15 | * @author Qualiteam Software
16 | * @category Cdev
17 | * @package Cdev_XPaymentsCloud
18 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
19 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20 | */
21 |
22 | window.XPaymentsLoader = Class.create();
23 |
24 | window.XPaymentsLoader.prototype = {
25 |
26 | /**
27 | * ID of the loader element
28 | */
29 | elementId: 'xpayments-loader',
30 |
31 | /**
32 | * Constructor. Create loader element
33 | */
34 | initialize: function (container, elementId) {
35 |
36 | if ('undefined' != typeof elementId) {
37 | this.elementId = elementId;
38 | }
39 |
40 | if ($(this.elementId)) {
41 | return this;
42 | }
43 |
44 | container = document.querySelector(container);
45 |
46 | if (container) {
47 |
48 | var loaderIcon = document.createElement('div');
49 | loaderIcon.id = 'xpayments-loader-icon';
50 |
51 | var loader = document.createElement('div');
52 | loader.id = 'xpayments-loader';
53 | loader.appendChild(loaderIcon);
54 |
55 | container.appendChild(loader);
56 | }
57 |
58 | return this;
59 | },
60 |
61 | /**
62 | * Show loader
63 | */
64 | show: function () {
65 |
66 | if ($(this.elementId)) {
67 | $(this.elementId).show();
68 | }
69 |
70 | return this;
71 | },
72 |
73 | /**
74 | * Hide loader
75 | */
76 | hide: function () {
77 |
78 | if ($(this.elementId)) {
79 | $(this.elementId).hide();
80 | }
81 |
82 | return this;
83 | }
84 | };
85 |
86 | /**
87 | * Initialize X-Payments widget
88 | */
89 | window.XPaymentsWidget.prototype.init = XPaymentsWidget.prototype.init.wrap(
90 | function(parentMethod, settings) {
91 |
92 | Object.extend(
93 | this.config,
94 | {
95 | devUrl: '',
96 | }
97 | );
98 |
99 | parentMethod(settings);
100 |
101 | return this;
102 | }
103 | );
104 |
105 | /**
106 | * Redefine server URL (if necessary)
107 | */
108 | window.XPaymentsWidget.prototype.getServerUrl = XPaymentsWidget.prototype.getServerUrl.wrap(
109 | function (parentMethod) {
110 |
111 | var devUrl = this.config.devUrl;
112 |
113 | if (devUrl) {
114 |
115 | if ('/' === devUrl.substr(-1)) {
116 | devUrl = devUrl.substr(0, devUrl.length - 1);
117 | }
118 |
119 | var url = devUrl;
120 |
121 | } else {
122 |
123 | var url = parentMethod();
124 | }
125 |
126 | return url;
127 | }
128 | );
129 |
130 | window.XPayments = Class.create();
131 |
132 | window.XPayments.prototype = {
133 |
134 | /**
135 | * Original submit payment form function
136 | */
137 | origSubmitPayment: function () {
138 | return false;
139 | },
140 |
141 | /**
142 | * Check if X-Payments Cloud is currently used payment method
143 | */
144 | isCurrent: function () {
145 | return false;
146 | },
147 |
148 | /**
149 | * Toggle Apple Pay button
150 | */
151 | toggleApplePayButton: function (isApple) {
152 | return false;
153 | },
154 |
155 | /**
156 | * Constructor
157 | */
158 | initialize: function (settings) {
159 |
160 | this.settings = settings;
161 |
162 | this.loader = new XPaymentsLoader(this.settings.container);
163 | this.getWidget();
164 | },
165 |
166 | /**
167 | * Initialize widget
168 | */
169 | getWidget: function () {
170 |
171 | try {
172 |
173 | if (!window._widgetInstance) {
174 |
175 | window._widgetInstance = new XPaymentsWidget();
176 | window._widgetInstance.init(this.settings);
177 |
178 | window._widgetInstance.on(
179 | 'success',
180 | (function (params) { this.onSuccess(params); }).bind(this)
181 | );
182 |
183 | window._widgetInstance.on(
184 | 'fail',
185 | (function () { this.onFail(); }).bind(this)
186 | );
187 |
188 | window._widgetInstance.on(
189 | 'loaded',
190 | (function () { this.onLoaded(); }).bind(this)
191 | );
192 |
193 | window._widgetInstance.on(
194 | 'paymentmethod.change',
195 | (function (params) { this.toggleApplePayButton('apple_pay' === params.newId); }).bind(this)
196 | );
197 | }
198 |
199 | } catch (error) {
200 |
201 | console.error(error);
202 | }
203 |
204 | return window._widgetInstance;
205 | },
206 |
207 | /**
208 | * Get input for X-Payments token
209 | */
210 | getTokenInput: function () {
211 |
212 | var input = $(this.settings.tokenInputId);
213 |
214 | if (!input) {
215 | input = document.createElement('input');
216 | input.type = 'hidden';
217 | input.name = this.settings.tokenInputName;
218 | input.id = this.settings.tokenInputId;
219 |
220 | this.getWidget().getFormElm().appendChild(input);
221 | }
222 |
223 | return input;
224 | },
225 |
226 | /**
227 | * Load X-Payments Cloud widget
228 | */
229 | load: function () {
230 | this.loader.show();
231 | this.getWidget().load();
232 | },
233 |
234 | /**
235 | * Process widget loaded event
236 | */
237 | onLoaded: function () {
238 | this.loader.hide();
239 | },
240 |
241 | /**
242 | * Switch payment method event
243 | */
244 | onSwitchPaymentMethod: function () {
245 | if (this.isCurrent()) {
246 | this.load();
247 | } else {
248 | this.getWidget().resize(0);
249 | }
250 | },
251 |
252 | /**
253 | * Submit payment form event
254 | */
255 | onSubmitPayment: function (origSubmitPayment) {
256 |
257 | if ('function' == typeof origSubmitPayment) {
258 | this.origSubmitPayment = origSubmitPayment;
259 | }
260 |
261 | if (this.isCurrent()) {
262 | this.loader.show();
263 | this.getWidget().submit();
264 | } else {
265 | this.origSubmitPayment();
266 | }
267 | },
268 |
269 | /**
270 | * Successfully tokenized payment event
271 | */
272 | onSuccess: function (params) {
273 |
274 | var formElm = this.getWidget().getFormElm();
275 |
276 | if (formElm) {
277 |
278 | var inputElm = this.getTokenInput();
279 |
280 | inputElm.value = params.token;
281 |
282 | if (this.settings.autoSubmit) {
283 | formElm.submit();
284 | } else {
285 | this.origSubmitPayment();
286 | }
287 | }
288 | },
289 |
290 | /**
291 | * Something went wronng
292 | */
293 | onFail: function (params) {
294 | this.loader.hide();
295 | }
296 | };
297 |
--------------------------------------------------------------------------------
/etc/adminhtml/system.xml:
--------------------------------------------------------------------------------
1 |
2 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | 1
34 | Magento\Config\Block\System\Config\Form\Fieldset
35 |
36 |
37 | payment/xpayments_cloud/account
38 |
39 | 1
40 |
41 |
42 |
43 |
44 | payment/xpayments_cloud/api_key
45 |
46 | 1
47 |
48 |
49 |
50 |
51 | payment/xpayments_cloud/secret_key
52 |
53 | 1
54 |
55 |
56 |
57 |
58 | payment/xpayments_cloud/widget_key
59 |
60 | 1
61 |
62 |
63 |
64 |
65 | payment/xpayments_cloud/quick_access_key
66 |
67 | 1
68 |
69 |
70 |
71 |
72 |
73 | CDev\XPaymentsCloud\Block\System\Config\CloudIframe
74 |
75 |
76 |
77 |
78 |
79 |
80 | 1
81 | Magento\Config\Block\System\Config\Form\Fieldset
82 |
83 |
84 | Magento\Config\Model\Config\Source\Yesno
85 | payment/xpayments_cloud/active
86 |
87 |
88 |
89 | payment/xpayments_cloud/title
90 |
91 |
92 |
93 | payment/xpayments_cloud/sort_order
94 | validate-number
95 |
96 |
97 |
98 |
99 |
100 | 0
101 | Magento\Config\Block\System\Config\Form\Fieldset
102 |
103 |
104 | payment/xpayments_cloud/min_order_total
105 | validate-number validate-zero-or-greater
106 |
107 |
108 |
109 | payment/xpayments_cloud/max_order_total
110 | validate-number validate-zero-or-greater
111 |
112 |
113 |
114 | Magento\Payment\Model\Config\Source\Allspecificcountries
115 | payment/xpayments_cloud/allowspecific
116 |
117 |
118 |
119 | Magento\Directory\Model\Config\Source\Country
120 | payment/xpayments_cloud/specificcountry
121 |
122 |
123 |
124 |
125 |
126 | 0
127 | Magento\Config\Block\System\Config\Form\Fieldset
128 |
129 |
130 | Magento\Config\Model\Config\Source\Yesno
131 | payment/xpayments_cloud/debug
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/Model/Payment/Method/XPaymentsCloud.php:
--------------------------------------------------------------------------------
1 |
17 | * @category CDev
18 | * @package CDev_XPaymentsCloud
19 | * @copyright (c) 2010-present Qualiteam software Ltd . All rights reserved
20 | * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
21 | */
22 |
23 | namespace CDev\XPaymentsCloud\Model\Payment\Method;
24 |
25 | /**
26 | * X-Payments Cloud payment method
27 | */
28 | class XPaymentsCloud extends \Magento\Payment\Model\Method\AbstractMethod
29 | {
30 | /**
31 | * Payment method code
32 | */
33 | public const CODE = 'xpayments_cloud';
34 |
35 | /**
36 | * Payment method code
37 | *
38 | * @var string
39 | */
40 | protected $_code = self::CODE;
41 |
42 | /**
43 | * Payment Info block
44 | *
45 | * @var string
46 | */
47 | protected $_infoBlockType = \CDev\XPaymentsCloud\Block\Payment\Info::class;
48 |
49 | /**
50 | * Payment method flags
51 | *
52 | * @var bool
53 | */
54 | protected $_isGateway = false;
55 |
56 | protected $_canUseCheckout = true;
57 | protected $_canUseInternal = false;
58 | protected $_canUseForMultishipping = false;
59 |
60 | protected $_canCapture = true;
61 | protected $_canCapturePartial = true;
62 |
63 | protected $_canRefund = true;
64 | protected $_canRefundInvoicePartial = true;
65 |
66 | protected $_canVoid = true;
67 |
68 | protected $_canReviewPayment = true;
69 |
70 | /**
71 | * Customer repository
72 | *
73 | * @var \Magento\Customer\Api\CustomerRepositoryInterface
74 | */
75 | protected $customerRepository = null;
76 |
77 | /**
78 | * Customer model
79 | *
80 | * @var \Magento\Sales\Api\Data\CustomerInterface
81 | */
82 | protected $customer = null;
83 |
84 | /**
85 | * URL builder
86 | *
87 | * @var \Magento\Framework\UrlInterface
88 | */
89 | protected $urlBuilder = null;
90 |
91 | /**
92 | * Cart helper
93 | *
94 | * @var \CDev\XPaymentsCloud\Helper\Cart
95 | */
96 | protected $cartHelper = null;
97 |
98 | /**
99 | * SDK Client helper
100 | *
101 | * @var \CDev\XPaymentsCloud\Helper\Client
102 | */
103 | protected $clientHelper = null;
104 |
105 | /**
106 | * Logger
107 | *
108 | * @var \CDev\XPaymentsCloud\Logger\Logger
109 | */
110 | protected $xpaymentsLogger = null;
111 |
112 | /**
113 | * Constructor
114 | *
115 | * @param \Magento\Framework\Model\Context $context
116 | * @param \Magento\Framework\Registry $registry
117 | * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
118 | * @param \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory
119 | * @param \Magento\Payment\Helper\Data $paymentData
120 | * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
121 | * @param \Magento\Payment\Model\Method\Logger $logger
122 | * @param \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository
123 | * @param \Magento\Framework\UrlInterface $urlBuilder
124 | * @param \CDev\XPaymentsCloud\Helper\Cart $cartHelper
125 | * @param \CDev\XPaymentsCloud\Helper\Client $clientHelper
126 | * @param \CDev\XPaymentsCloud\Logger\Logger $xpaymentsLogger
127 | * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
128 | * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
129 | * @param array $data
130 | * @param \Magento\Directory\Helper\Data $directory
131 | *
132 | * @SuppressWarnings(PHPMD.ExcessiveParameterList)
133 | */
134 | public function __construct(
135 | \Magento\Framework\Model\Context $context,
136 | \Magento\Framework\Registry $registry,
137 | \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
138 | \Magento\Framework\Api\AttributeValueFactory $customAttributeFactory,
139 | \Magento\Payment\Helper\Data $paymentData,
140 | \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
141 | \Magento\Payment\Model\Method\Logger $logger,
142 | \Magento\Customer\Api\CustomerRepositoryInterface $customerRepository,
143 | \Magento\Framework\UrlInterface $urlBuilder,
144 | \CDev\XPaymentsCloud\Helper\Cart $cartHelper,
145 | \CDev\XPaymentsCloud\Helper\Client $clientHelper,
146 | \CDev\XPaymentsCloud\Logger\Logger $xpaymentsLogger,
147 | \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
148 | \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
149 | array $data = [],
150 | \Magento\Directory\Helper\Data $directory = null
151 | ) {
152 |
153 | parent::__construct(
154 | $context,
155 | $registry,
156 | $extensionFactory,
157 | $customAttributeFactory,
158 | $paymentData,
159 | $scopeConfig,
160 | $logger,
161 | $resource,
162 | $resourceCollection,
163 | $data,
164 | $directory
165 | );
166 |
167 | $this->customerRepository = $customerRepository;
168 |
169 | $this->urlBuilder = $urlBuilder;
170 |
171 | $this->cartHelper = $cartHelper;
172 | $this->clientHelper = $clientHelper;
173 |
174 | $this->xpaymentsLogger = $xpaymentsLogger;
175 | }
176 |
177 | /**
178 | * Get xpid from parent transaction
179 | *
180 | * @param \Magento\Payment\Model\InfoInterface $payment
181 | *
182 | * @return string
183 | */
184 | protected function getParentXpid(\Magento\Payment\Model\InfoInterface $payment)
185 | {
186 | return substr($payment->getParentTransactionId(), 0, 32);
187 | }
188 |
189 | /**
190 | * Get xpid from last transaction
191 | *
192 | * @param \Magento\Payment\Model\InfoInterface $payment
193 | *
194 | * @return string
195 | */
196 | protected function getLastXpid(\Magento\Payment\Model\InfoInterface $payment)
197 | {
198 | return substr($payment->getLastTransId(), 0, 32);
199 | }
200 |
201 | /**
202 | * Get customer
203 | *
204 | * @param \Magento\Payment\Model\InfoInterface $payment
205 | *
206 | * @return \Magento\Sales\Api\Data\CustomerInterface
207 | */
208 | protected function getCustomer(\Magento\Payment\Model\InfoInterface $payment)
209 | {
210 | if (
211 | null === $this->customer
212 | && $payment->getOrder()->getCustomerId()
213 | ) {
214 | $this->customer = $this->customerRepository
215 | ->getById($payment->getOrder()->getCustomerId());
216 | }
217 |
218 | return $this->customer;
219 | }
220 |
221 | /**
222 | * Get X-Payments customer ID
223 | *
224 | * @param \Magento\Payment\Model\InfoInterface $payment
225 | *
226 | * @return string
227 | */
228 | protected function getXpaymentsCustomerId(\Magento\Payment\Model\InfoInterface $payment)
229 | {
230 | $xpaymentsCustomerId = '';
231 |
232 | if ($this->getcustomer($payment)) {
233 |
234 | $attribute = $this->getCustomer($payment)
235 | ->getCustomAttribute('xpayments_customer_id');
236 |
237 | if ($attribute) {
238 | $xpaymentsCustomerId = $attribute->getValue();
239 | }
240 | }
241 |
242 | return $xpaymentsCustomerId;
243 | }
244 |
245 | /**
246 | * Set X-Payments customer ID
247 | *
248 | * @param \Magento\Payment\Model\InfoInterface $payment
249 | * @param string $xpaymentsCustomerId
250 | *
251 | * @return void
252 | */
253 | protected function setXpaymentsCustomerId(\Magento\Payment\Model\InfoInterface $payment, $xpaymentsCustomerId)
254 | {
255 | if ($this->getcustomer($payment)) {
256 |
257 | $payment->setXpaymentsCustomerId($xpaymentsCustomerId);
258 |
259 | // TODO: Rework via fieldsets
260 | $this->getCustomer($payment)
261 | ->setCustomAttribute('xpayments_customer_id', $xpaymentsCustomerId);
262 |
263 | $this->customerRepository->save($this->getCustomer($payment));
264 | }
265 |
266 | return $xpaymentsCustomerId;
267 | }
268 |
269 | /**
270 | * Compose URL for action
271 | *
272 | * @param string $action
273 | *
274 | * @return string
275 | */
276 | protected function composeUrl($action)
277 | {
278 | return $this->urlBuilder->getUrl('xpayments_cloud/processing/' . $action);
279 | }
280 |
281 | /**
282 | * Authorize payment
283 | *
284 | * @param \Magento\Payment\Model\InfoInterface $payment
285 | * @param float $amount
286 | *
287 | * @throws \Magento\Framework\Exception\LocalizedException
288 | *
289 | * @return $this
290 | */
291 | public function authorize(\Magento\Payment\Model\InfoInterface $payment, $amount)
292 | {
293 | try {
294 |
295 | $cart = $this->cartHelper
296 | ->prepareCart($payment->getOrder());
297 |
298 | $refId = $payment->getOrder()->getIncrementId();
299 |
300 | $token = $payment->getAdditionalInformation()['xpayments_token'];
301 |
302 | $response = $this->clientHelper
303 | ->getClient()
304 | ->doPay(
305 | $token,
306 | $refId,
307 | $this->getXpaymentsCustomerId($payment),
308 | $cart,
309 | $this->composeUrl('return'),
310 | $this->composeUrl('callback')
311 | );
312 |
313 | $this->processResponse($response, $payment);
314 |
315 | } catch (\Exception $exception) {
316 |
317 | $message = $this->xpaymentsLogger->processException($exception);
318 |
319 | throw new \Magento\Framework\Exception\LocalizedException(__($message));
320 | }
321 |
322 | return $this;
323 | }
324 |
325 | /**
326 | * Capture specified amount for payment
327 | *
328 | * @param \Magento\Payment\Model\InfoInterface $payment
329 | * @param float $amount
330 | *
331 | * @throws \Magento\Framework\Exception\LocalizedException
332 | *
333 | * @return $this
334 | */
335 | public function capture(\Magento\Payment\Model\InfoInterface $payment, $amount)
336 | {
337 | try {
338 |
339 | $response = $this->clientHelper
340 | ->getClient()
341 | ->doCapture(
342 | $this->getParentXpid($payment),
343 | $amount
344 | );
345 |
346 | $this->processResponse($response, $payment);
347 |
348 | } catch (\Exception $exception) {
349 |
350 | $message = $this->xpaymentsLogger->processException($exception);
351 |
352 | throw new \Magento\Framework\Exception\LocalizedException(__($message));
353 | }
354 |
355 | return $this;
356 | }
357 |
358 | /**
359 | * Refund specified amount for payment
360 | *
361 | * @param \Magento\Payment\Model\InfoInterface $payment
362 | * @param float $amount
363 | *
364 | * @throws \Magento\Framework\Exception\LocalizedException
365 | *
366 | * @return $this
367 | */
368 | public function refund(\Magento\Payment\Model\InfoInterface $payment, $amount)
369 | {
370 | try {
371 |
372 | $response = $this->clientHelper
373 | ->getClient()
374 | ->doRefund(
375 | $this->getParentXpid($payment),
376 | $amount
377 | );
378 |
379 | $this->processResponse($response, $payment);
380 |
381 | } catch (\Exception $exception) {
382 |
383 | $message = $this->xpaymentsLogger->processException($exception);
384 |
385 | throw new \Magento\Framework\Exception\LocalizedException(__($message));
386 | }
387 |
388 | return $this;
389 | }
390 |
391 | /**
392 | * Void payment
393 | *
394 | * @param \Magento\Payment\Model\InfoInterface $payment
395 | *
396 | * @throws \Magento\Framework\Exception\LocalizedException
397 | *
398 | * @return $this
399 | */
400 | public function void(\Magento\Payment\Model\InfoInterface $payment)
401 | {
402 | try {
403 |
404 | $response = $this->clientHelper
405 | ->getClient()
406 | ->doVoid($this->getParentXpid($payment));
407 |
408 | $this->processResponse($response, $payment);
409 |
410 | } catch (\Exception $exception) {
411 |
412 | $message = $this->xpaymentsLogger->processException($exception);
413 |
414 | throw new \Magento\Framework\Exception\LocalizedException(__($message));
415 | }
416 |
417 | return $this;
418 | }
419 |
420 | /**
421 | * Cancel payment
422 | *
423 | * @param \Magento\Payment\Model\InfoInterface $payment
424 | *
425 | * @throws \Magento\Framework\Exception\LocalizedException
426 | *
427 | * @return $this
428 | */
429 | public function cancel(\Magento\Payment\Model\InfoInterface $payment)
430 | {
431 | return $this->void($payment);
432 | }
433 |
434 | /**
435 | * Accept payment
436 | *
437 | * @param \Magento\Payment\Model\InfoInterface $payment
438 | *
439 | * @throws \Magento\Framework\Exception\LocalizedException
440 | *
441 | * @return bool
442 | */
443 | public function acceptPayment(\Magento\Payment\Model\InfoInterface $payment)
444 | {
445 | try {
446 |
447 | $xpid = $this->getLastXpid($payment);
448 |
449 | $response = $this->clientHelper
450 | ->getClient()
451 | ->doAccept($xpid);
452 |
453 | $result = (bool)$response->result;
454 |
455 | } catch (\Exception $exception) {
456 |
457 | $message = $this->xpaymentsLogger->processException($exception);
458 |
459 | throw new \Magento\Framework\Exception\LocalizedException(__($message));
460 | }
461 |
462 | return $result;
463 | }
464 |
465 | /**
466 | * Decline payment
467 | *
468 | * @param \Magento\Payment\Model\InfoInterface $payment
469 | *
470 | * @throws \Magento\Framework\Exception\LocalizedException
471 | *
472 | * @return bool
473 | */
474 | public function denyPayment(\Magento\Payment\Model\InfoInterface $payment)
475 | {
476 | try {
477 |
478 | $xpid = $this->getLastXpid($payment);
479 |
480 | $response = $this->clientHelper
481 | ->getClient()
482 | ->doDecline($xpid);
483 |
484 | $result = (bool)$response->result;
485 |
486 | } catch (\Exception $exception) {
487 |
488 | $message = $this->xpaymentsLogger->processException($exception);
489 |
490 | throw new \Magento\Framework\Exception\LocalizedException(__($message));
491 | }
492 |
493 | return $result;
494 | }
495 |
496 | /**
497 | * Process X-Payments Cloud payment response
498 | *
499 | * @param \XPaymentsCloud\Response $response
500 | * @param \Magento\Payment\Model\InfoInterface $payment
501 | *
502 | * @return \Cdev\XPaymentsCloud\Model\Payment\Cloud
503 | */
504 | protected function processResponse(
505 | \XPaymentsCloud\Response $response,
506 | \Magento\Payment\Model\InfoInterface $payment
507 | ) {
508 | if (!$response->isLastTransactionSuccessful()) {
509 | throw new \Magento\Framework\Exception\LocalizedException(__($response->message));
510 | }
511 |
512 | $info = $response->getPayment();
513 |
514 | // Compose transaction ID preventing duplicates
515 | $transactionId = sprintf('%s-%s', $info->xpid, $info->lastTransaction->action);
516 |
517 | // Set some basic information about the payment
518 | $payment->setStatus(self::STATUS_APPROVED)
519 | ->setCcTransId($info->lastTransaction->txnId)
520 | ->setLastTransId($info->lastTransaction->txnId)
521 | ->setTransactionId($transactionId)
522 | ->setIsTransactionClosed(false)
523 | ->setAmount($info->amount)
524 | ->setShouldCloseParentTransaction(false);
525 |
526 | // Set information about the card
527 | $payment->setCcLast4($info->card->last4)
528 | ->setCcFirst6($info->card->first6)
529 | ->setCcType($info->card->type)
530 | ->setCcExpMonth($info->card->expireMonth)
531 | ->setCcExpYear($info->card->expireYear)
532 | ->setCcOwner($info->card->cardholderName);
533 |
534 | // Set transaction details
535 | if (!empty($info->details)) {
536 |
537 | $details = array_filter(
538 | get_object_vars($info->details)
539 | );
540 |
541 | $payment->setTransactionAdditionalInfo(
542 | \Magento\Sales\Model\Order\Payment\Transaction::RAW_DETAILS,
543 | $details
544 | );
545 | }
546 |
547 | // Set fraudulent flag
548 | $payment->setIsTransactionPending(
549 | (bool)$info->isFraudulent
550 | );
551 |
552 | // Set X-Payments Cloud customerId
553 | $this->setXpaymentsCustomerId($payment, $info->customerId);
554 |
555 | return $this;
556 | }
557 | }
558 |
--------------------------------------------------------------------------------
/view/frontend/web/js/lib/widget.js:
--------------------------------------------------------------------------------
1 | /*
2 | * X-Payments Cloud SDK - Payment Widget
3 | */
4 |
5 | window.XPaymentsWidget = function()
6 | {
7 | this.serverDomain = 'xpayments.com';
8 | this.messageNamespace = 'xpayments.widget.';
9 | this.receiverNamespace = 'xpayments.checkout.';
10 | this.widgetId = this.generateId();
11 | this.previousHeight = -1;
12 | this.applePay = {
13 | session: null,
14 | supportedNetworks: [],
15 | merchantCapabilities: [],
16 | merchantId: '',
17 | };
18 | this.paymentMethod = null;
19 |
20 | this.config = {
21 | debug: false,
22 | account: '',
23 | widgetKey: '',
24 | container: '',
25 | form: '',
26 | language: '',
27 | customerId: '',
28 | tokenName: 'xpaymentsToken',
29 | showSaveCard: true,
30 | enableWallets: true,
31 | applePay: {
32 | enabled: true,
33 | checkoutMode: false,
34 | shippingMethods: [],
35 | requiredShippingFields: [
36 | 'email',
37 | 'name',
38 | 'phone',
39 | 'postalAddress'
40 | ],
41 | requiredBillingFields: [
42 | 'postalAddress'
43 | ]
44 | },
45 | company: {
46 | name: '',
47 | domain: document.location.hostname,
48 | countryCode: '',
49 | },
50 | order: {
51 | tokenizeCard: false,
52 | total: -1,
53 | currency: ''
54 | }
55 | };
56 |
57 | this.handlers = {};
58 |
59 | this.bindedListener = false;
60 | this.bindedSubmit = false;
61 |
62 | }
63 |
64 | XPaymentsWidget.prototype.on = function(event, handler, context)
65 | {
66 | if ('undefined' === typeof context) {
67 | context = this;
68 | }
69 |
70 | if ('formSubmit' !== event) {
71 |
72 | this.handlers[event] = handler.bind(context);
73 |
74 | } else {
75 | var formElm = this.getFormElm();
76 |
77 | if (formElm) {
78 | if (this.bindedSubmit) {
79 | formElm.removeEventListener('submit', this.bindedSubmit);
80 | }
81 | this.bindedSubmit = handler.bind(context);
82 | formElm.addEventListener('submit', this.bindedSubmit);
83 | }
84 | }
85 |
86 | return this;
87 | }
88 |
89 |
90 | XPaymentsWidget.prototype.trigger = function(event, params)
91 | {
92 | if ('function' === typeof this.handlers[event]) {
93 | this.handlers[event](params);
94 | }
95 |
96 | this._log('X-Payments widget triggered: ' + event, params);
97 |
98 | return this;
99 | }
100 |
101 | XPaymentsWidget.prototype.init = function(settings)
102 | {
103 | for (var key in settings) {
104 | if ('undefined' !== typeof this.config[key]) {
105 | if ('object' === typeof this.config[key]) {
106 | for (var subkey in settings[key]) {
107 | if ('undefined' !== typeof this.config[key][subkey]) {
108 | this.config[key][subkey] = settings[key][subkey];
109 | }
110 | }
111 | } else {
112 | this.config[key] = settings[key];
113 | }
114 | }
115 | }
116 |
117 | if (this.config.order.tokenizeCard) {
118 | this.config.showSaveCard = false;
119 | }
120 |
121 | // Set default handlers
122 | this.on('formSubmit', function (domEvent) {
123 | // "this" here is the widget
124 | if (this.isValid()) {
125 | this.submit();
126 | domEvent.preventDefault();
127 | }
128 | })
129 | .on('success', this._defaultSuccessHandler)
130 | .on('applepay.paymentauthorized', this._applePayAuthorized)
131 | .on('alert', function(params) {
132 | window.alert(params.message);
133 | });
134 |
135 | this.bindedListener = this.messageListener.bind(this);
136 | window.addEventListener('message', this.bindedListener);
137 |
138 | if (
139 | 'undefined' !== typeof settings.autoload
140 | && settings.autoload
141 | ) {
142 | this.load();
143 | }
144 |
145 | return this;
146 | }
147 |
148 | XPaymentsWidget.prototype.initCheckoutWithApplePay = function(settings)
149 | {
150 | this.config.container = 'body';
151 | this.config.applePay.checkoutMode = true;
152 | this.init(settings);
153 | }
154 |
155 | XPaymentsWidget.prototype.generateId = function()
156 | {
157 | return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
158 | }
159 |
160 | XPaymentsWidget.prototype.getIframeId = function()
161 | {
162 | return 'xpayments-' + this.widgetId;
163 | }
164 |
165 | XPaymentsWidget.prototype.getIframeElm = function()
166 | {
167 | return document.getElementById(this.getIframeId());
168 | }
169 |
170 | XPaymentsWidget.prototype.getContainerElm = function()
171 | {
172 | return this.safeQuerySelector(this.config.container);
173 | }
174 |
175 | XPaymentsWidget.prototype.getFormElm = function()
176 | {
177 | return this.safeQuerySelector(this.config.form);
178 | }
179 |
180 | XPaymentsWidget.prototype.isValid = function()
181 | {
182 | return this.getIframeElm() && this.getFormElm();
183 | }
184 |
185 | XPaymentsWidget.prototype.safeQuerySelector = function(selector)
186 | {
187 | var elm = false;
188 | if (selector) {
189 | elm = document.querySelector(selector);
190 | }
191 | return elm;
192 | }
193 |
194 | XPaymentsWidget.prototype.load = function()
195 | {
196 | var containerElm = this.getContainerElm();
197 | if (!containerElm) {
198 | return this;
199 | }
200 |
201 | var elm = this.getIframeElm();
202 | if (!elm) {
203 | elm = document.createElement('iframe');
204 | elm.id = this.getIframeId();
205 | elm.style.width = '100%';
206 | elm.style.height = '0';
207 | elm.style.overflow = 'hidden';
208 | elm.style.border = 'none';
209 | if (this.config.applePay.checkoutMode) {
210 | elm.style.display = 'none';
211 | }
212 | elm.setAttribute('scrolling', 'no');
213 | containerElm.appendChild(elm);
214 | }
215 |
216 | var url =
217 | this.getServerUrl() + '/payment.php' +
218 | '?widget_key=' + encodeURIComponent(this.config.widgetKey) +
219 | '&widget_id=' + encodeURIComponent(this.widgetId);
220 | if (this.config.customerId) {
221 | url += '&customer_id=' + encodeURIComponent(this.config.customerId);
222 | }
223 | if (this.config.language) {
224 | url += '&language=' + encodeURIComponent(this.config.language);
225 | }
226 | if (this.config.applePay.checkoutMode) {
227 | url += '&target=checkout_apple_pay';
228 | }
229 | elm.src = url;
230 |
231 | return this;
232 | }
233 |
234 | XPaymentsWidget.prototype.getServerHost = function()
235 | {
236 | return this.config.account + '.' + this.serverDomain;
237 | }
238 |
239 | XPaymentsWidget.prototype.getServerUrl = function()
240 | {
241 | return 'https://' + this.getServerHost();
242 | }
243 |
244 | XPaymentsWidget.prototype.submit = function()
245 | {
246 | if (!this.config.applePay.checkoutMode) {
247 | this._sendEvent('submit');
248 | } else {
249 | this.beginCheckoutWithApplePay();
250 | }
251 | }
252 |
253 | XPaymentsWidget.prototype.beginCheckoutWithApplePay = function()
254 | {
255 | if (this._isApplePayAvailable()) {
256 | this.trigger('applepay.start');
257 | this._applePayStart();
258 | }
259 | }
260 |
261 | XPaymentsWidget.prototype._afterLoad = function(params)
262 | {
263 | this.showSaveCard();
264 | if (this.config.enableWallets) {
265 | if (this._isApplePayAvailable()) {
266 | this._sendEvent('applepay.enable');
267 | }
268 | }
269 | this.setOrder();
270 | this.resize(params.height);
271 | }
272 |
273 | XPaymentsWidget.prototype._defaultSuccessHandler = function(params) {
274 | var formElm = this.getFormElm();
275 | if (formElm) {
276 | var input = document.getElementById(this.config.tokenName);
277 | if (!input) {
278 | input = document.createElement('input');
279 | input.type = 'hidden';
280 | input.name = input.id = this.config.tokenName;
281 | formElm.appendChild(input);
282 | }
283 | input.value = params.token;
284 | formElm.submit();
285 | }
286 | }
287 |
288 | XPaymentsWidget.prototype.getPaymentMethod = function()
289 | {
290 | return (!this.config.applePay.checkoutMode) ? this.paymentMethod : 'apple_pay';
291 | }
292 |
293 | XPaymentsWidget.prototype._paymentMethodChange = function(params)
294 | {
295 | this.paymentMethod = params.newId;
296 | }
297 |
298 | XPaymentsWidget.prototype._applePayValidated = function(params)
299 | {
300 | try {
301 | this.applePay.session.completeMerchantValidation(params.data);
302 | } catch (e) {
303 | }
304 | }
305 |
306 | XPaymentsWidget.prototype._applePayAuthorized = function(params)
307 | {
308 | this.succeedApplePayPayment(params);
309 | }
310 |
311 | XPaymentsWidget.prototype._applePayCompleted = function(params)
312 | {
313 | this.completeApplePayPayment({ status: ApplePaySession.STATUS_SUCCESS, errors: [] });
314 | }
315 |
316 | XPaymentsWidget.prototype._applePayError = function(params)
317 | {
318 | try {
319 | this.applePay.session.abort();
320 | } catch (e) {
321 | // Skip errors if any
322 | }
323 | }
324 |
325 | XPaymentsWidget.prototype._applePayStart = function()
326 | {
327 | var request = {
328 | countryCode: this.config.company.countryCode,
329 | currencyCode: this.config.order.currency,
330 | supportedNetworks: this.applePay.supportedNetworks,
331 | merchantCapabilities: this.applePay.merchantCapabilities,
332 | total: {
333 | label: this.config.company.name,
334 | amount: this.config.order.total
335 | },
336 | };
337 |
338 | this.applePayCustomerAddress = null;
339 | if (this.config.applePay.checkoutMode) {
340 | if (this.config.applePay.shippingMethods) {
341 | request.shippingMethods = this.config.applePay.shippingMethods;
342 | }
343 | if (this.config.applePay.requiredShippingFields) {
344 | request.requiredShippingContactFields = this.config.applePay.requiredShippingFields;
345 | }
346 | if (this.config.applePay.requiredBillingFields) {
347 | request.requiredBillingContactFields = this.config.applePay.requiredBillingFields;
348 | }
349 | }
350 |
351 | this.applePay.session = new ApplePaySession(3, request);
352 |
353 | this.applePay.session.onvalidatemerchant = (function(event) {
354 | this._sendEvent('applepay.validatemerchant', {
355 | validationURL: event.validationURL,
356 | displayName: this.config.company.name,
357 | context: this.config.company.domain,
358 | });
359 | }).bind(this);
360 |
361 | this.applePay.session.onpaymentauthorized = (function(event) {
362 | this.trigger('applepay.paymentauthorized', event.payment);
363 | }).bind(this);
364 |
365 | this.applePay.session.oncancel = (function(event) {
366 | this._sendEvent('applepay.cancel');
367 | }).bind(this);
368 |
369 | if (this.config.applePay.checkoutMode) {
370 | this.applePay.session.onshippingcontactselected = (function(event) {
371 | this.trigger('applepay.shippingcontactselected', event.shippingContact);
372 | }).bind(this);
373 | this.applePay.session.onshippingmethodselected = (function(event) {
374 | this.trigger('applepay.shippingmethodselected', event.shippingMethod);
375 | }).bind(this);
376 | }
377 |
378 | this.applePay.session.begin();
379 |
380 | }
381 |
382 | XPaymentsWidget.prototype._parseApplePayNewTotal = function(updateData)
383 | {
384 | this.setOrder(updateData.newTotal.amount);
385 | if ('undefined' != typeof updateData.newTotal && 'undefined' == typeof updateData.newTotal.label) {
386 | updateData.newTotal.label = this.config.company.name;
387 | }
388 | return updateData;
389 | }
390 |
391 | XPaymentsWidget.prototype.completeApplePayShippingContactSelection = function(updateData) {
392 | this.applePay.session.completeShippingContactSelection(this._parseApplePayNewTotal(updateData));
393 | }
394 |
395 | XPaymentsWidget.prototype.completeApplePayShippingMethodSelection = function(updateData) {
396 | this.applePay.session.completeShippingMethodSelection(this._parseApplePayNewTotal(updateData));
397 | }
398 |
399 | XPaymentsWidget.prototype.completeApplePayPayment = function(updateData) {
400 | this.applePay.session.completePayment(updateData);
401 | }
402 |
403 | XPaymentsWidget.prototype.succeedApplePayPayment = function(payment) {
404 | this._sendEvent('applepay.paymentauthorized', { payment: payment });
405 | }
406 |
407 |
408 | XPaymentsWidget.prototype.isApplePaySupportedByDevice = function() {
409 | return (window.ApplePaySession && ApplePaySession.canMakePayments());
410 | }
411 |
412 | XPaymentsWidget.prototype._isApplePayAvailable = function() {
413 | return this.config.applePay.enabled && this.isApplePaySupportedByDevice();
414 | }
415 |
416 | XPaymentsWidget.prototype._checkApplePayActiveCard = function()
417 | {
418 | var promise = ApplePaySession.canMakePaymentsWithActiveCard(this.applePay.merchantId);
419 | promise.then((function (canMakePayments) {
420 | if (canMakePayments) {
421 | this.trigger('applepay.forceselect');
422 | this._sendEvent('applepay.select');
423 | }
424 | }).bind(this));
425 | }
426 |
427 | XPaymentsWidget.prototype._applePayInit = function(params)
428 | {
429 | this.applePay.supportedNetworks = params.supportedNetworks;
430 | this.applePay.merchantCapabilities = params.merchantCapabilities;
431 | this.applePay.merchantId = params.merchantId;
432 | this._checkApplePayActiveCard();
433 | }
434 |
435 | XPaymentsWidget.prototype.showSaveCard = function(value)
436 | {
437 | if ('undefined' === typeof value) {
438 | value = this.config.showSaveCard;
439 | } else {
440 | this.config.showSaveCard = (true === value);
441 | }
442 | this._sendEvent('savecard', { show: value });
443 | }
444 |
445 |
446 | XPaymentsWidget.prototype.refresh = function()
447 | {
448 | this._sendEvent('refresh');
449 | }
450 |
451 | XPaymentsWidget.prototype.resize = function(height)
452 | {
453 | var elm = this.getIframeElm();
454 | if (elm) {
455 | this.previousHeight = elm.style.height;
456 | elm.style.height = height + 'px';
457 | }
458 | }
459 |
460 | XPaymentsWidget.prototype.setOrder = function(total, currency)
461 | {
462 | if ('undefined' !== typeof total) {
463 | this.config.order.total = total;
464 | }
465 | if ('undefined' !== typeof currency) {
466 | this.config.order.currency = currency;
467 | }
468 |
469 | this._sendEvent('details', {
470 | tokenizeCard: this.config.order.tokenizeCard,
471 | total: this.config.order.total,
472 | currency: this.config.order.currency
473 | });
474 | }
475 |
476 | XPaymentsWidget.prototype.destroy = function()
477 | {
478 | if (this.bindedListener) {
479 | window.removeEventListener('message', this.bindedListener);
480 | }
481 |
482 | var formElm = this.getFormElm();
483 | if (this.bindedSubmit && formElm) {
484 | formElm.removeEventListener('submit', this.bindedSubmit);
485 | }
486 |
487 | var containerElm = this.getContainerElm();
488 | if (containerElm) {
489 | var elm = this.getIframeElm();
490 | if (elm && containerElm.contains(elm)) {
491 | containerElm.removeChild(elm);
492 | }
493 | }
494 | }
495 |
496 | XPaymentsWidget.prototype.messageListener = function(event)
497 | {
498 | if (window.JSON) {
499 | var msg = false;
500 | if (-1 !== this.getServerUrl().toLowerCase().indexOf(event.origin.toLowerCase())) {
501 | try {
502 | msg = window.JSON.parse(event.data);
503 | } catch (e) {
504 | // Skip invalid messages
505 | }
506 | }
507 |
508 | if (
509 | msg &&
510 | msg.event &&
511 | 0 === msg.event.indexOf(this.messageNamespace) &&
512 | (!msg.widgetId || msg.widgetId === this.widgetId)
513 | ) {
514 | this._log('Received from X-Payments: ' + msg.event);
515 |
516 | var eventType = msg.event.substr(this.messageNamespace.length);
517 |
518 | if ('loaded' === eventType) {
519 | this._afterLoad(msg.params);
520 | } else if ('applepay.start' === eventType) {
521 | this._applePayStart(msg.params);
522 | } else if ('applepay.init' === eventType) {
523 | this._applePayInit(msg.params);
524 | } else if ('applepay.merchantvalidated' === eventType) {
525 | this._applePayValidated(msg.params);
526 | } else if ('applepay.completed' === eventType) {
527 | this._applePayCompleted(msg.params);
528 | } else if ('applepay.error' === eventType) {
529 | this._applePayError(msg.params);
530 | } else if ('paymentmethod.change' === eventType) {
531 | this._paymentMethodChange(msg.params);
532 | } else if ('resize' === eventType) {
533 | this.resize(msg.params.height);
534 | } else if ('alert' === eventType) {
535 | msg.params.message =
536 | ('string' === typeof msg.params.message)
537 | ? msg.params.message.replace(/<\/?[^>]+>/gi, '')
538 | : '';
539 | }
540 |
541 | this.trigger(eventType, msg.params);
542 | }
543 |
544 | }
545 | }
546 |
547 | XPaymentsWidget.prototype._isDebugMode = function()
548 | {
549 | return this.config.debug;
550 | }
551 |
552 | XPaymentsWidget.prototype._log = function(msg, params)
553 | {
554 | if (this._isDebugMode()) {
555 | if ('undefined' !== typeof params) {
556 | msg = msg + "\n" + JSON.stringify(params);
557 | }
558 | console.log(msg);
559 | }
560 | }
561 |
562 | XPaymentsWidget.prototype._sendEvent = function(eventName, eventParams)
563 | {
564 | if ('undefined' === typeof eventParams) {
565 | eventParams = {};
566 | }
567 |
568 | this._postMessage({
569 | event: this.receiverNamespace + eventName,
570 | params: eventParams
571 | })
572 | }
573 |
574 | XPaymentsWidget.prototype._postMessage = function(message)
575 | {
576 | var elm = this.getIframeElm();
577 | if (
578 | window.postMessage
579 | && window.JSON
580 | && elm
581 | && elm.contentWindow
582 | ) {
583 | this._log('Sent to X-Payments: ' + message.event, message.params);
584 | elm.contentWindow.postMessage(window.JSON.stringify(message), '*');
585 | } else {
586 | this._log('Error sending message - iframe wasn\'t initialized!');
587 | }
588 | }
589 |
--------------------------------------------------------------------------------