diff --git a/.phpcs.xml b/.phpcs.xml
index 6118f7a..aab5a6c 100644
--- a/.phpcs.xml
+++ b/.phpcs.xml
@@ -5,4 +5,6 @@
*/vendor/*
+ *.min.js
+ *.min.css
diff --git a/.pronto.yml b/.pronto.yml
deleted file mode 100644
index 752c7a0..0000000
--- a/.pronto.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-github:
- slug: eMerchantPay/opencart4-emp-plugin
- access_token: ENV['PRONTO_GITHUB_ACCESS_TOKEN']
- api_endpoint: ENV['PRONTO_GITHUB_API_ENDPOINT']
- web_endpoint: ENV['PRONTO_GITHUB_WEB_ENDPOINT']
-verbose: false
diff --git a/Gemfile b/Gemfile
deleted file mode 100644
index 5f29bc2..0000000
--- a/Gemfile
+++ /dev/null
@@ -1,6 +0,0 @@
-source 'http://rubygems.org'
-
-# code analysis
-gem 'pronto', '~> 0.9.5'
-gem 'pronto-phpcs', '~> 0.4.0', require: false
-gem 'pronto-phpmd', '~> 0.4.0', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
deleted file mode 100644
index 925f5be..0000000
--- a/Gemfile.lock
+++ /dev/null
@@ -1,53 +0,0 @@
-GEM
- remote: http://rubygems.org/
- specs:
- addressable (2.8.1)
- public_suffix (>= 2.0.2, < 6.0)
- faraday (1.0.1)
- multipart-post (>= 1.2, < 3)
- gitlab (4.14.0)
- httparty (~> 0.14, >= 0.14.0)
- terminal-table (~> 1.5, >= 1.5.1)
- httparty (0.21.0)
- mini_mime (>= 1.0.0)
- multi_xml (>= 0.5.2)
- mini_mime (1.1.2)
- multi_xml (0.6.0)
- multipart-post (2.3.0)
- octokit (4.25.1)
- faraday (>= 1, < 3)
- sawyer (~> 0.9)
- pronto (0.9.5)
- gitlab (~> 4.0, >= 4.0.0)
- httparty (>= 0.13.7)
- octokit (~> 4.7, >= 4.7.0)
- rainbow (~> 2.1)
- rugged (~> 0.24, >= 0.23.0)
- thor (~> 0.19.0)
- pronto-phpcs (0.4.0)
- pronto (~> 0.9.0)
- pronto-phpmd (0.4.0)
- pronto (~> 0.9.0)
- public_suffix (4.0.7)
- rainbow (2.2.2)
- rake
- rake (13.0.6)
- rugged (0.99.0)
- sawyer (0.9.2)
- addressable (>= 2.3.5)
- faraday (>= 0.17.3, < 3)
- terminal-table (1.8.0)
- unicode-display_width (~> 1.1, >= 1.1.1)
- thor (0.19.4)
- unicode-display_width (1.8.0)
-
-PLATFORMS
- ruby
-
-DEPENDENCIES
- pronto (~> 0.9.5)
- pronto-phpcs (~> 0.4.0)
- pronto-phpmd (~> 0.4.0)
-
-BUNDLED WITH
- 1.17.3
diff --git a/README.md b/README.md
index 54d234f..679b124 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Requirements
------------
* OpenCart 4.0.2.X (due to architectural changes, this module is __incompatible__ with older OpenCart versions)
-* [GenesisPHP v1.24.0](https://github.com/GenesisGateway/genesis_php/tree/1.24.0) - (Integrated in Module)
+* [GenesisPHP v1.24.2](https://github.com/GenesisGateway/genesis_php/tree/1.24.2) - (Integrated in Module)
* PCI-certified server in order to use ```emerchantpay Direct```
GenesisPHP Requirements
diff --git a/admin/controller/payment/emerchantpay_direct.php b/admin/controller/payment/emerchantpay_direct.php
index 45bf787..51e2d5a 100644
--- a/admin/controller/payment/emerchantpay_direct.php
+++ b/admin/controller/payment/emerchantpay_direct.php
@@ -66,7 +66,7 @@ protected function validate(): bool
{
parent::validate();
- if (@empty($this->request->post["{$this->module_name}_token"])) {
+ if (empty($this->request->post["{$this->module_name}_token"])) {
$this->error['token'] = $this->language->get('error_token');
}
diff --git a/admin/language/en-gb/payment/emerchantpay_checkout.php b/admin/language/en-gb/payment/emerchantpay_checkout.php
index 4a435a5..d8279b4 100644
--- a/admin/language/en-gb/payment/emerchantpay_checkout.php
+++ b/admin/language/en-gb/payment/emerchantpay_checkout.php
@@ -37,30 +37,34 @@
$_['text_select_status'] = 'Select Status';
// Entry
-$_['entry_username'] = 'Genesis Username';
-$_['entry_password'] = 'Genesis Password';
-$_['entry_token'] = 'Genesis Token';
-$_['entry_sandbox'] = 'Test Mode';
-$_['entry_transaction_type'] = 'Transaction Types';
-$_['entry_wpf_tokenization'] = 'WPF Tokenization Enabled';
-$_['entry_supports_partial_capture'] = 'Partial Capture';
-$_['entry_supports_partial_refund'] = 'Partial Refund';
-$_['entry_supports_void'] = 'Cancel Transaction';
-$_['entry_total'] = 'Total';
-$_['entry_order_status'] = 'Order Status';
-$_['entry_order_status_failure'] = 'Order Status (Failed)';
-$_['entry_geo_zone'] = 'Geo Zone';
-$_['entry_status'] = 'Status';
-$_['entry_debug'] = 'Error Logging';
-$_['entry_sort_order'] = 'Sort Order';
-$_['entry_supports_recurring'] = 'Recurring Payments';
-$_['entry_recurring_transaction_type'] = 'Recurring Transaction Types';
-$_['entry_recurring_log'] = 'Recurring Log';
-$_['entry_recurring_token'] = 'Recurring Token';
-$_['entry_cron_time_limit'] = 'Processing time for re-billing';
-$_['entry_cron_allowed_ip'] = 'IP address';
-$_['entry_cron_last_execution'] = 'Cron/schtasks last execution';
-$_['entry_bank_codes'] = 'Bank code(s) for Online banking';
+$_['entry_username'] = 'Genesis Username';
+$_['entry_password'] = 'Genesis Password';
+$_['entry_token'] = 'Genesis Token';
+$_['entry_sandbox'] = 'Test Mode';
+$_['entry_transaction_type'] = 'Transaction Types';
+$_['entry_wpf_tokenization'] = 'WPF Tokenization Enabled';
+$_['entry_supports_partial_capture'] = 'Partial Capture';
+$_['entry_supports_partial_refund'] = 'Partial Refund';
+$_['entry_supports_void'] = 'Cancel Transaction';
+$_['entry_total'] = 'Total';
+$_['entry_order_status'] = 'Order Status';
+$_['entry_order_status_failure'] = 'Order Status (Failed)';
+$_['entry_geo_zone'] = 'Geo Zone';
+$_['entry_status'] = 'Status';
+$_['entry_debug'] = 'Error Logging';
+$_['entry_sort_order'] = 'Sort Order';
+$_['entry_supports_recurring'] = 'Recurring Payments';
+$_['entry_recurring_transaction_type'] = 'Recurring Transaction Types';
+$_['entry_recurring_log'] = 'Recurring Log';
+$_['entry_recurring_token'] = 'Recurring Token';
+$_['entry_cron_time_limit'] = 'Processing time for re-billing';
+$_['entry_cron_allowed_ip'] = 'IP address';
+$_['entry_cron_last_execution'] = 'Cron/schtasks last execution';
+$_['entry_bank_codes'] = 'Bank code(s) for Online banking';
+$_['entry_threeds_allowed'] = 'Enable 3DSv2';
+$_['entry_threeds_challenge_indicator'] = '3DSv2 Challenge';
+$_['entry_sca_exemption'] = 'SCA Exemption';
+$_['entry_sca_exemption_amount'] = 'Exemption Amount';
// Transaction Types
//$_ = array_merge($_, EmerchantpayHelper::getTransactionTypeNames());
@@ -138,6 +142,10 @@
$_['help_cron_time_limit'] = 'Тhe total time in seconds allowed for re-billing recurring orders in a single execution of the cron / schtasks. If there is a re-billing in process while reaching this limit, it will try to continue and respectively the execution time will exceed the allowed time.';
$_['help_cron_allowed_ip'] = 'The IP address allowed to send HTTP requests to the cron-handling URLs.';
$_['help_cron_last_execution'] = 'The time the cron / schtasks was last executed.';
+$_['help_threeds_allowed'] = 'Enable 3DSv2 optional parameters.';
+$_['help_threeds_challenge_indicator'] = 'The value has weight and might impact the decision whether a challenge will be required for the transaction or not.';
+$_['help_sca_exemption'] = 'Exemption for the Strong Customer Authentication.';
+$_['help_sca_exemption_amount'] = 'Exemption Amount determinate if the SCA Exemption should be included in the request to the Gateway.';
// Error
$_['error_permission'] = 'Warning: You do not have permission to modify payment module emerchantpay!';
@@ -147,6 +155,7 @@
$_['error_controls_invalidated'] = 'Warning: You have to fill-in all the required fields';
$_['error_order_status'] = 'Order Status is Required';
$_['error_order_failure_status'] = 'Order Status (Failed) is Required';
+$_['error_sca_exemption_amount'] = 'SCA Exemption amount must have positive value';
//Alert
$_['alert_disable_recurring'] = 'Warning: Disabling the Recurring Payments disables placing new recurring orders. It does not disable the re-billing of the existing ones.';
diff --git a/admin/language/en-gb/payment/emerchantpay_direct.php b/admin/language/en-gb/payment/emerchantpay_direct.php
index 657202f..ac322ba 100644
--- a/admin/language/en-gb/payment/emerchantpay_direct.php
+++ b/admin/language/en-gb/payment/emerchantpay_direct.php
@@ -61,6 +61,10 @@
$_['entry_cron_time_limit'] = 'Processing time for re-billing';
$_['entry_cron_allowed_ip'] = 'IP address';
$_['entry_cron_last_execution'] = 'Cron/schtasks last execution';
+$_['entry_threeds_allowed'] = 'Enable 3DSv2';
+$_['entry_threeds_challenge_indicator'] = '3DSv2 Challenge';
+$_['entry_sca_exemption'] = 'SCA Exemption';
+$_['entry_sca_exemption_amount'] = 'Exemption Amount';
// Transaction Types
//$_ = array_merge($_, EmerchantpayHelper::getTransactionTypeNames());
@@ -138,6 +142,10 @@
$_['help_cron_time_limit'] = 'Тhe total time in seconds allowed for re-billing recurring orders in a single execution of the cron / schtasks. If there is a re-billing in process while reaching this limit, it will try to continue and respectively the actual the execution time will exceed the allowed time.';
$_['help_cron_allowed_ip'] = 'The IP address allowed to send HTTP requests to the cron-handling URLs.';
$_['help_cron_last_execution'] = 'The time the cron / schtasks was last executed.';
+$_['help_threeds_allowed'] = 'Enable 3DSv2 optional parameters.';
+$_['help_threeds_challenge_indicator'] = 'The value has weight and might impact the decision whether a challenge will be required for the transaction or not.';
+$_['help_sca_exemption'] = 'Exemption for the Strong Customer Authentication.';
+$_['help_sca_exemption_amount'] = 'Exemption Amount determinate if the SCA Exemption should be included in the request to the Gateway.';
// Error
$_['error_permission'] = 'Warning: You do not have permission to modify payment module emerchantpay!';
@@ -150,6 +158,7 @@
$_['error_order_status'] = 'Order Status is Required';
$_['error_order_failure_status'] = 'Order Status (Failed) is Required';
$_['error_async_order_status'] = 'Order Status (Async) is Required';
+$_['error_sca_exemption_amount'] = 'SCA Exemption amount must have positive value';
//Alert
$_['alert_disable_recurring'] = 'Warning: Disabling the Recurring Payments disables placing new recurring orders. It does not disable the re-billing of the existing ones.';
diff --git a/admin/model/payment/emerchantpay/base_model.php b/admin/model/payment/emerchantpay/base_model.php
new file mode 100644
index 0000000..30fefe2
--- /dev/null
+++ b/admin/model/payment/emerchantpay/base_model.php
@@ -0,0 +1,62 @@
+ 'Low risk',
+ ScaExemptions::EXEMPTION_LOW_VALUE => 'Low value',
+ ];
+
+ foreach ($sca_exemptions as $value => $label) {
+ $data[] = [
+ 'id' => $value,
+ 'name' => $label
+ ];
+ }
+
+ return $data;
+ }
+}
diff --git a/admin/model/payment/emerchantpay_checkout.php b/admin/model/payment/emerchantpay_checkout.php
index a1108f2..ec827d4 100644
--- a/admin/model/payment/emerchantpay_checkout.php
+++ b/admin/model/payment/emerchantpay_checkout.php
@@ -30,27 +30,19 @@
use Genesis\API\Request\Financial\Alternatives\Klarna\Items as KlarnaItems;
use Genesis\Config;
use Genesis\Genesis;
+use Opencart\Admin\Model\Extension\Emerchantpay\Payment\emerchantpay\BaseModel;
use Opencart\Extension\Emerchantpay\System\DbHelper;
use Opencart\Extension\Emerchantpay\System\EmerchantpayHelper;
-use Opencart\System\Engine\Model;
/**
* Backend model for the "emerchantpay Checkout" module
*
* @package EMerchantpayCheckout
*/
-class EmerchantpayCheckout extends Model
+class EmerchantpayCheckout extends BaseModel
{
protected $module_name = 'emerchantpay_checkout';
- /**
- * Holds the current module version
- * Will be displayed on Admin Settings Form
- *
- * @var string
- */
- protected $module_version = '1.1.3';
-
/**
* Perform installation logic
*
@@ -70,7 +62,7 @@ public function install(): void
`message` VARCHAR(255) NULL,
`technical_message` VARCHAR(255) NULL,
`terminal_token` VARCHAR(255) NULL,
- `amount` DECIMAL( 10, 2 ) DEFAULT NULL,
+ `amount` DECIMAL( 15, 4 ) DEFAULT NULL,
`currency` CHAR(3) NULL,
PRIMARY KEY (`unique_id`)
) ENGINE=InnoDB DEFAULT COLLATE=utf8_general_ci;
@@ -243,7 +235,7 @@ public function capture($type, $reference_id, $amount, $currency, $usage, $order
$this->genTransactionId('ocart-')
)
->setRemoteIp(
- $this->request->server['REMOTE_ADDR']
+ EmerchantpayHelper::getFirstRemoteAddress($this->request->server['REMOTE_ADDR'])
)
->setUsage($usage)
->setReferenceId($reference_id)
@@ -292,7 +284,7 @@ public function refund($type, $reference_id, $amount, $currency, $usage = '', $t
$this->genTransactionId('ocart-')
)
->setRemoteIp(
- $this->request->server['REMOTE_ADDR']
+ EmerchantpayHelper::getFirstRemoteAddress($this->request->server['REMOTE_ADDR'])
)
->setUsage($usage)
->setReferenceId($reference_id)
@@ -335,7 +327,7 @@ public function void($reference_id, $usage = '', $token = null): object|string
$this->genTransactionId('ocart-')
)
->setRemoteIp(
- $this->request->server['REMOTE_ADDR']
+ EmerchantpayHelper::getFirstRemoteAddress($this->request->server['REMOTE_ADDR'])
)
->setUsage($usage)
->setReferenceId($reference_id);
diff --git a/admin/model/payment/emerchantpay_direct.php b/admin/model/payment/emerchantpay_direct.php
index 804fb4d..7a05e8e 100644
--- a/admin/model/payment/emerchantpay_direct.php
+++ b/admin/model/payment/emerchantpay_direct.php
@@ -25,27 +25,19 @@
use Genesis\API\Constants\Transaction\Types;
use Genesis\Config;
use Genesis\Genesis;
+use Opencart\Admin\Model\Extension\Emerchantpay\Payment\emerchantpay\BaseModel;
use Opencart\Extension\Emerchantpay\System\DbHelper;
use Opencart\Extension\Emerchantpay\System\EmerchantpayHelper;
-use Opencart\System\Engine\Model;
/**
* Backend model for the "emerchantpay Direct" module
*
* @package EMerchantpayDirect
*/
-class EmerchantpayDirect extends Model
+class EmerchantpayDirect extends BaseModel
{
protected $module_name = "emerchantpay_direct";
- /**
- * Holds the current module version
- * Will be displayed on Admin Settings Form
- *
- * @var string
- */
- protected $module_version = '1.1.3';
-
/**
* Perform installation logic
*
@@ -64,7 +56,7 @@ public function install(): void
`status` CHAR(32) NOT NULL,
`message` VARCHAR(255) NULL,
`technical_message` VARCHAR(255) NULL,
- `amount` DECIMAL( 10, 2 ) DEFAULT NULL,
+ `amount` DECIMAL( 15, 4 ) DEFAULT NULL,
`currency` CHAR(3) NULL,
PRIMARY KEY (`unique_id`)
) ENGINE=InnoDB DEFAULT COLLATE=utf8_general_ci;
@@ -224,7 +216,7 @@ public function capture($type, $reference_id, $amount, $currency, $usage): objec
$this->genTransactionId('ocart-')
)
->setRemoteIp(
- $this->request->server['REMOTE_ADDR']
+ EmerchantpayHelper::getFirstRemoteAddress($this->request->server['REMOTE_ADDR'])
)
->setUsage($usage)
->setReferenceId($reference_id)
@@ -266,7 +258,7 @@ public function refund($type, $reference_id, $amount, $currency, $usage = ''): o
$this->genTransactionId('ocart-')
)
->setRemoteIp(
- $this->request->server['REMOTE_ADDR']
+ EmerchantpayHelper::getFirstRemoteAddress($this->request->server['REMOTE_ADDR'])
)
->setUsage($usage)
->setReferenceId($reference_id)
@@ -304,7 +296,7 @@ public function void($reference_id, $usage = ''): object|string
$this->genTransactionId('ocart-')
)
->setRemoteIp(
- $this->request->server['REMOTE_ADDR']
+ EmerchantpayHelper::getFirstRemoteAddress($this->request->server['REMOTE_ADDR'])
)
->setUsage($usage)
->setReferenceId($reference_id);
diff --git a/admin/view/javascript/emerchantpay/treegrid/js/jquery.treegrid.js b/admin/view/javascript/emerchantpay/treegrid/js/jquery.treegrid.js
index 1785e53..600f231 100644
--- a/admin/view/javascript/emerchantpay/treegrid/js/jquery.treegrid.js
+++ b/admin/view/javascript/emerchantpay/treegrid/js/jquery.treegrid.js
@@ -1,619 +1,619 @@
-/*
- * jQuery treegrid Plugin 0.2.0
- * https://github.com/maxazan/jquery-treegrid
- *
- * Copyright 2013, Pomazan Max
- * Licensed under the MIT licenses.
- */
-(function($) {
-
- var methods = {
- /**
- * Initialize tree
- *
- * @param {Object} options
- * @returns {Object[]}
- */
- initTree: function(options) {
- var settings = $.extend({}, this.treegrid.defaults, options);
- return this.each(function() {
- var $this = $(this);
- $this.treegrid('setTreeContainer', $(this));
- $this.treegrid('setSettings', settings);
- settings.getRootNodes.apply(this, [$(this)]).treegrid('initNode', settings);
- });
- },
- /**
- * Initialize node
- *
- * @param {Object} settings
- * @returns {Object[]}
- */
- initNode: function(settings) {
- return this.each(function() {
- var $this = $(this);
- $this.treegrid('setTreeContainer', settings.getTreeGridContainer.apply(this));
- $this.treegrid('getChildNodes').treegrid('initNode', settings);
- $this.treegrid('initExpander').treegrid('initIndent').treegrid('initEvents').treegrid('initState').treegrid("initSettingsEvents");
- });
- },
- /**
- * Initialize node events
- *
- * @returns {Node}
- */
- initEvents: function() {
- var $this = $(this);
- //Save state on change
- $this.on("change", function() {
- var $this = $(this);
- $this.treegrid('render');
- if ($this.treegrid('getSetting', 'saveState')) {
- $this.treegrid('saveState');
- }
- });
- //Default behavior on collapse
- $this.on("collapse", function() {
- var $this = $(this);
- $this.removeClass('treegrid-expanded');
- $this.addClass('treegrid-collapsed');
- });
- //Default behavior on expand
- $this.on("expand", function() {
- var $this = $(this);
- $this.removeClass('treegrid-collapsed');
- $this.addClass('treegrid-expanded');
- });
-
- return $this;
- },
- /**
- * Initialize events from settings
- *
- * @returns {Node}
- */
- initSettingsEvents: function() {
- var $this = $(this);
- //Save state on change
- $this.on("change", function() {
- var $this = $(this);
- if (typeof ($this.treegrid('getSetting', 'onChange')) === "function") {
- $this.treegrid('getSetting', 'onChange').apply($this);
- }
- });
- //Default behavior on collapse
- $this.on("collapse", function() {
- var $this = $(this);
- if (typeof ($this.treegrid('getSetting', 'onCollapse')) === "function") {
- $this.treegrid('getSetting', 'onCollapse').apply($this);
- }
- });
- //Default behavior on expand
- $this.on("expand", function() {
- var $this = $(this);
- if (typeof ($this.treegrid('getSetting', 'onExpand')) === "function") {
- $this.treegrid('getSetting', 'onExpand').apply($this);
- }
-
- });
-
- return $this;
- },
- /**
- * Initialize expander for node
- *
- * @returns {Node}
- */
- initExpander: function() {
- var $this = $(this);
- var cell = $this.find('td').get($this.treegrid('getSetting', 'treeColumn'));
- var tpl = $this.treegrid('getSetting', 'expanderTemplate');
- var expander = $this.treegrid('getSetting', 'getExpander').apply(this);
- if (expander) {
- expander.remove();
- }
- $(tpl).prependTo(cell).click(function() {
- $($(this).closest('tr')).treegrid('toggle');
- });
- return $this;
- },
- /**
- * Initialize indent for node
- *
- * @returns {Node}
- */
- initIndent: function() {
- var $this = $(this);
- $this.find('.treegrid-indent').remove();
- for (var i = 0; i < $(this).treegrid('getDepth'); i++) {
- $($this.treegrid('getSetting', 'indentTemplate')).insertBefore($this.find('.treegrid-expander'));
- }
- return $this;
- },
- /**
- * Initialise state of node
- *
- * @returns {Node}
- */
- initState: function() {
- var $this = $(this);
- if ($this.treegrid('getSetting', 'saveState') && !$this.treegrid('isFirstInit')) {
- $this.treegrid('restoreState');
- } else {
- if ($this.treegrid('getSetting', 'initialState') === "expanded") {
- $this.treegrid('expand');
- } else {
- $this.treegrid('collapse');
- }
- }
- return $this;
- },
- /**
- * Return true if this tree was never been initialised
- *
- * @returns {Boolean}
- */
- isFirstInit: function() {
- var tree = $(this).treegrid('getTreeContainer');
- if (tree.data('first_init') === undefined) {
- tree.data('first_init', $.cookie(tree.treegrid('getSetting', 'saveStateName')) === undefined);
- }
- return tree.data('first_init');
- },
- /**
- * Save state of current node
- *
- * @returns {Node}
- */
- saveState: function() {
- var $this = $(this);
- if ($this.treegrid('getSetting', 'saveStateMethod') === 'cookie') {
-
- var stateArrayString = $.cookie($this.treegrid('getSetting', 'saveStateName')) || '';
- var stateArray = (stateArrayString === '' ? [] : stateArrayString.split(','));
- var nodeId = $this.treegrid('getNodeId');
-
- if ($this.treegrid('isExpanded')) {
- if ($.inArray(nodeId, stateArray) === -1) {
- stateArray.push(nodeId);
- }
- } else if ($this.treegrid('isCollapsed')) {
- if ($.inArray(nodeId, stateArray) !== -1) {
- stateArray.splice($.inArray(nodeId, stateArray), 1);
- }
- }
- $.cookie($this.treegrid('getSetting', 'saveStateName'), stateArray.join(','));
- }
- return $this;
- },
- /**
- * Restore state of current node.
- *
- * @returns {Node}
- */
- restoreState: function() {
- var $this = $(this);
- if ($this.treegrid('getSetting', 'saveStateMethod') === 'cookie') {
- var stateArray = $.cookie($this.treegrid('getSetting', 'saveStateName')).split(',');
- if ($.inArray($this.treegrid('getNodeId'), stateArray) !== -1) {
- $this.treegrid('expand');
- } else {
- $this.treegrid('collapse');
- }
-
- }
- return $this;
- },
- /**
- * Method return setting by name
- *
- * @param {type} name
- * @returns {unresolved}
- */
- getSetting: function(name) {
- if (!$(this).treegrid('getTreeContainer')) {
- return null;
- }
- return $(this).treegrid('getTreeContainer').data('settings')[name];
- },
- /**
- * Add new settings
- *
- * @param {Object} settings
- */
- setSettings: function(settings) {
- $(this).treegrid('getTreeContainer').data('settings', settings);
- },
- /**
- * Return tree container
- *
- * @returns {HtmlElement}
- */
- getTreeContainer: function() {
- return $(this).data('treegrid');
- },
- /**
- * Set tree container
- *
- * @param {HtmlE;ement} container
- */
- setTreeContainer: function(container) {
- return $(this).data('treegrid', container);
- },
- /**
- * Method return all root nodes of tree.
- *
- * Start init all child nodes from it.
- *
- * @returns {Array}
- */
- getRootNodes: function() {
- return $(this).treegrid('getSetting', 'getRootNodes').apply(this, [$(this).treegrid('getTreeContainer')]);
- },
- /**
- * Method return all nodes of tree.
- *
- * @returns {Array}
- */
- getAllNodes: function() {
- return $(this).treegrid('getSetting', 'getAllNodes').apply(this, [$(this).treegrid('getTreeContainer')]);
- },
- /**
- * Mthod return true if element is Node
- *
- * @returns {String}
- */
- isNode: function() {
- return $(this).treegrid('getNodeId') !== null;
- },
- /**
- * Mthod return id of node
- *
- * @returns {String}
- */
- getNodeId: function() {
- if ($(this).treegrid('getSetting', 'getNodeId') === null) {
- return null;
- } else {
- return $(this).treegrid('getSetting', 'getNodeId').apply(this);
- }
- },
- /**
- * Method return parent id of node or null if root node
- *
- * @returns {String}
- */
- getParentNodeId: function() {
- return $(this).treegrid('getSetting', 'getParentNodeId').apply(this);
- },
- /**
- * Method return parent node or null if root node
- *
- * @returns {Object[]}
- */
- getParentNode: function() {
- if ($(this).treegrid('getParentNodeId') === null) {
- return null;
- } else {
- return $(this).treegrid('getSetting', 'getNodeById').apply(this, [$(this).treegrid('getParentNodeId'), $(this).treegrid('getTreeContainer')]);
- }
- },
- /**
- * Method return array of child nodes or null if node is leaf
- *
- * @returns {Object[]}
- */
- getChildNodes: function() {
- return $(this).treegrid('getSetting', 'getChildNodes').apply(this, [$(this).treegrid('getNodeId'), $(this).treegrid('getTreeContainer')]);
- },
- /**
- * Method return depth of tree.
- *
- * This method is needs for calculate indent
- *
- * @returns {Number}
- */
- getDepth: function() {
- if ($(this).treegrid('getParentNode') === null) {
- return 0;
- }
- return $(this).treegrid('getParentNode').treegrid('getDepth') + 1;
- },
- /**
- * Method return true if node is root
- *
- * @returns {Boolean}
- */
- isRoot: function() {
- return $(this).treegrid('getDepth') === 0;
- },
- /**
- * Method return true if node has no child nodes
- *
- * @returns {Boolean}
- */
- isLeaf: function() {
- return $(this).treegrid('getChildNodes').length === 0;
- },
- /**
- * Method return true if node last in branch
- *
- * @returns {Boolean}
- */
- isLast: function() {
- if ($(this).treegrid('isNode')) {
- var parentNode = $(this).treegrid('getParentNode');
- if (parentNode === null) {
- if ($(this).treegrid('getNodeId') === $(this).treegrid('getRootNodes').last().treegrid('getNodeId')) {
- return true;
- }
- } else {
- if ($(this).treegrid('getNodeId') === parentNode.treegrid('getChildNodes').last().treegrid('getNodeId')) {
- return true;
- }
- }
- }
- return false;
- },
- /**
- * Method return true if node first in branch
- *
- * @returns {Boolean}
- */
- isFirst: function() {
- if ($(this).treegrid('isNode')) {
- var parentNode = $(this).treegrid('getParentNode');
- if (parentNode === null) {
- if ($(this).treegrid('getNodeId') === $(this).treegrid('getRootNodes').first().treegrid('getNodeId')) {
- return true;
- }
- } else {
- if ($(this).treegrid('getNodeId') === parentNode.treegrid('getChildNodes').first().treegrid('getNodeId')) {
- return true;
- }
- }
- }
- return false;
- },
- /**
- * Return true if node expanded
- *
- * @returns {Boolean}
- */
- isExpanded: function() {
- return $(this).hasClass('treegrid-expanded');
- },
- /**
- * Return true if node collapsed
- *
- * @returns {Boolean}
- */
- isCollapsed: function() {
- return $(this).hasClass('treegrid-collapsed');
- },
- /**
- * Return true if at least one of parent node is collapsed
- *
- * @returns {Boolean}
- */
- isOneOfParentsCollapsed: function() {
- var $this = $(this);
- if ($this.treegrid('isRoot')) {
- return false;
- } else {
- if ($this.treegrid('getParentNode').treegrid('isCollapsed')) {
- return true;
- } else {
- return $this.treegrid('getParentNode').treegrid('isOneOfParentsCollapsed');
- }
- }
- },
- /**
- * Expand node
- *
- * @returns {Node}
- */
- expand: function() {
- return $(this).each(function() {
- var $this = $(this);
- if (!$this.treegrid('isLeaf') && !$this.treegrid("isExpanded")) {
- $this.trigger("expand");
- $this.trigger("change");
- }
- });
- },
- /**
- * Expand all nodes
- *
- * @returns {Node}
- */
- expandAll: function() {
- var $this = $(this);
- $this.treegrid('getRootNodes').treegrid('expandRecursive');
- return $this;
- },
- /**
- * Expand current node and all child nodes begin from current
- *
- * @returns {Node}
- */
- expandRecursive: function() {
- return $(this).each(function() {
- var $this = $(this);
- $this.treegrid('expand');
- if (!$this.treegrid('isLeaf')) {
- $this.treegrid('getChildNodes').treegrid('expandRecursive');
- }
- });
- },
- /**
- * Collapse node
- *
- * @returns {Node}
- */
- collapse: function() {
- return $(this).each(function() {
- var $this = $(this);
- if (!$this.treegrid('isLeaf') && !$this.treegrid("isCollapsed")) {
- $this.trigger("collapse");
- $this.trigger("change");
- }
- });
- },
- /**
- * Collapse all nodes
- *
- * @returns {Node}
- */
- collapseAll: function() {
- var $this = $(this);
- $this.treegrid('getRootNodes').treegrid('collapseRecursive');
- return $this;
- },
- /**
- * Collapse current node and all child nodes begin from current
- *
- * @returns {Node}
- */
- collapseRecursive: function() {
- return $(this).each(function() {
- var $this = $(this);
- $this.treegrid('collapse');
- if (!$this.treegrid('isLeaf')) {
- $this.treegrid('getChildNodes').treegrid('collapseRecursive');
- }
- });
- },
- /**
- * Expand if collapsed, Collapse if expanded
- *
- * @returns {Node}
- */
- toggle: function() {
- var $this = $(this);
- if ($this.treegrid('isExpanded')) {
- $this.treegrid('collapse');
- } else {
- $this.treegrid('expand');
- }
- return $this;
- },
- /**
- * Rendering node
- *
- * @returns {Node}
- */
- render: function() {
- return $(this).each(function() {
- var $this = $(this);
-
- if ($this.treegrid('isOneOfParentsCollapsed')) {
- $this.hide();
- } else {
- $this.show();
- }
- if (!$this.treegrid('isLeaf')) {
- $this.treegrid('renderExpander');
- $this.treegrid('getChildNodes').treegrid('render');
- }
- });
- },
- /**
- * Rendering expander depends on node state
- *
- * @returns {Node}
- */
- renderExpander: function() {
- return $(this).each(function() {
- var $this = $(this);
- var expander = $this.treegrid('getSetting', 'getExpander').apply(this);
- if (expander) {
-
- if (!$this.treegrid('isCollapsed')) {
- expander.removeClass($this.treegrid('getSetting', 'expanderCollapsedClass'));
- expander.addClass($this.treegrid('getSetting', 'expanderExpandedClass'));
- } else {
- expander.removeClass($this.treegrid('getSetting', 'expanderExpandedClass'));
- expander.addClass($this.treegrid('getSetting', 'expanderCollapsedClass'));
- }
- } else {
- $this.treegrid('initExpander');
- $this.treegrid('renderExpander');
- }
- });
- }
- };
- $.fn.treegrid = function(method) {
- if (methods[method]) {
- return methods[ method ].apply(this, Array.prototype.slice.call(arguments, 1));
- } else if (typeof method === 'object' || !method) {
- return methods.initTree.apply(this, arguments);
- } else {
- $.error('Method with name ' + method + ' does not exists for jQuery.treegrid');
- }
- };
- /**
- * Plugin's default options
- */
- $.fn.treegrid.defaults = {
- initialState: 'expanded',
- saveState: false,
- saveStateMethod: 'cookie',
- saveStateName: 'tree-grid-state',
- expanderTemplate: '',
- indentTemplate: '',
- expanderExpandedClass: 'treegrid-expander-expanded',
- expanderCollapsedClass: 'treegrid-expander-collapsed',
- treeColumn: 0,
- getExpander: function() {
- return $(this).find('.treegrid-expander');
- },
- getNodeId: function() {
- var template = /treegrid-([A-Za-z0-9_-]+)/;
- if (template.test($(this).attr('class'))) {
- return template.exec($(this).attr('class'))[1];
- }
- return null;
- },
- getParentNodeId: function() {
- var template = /treegrid-parent-([A-Za-z0-9_-]+)/;
- if (template.test($(this).attr('class'))) {
- return template.exec($(this).attr('class'))[1];
- }
- return null;
- },
- getNodeById: function(id, treegridContainer) {
- var templateClass = "treegrid-" + id;
- return treegridContainer.find('tr.' + templateClass);
- },
- getChildNodes: function(id, treegridContainer) {
- var templateClass = "treegrid-parent-" + id;
- return treegridContainer.find('tr.' + templateClass);
- },
- getTreeGridContainer: function() {
- return $(this).closest('table');
- },
- getRootNodes: function(treegridContainer) {
- var result = $.grep(treegridContainer.find('tr'), function(element) {
- var classNames = $(element).attr('class');
- var templateClass = /treegrid-([A-Za-z0-9_-]+)/;
- var templateParentClass = /treegrid-parent-([A-Za-z0-9_-]+)/;
- return templateClass.test(classNames) && !templateParentClass.test(classNames);
- });
- return $(result);
- },
- getAllNodes: function(treegridContainer) {
- var result = $.grep(treegridContainer.find('tr'), function(element) {
- var classNames = $(element).attr('class');
- var templateClass = /treegrid-([A-Za-z0-9_-]+)/;
- return templateClass.test(classNames);
- });
- return $(result);
- },
- //Events
- onCollapse: null,
- onExpand: null,
- onChange: null
-
- };
+/*
+ * jQuery treegrid Plugin 0.2.0
+ * https://github.com/maxazan/jquery-treegrid
+ *
+ * Copyright 2013, Pomazan Max
+ * Licensed under the MIT licenses.
+ */
+(function($) {
+
+ var methods = {
+ /**
+ * Initialize tree
+ *
+ * @param {Object} options
+ * @returns {Object[]}
+ */
+ initTree: function(options) {
+ var settings = $.extend({}, this.treegrid.defaults, options);
+ return this.each(function() {
+ var $this = $(this);
+ $this.treegrid('setTreeContainer', $(this));
+ $this.treegrid('setSettings', settings);
+ settings.getRootNodes.apply(this, [$(this)]).treegrid('initNode', settings);
+ });
+ },
+ /**
+ * Initialize node
+ *
+ * @param {Object} settings
+ * @returns {Object[]}
+ */
+ initNode: function(settings) {
+ return this.each(function() {
+ var $this = $(this);
+ $this.treegrid('setTreeContainer', settings.getTreeGridContainer.apply(this));
+ $this.treegrid('getChildNodes').treegrid('initNode', settings);
+ $this.treegrid('initExpander').treegrid('initIndent').treegrid('initEvents').treegrid('initState').treegrid("initSettingsEvents");
+ });
+ },
+ /**
+ * Initialize node events
+ *
+ * @returns {Node}
+ */
+ initEvents: function() {
+ var $this = $(this);
+ //Save state on change
+ $this.on("change", function() {
+ var $this = $(this);
+ $this.treegrid('render');
+ if ($this.treegrid('getSetting', 'saveState')) {
+ $this.treegrid('saveState');
+ }
+ });
+ //Default behavior on collapse
+ $this.on("collapse", function() {
+ var $this = $(this);
+ $this.removeClass('treegrid-expanded');
+ $this.addClass('treegrid-collapsed');
+ });
+ //Default behavior on expand
+ $this.on("expand", function() {
+ var $this = $(this);
+ $this.removeClass('treegrid-collapsed');
+ $this.addClass('treegrid-expanded');
+ });
+
+ return $this;
+ },
+ /**
+ * Initialize events from settings
+ *
+ * @returns {Node}
+ */
+ initSettingsEvents: function() {
+ var $this = $(this);
+ //Save state on change
+ $this.on("change", function() {
+ var $this = $(this);
+ if (typeof ($this.treegrid('getSetting', 'onChange')) === "function") {
+ $this.treegrid('getSetting', 'onChange').apply($this);
+ }
+ });
+ //Default behavior on collapse
+ $this.on("collapse", function() {
+ var $this = $(this);
+ if (typeof ($this.treegrid('getSetting', 'onCollapse')) === "function") {
+ $this.treegrid('getSetting', 'onCollapse').apply($this);
+ }
+ });
+ //Default behavior on expand
+ $this.on("expand", function() {
+ var $this = $(this);
+ if (typeof ($this.treegrid('getSetting', 'onExpand')) === "function") {
+ $this.treegrid('getSetting', 'onExpand').apply($this);
+ }
+
+ });
+
+ return $this;
+ },
+ /**
+ * Initialize expander for node
+ *
+ * @returns {Node}
+ */
+ initExpander: function() {
+ var $this = $(this);
+ var cell = $this.find('td').get($this.treegrid('getSetting', 'treeColumn'));
+ var tpl = $this.treegrid('getSetting', 'expanderTemplate');
+ var expander = $this.treegrid('getSetting', 'getExpander').apply(this);
+ if (expander) {
+ expander.remove();
+ }
+ $(tpl).prependTo(cell).click(function() {
+ $($(this).closest('tr')).treegrid('toggle');
+ });
+ return $this;
+ },
+ /**
+ * Initialize indent for node
+ *
+ * @returns {Node}
+ */
+ initIndent: function() {
+ var $this = $(this);
+ $this.find('.treegrid-indent').remove();
+ for (var i = 0; i < $(this).treegrid('getDepth'); i++) {
+ $($this.treegrid('getSetting', 'indentTemplate')).insertBefore($this.find('.treegrid-expander'));
+ }
+ return $this;
+ },
+ /**
+ * Initialise state of node
+ *
+ * @returns {Node}
+ */
+ initState: function() {
+ var $this = $(this);
+ if ($this.treegrid('getSetting', 'saveState') && !$this.treegrid('isFirstInit')) {
+ $this.treegrid('restoreState');
+ } else {
+ if ($this.treegrid('getSetting', 'initialState') === "expanded") {
+ $this.treegrid('expand');
+ } else {
+ $this.treegrid('collapse');
+ }
+ }
+ return $this;
+ },
+ /**
+ * Return true if this tree was never been initialised
+ *
+ * @returns {Boolean}
+ */
+ isFirstInit: function() {
+ var tree = $(this).treegrid('getTreeContainer');
+ if (tree.data('first_init') === undefined) {
+ tree.data('first_init', $.cookie(tree.treegrid('getSetting', 'saveStateName')) === undefined);
+ }
+ return tree.data('first_init');
+ },
+ /**
+ * Save state of current node
+ *
+ * @returns {Node}
+ */
+ saveState: function() {
+ var $this = $(this);
+ if ($this.treegrid('getSetting', 'saveStateMethod') === 'cookie') {
+
+ var stateArrayString = $.cookie($this.treegrid('getSetting', 'saveStateName')) || '';
+ var stateArray = (stateArrayString === '' ? [] : stateArrayString.split(','));
+ var nodeId = $this.treegrid('getNodeId');
+
+ if ($this.treegrid('isExpanded')) {
+ if ($.inArray(nodeId, stateArray) === -1) {
+ stateArray.push(nodeId);
+ }
+ } else if ($this.treegrid('isCollapsed')) {
+ if ($.inArray(nodeId, stateArray) !== -1) {
+ stateArray.splice($.inArray(nodeId, stateArray), 1);
+ }
+ }
+ $.cookie($this.treegrid('getSetting', 'saveStateName'), stateArray.join(','));
+ }
+ return $this;
+ },
+ /**
+ * Restore state of current node.
+ *
+ * @returns {Node}
+ */
+ restoreState: function() {
+ var $this = $(this);
+ if ($this.treegrid('getSetting', 'saveStateMethod') === 'cookie') {
+ var stateArray = $.cookie($this.treegrid('getSetting', 'saveStateName')).split(',');
+ if ($.inArray($this.treegrid('getNodeId'), stateArray) !== -1) {
+ $this.treegrid('expand');
+ } else {
+ $this.treegrid('collapse');
+ }
+
+ }
+ return $this;
+ },
+ /**
+ * Method return setting by name
+ *
+ * @param {type} name
+ * @returns {unresolved}
+ */
+ getSetting: function(name) {
+ if (!$(this).treegrid('getTreeContainer')) {
+ return null;
+ }
+ return $(this).treegrid('getTreeContainer').data('settings')[name];
+ },
+ /**
+ * Add new settings
+ *
+ * @param {Object} settings
+ */
+ setSettings: function(settings) {
+ $(this).treegrid('getTreeContainer').data('settings', settings);
+ },
+ /**
+ * Return tree container
+ *
+ * @returns {HtmlElement}
+ */
+ getTreeContainer: function() {
+ return $(this).data('treegrid');
+ },
+ /**
+ * Set tree container
+ *
+ * @param {HtmlE;ement} container
+ */
+ setTreeContainer: function(container) {
+ return $(this).data('treegrid', container);
+ },
+ /**
+ * Method return all root nodes of tree.
+ *
+ * Start init all child nodes from it.
+ *
+ * @returns {Array}
+ */
+ getRootNodes: function() {
+ return $(this).treegrid('getSetting', 'getRootNodes').apply(this, [$(this).treegrid('getTreeContainer')]);
+ },
+ /**
+ * Method return all nodes of tree.
+ *
+ * @returns {Array}
+ */
+ getAllNodes: function() {
+ return $(this).treegrid('getSetting', 'getAllNodes').apply(this, [$(this).treegrid('getTreeContainer')]);
+ },
+ /**
+ * Mthod return true if element is Node
+ *
+ * @returns {String}
+ */
+ isNode: function() {
+ return $(this).treegrid('getNodeId') !== null;
+ },
+ /**
+ * Mthod return id of node
+ *
+ * @returns {String}
+ */
+ getNodeId: function() {
+ if ($(this).treegrid('getSetting', 'getNodeId') === null) {
+ return null;
+ } else {
+ return $(this).treegrid('getSetting', 'getNodeId').apply(this);
+ }
+ },
+ /**
+ * Method return parent id of node or null if root node
+ *
+ * @returns {String}
+ */
+ getParentNodeId: function() {
+ return $(this).treegrid('getSetting', 'getParentNodeId').apply(this);
+ },
+ /**
+ * Method return parent node or null if root node
+ *
+ * @returns {Object[]}
+ */
+ getParentNode: function() {
+ if ($(this).treegrid('getParentNodeId') === null) {
+ return null;
+ } else {
+ return $(this).treegrid('getSetting', 'getNodeById').apply(this, [$(this).treegrid('getParentNodeId'), $(this).treegrid('getTreeContainer')]);
+ }
+ },
+ /**
+ * Method return array of child nodes or null if node is leaf
+ *
+ * @returns {Object[]}
+ */
+ getChildNodes: function() {
+ return $(this).treegrid('getSetting', 'getChildNodes').apply(this, [$(this).treegrid('getNodeId'), $(this).treegrid('getTreeContainer')]);
+ },
+ /**
+ * Method return depth of tree.
+ *
+ * This method is needs for calculate indent
+ *
+ * @returns {Number}
+ */
+ getDepth: function() {
+ if ($(this).treegrid('getParentNode') === null) {
+ return 0;
+ }
+ return $(this).treegrid('getParentNode').treegrid('getDepth') + 1;
+ },
+ /**
+ * Method return true if node is root
+ *
+ * @returns {Boolean}
+ */
+ isRoot: function() {
+ return $(this).treegrid('getDepth') === 0;
+ },
+ /**
+ * Method return true if node has no child nodes
+ *
+ * @returns {Boolean}
+ */
+ isLeaf: function() {
+ return $(this).treegrid('getChildNodes').length === 0;
+ },
+ /**
+ * Method return true if node last in branch
+ *
+ * @returns {Boolean}
+ */
+ isLast: function() {
+ if ($(this).treegrid('isNode')) {
+ var parentNode = $(this).treegrid('getParentNode');
+ if (parentNode === null) {
+ if ($(this).treegrid('getNodeId') === $(this).treegrid('getRootNodes').last().treegrid('getNodeId')) {
+ return true;
+ }
+ } else {
+ if ($(this).treegrid('getNodeId') === parentNode.treegrid('getChildNodes').last().treegrid('getNodeId')) {
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+ /**
+ * Method return true if node first in branch
+ *
+ * @returns {Boolean}
+ */
+ isFirst: function() {
+ if ($(this).treegrid('isNode')) {
+ var parentNode = $(this).treegrid('getParentNode');
+ if (parentNode === null) {
+ if ($(this).treegrid('getNodeId') === $(this).treegrid('getRootNodes').first().treegrid('getNodeId')) {
+ return true;
+ }
+ } else {
+ if ($(this).treegrid('getNodeId') === parentNode.treegrid('getChildNodes').first().treegrid('getNodeId')) {
+ return true;
+ }
+ }
+ }
+ return false;
+ },
+ /**
+ * Return true if node expanded
+ *
+ * @returns {Boolean}
+ */
+ isExpanded: function() {
+ return $(this).hasClass('treegrid-expanded');
+ },
+ /**
+ * Return true if node collapsed
+ *
+ * @returns {Boolean}
+ */
+ isCollapsed: function() {
+ return $(this).hasClass('treegrid-collapsed');
+ },
+ /**
+ * Return true if at least one of parent node is collapsed
+ *
+ * @returns {Boolean}
+ */
+ isOneOfParentsCollapsed: function() {
+ var $this = $(this);
+ if ($this.treegrid('isRoot')) {
+ return false;
+ } else {
+ if ($this.treegrid('getParentNode').treegrid('isCollapsed')) {
+ return true;
+ } else {
+ return $this.treegrid('getParentNode').treegrid('isOneOfParentsCollapsed');
+ }
+ }
+ },
+ /**
+ * Expand node
+ *
+ * @returns {Node}
+ */
+ expand: function() {
+ return $(this).each(function() {
+ var $this = $(this);
+ if (!$this.treegrid('isLeaf') && !$this.treegrid("isExpanded")) {
+ $this.trigger("expand");
+ $this.trigger("change");
+ }
+ });
+ },
+ /**
+ * Expand all nodes
+ *
+ * @returns {Node}
+ */
+ expandAll: function() {
+ var $this = $(this);
+ $this.treegrid('getRootNodes').treegrid('expandRecursive');
+ return $this;
+ },
+ /**
+ * Expand current node and all child nodes begin from current
+ *
+ * @returns {Node}
+ */
+ expandRecursive: function() {
+ return $(this).each(function() {
+ var $this = $(this);
+ $this.treegrid('expand');
+ if (!$this.treegrid('isLeaf')) {
+ $this.treegrid('getChildNodes').treegrid('expandRecursive');
+ }
+ });
+ },
+ /**
+ * Collapse node
+ *
+ * @returns {Node}
+ */
+ collapse: function() {
+ return $(this).each(function() {
+ var $this = $(this);
+ if (!$this.treegrid('isLeaf') && !$this.treegrid("isCollapsed")) {
+ $this.trigger("collapse");
+ $this.trigger("change");
+ }
+ });
+ },
+ /**
+ * Collapse all nodes
+ *
+ * @returns {Node}
+ */
+ collapseAll: function() {
+ var $this = $(this);
+ $this.treegrid('getRootNodes').treegrid('collapseRecursive');
+ return $this;
+ },
+ /**
+ * Collapse current node and all child nodes begin from current
+ *
+ * @returns {Node}
+ */
+ collapseRecursive: function() {
+ return $(this).each(function() {
+ var $this = $(this);
+ $this.treegrid('collapse');
+ if (!$this.treegrid('isLeaf')) {
+ $this.treegrid('getChildNodes').treegrid('collapseRecursive');
+ }
+ });
+ },
+ /**
+ * Expand if collapsed, Collapse if expanded
+ *
+ * @returns {Node}
+ */
+ toggle: function() {
+ var $this = $(this);
+ if ($this.treegrid('isExpanded')) {
+ $this.treegrid('collapse');
+ } else {
+ $this.treegrid('expand');
+ }
+ return $this;
+ },
+ /**
+ * Rendering node
+ *
+ * @returns {Node}
+ */
+ render: function() {
+ return $(this).each(function() {
+ var $this = $(this);
+
+ if ($this.treegrid('isOneOfParentsCollapsed')) {
+ $this.hide();
+ } else {
+ $this.show();
+ }
+ if (!$this.treegrid('isLeaf')) {
+ $this.treegrid('renderExpander');
+ $this.treegrid('getChildNodes').treegrid('render');
+ }
+ });
+ },
+ /**
+ * Rendering expander depends on node state
+ *
+ * @returns {Node}
+ */
+ renderExpander: function() {
+ return $(this).each(function() {
+ var $this = $(this);
+ var expander = $this.treegrid('getSetting', 'getExpander').apply(this);
+ if (expander) {
+
+ if (!$this.treegrid('isCollapsed')) {
+ expander.removeClass($this.treegrid('getSetting', 'expanderCollapsedClass'));
+ expander.addClass($this.treegrid('getSetting', 'expanderExpandedClass'));
+ } else {
+ expander.removeClass($this.treegrid('getSetting', 'expanderExpandedClass'));
+ expander.addClass($this.treegrid('getSetting', 'expanderCollapsedClass'));
+ }
+ } else {
+ $this.treegrid('initExpander');
+ $this.treegrid('renderExpander');
+ }
+ });
+ }
+ };
+ $.fn.treegrid = function(method) {
+ if (methods[method]) {
+ return methods[ method ].apply(this, Array.prototype.slice.call(arguments, 1));
+ } else if (typeof method === 'object' || !method) {
+ return methods.initTree.apply(this, arguments);
+ } else {
+ $.error('Method with name ' + method + ' does not exists for jQuery.treegrid');
+ }
+ };
+ /**
+ * Plugin's default options
+ */
+ $.fn.treegrid.defaults = {
+ initialState: 'expanded',
+ saveState: false,
+ saveStateMethod: 'cookie',
+ saveStateName: 'tree-grid-state',
+ expanderTemplate: '',
+ indentTemplate: '',
+ expanderExpandedClass: 'treegrid-expander-expanded',
+ expanderCollapsedClass: 'treegrid-expander-collapsed',
+ treeColumn: 0,
+ getExpander: function() {
+ return $(this).find('.treegrid-expander');
+ },
+ getNodeId: function() {
+ var template = /treegrid-([A-Za-z0-9_-]+)/;
+ if (template.test($(this).attr('class'))) {
+ return template.exec($(this).attr('class'))[1];
+ }
+ return null;
+ },
+ getParentNodeId: function() {
+ var template = /treegrid-parent-([A-Za-z0-9_-]+)/;
+ if (template.test($(this).attr('class'))) {
+ return template.exec($(this).attr('class'))[1];
+ }
+ return null;
+ },
+ getNodeById: function(id, treegridContainer) {
+ var templateClass = "treegrid-" + id;
+ return treegridContainer.find('tr.' + templateClass);
+ },
+ getChildNodes: function(id, treegridContainer) {
+ var templateClass = "treegrid-parent-" + id;
+ return treegridContainer.find('tr.' + templateClass);
+ },
+ getTreeGridContainer: function() {
+ return $(this).closest('table');
+ },
+ getRootNodes: function(treegridContainer) {
+ var result = $.grep(treegridContainer.find('tr'), function(element) {
+ var classNames = $(element).attr('class');
+ var templateClass = /treegrid-([A-Za-z0-9_-]+)/;
+ var templateParentClass = /treegrid-parent-([A-Za-z0-9_-]+)/;
+ return templateClass.test(classNames) && !templateParentClass.test(classNames);
+ });
+ return $(result);
+ },
+ getAllNodes: function(treegridContainer) {
+ var result = $.grep(treegridContainer.find('tr'), function(element) {
+ var classNames = $(element).attr('class');
+ var templateClass = /treegrid-([A-Za-z0-9_-]+)/;
+ return templateClass.test(classNames);
+ });
+ return $(result);
+ },
+ //Events
+ onCollapse: null,
+ onExpand: null,
+ onChange: null
+
+ };
})(jQuery);
\ No newline at end of file
diff --git a/admin/view/template/extension/payment/emerchantpay_checkout.twig b/admin/view/template/extension/payment/emerchantpay_checkout.twig
index 9a38257..fdbde37 100644
--- a/admin/view/template/extension/payment/emerchantpay_checkout.twig
+++ b/admin/view/template/extension/payment/emerchantpay_checkout.twig
@@ -147,6 +147,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -105,4 +112,6 @@
});
});
});
+
+ empPopulateBrowserParams.execute(document);
diff --git a/composer.json b/composer.json
index 7617012..f6b9d93 100644
--- a/composer.json
+++ b/composer.json
@@ -3,7 +3,7 @@
"description": "emerchantpay Gateway Module for OpenCart",
"type": "opencart-module",
"license": "GPL-2.0",
- "version": "1.1.3",
+ "version": "1.1.4",
"authors": [
{
"name": "emerchantpay",
diff --git a/install.json b/install.json
index b818387..ca75182 100644
--- a/install.json
+++ b/install.json
@@ -1,6 +1,6 @@
{
"name": "emerchantpay Payments",
- "version": "1.1.3",
+ "version": "1.1.4",
"author": "emerchantpay Ltd.",
"link": "https://emerchantpay.com"
}
diff --git a/system/admin/base_controller.php b/system/admin/base_controller.php
index fb11a8b..b9d9c84 100644
--- a/system/admin/base_controller.php
+++ b/system/admin/base_controller.php
@@ -23,8 +23,12 @@
require DIR_STORAGE . 'vendor/genesisgateway/genesis_php/vendor/autoload.php';
}
+use Exception;
+use Genesis\API\Constants\Transaction\Parameters\ScaExemptions;
use Genesis\API\Constants\Transaction\States;
use Genesis\API\Constants\Transaction\Types;
+use Opencart\Extension\Emerchantpay\System\Catalog\SettingsHelper;
+use Opencart\Extension\Emerchantpay\System\Catalog\ThreedsHelper;
use Opencart\Extension\Emerchantpay\System\EmerchantpayHelper;
use Opencart\System\Engine\Controller;
@@ -75,7 +79,8 @@ abstract class BaseController extends Controller
'transaction_type',
'order_status',
'order_async_status',
- 'order_failure_status'
+ 'order_failure_status',
+ 'error_sca_exemption_amount',
);
/**
@@ -89,14 +94,14 @@ abstract protected function isModuleRequiresSsl(): bool;
* BaseController constructor.
* @param $registry
*
- * @throws \Exception
+ * @throws Exception
*/
public function __construct($registry)
{
parent::__construct($registry);
if (is_null($this->module_name)) {
- throw new \Exception('Module name not supplied in EMerchantPay controller');
+ throw new Exception('Module name not supplied in EMerchantPay controller');
}
}
@@ -109,15 +114,18 @@ public function index()
{
if ($this->isInstallRequest()) {
$this->install();
+
return true;
} elseif ($this->isUninstallRequest()) {
$this->uninstall();
+
return true;
} elseif ($this->isOrderInfoRequest()) {
return $this->orderAction();
} else if ($this->isModuleSubActionRequest(['getModalForm', 'capture', 'refund', 'void'])) {
$method = $this->request->get['action'];
call_user_func(array($this, $method));
+
return true;
}
@@ -200,13 +208,11 @@ public function order()
// 2. Sort by relations, i.e. every parent has the child nodes immediately after
// Ascending Date/Timestamp sorting
- // TODO Remove @
uasort($transactions, function ($element1, $element2) {
- // sort by timestamp (date) first
- if (@$element1["timestamp"] == @$element2["timestamp"]) {
- return 0;
- }
- return (@$element1["timestamp"] > @$element2["timestamp"]) ? 1 : -1;
+ $timestamp1 = $element1['timestamp'] ?? null;
+ $timestamp2 = $element2['timestamp'] ?? null;
+
+ return $timestamp1 <=> $timestamp2;
});
// Create the parent/child relations from a flat array
@@ -450,10 +456,8 @@ public function refund(): void
if (isset($this->request->post['reference_id']) && trim($this->request->post['reference_id']) != '') {
$this->loadPaymentMethodModel();
- $transaction = $this->getModelInstance()->getTransactionById($this->request->post['reference_id']);
-
- $terminal_token =
- array_key_exists('terminal_token', $transaction) ? $transaction['terminal_token'] : null;
+ $transaction = $this->getModelInstance()->getTransactionById($this->request->post['reference_id']);
+ $terminal_token = array_key_exists('terminal_token', $transaction) ? $transaction['terminal_token'] : null;
if (isset($transaction['order_id']) && intval($transaction['order_id']) > 0) {
$amount = $this->request->post['amount'];
@@ -470,8 +474,7 @@ public function refund(): void
if (isset($refund->unique_id)) {
$timestamp = ($refund->timestamp instanceof \DateTime) ? $refund->timestamp->format('c') : $refund->timestamp;
-
- $data = array(
+ $data = array(
'order_id' => $transaction['order_id'],
'reference_id' => $transaction['unique_id'],
'unique_id' => $refund->unique_id,
@@ -480,8 +483,8 @@ public function refund(): void
'amount' => $refund->amount,
'currency' => $refund->currency,
'timestamp' => $timestamp,
- 'message' => isset($refund->message) ? $refund->message : '',
- 'technical_message' => isset($refund->technical_message) ? $refund->technical_message : '',
+ 'message' => $refund->message ?? '',
+ 'technical_message' => $refund->technical_message ?? '',
);
if (array_key_exists('terminal_token', $transaction)) {
@@ -542,10 +545,7 @@ public function refund(): void
}
$this->response->addHeader('Content-Type: application/json');
-
- $this->response->setOutput(
- json_encode($json)
- );
+ $this->response->setOutput(json_encode($json));
}
/**
@@ -1051,7 +1051,7 @@ protected function processPostIndexAction(): void
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
- } catch (\Exception $e) {
+ } catch (Exception $e) {
$this->response->addHeader('HTTP/1.0 500 Internal Server Error');
}
}
@@ -1080,6 +1080,9 @@ protected function processGetIndexAction(): void
$this->load->model('localisation/order_status');
$this->loadPaymentMethodModel();
+ $threedshelper = new ThreedsHelper();
+ $challenge_indicators = $threedshelper->getThreedsChallengeIndicators();
+
$data = $this->buildLanguagePhrases();
$data += array(
@@ -1091,31 +1094,6 @@ protected function processGetIndexAction(): void
'error_warning' => isset($this->error['warning']) ? $this->error['warning'] : '',
'enable_recurring_tab' => true,
- // Settings
- "{$this->module_name}_username" => $this->getFieldValue("{$this->module_name}_username"),
- "{$this->module_name}_password" => $this->getFieldValue("{$this->module_name}_password"),
- "{$this->module_name}_token" => $this->getFieldValue("{$this->module_name}_token"),
- "{$this->module_name}_sandbox" => $this->getFieldValue("{$this->module_name}_sandbox"),
- "{$this->module_name}_transaction_type" => $this->getFieldValue("{$this->module_name}_transaction_type"),
- "{$this->module_name}_wpf_tokenization" => $this->getFieldValue("{$this->module_name}_wpf_tokenization"),
- "{$this->module_name}_total" => $this->getFieldValue("{$this->module_name}_total"),
- "{$this->module_name}_order_status_id" => $this->getFieldValue("{$this->module_name}_order_status_id"),
- "{$this->module_name}_order_failure_status_id" => $this->getFieldValue("{$this->module_name}_order_failure_status_id"),
- "{$this->module_name}_async_order_status_id" => $this->getFieldValue("{$this->module_name}_async_order_status_id"),
- "{$this->module_name}_geo_zone_id" => $this->getFieldValue("{$this->module_name}_geo_zone_id"),
- "{$this->module_name}_status" => $this->getFieldValue("{$this->module_name}_status"),
- "{$this->module_name}_sort_order" => $this->getFieldValue("{$this->module_name}_sort_order"),
- "{$this->module_name}_debug" => $this->getFieldValue("{$this->module_name}_debug"),
- "{$this->module_name}_supports_partial_capture" => $this->getFieldValue("{$this->module_name}_supports_partial_capture"),
- "{$this->module_name}_supports_partial_refund" => $this->getFieldValue("{$this->module_name}_supports_partial_refund"),
- "{$this->module_name}_supports_void" => $this->getFieldValue("{$this->module_name}_supports_void"),
- "{$this->module_name}_supports_recurring" => $this->getFieldValue("{$this->module_name}_supports_recurring"),
- "{$this->module_name}_recurring_transaction_type" => $this->getFieldValue("{$this->module_name}_recurring_transaction_type"),
- "{$this->module_name}_recurring_token" => $this->getFieldValue("{$this->module_name}_recurring_token"),
- "{$this->module_name}_cron_allowed_ip" => $this->getFieldValue("{$this->module_name}_cron_allowed_ip"),
- "{$this->module_name}_cron_time_limit" => $this->getFieldValue("{$this->module_name}_cron_time_limit"),
- "{$this->module_name}_bank_codes" => $this->getFieldValue("{$this->module_name}_bank_codes"),
-
'action' => $this->url->link("{$this->route_prefix}payment/{$this->module_name}", $this->getTokenParam() . '=' . $this->getToken(), true),
// TODO I'm not sure if this is used somewhere
'cancel' => $this->getPaymentLink($this->getToken()),
@@ -1127,27 +1105,23 @@ protected function processGetIndexAction(): void
'cron_last_execution' => $this->getLastCronExecTime(),
'cron_last_execution_status' => $this->getCronExecStatus(),
- 'module_name' => $this->module_name
+ 'module_name' => $this->module_name,
+ 'threeds_challenge_indicators' => $challenge_indicators,
+ 'sca_exemptions' => $this->getModelInstance()->getScaExemptions()
);
+ $settings = new SettingsHelper($this);
+
+ $data = array_merge($data, $settings->getBaseSettings($this->module_name));
+ $data = array_merge($data, $settings->getModuleSettings($this->module_name));
+
if ($this->module_name == 'emerchantpay_checkout') {
- $data += ['bank_codes' => $this->getModelInstance()->getBankCodes()];
+ $data += [
+ 'bank_codes' => $this->getModelInstance()->getBankCodes(),
+ ];
}
- $default_param_values = array(
- "{$this->module_name}_sandbox" => 1,
- "{$this->module_name}_status" => 0,
- "{$this->module_name}_debug" => 1,
- "{$this->module_name}_supports_partial_capture" => 1,
- "{$this->module_name}_supports_partial_refund" => 1,
- "{$this->module_name}_supports_void" => 1,
- "{$this->module_name}_supports_recurring" => 0,
- "{$this->module_name}_cron_allowed_ip" => $this->getServerAddress(),
- "{$this->module_name}_cron_time_limit" => 25
- );
-
- foreach ($default_param_values as $key => $default_value)
- $data[$key] = (is_null($data[$key]) ? $default_value : $data[$key]);
+ $data = $settings->setDefaultOptions($data, $this->module_name);
$data['breadcrumbs'] = array();
@@ -1218,6 +1192,10 @@ protected function buildLanguagePhrases(): array
'entry_cron_allowed_ip',
'entry_cron_last_execution',
'entry_bank_codes',
+ 'entry_threeds_allowed',
+ 'entry_threeds_challenge_indicator',
+ 'entry_sca_exemption',
+ 'entry_sca_exemption_value',
'entry_order_status',
'entry_async_order_status',
@@ -1246,6 +1224,10 @@ protected function buildLanguagePhrases(): array
'help_cron_time_limit',
'help_cron_allowed_ip',
'help_cron_last_execution',
+ 'help_threeds_allowed',
+ 'help_threeds_challenge_indicator',
+ 'help_sca_exemption',
+ 'help_sca_exemption_value',
'button_save',
'button_cancel',
@@ -1276,53 +1258,19 @@ protected function buildLanguagePhrases(): array
*/
protected function validate(): bool
{
+ $this->validateRequiredFields();
+
if (!$this->user->hasPermission('modify', "{$this->route_prefix}payment/{$this->module_name}")) {
$this->error['warning'] = $this->language->get('error_permission');
}
- if (empty($this->request->post["{$this->module_name}_username"])) {
- $this->error['username'] = $this->language->get('error_username');
- }
-
- if (empty($this->request->post["{$this->module_name}_password"])) {
- $this->error['password'] = $this->language->get('error_password');
- }
-
- if (empty($this->request->post["{$this->module_name}_transaction_type"])) {
- $this->error['transaction_type'] = $this->language->get('error_transaction_type');
- }
-
- if (empty($this->request->post["{$this->module_name}_order_status_id"])) {
- $this->error['order_status'] = $this->language->get('error_order_status');
- }
-
- if (empty($this->request->post["{$this->module_name}_order_failure_status_id"])) {
- $this->error['order_failure_status'] = $this->language->get('error_order_failure_status');
- }
-
- if ($this->module_name === 'emerchantpay_direct' && empty($this->request->post["{$this->module_name}_async_order_status_id"])) {
- $this->error['order_async_status'] = $this->language->get('error_async_order_status');
+ if ((float)$this->request->post["{$this->module_name}_sca_exemption_amount"] < 0) {
+ $this->error['error_sca_exemption_amount'] = $this->language->get('error_sca_exemption_amount');
}
return !$this->error;
}
- /**
- * Check if there's a POST parameter or use the existing configuration value
- *
- * @param $key string
- *
- * @return mixed
- */
- protected function getFieldValue($key): mixed
- {
- if (isset($this->request->post[$key])) {
- return $this->request->post[$key];
- }
-
- return $this->config->get($key);
- }
-
/**
* Check if the current visitor is logged in and has permission to access
* this page
@@ -1600,20 +1548,6 @@ protected function getLink($link_parameters): string
);
}
- /**
- * @return string
- */
- protected function getServerAddress(): string
- {
- $server_name = $this->request->server['SERVER_NAME'];
-
- if (empty($server_name) || !function_exists('gethostbyname')) {
- return $this->request->server['SERVER_ADDR'];
- }
-
- return gethostbyname($server_name);
- }
-
/**
* Determine if Google Pay, PayPal ot Apple Pay Method is chosen inside the Payment settings
*
@@ -1706,8 +1640,6 @@ protected function checkReferenceActionByCustomAttr($action, $transaction_type):
default:
return false;
} // end Switch
-
- return false;
}
/**
@@ -1727,4 +1659,30 @@ protected function hasApprovedState($transaction_type): bool
return $state->isApproved();
}
+
+ /**
+ * Check if any of the required fields is empty
+ *
+ * @return void
+ */
+ private function validateRequiredFields(): void
+ {
+ $required_fields = [
+ "{$this->module_name}_username" => 'username',
+ "{$this->module_name}_password" => 'password',
+ "{$this->module_name}_transaction_type" => 'transaction_type',
+ "{$this->module_name}_order_status_id" => 'order_status',
+ "{$this->module_name}_order_failure_status_id" => 'order_failure_status',
+ ];
+
+ if ($this->module_name === 'emerchantpay_direct') {
+ $required_fields["{$this->module_name}_async_order_status_id"] = 'order_async_status';
+ }
+
+ foreach ($required_fields as $field => $error_key) {
+ if (empty($this->request->post[$field])) {
+ $this->error[$error_key] = $this->language->get("error_$error_key");
+ }
+ }
+ }
}
diff --git a/system/catalog/base_controller.php b/system/catalog/base_controller.php
index 5a55b6a..83f7991 100644
--- a/system/catalog/base_controller.php
+++ b/system/catalog/base_controller.php
@@ -23,13 +23,20 @@
require DIR_STORAGE . 'vendor/genesisgateway/genesis_php/vendor/autoload.php';
}
+use Genesis\API\Constants\Transaction\Parameters\Threeds\V2\CardHolderAccount\RegistrationIndicators;
+use Genesis\API\Constants\Transaction\Parameters\Threeds\V2\MerchantRisk\DeliveryTimeframes;
+use Genesis\API\Constants\Transaction\Parameters\Threeds\V2\Purchase\Categories;
+use Opencart\Catalog\Model\Extension\Emerchantpay\Payment\EmerchantpayCheckout as ModelEmerchantpayCheckout;
use Opencart\Extension\Emerchantpay\System\EmerchantpayHelper;
use Opencart\System\Engine\Controller;
+use Opencart\System\Engine\Model;
/**
* Base Abstract Class for Method Front Controllers
*
* Class BaseController
+ *
+ * @SuppressWarnings(PHPMD.LongVariable)
*/
abstract class BaseController extends Controller
{
@@ -125,4 +132,236 @@ protected function populateAddresses($order_info, &$data): void
);
}
}
+
+ /**
+ * Populate order data with 3DSv2 parameters
+ *
+ * @param Controller $controller
+ * @param array $product_info
+ * @param array $order_info
+ * @param $data
+ *
+ * @return array
+ */
+ protected function populateTreedsParams($controller, $product_info, $order_info): array
+ {
+ $model_account_order = $controller->model_account_order;
+ $model_account_customer = $controller->model_account_customer;
+
+ $emerchantpay_threeds_helper = new ThreedsHelper();
+
+ /**
+ * Get all customer's orders
+ * Default limit is 20, and they are sorted in descending order
+ */
+ $customer_orders = $emerchantpay_threeds_helper->getCustomerOrders(
+ $controller->db,
+ $this->getCustomerId($controller),
+ (int)$controller->config->get('config_store_id'),
+ (int)$controller->config->get('config_language_id'),
+ ModelEmerchantpayCheckout::METHOD_CODE
+ );
+
+ $is_guest = !$controller->customer->isLogged();
+ $has_physical_products = $emerchantpay_threeds_helper->hasPhysicalProduct($product_info);
+ $threeds_challenge_indicator = $controller->config->get('emerchantpay_checkout_threeds_challenge_indicator');
+
+ $threeds_purchase_category = $emerchantpay_threeds_helper->hasPhysicalProduct($product_info) ? Categories::GOODS : Categories::SERVICE;
+ $threeds_delivery_timeframe = ($has_physical_products) ? DeliveryTimeframes::ANOTHER_DAY : DeliveryTimeframes::ELECTRONICS;
+ $threeds_shipping_indicator = $emerchantpay_threeds_helper->getShippingIndicator($has_physical_products, $order_info, $is_guest);
+ $threeds_reorder_items_indicator = $emerchantpay_threeds_helper->getReorderItemsIndicator(
+ $model_account_order,
+ $is_guest, $product_info,
+ $customer_orders
+ );
+ $threeds_registration_date = null;
+ $threeds_registration_indicator = RegistrationIndicators::GUEST_CHECKOUT;
+
+ if (!$is_guest) {
+ $threeds_registration_date = $emerchantpay_threeds_helper->findFirstCustomerOrderDate($customer_orders);
+ $threeds_registration_indicator = $emerchantpay_threeds_helper->getRegistrationIndicator($threeds_registration_date);
+ $threeds_creation_date = $emerchantpay_threeds_helper->getCreationDate($model_account_customer, $order_info['customer_id']);
+
+ $shipping_address_date_first_used = $emerchantpay_threeds_helper->findShippingAddressDateFirstUsed(
+ $model_account_order,
+ $order_info,
+ $customer_orders
+ );
+ $threads_shipping_address_date_first_used = $shipping_address_date_first_used;
+ $threeds_shipping_address_usage_indicator = $emerchantpay_threeds_helper->getShippingAddressUsageIndicator($shipping_address_date_first_used);
+
+ $orders_for_a_period = $emerchantpay_threeds_helper->findNumberOfOrdersForaPeriod(
+ $model_account_order,
+ $customer_orders
+ );
+ $transactions_activity_last_24_hours = $orders_for_a_period['last_24h'];
+ $transactions_activity_previous_year = $orders_for_a_period['last_year'];
+ $purchases_count_last_6_months = $orders_for_a_period['last_6m'];
+ }
+
+ $data = [
+ 'is_guest' => $is_guest,
+ 'threeds_challenge_indicator' => $threeds_challenge_indicator,
+ 'threeds_purchase_category' => $threeds_purchase_category,
+ 'threeds_delivery_timeframe' => $threeds_delivery_timeframe,
+ 'threeds_shipping_indicator' => $threeds_shipping_indicator,
+ 'threeds_reorder_items_indicator' => $threeds_reorder_items_indicator,
+ 'threeds_registration_indicator' => $threeds_registration_indicator,
+ 'threeds_registration_date' => $threeds_registration_date,
+ 'sca_exemption_value' => $controller->config->get($controller->module_name . '_sca_exemption'),
+ 'sca_exemption_amount' => $controller->config->get($controller->module_name . '_sca_exemption_amount'),
+ ];
+
+ if (!$is_guest) {
+ $data['threeds_creation_date'] = $threeds_creation_date;
+ $data['threads_shipping_address_date_first_used'] = $threads_shipping_address_date_first_used;
+ $data['threeds_shipping_address_usage_indicator'] = $threeds_shipping_address_usage_indicator;
+ $data['transactions_activity_last_24_hours'] = $transactions_activity_last_24_hours;
+ $data['transactions_activity_previous_year'] = $transactions_activity_previous_year;
+ $data['purchases_count_last_6_months'] = $purchases_count_last_6_months;
+ }
+
+ return $data;
+ }
+
+ /**
+ * Return 0 if guest or customerId if customer is logged on
+ *
+ * @param $controller
+ *
+ * @return int
+ */
+ protected function getCustomerId($controller): int
+ {
+ if ($controller->customer->isLogged()) {
+ return $controller->customer->getId();
+ }
+
+ return 0;
+ }
+
+ /**
+ * Create the return urls
+ *
+ * @return array
+ */
+ protected function buildActionUrls($module_name): array
+ {
+ return [
+ 'notification_url' =>
+ $this->buildUrl(
+ 'extension/emerchantpay/payment/' . $module_name,
+ 'callback'
+ ),
+ 'return_success_url' =>
+ $this->buildUrl(
+ 'extension/emerchantpay/payment/' . $module_name,
+ 'success'
+ ),
+ 'return_failure_url' =>
+ $this->buildUrl(
+ 'extension/emerchantpay/payment/' . $module_name,
+ 'failure'
+ ),
+ ];
+ }
+
+ /**
+ * Respond json error message
+ *
+ * @param $message
+ *
+ * @return void
+ */
+ protected function respondWithError($message): void
+ {
+ $this->response->addHeader('Content-Type: application/json');
+ $this->response->setOutput(json_encode(['error' => $message]));
+ }
+
+ /**
+ * Return common request data
+ *
+ * @param Model $model
+ * @param $order_info
+ *
+ * @return array
+ */
+ protected function populateCommonData($model, $order_info): array
+ {
+ return [
+ 'transaction_id' => $model->genTransactionId(self::PLATFORM_TRANSACTION_PREFIX),
+
+ 'remote_address' => EmerchantpayHelper::getFirstRemoteAddress($this->request->server['REMOTE_ADDR']),
+
+ 'usage' => $model->getUsage(),
+ 'description' => $model->getOrderProducts($this->session->data['order_id']),
+
+ 'currency' => $model->getCurrencyCode(),
+ 'amount' => (float)$order_info['total'],
+
+ 'customer_email' => $order_info['email'],
+ 'customer_phone' => $order_info['telephone'],
+ ];
+ }
+
+ /**
+ * Get $data values upon UniqId
+ *
+ * @param $transaction
+ * @param $order_info
+ *
+ * @return array
+ */
+ protected function populateDataUniqIdTrx($transaction, $order_info): array
+ {
+ $timestamp = ($transaction->timestamp instanceof \DateTime) ? $transaction->timestamp->format('c') : $transaction->timestamp;
+
+ return [
+ 'reference_id' => '0',
+ 'order_id' => $order_info['order_id'],
+ 'unique_id' => $transaction->unique_id,
+ 'type' => $transaction->transaction_type ?? 'checkout',
+ 'status' => $transaction->status,
+ 'message' => $transaction->message ?? '',
+ 'technical_message' => $transaction->technical_message ?? '',
+ 'amount' => $transaction->amount,
+ 'currency' => $transaction->currency,
+ 'timestamp' => $timestamp,
+ ];
+ }
+
+ /**
+ * Prepares data for the view when cart content is mixed
+ *
+ * @return array
+ */
+ protected function prepareViewDataMixedCart(): array
+ {
+ return [
+ 'text_loading' => $this->language->get('text_loading'),
+ 'text_payment_mixed_cart_content' => $this->language->get('text_payment_mixed_cart_content'),
+ 'button_shopping_cart' => $this->language->get('button_shopping_cart'),
+ 'button_target' => $this->buildUrl('checkout/cart')
+ ];
+ }
+
+ /**
+ * Adds recurring order
+ *
+ * @param string $payment_reference
+ * @param Model $model
+ *
+ * @return void
+ */
+ public function addOrderRecurring($payment_reference, $model): void
+ {
+ $recurring_products = $this->cart->getRecurringProducts();
+ if (!empty($recurring_products)) {
+ $model->addOrderRecurring(
+ $recurring_products,
+ $payment_reference
+ );
+ }
+ }
}
diff --git a/system/catalog/settings_helper.php b/system/catalog/settings_helper.php
new file mode 100644
index 0000000..4e85a84
--- /dev/null
+++ b/system/catalog/settings_helper.php
@@ -0,0 +1,159 @@
+controller = $controller;
+ }
+
+ /**
+ * @param string $module_name
+ *
+ * @return array
+ */
+ public function getBaseSettings($module_name)
+ {
+ return [
+ "{$module_name}_username" => $this->getFieldValue("{$module_name}_username"),
+ "{$module_name}_password" => $this->getFieldValue("{$module_name}_password"),
+ "{$module_name}_token" => $this->getFieldValue("{$module_name}_token"),
+ "{$module_name}_sandbox" => $this->getFieldValue("{$module_name}_sandbox"),
+ ];
+
+ }
+
+ /**
+ * @param string $module_name
+ *
+ * @return array
+ */
+ public function getModuleSettings($module_name)
+ {
+ return [
+ "{$module_name}_transaction_type" => $this->getFieldValue("{$module_name}_transaction_type"),
+ "{$module_name}_wpf_tokenization" => $this->getFieldValue("{$module_name}_wpf_tokenization"),
+ "{$module_name}_total" => $this->getFieldValue("{$module_name}_total"),
+ "{$module_name}_order_status_id" => $this->getFieldValue("{$module_name}_order_status_id"),
+ "{$module_name}_order_failure_status_id" => $this->getFieldValue("{$module_name}_order_failure_status_id"),
+ "{$module_name}_async_order_status_id" => $this->getFieldValue("{$module_name}_async_order_status_id"),
+ "{$module_name}_geo_zone_id" => $this->getFieldValue("{$module_name}_geo_zone_id"),
+ "{$module_name}_status" => $this->getFieldValue("{$module_name}_status"),
+ "{$module_name}_sort_order" => $this->getFieldValue("{$module_name}_sort_order"),
+ "{$module_name}_debug" => $this->getFieldValue("{$module_name}_debug"),
+ "{$module_name}_supports_partial_capture" => $this->getFieldValue("{$module_name}_supports_partial_capture"),
+ "{$module_name}_supports_partial_refund" => $this->getFieldValue("{$module_name}_supports_partial_refund"),
+ "{$module_name}_supports_void" => $this->getFieldValue("{$module_name}_supports_void"),
+ "{$module_name}_supports_recurring" => $this->getFieldValue("{$module_name}_supports_recurring"),
+ "{$module_name}_recurring_transaction_type" => $this->getFieldValue("{$module_name}_recurring_transaction_type"),
+ "{$module_name}_recurring_token" => $this->getFieldValue("{$module_name}_recurring_token"),
+ "{$module_name}_cron_allowed_ip" => $this->getFieldValue("{$module_name}_cron_allowed_ip"),
+ "{$module_name}_cron_time_limit" => $this->getFieldValue("{$module_name}_cron_time_limit"),
+ "{$module_name}_bank_codes" => $this->getFieldValue("{$module_name}_bank_codes"),
+ "{$module_name}_threeds_allowed" => $this->getFieldValue("{$module_name}_threeds_allowed"),
+ "{$module_name}_threeds_challenge_indicator" => $this->getFieldValue("{$module_name}_threeds_challenge_indicator"),
+ "{$module_name}_sca_exemption" => $this->getFieldValue("{$module_name}_sca_exemption"),
+ "{$module_name}_sca_exemption_amount" => $this->getFieldValue("{$module_name}_sca_exemption_amount"),
+ ];
+ }
+
+ /**
+ * @param array $data
+ * @param string $module_name
+ *
+ * @return mixed
+ */
+ public function setDefaultOptions($data, $module_name)
+ {
+ $default_param_values = array(
+ "{$module_name}_sandbox" => 1,
+ "{$module_name}_status" => 0,
+ "{$module_name}_debug" => 1,
+ "{$module_name}_supports_partial_capture" => 1,
+ "{$module_name}_supports_partial_refund" => 1,
+ "{$module_name}_supports_void" => 1,
+ "{$module_name}_supports_recurring" => 0,
+ "{$module_name}_cron_allowed_ip" => $this->getServerAddress(),
+ "{$module_name}_cron_time_limit" => 25,
+ "{$module_name}_threeds_allowed" => 1,
+ "{$module_name}_threeds_challenge_indicator" => ChallengeIndicators::NO_PREFERENCE,
+ "{$module_name}_sca_exemption" => ScaExemptions::EXEMPTION_LOW_RISK,
+ "{$module_name}_sca_exemption_amount" => 100,
+ );
+
+ foreach ($default_param_values as $key => $default_value)
+ $data[$key] = $data[$key] ?? $default_value;
+
+ return $data;
+ }
+
+ /**
+ * @return string
+ */
+ private function getServerAddress(): string
+ {
+ $server_name = $this->controller->request->server['SERVER_NAME'];
+
+ if (empty($server_name) || !function_exists('gethostbyname')) {
+ return $this->controller->request->server['SERVER_ADDR'];
+ }
+
+ return gethostbyname($server_name);
+ }
+
+ /**
+ * Check if there's a POST parameter or use the existing configuration value
+ *
+ * @param string $key
+ *
+ * @return mixed
+ */
+ public function getFieldValue($key): mixed
+ {
+ if (isset($this->controller->request->post[$key])) {
+ return $this->controller->request->post[$key];
+ }
+
+ return $this->controller->config->get($key);
+ }
+}
diff --git a/system/catalog/threeds_helper.php b/system/catalog/threeds_helper.php
new file mode 100644
index 0000000..dc6ffad
--- /dev/null
+++ b/system/catalog/threeds_helper.php
@@ -0,0 +1,466 @@
+areAddressesSame($order_info)) {
+ $indicator = ShippingIndicators::SAME_AS_BILLING;
+ }
+ }
+
+ return $indicator;
+ }
+
+ /**
+ * Get Reorder indicator
+ *
+ * @param Model $model
+ * @param bool $is_quest
+ * @param array $product_info
+ *
+ * @return string
+ */
+ public function getReorderItemsIndicator($model, $is_quest, $product_info, $customer_orders)
+ {
+ if ($is_quest) {
+ return ReorderItemIndicators::FIRST_TIME;
+ }
+
+ $bought_product_ids = $this->getBoughtProducts($model, $customer_orders);
+ $product_ids = array_column($product_info, 'product_id');
+
+ foreach ($product_ids as $product_id) {
+ if (in_array($product_id, $bought_product_ids)) {
+ return ReorderItemIndicators::REORDERED;
+ }
+ }
+
+ return ReorderItemIndicators::FIRST_TIME;
+ }
+
+ /**
+ * Get Shipping indicator
+ *
+ * @param string $date
+ *
+ * @return string
+ */
+ public function getShippingAddressUsageIndicator($date)
+ {
+ return $this->getIndicatorValue($date, ShippingAddressUsageIndicators::class);
+ }
+
+ /**
+ * Get Registration indicator
+ *
+ * @param string $order_date
+ *
+ * @return string
+ */
+ public function getRegistrationIndicator($order_date)
+ {
+ return $this->getIndicatorValue($order_date, RegistrationIndicators::class);
+ }
+
+ /**
+ * Find the date when customer placed first order
+ *
+ * @param Model $model
+ *
+ * @return string
+ */
+ public function findFirstCustomerOrderDate($customer_orders)
+ {
+ $order_date = (new DateTime())->format(self::OC_DATETIME_FORMAT);
+
+ if (CommonUtils::isValidArray($customer_orders)) {
+ $order_date = $customer_orders[0]['date_added'];
+ }
+
+ return $order_date;
+ }
+
+ /**
+ * Date when the customer has been registered
+ *
+ * @param Model $model
+ * @param string $customer_id
+ *
+ * @return string
+ */
+ public function getCreationDate($model, $customer_id)
+ {
+ $customer = $model->getCustomer($customer_id);
+
+ return $customer['date_added'];
+ }
+
+ /**
+ * Finds the date when current shipping address has been used for the first time
+ *
+ * @param Model $model
+ * @param array $order_info
+ *
+ * @return string
+ */
+ public function findShippingAddressDateFirstUsed($model, $order_info, $customer_orders)
+ {
+ $cart_shipping_address = [
+ $order_info['shipping_firstname'],
+ $order_info['shipping_lastname'],
+ $order_info['shipping_address_1'],
+ $order_info['shipping_address_2'],
+ $order_info['shipping_postcode'],
+ $order_info['shipping_city'],
+ $order_info['shipping_zone_code'],
+ $order_info['shipping_country_id'],
+ ];
+
+ if (CommonUtils::isValidArray($customer_orders)) {
+ foreach ($customer_orders as $customer_order) {
+ $order = $model->getOrder($customer_order['order_id']);
+ $order_shipping_address = [
+ $order['shipping_firstname'],
+ $order['shipping_lastname'],
+ $order['shipping_address_1'],
+ $order['shipping_address_2'],
+ $order['shipping_postcode'],
+ $order['shipping_city'],
+ $order['shipping_zone_code'],
+ $order['shipping_country_id'],
+ ];
+
+ if (count(array_diff($cart_shipping_address, $order_shipping_address)) === 0) {
+ return $customer_order['date_added'];
+ }
+ }
+ }
+
+ return (new DateTime())->format(self::OC_DATETIME_FORMAT);
+ }
+
+ /**
+ * How many orders has been placed for a given period
+ *
+ * @param Model $model
+ *
+ * @return array
+ *
+ * @throws Exception
+ */
+ public function findNumberOfOrdersForaPeriod($model, $customer_orders)
+ {
+ $customer_orders = array_reverse($customer_orders);
+ $start_date_last_24h = (new DateTime())->sub(new DateInterval(self::ACTIVITY_24_HOURS));
+ $start_date_last_6m = (new DateTime())->sub(new DateInterval(self::ACTIVITY_6_MONTHS));
+ $start_date_last_year = (new DateTime())->sub(new DateInterval(self::ACTIVITY_1_YEAR));
+
+ $number_of_orders_last_24h = 0;
+ $number_of_orders_last_6m = 0;
+ $number_of_orders_last_year = 0;
+
+ if (CommonUtils::isValidArray($customer_orders)) {
+ foreach ($customer_orders as $customer_order) {
+ $order_date = DateTime::createFromFormat(
+ self::OC_DATETIME_FORMAT,
+ $customer_order['date_added']
+ );
+
+ // We don't need orders older than a year
+ if ($order_date < $start_date_last_year) {
+ break;
+ }
+
+ // Get order details only if the order was placed within the last 6 months
+ if ($order_date >= $start_date_last_6m) {
+ $order = $model->getOrder($customer_order['order_id']);
+
+ // Check if the order status is complete or shipped
+ $number_of_orders_last_6m += (in_array($order['order_status_id'], $this->complete_statuses)) ? 1 : 0;
+ }
+
+ $number_of_orders_last_24h += ($order_date >= $start_date_last_24h) ? 1 : 0;
+ $number_of_orders_last_year++;
+ }
+ }
+
+ return [
+ 'last_24h' => $number_of_orders_last_24h,
+ 'last_6m' => $number_of_orders_last_6m,
+ 'last_year' => $number_of_orders_last_year
+ ];
+ }
+
+ /**
+ * Get list of customer orders, filtered by payment code
+ *
+ * @param object $db_obj database object
+ * @param int $customer_id current customer's id
+ * @param int $store_id Store id from config file
+ * @param int $language_id Language id from config, to have translated order's status
+ * @param string $payment_code We want to check for particular payment method
+ *
+ * @return array
+ */
+ public static function getCustomerOrders($db_obj, $customer_id, $store_id, $language_id, $payment_code)
+ {
+ $raw_query = sprintf("
+ SELECT
+ o.order_id,
+ o.firstname,
+ o.lastname,
+ os.name as status,
+ o.date_added,
+ o.total,
+ o.currency_code,
+ o.currency_value
+ FROM
+ `%1\$sorder` o
+ LEFT JOIN
+ %1\$sorder_status os ON (o.order_status_id = os.order_status_id)
+ WHERE
+ o.customer_id = '%2\$d' AND
+ o.order_status_id > 0 AND
+ o.store_id = '%3\$d' AND
+ os.language_id = '%4\$d' AND
+ JSON_SEARCH(o.payment_method, 'one', '%5\$s') IS NOT NULL
+ ORDER BY
+ o.date_added ASC",
+ DB_PREFIX,
+ $customer_id,
+ $store_id,
+ $language_id,
+ $payment_code
+ );
+ $query = $db_obj->query($raw_query);
+
+ return $query->rows;
+ }
+
+ /**
+ * Returns formatted array with available threeds challenge indicators
+ *
+ * @return array
+ */
+ public function getThreedsChallengeIndicators()
+ {
+ $data = [];
+ $challenge_indicators = [
+ ChallengeIndicators::NO_PREFERENCE => 'No preference',
+ ChallengeIndicators::NO_CHALLENGE_REQUESTED => 'No challenge requested',
+ ChallengeIndicators::PREFERENCE => 'Preference',
+ ChallengeIndicators::MANDATE => 'Mandate'
+ ];
+
+ foreach ($challenge_indicators as $value => $label) {
+ $data[] = [
+ 'id' => $value,
+ 'name' => $label
+ ];
+ }
+
+ return $data;
+ }
+
+ /**
+ * Compare billing and shipping addresses
+ *
+ * @param array $order_info
+ *
+ * @return bool
+ */
+ private function areAddressesSame($order_info)
+ {
+ $shipping = [
+ $order_info['shipping_firstname'],
+ $order_info['shipping_lastname'],
+ $order_info['shipping_address_1'],
+ $order_info['shipping_address_2'],
+ $order_info['shipping_postcode'],
+ $order_info['shipping_city'],
+ $order_info['shipping_zone_code'],
+ $order_info['shipping_iso_code_2'],
+ ];
+
+ $billing = [
+ $order_info['payment_firstname'],
+ $order_info['payment_lastname'],
+ $order_info['payment_address_1'],
+ $order_info['payment_address_2'],
+ $order_info['payment_postcode'],
+ $order_info['payment_city'],
+ $order_info['payment_zone_code'],
+ $order_info['payment_iso_code_2'],
+ ];
+
+ return count(array_diff($shipping, $billing) ) === 0;
+ }
+
+ /**
+ * Returns distinct array of all bought products by this customer
+ *
+ * @param Model $model
+ * @param array $customer_orders
+ *
+ * @return array
+ */
+ private function getBoughtProducts($model, $customer_orders)
+ {
+ $bought_products = [];
+ $order_ids = array_column($customer_orders, 'order_id');
+
+ foreach ($order_ids as $order_id) {
+ $order_products = $model->getProducts($order_id);
+ $bought_products = array_merge($bought_products, array_column($order_products, 'product_id'));
+ }
+
+ return $bought_products;
+ }
+
+ /**
+ * Get indicator value according the given period of time
+ *
+ * @param string $date
+ * @param string $indicator_class
+ *
+ * @return string
+ */
+ private function getIndicatorValue($date, $indicator_class)
+ {
+ switch ($this->getDateIndicator($date)) {
+ case static::LESS_THAN_30_DAYS_INDICATOR:
+ return $indicator_class::LESS_THAN_30DAYS;
+ case static::MORE_THAN_30_LESS_THAN_60_INDICATOR:
+ return $indicator_class::FROM_30_TO_60_DAYS;
+ case static::MORE_THAN_60_DAYS_INDICATOR:
+ return $indicator_class::MORE_THAN_60DAYS;
+ default:
+ return $indicator_class::CURRENT_TRANSACTION;
+ }
+ }
+
+ /**
+ * Check if date is less than 30, between 30 and 60 or more than 60 days
+ *
+ * @param string $date
+ *
+ * @return string
+ */
+ private function getDateIndicator($date)
+ {
+ $now = new DateTime();
+ $check_date = DateTime::createFromFormat(self::OC_DATETIME_FORMAT, $date);
+ $days = $check_date->diff($now)->days;
+
+ if ($days < 1) {
+ return self::CURRENT_TRANSACTION_INDICATOR;
+ }
+ if ($days < 30) {
+ return self::LESS_THAN_30_DAYS_INDICATOR;
+ }
+ if ($days < 60) {
+ return self::MORE_THAN_30_LESS_THAN_60_INDICATOR;
+ }
+
+ return self::MORE_THAN_60_DAYS_INDICATOR;
+ }
+}
diff --git a/system/emerchantpay_helper.php b/system/emerchantpay_helper.php
index bf0d5f2..c80a8d8 100644
--- a/system/emerchantpay_helper.php
+++ b/system/emerchantpay_helper.php
@@ -248,4 +248,18 @@ public static function isSecureConnection($request): bool
return false;
}
+
+ /**
+ * Return the first ip address from the list
+ *
+ * @param string $remote_address
+ *
+ * @return string
+ */
+ public static function getFirstRemoteAddress($remote_address): string
+ {
+ $ips = explode(",", $remote_address);
+
+ return trim($ips[0]);
+ }
}
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Constants/BankAccountTypes.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Constants/BankAccountTypes.php
index c659505..64eb841 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Constants/BankAccountTypes.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Constants/BankAccountTypes.php
@@ -46,12 +46,18 @@ class BankAccountTypes
*/
const MAESTRA_ACCOUNTS = 'M';
+ /**
+ * P: for Payment accounts
+ */
+ const PAYMENT_ACCOUNT = 'P';
+
public static function getAll()
{
return [
self::CHECKING_ACCOUNT,
self::SAVINGS_ACCOUNT,
- self::MAESTRA_ACCOUNTS
+ self::MAESTRA_ACCOUNTS,
+ self::PAYMENT_ACCOUNT
];
}
}
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Constants/Transaction/CustomRequiredParameters.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Constants/Transaction/CustomRequiredParameters.php
index d29eaba..9418122 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Constants/Transaction/CustomRequiredParameters.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Constants/Transaction/CustomRequiredParameters.php
@@ -110,4 +110,16 @@ public static function forKlarnaAuthorize()
'billing_country' => Authorize::getAllowedCountries()
];
}
+
+ /**
+ * Required custom attribute for Paysafecard
+ *
+ * @return array
+ */
+ public static function forPaysafecard()
+ {
+ return [
+ 'customer_id' => null
+ ];
+ }
}
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Constants/Transaction/States.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Constants/Transaction/States.php
index c3e36ad..1da8126 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Constants/Transaction/States.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Constants/Transaction/States.php
@@ -54,6 +54,7 @@
* @method bool isTimeout()
* @method bool isChargebacked()
* @method bool isChargebackReversed()
+ * @method bool isRepresentmentReversed()
* @method bool isPreArbitrated()
* @method bool isActive()
* @method bool isInvalidated()
@@ -207,6 +208,11 @@ class States
*/
const CHARGEBACK_REVERSAL = 'chargeback_reversal';
+ /**
+ * Once a represented transaction is reversed, the state changes to representment reversed.
+ */
+ const REPRESENTMENT_REVERSED = 'representment_reversed';
+
/**
* The transaction is on hold, a manual review needs to be performed.
*/
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request.php
index ab2032d..892c95f 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request.php
@@ -349,8 +349,7 @@ protected function initApiGatewayConfiguration(
$requestPath = 'process',
$includeToken = true,
$subdomain = 'gateway'
- )
- {
+ ) {
$this->setApiConfig(
'url',
$this->buildRequestURL(
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Base/Financial.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Base/Financial.php
index 95e91f0..a796a33 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Base/Financial.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Base/Financial.php
@@ -26,7 +26,8 @@
namespace Genesis\API\Request\Base;
use Genesis\API\Traits\Request\BaseAttributes;
-use Genesis\API\Validators\Request\Base\Validator as RequestValidator;
+use Genesis\Config;
+use Genesis\Exceptions\EnvironmentNotSet;
use Genesis\Utils\Common as CommonUtils;
/**
@@ -35,11 +36,33 @@
* Base Abstract Class for all Financial Requests
*
* @package Genesis\API\Request\Base
+ *
+ * @method getUseSmartRouter() Get Smart Router usage. Whether Financial transaction endpoint is a Smart Router or not.
*/
abstract class Financial extends \Genesis\API\Request
{
use BaseAttributes;
+ /**
+ * Force Smart Router endpoint for Financial transactions
+ *
+ * @var bool
+ */
+ protected $use_smart_router = false;
+
+ /**
+ * Use Smart Router endpoint for Financial transactions
+ *
+ * @param $value
+ * @return $this
+ */
+ public function setUseSmartRouter($value)
+ {
+ $this->use_smart_router = CommonUtils::toBoolean($value);
+
+ return $this;
+ }
+
/**
* Returns the Request transaction type
* @return string
@@ -54,27 +77,37 @@ abstract protected function getPaymentTransactionStructure();
/**
* Initialize per-request configuration
+ *
+ * @throws EnvironmentNotSet
*/
protected function initConfiguration()
{
$this->initXmlConfiguration();
$this->initApiGatewayConfiguration();
+
+ if (Config::getForceSmartRouting()) {
+ $this->initializeSmartRouter();
+ }
}
/**
- * Perform field validation
+ * Process Request Params
*
* @return void
- * @throws \Genesis\Exceptions\InvalidArgument
+ *
+ * @throws EnvironmentNotSet
* @throws \Genesis\Exceptions\ErrorParameter
+ * @throws \Genesis\Exceptions\InvalidArgument
* @throws \Genesis\Exceptions\InvalidClassMethod
*/
- protected function checkRequirements()
+ protected function processRequestParameters()
{
- parent::checkRequirements();
+ if ($this->getUseSmartRouter()) {
+ $this->initializeSmartRouter();
+ }
- $this->validateConditionalValuesRequirements();
+ parent::processRequestParameters();
}
/**
@@ -97,4 +130,15 @@ protected function populateStructure()
$this->treeStructure = \Genesis\Utils\Common::createArrayObject($treeStructure);
}
+
+ /**
+ * Initialize Smart Router endpoint
+ *
+ * @return void
+ * @throws \Genesis\Exceptions\EnvironmentNotSet
+ */
+ protected function initializeSmartRouter()
+ {
+ $this->initApiGatewayConfiguration('transactions', false, 'smart_router');
+ }
}
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Authorize.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Authorize.php
index 6bd9935..9de00a3 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Authorize.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Authorize.php
@@ -39,6 +39,7 @@
use Genesis\API\Traits\Request\MotoAttributes;
use Genesis\API\Traits\Request\AddressInfoAttributes;
use Genesis\API\Traits\Request\RiskAttributes;
+use Genesis\API\Traits\Request\Financial\AccountOwnerAttributes;
use Genesis\API\Traits\Request\Financial\DescriptorAttributes;
use Genesis\API\Traits\Request\Financial\TravelData\TravelDataAttributes;
use Genesis\API\Traits\Request\Financial\FundingAttributes;
@@ -56,7 +57,8 @@ class Authorize extends \Genesis\API\Request\Base\Financial\Cards\CreditCard
use GamingAttributes, MotoAttributes, AddressInfoAttributes, RiskAttributes, DescriptorAttributes,
PreauthorizationAttributes, TravelDataAttributes, FxRateAttributes,
CryptoAttributes, BusinessAttributes, ScaAttributes, UcofAttributes, RecurringTypeAttributes,
- ManagedRecurringAttributes, RecurringCategoryAttributes, ReferenceAttributes, FundingAttributes;
+ ManagedRecurringAttributes, RecurringCategoryAttributes, ReferenceAttributes, FundingAttributes,
+ AccountOwnerAttributes;
/**
* Returns the Request transaction type
@@ -148,7 +150,8 @@ protected function getTransactionAttributes()
'managed_recurring' => $this->getManagedRecurringAttributesStructure(),
'recurring_category' => $this->recurring_category,
'reference_id' => $this->reference_id,
- 'funding' => $this->getFundingAttributesStructure()
+ 'funding' => $this->getFundingAttributesStructure(),
+ 'account_owner' => $this->getAccountOwnerAttributesStructure()
],
$this->getScaAttributesStructure(),
$this->getUcofAttributesStructure()
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Authorize3D.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Authorize3D.php
index 7b41837..5c277f6 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Authorize3D.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Authorize3D.php
@@ -39,6 +39,7 @@
use Genesis\API\Traits\Request\Financial\AsyncAttributes;
use Genesis\API\Traits\Request\AddressInfoAttributes;
use Genesis\API\Traits\Request\RiskAttributes;
+use Genesis\API\Traits\Request\Financial\AccountOwnerAttributes;
use Genesis\API\Traits\Request\Financial\DescriptorAttributes;
use Genesis\API\Traits\Request\Financial\FundingAttributes;
use Genesis\API\Traits\Request\Financial\TravelData\TravelDataAttributes;
@@ -59,7 +60,7 @@ class Authorize3D extends \Genesis\API\Request\Base\Financial\Cards\CreditCard3D
RiskAttributes, DescriptorAttributes, PreauthorizationAttributes, TravelDataAttributes,
ScaAttributes, FxRateAttributes, CryptoAttributes, BusinessAttributes,
RecurringTypeAttributes, ManagedRecurringAttributes, RecurringCategoryAttributes,
- FundingAttributes;
+ FundingAttributes, AccountOwnerAttributes;
/**
* Returns the Request transaction type
@@ -166,7 +167,8 @@ protected function getTransactionAttributes()
'recurring_type' => $this->getRecurringType(),
'managed_recurring' => $this->getManagedRecurringAttributesStructure(),
'recurring_category' => $this->recurring_category,
- 'funding' => $this->getFundingAttributesStructure()
+ 'funding' => $this->getFundingAttributesStructure(),
+ 'account_owner' => $this->getAccountOwnerAttributesStructure()
],
$this->getScaAttributesStructure(),
$this->get3DSTransactionAttributes()
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Credit.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Credit.php
index 0f973da..bc0a50f 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Credit.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Credit.php
@@ -25,6 +25,7 @@
namespace Genesis\API\Request\Financial\Cards;
+use Genesis\API\Traits\Request\Financial\AccountOwnerAttributes;
use Genesis\API\Traits\Request\Financial\CustomerIdentificationData;
use Genesis\API\Traits\Request\Financial\SourceOfFundsAttributes;
@@ -37,7 +38,7 @@
*/
class Credit extends \Genesis\API\Request\Base\Financial\Reference
{
- use SourceOfFundsAttributes, CustomerIdentificationData;
+ use SourceOfFundsAttributes, CustomerIdentificationData, AccountOwnerAttributes;
/**
* Returns the Request transaction type
@@ -59,7 +60,8 @@ protected function getPaymentTransactionStructure()
parent::getPaymentTransactionStructure(),
$this->getSourceOfFundsStructure(),
[
- 'customer_identification' => $this->getCustomerIdentificationDataStructure()
+ 'customer_identification' => $this->getCustomerIdentificationDataStructure(),
+ 'account_owner' => $this->getAccountOwnerAttributesStructure()
]
);
}
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Payout.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Payout.php
index 84c7b7b..87e14ec 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Payout.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Payout.php
@@ -29,6 +29,7 @@
use Genesis\API\Traits\Request\Financial\DescriptorAttributes;
use Genesis\API\Traits\Request\Financial\FxRateAttributes;
use Genesis\API\Traits\Request\AddressInfoAttributes;
+use Genesis\API\Traits\Request\Financial\AccountOwnerAttributes;
use Genesis\API\Traits\Request\Financial\SourceOfFundsAttributes;
use Genesis\API\Traits\Request\Payout\MoneyTransferPayoutAttributes;
use Genesis\Utils\Common as CommonUtils;
@@ -44,7 +45,7 @@ class Payout extends \Genesis\API\Request\Base\Financial\Cards\CreditCard
{
use AddressInfoAttributes, SourceOfFundsAttributes,
FxRateAttributes, DescriptorAttributes, MoneyTransferPayoutAttributes,
- CustomerIdentificationData;
+ CustomerIdentificationData, AccountOwnerAttributes;
const MONEY_TRANSFER_SENDER_ACCOUNT_NUMBER_MAX_LENGTH = 33;
const MONEY_TRANSFER_SERVICE_PROVIDER_NAME_MAX_LENGTH = 25;
@@ -91,6 +92,7 @@ protected function getTransactionAttributes()
'dynamic_descriptor_params' => $this->getDynamicDescriptorParamsStructure(),
'money_transfer' => $this->getMoneyTransferPayoutStructure(),
'customer_identification' => $this->getCustomerIdentificationDataStructure(),
+ 'account_owner' => $this->getAccountOwnerAttributesStructure()
],
$this->getSourceOfFundsStructure()
);
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Recurring/InitRecurringSale.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Recurring/InitRecurringSale.php
index ddd5713..042ce9c 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Recurring/InitRecurringSale.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Recurring/InitRecurringSale.php
@@ -32,6 +32,7 @@
use Genesis\API\Traits\Request\MotoAttributes;
use Genesis\API\Traits\Request\AddressInfoAttributes;
use Genesis\API\Traits\Request\RiskAttributes;
+use Genesis\API\Traits\Request\Financial\AccountOwnerAttributes;
use Genesis\API\Traits\Request\Financial\DescriptorAttributes;
use Genesis\API\Traits\Request\Financial\FundingAttributes;
use Genesis\API\Traits\Request\Financial\TravelData\TravelDataAttributes;
@@ -48,7 +49,7 @@ class InitRecurringSale extends \Genesis\API\Request\Base\Financial\Cards\Credit
{
use MotoAttributes, AddressInfoAttributes, RiskAttributes, DescriptorAttributes,
TravelDataAttributes, FxRateAttributes, BusinessAttributes,
- ManagedRecurringAttributes, RecurringCategoryAttributes, FundingAttributes;
+ ManagedRecurringAttributes, RecurringCategoryAttributes, FundingAttributes, AccountOwnerAttributes;
/**
* Returns the Request transaction type
@@ -112,7 +113,8 @@ protected function getTransactionAttributes()
'business_attributes' => $this->getBusinessAttributesStructure(),
'managed_recurring' => $this->getManagedRecurringAttributesStructure(),
'recurring_category' => $this->recurring_category,
- 'funding' => $this->getFundingAttributesStructure()
+ 'funding' => $this->getFundingAttributesStructure(),
+ 'account_owner' => $this->getAccountOwnerAttributesStructure()
];
}
}
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Recurring/InitRecurringSale3D.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Recurring/InitRecurringSale3D.php
index 282c845..db0fbea 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Recurring/InitRecurringSale3D.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Recurring/InitRecurringSale3D.php
@@ -35,6 +35,7 @@
use Genesis\API\Traits\Request\Financial\AsyncAttributes;
use Genesis\API\Traits\Request\AddressInfoAttributes;
use Genesis\API\Traits\Request\RiskAttributes;
+use Genesis\API\Traits\Request\Financial\AccountOwnerAttributes;
use Genesis\API\Traits\Request\Financial\DescriptorAttributes;
use Genesis\API\Traits\Request\Financial\FundingAttributes;
use Genesis\API\Traits\Request\Financial\TravelData\TravelDataAttributes;
@@ -54,7 +55,7 @@ class InitRecurringSale3D extends \Genesis\API\Request\Base\Financial\Cards\Cred
use MotoAttributes, NotificationAttributes, AsyncAttributes, AddressInfoAttributes,
RiskAttributes, DescriptorAttributes, TravelDataAttributes, ScaAttributes,
FxRateAttributes, BusinessAttributes,
- ManagedRecurringAttributes, RecurringCategoryAttributes, FundingAttributes;
+ ManagedRecurringAttributes, RecurringCategoryAttributes, FundingAttributes, AccountOwnerAttributes;
/**
* Returns the Request transaction type
@@ -154,7 +155,8 @@ protected function getTransactionAttributes()
'business_attributes' => $this->getBusinessAttributesStructure(),
'managed_recurring' => $this->getManagedRecurringAttributesStructure(),
'recurring_category' => $this->recurring_category,
- 'funding' => $this->getFundingAttributesStructure()
+ 'funding' => $this->getFundingAttributesStructure(),
+ 'account_owner' => $this->getAccountOwnerAttributesStructure()
],
$this->getScaAttributesStructure(),
$this->get3DSTransactionAttributes()
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Sale.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Sale.php
index 7f4d9d0..48ecd4e 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Sale.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Sale.php
@@ -37,6 +37,7 @@
use Genesis\API\Traits\Request\MotoAttributes;
use Genesis\API\Traits\Request\AddressInfoAttributes;
use Genesis\API\Traits\Request\RiskAttributes;
+use Genesis\API\Traits\Request\Financial\AccountOwnerAttributes;
use Genesis\API\Traits\Request\Financial\DescriptorAttributes;
use Genesis\API\Traits\Request\Financial\ReferenceAttributes;
use Genesis\API\Traits\Request\Financial\FundingAttributes;
@@ -56,7 +57,7 @@ class Sale extends \Genesis\API\Request\Base\Financial\Cards\CreditCard
use GamingAttributes, MotoAttributes, AddressInfoAttributes, RiskAttributes, DescriptorAttributes,
ReferenceAttributes, TravelDataAttributes, FxRateAttributes, CryptoAttributes,
BusinessAttributes, ScaAttributes, UcofAttributes, RecurringTypeAttributes,
- ManagedRecurringAttributes, RecurringCategoryAttributes, FundingAttributes;
+ ManagedRecurringAttributes, RecurringCategoryAttributes, FundingAttributes, AccountOwnerAttributes;
/**
* Returns the Request transaction type
@@ -147,7 +148,8 @@ protected function getTransactionAttributes()
'recurring_type' => $this->getRecurringType(),
'managed_recurring' => $this->getManagedRecurringAttributesStructure(),
'recurring_category' => $this->recurring_category,
- 'funding' => $this->getFundingAttributesStructure()
+ 'funding' => $this->getFundingAttributesStructure(),
+ 'account_owner' => $this->getAccountOwnerAttributesStructure()
],
$this->getScaAttributesStructure(),
$this->getUcofAttributesStructure()
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Sale3D.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Sale3D.php
index b676c3a..8369ebc 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Sale3D.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Cards/Sale3D.php
@@ -38,6 +38,7 @@
use Genesis\API\Traits\Request\Financial\AsyncAttributes;
use Genesis\API\Traits\Request\AddressInfoAttributes;
use Genesis\API\Traits\Request\RiskAttributes;
+use Genesis\API\Traits\Request\Financial\AccountOwnerAttributes;
use Genesis\API\Traits\Request\Financial\DescriptorAttributes;
use Genesis\API\Traits\Request\Financial\ReferenceAttributes;
use Genesis\API\Traits\Request\Financial\FundingAttributes;
@@ -59,7 +60,7 @@ class Sale3D extends \Genesis\API\Request\Base\Financial\Cards\CreditCard3D
AddressInfoAttributes, RiskAttributes, DescriptorAttributes,
ReferenceAttributes, TravelDataAttributes, ScaAttributes, FxRateAttributes,
CryptoAttributes, BusinessAttributes, RecurringTypeAttributes,
- ManagedRecurringAttributes, RecurringCategoryAttributes, FundingAttributes;
+ ManagedRecurringAttributes, RecurringCategoryAttributes, FundingAttributes, AccountOwnerAttributes;
/**
* Returns the Request transaction type
@@ -166,7 +167,8 @@ protected function getTransactionAttributes()
'recurring_type' => $this->getRecurringType(),
'managed_recurring' => $this->getManagedRecurringAttributesStructure(),
'recurring_category' => $this->recurring_category,
- 'funding' => $this->getFundingAttributesStructure()
+ 'funding' => $this->getFundingAttributesStructure(),
+ 'account_owner' => $this->getAccountOwnerAttributesStructure()
],
$this->getScaAttributesStructure(),
$this->get3DSTransactionAttributes()
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Mobile/GooglePay.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Mobile/GooglePay.php
index 15ad167..da9f67f 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Mobile/GooglePay.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/Mobile/GooglePay.php
@@ -29,10 +29,12 @@
use Genesis\API\Constants\Transaction\Types as TransactionType;
use Genesis\API\Request\Base\Financial;
use Genesis\API\Traits\Request\DocumentAttributes;
+use Genesis\API\Traits\Request\Financial\AsyncAttributes;
use Genesis\API\Traits\Request\Financial\BirthDateAttributes;
use Genesis\API\Traits\Request\AddressInfoAttributes;
use Genesis\API\Traits\Request\Financial\Business\BusinessAttributes;
use Genesis\API\Traits\Request\Financial\DescriptorAttributes;
+use Genesis\API\Traits\Request\Financial\NotificationAttributes;
use Genesis\API\Traits\Request\Financial\PaymentAttributes;
use Genesis\API\Traits\Request\Financial\Threeds\V2\AllAttributes as AllThreedsV2Attributes;
use Genesis\API\Traits\Request\Mobile\GooglePayAttributes;
@@ -51,7 +53,7 @@ class GooglePay extends Financial
{
use AddressInfoAttributes, PaymentAttributes, GooglePayAttributes,
BirthDateAttributes, BusinessAttributes, DocumentAttributes,
- DescriptorAttributes, AllThreedsV2Attributes;
+ DescriptorAttributes, AllThreedsV2Attributes, NotificationAttributes, AsyncAttributes;
/**
* Used in Google token for signatures array
@@ -156,6 +158,9 @@ public function getPaymentTransactionStructure()
'customer_email' => $this->customer_email,
'customer_phone' => $this->customer_phone,
'birth_date' => $this->getBirthDate(),
+ 'notification_url' => $this->notification_url,
+ 'return_success_url' => $this->return_success_url,
+ 'return_failure_url' => $this->return_failure_url,
'billing_address' => $this->getBillingAddressParamsStructure(),
'shipping_address' => $this->getShippingAddressParamsStructure(),
'business_attributes' => $this->getBusinessAttributesStructure(),
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/OnlineBankingPayments/OnlineBanking/Payout.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/OnlineBankingPayments/OnlineBanking/Payout.php
index 8a3a411..4d01f6c 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/OnlineBankingPayments/OnlineBanking/Payout.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/OnlineBankingPayments/OnlineBanking/Payout.php
@@ -134,6 +134,7 @@ class Payout extends \Genesis\API\Request\Base\Financial
* C: for Checking accounts
* S: for Savings accounts
* M: for Maestra accounts(Only Peru)
+ * P: for Payment accounts
*
* @var string $bank_account_type
*/
@@ -456,16 +457,13 @@ protected function validateBRLCurrency()
}
$requiredFieldsGroups = [
- 'currency' => ['bank_code', 'bank_name'],
+ 'BRL Currency' => ['bank_code', 'bank_name']
];
$this->requiredFieldsGroups = Common::createArrayObject($requiredFieldsGroups);
- // Allow empty bank_name with non-empty bank_code
- if (!empty($this->bank_code)) {
- $requiredFieldValuesConditional = (array)$this->requiredFieldValuesConditional;
- $requiredFieldValuesConditional['currency']['BRL'][] = ['bank_code' => $this->bank_code];
-
- $this->requiredFieldValuesConditional = Common::createArrayObject($requiredFieldValuesConditional);
+ // Allow empty bank_name, only with Group bank_code and bank_name requirement
+ if (empty($this->bank_name)) {
+ unset($this->requiredFieldValuesConditional['currency']['BRL']);
}
}
}
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/SDD/Sale.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/SDD/Sale.php
index 56765c2..9ac86f1 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/SDD/Sale.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/Financial/SDD/Sale.php
@@ -29,6 +29,7 @@
use Genesis\API\Traits\Request\AddressInfoAttributes;
use Genesis\API\Traits\Request\Financial\BankAttributes;
use Genesis\API\Traits\Request\Financial\AsyncAttributes;
+use Genesis\API\Traits\Request\Financial\PendingPaymentAttributes;
/**
* Class Sale
@@ -39,7 +40,7 @@
*/
class Sale extends \Genesis\API\Request\Base\Financial
{
- use PaymentAttributes, AddressInfoAttributes, BankAttributes, AsyncAttributes;
+ use PaymentAttributes, AddressInfoAttributes, BankAttributes, AsyncAttributes, PendingPaymentAttributes;
/**
* Name of the company
@@ -113,7 +114,8 @@ protected function getPaymentTransactionStructure()
'billing_address' => $this->getBillingAddressParamsStructure(),
'shipping_address' => $this->getShippingAddressParamsStructure(),
'return_success_url' => $this->return_success_url,
- 'return_failure_url' => $this->return_failure_url
+ 'return_failure_url' => $this->return_failure_url,
+ 'return_pending_url' => $this->getReturnPendingUrl()
];
}
}
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/WPF/Create.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/WPF/Create.php
index 307b663..3b5ad69 100755
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/WPF/Create.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Request/WPF/Create.php
@@ -39,6 +39,7 @@
use Genesis\API\Traits\Request\RiskAttributes;
use Genesis\API\Traits\Request\Financial\DescriptorAttributes;
use Genesis\API\Traits\Request\Financial\FundingAttributes;
+use Genesis\API\Traits\Request\Financial\AccountOwnerAttributes;
use Genesis\Exceptions\ErrorParameter;
use Genesis\Exceptions\InvalidArgument;
use Genesis\Utils\Common;
@@ -78,7 +79,7 @@ class Create extends \Genesis\API\Request
NotificationAttributes, RiskAttributes, DescriptorAttributes,
BusinessAttributes, WpfThreedsV2Attributes,
PendingPaymentAttributes, RecurringCategoryAttributes,
- FundingAttributes;
+ FundingAttributes, AccountOwnerAttributes;
const REMINDERS_CHANNEL_EMAIL = 'email';
const REMINDERS_CHANNEL_SMS = 'sms';
@@ -702,7 +703,8 @@ protected function populateStructure()
'threeds_v2_params' => $this->getThreedsV2ParamsStructure(),
'web_payment_form_id' => $this->web_payment_form_id,
'recurring_category' => $this->recurring_category,
- 'funding' => $this->getFundingAttributesStructure()
+ 'funding' => $this->getFundingAttributesStructure(),
+ 'account_owner' => $this->getAccountOwnerAttributesStructure()
]
];
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Traits/Request/Financial/AccountOwnerAttributes.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Traits/Request/Financial/AccountOwnerAttributes.php
new file mode 100644
index 0000000..42fddf6
--- /dev/null
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Traits/Request/Financial/AccountOwnerAttributes.php
@@ -0,0 +1,78 @@
+ $this->account_first_name,
+ 'middle_name' => $this->account_middle_name,
+ 'last_name' => $this->account_last_name
+ ];
+ }
+}
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Traits/Request/Mobile/ApplePayAttributes.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Traits/Request/Mobile/ApplePayAttributes.php
index 99eb639..f71b717 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Traits/Request/Mobile/ApplePayAttributes.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/API/Traits/Request/Mobile/ApplePayAttributes.php
@@ -37,6 +37,13 @@
* @method $this setTokenNetwork($value) Sets payment network describes the backing the card
* @method $this setTokenType($value) Sets card’s type
* @method $this setTokenTransactionIdentifier($value) Sets a unique identifier for this payment.
+* @method $this setTokenApplicationData($value) Optional. Hash of the applicationData property of the original
+* PKPaymentRequest object for transactions that initiate in apps.
+* For transactions that initiate in Apple Pay on the Web, the value is
+* the hash of applicationData in ApplePayPaymentRequest or of
+* applicationData in ApplePayRequest. This key is omitted if the value of
+* that property is nil.
+* @method $this setTokenWrappedKey($value) The symmetric key wrapped using your RSA public key. RSA_v1 only.
*/
trait ApplePayAttributes
{
@@ -116,6 +123,25 @@ trait ApplePayAttributes
*/
protected $token_transaction_identifier;
+ /**
+ * Optional. Hash of the applicationData property of the original PKPaymentRequest object for transactions that
+ * initiate in apps. For transactions that initiate in Apple Pay on the Web, the value is the hash of
+ * applicationData in ApplePayPaymentRequest or of applicationData in ApplePayRequest.
+ *
+ * This key is omitted if the value of that property is nil.
+ *
+ * @var string
+ */
+ protected $token_application_data;
+
+ /**
+ * The symmetric key wrapped using your RSA public key.
+ * RSA_v1 only.
+ *
+ * @var string
+ */
+ protected $token_wrapped_key;
+
public function getPaymentTokenStructure()
{
return json_encode([
@@ -124,7 +150,9 @@ public function getPaymentTokenStructure()
'data' => $this->token_data,
'signature' => $this->token_signature,
'header' => [
+ 'applicationData' => $this->token_application_data,
'ephemeralPublicKey' => $this->token_ephemeral_public_key,
+ 'wrappedKey' => $this->token_wrapped_key,
'publicKeyHash' => $this->token_public_key_hash,
'transactionId' => $this->token_transaction_id
]
diff --git a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/Config.php b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/Config.php
index 4114712..a1bec82 100644
--- a/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/Config.php
+++ b/system/storage/vendor/genesisgateway/genesis_php/src/Genesis/Config.php
@@ -24,6 +24,8 @@
*/
namespace Genesis;
+use Genesis\Utils\Common as CommonUtils;
+
/**
* Class Config
*
@@ -31,20 +33,21 @@
*
* @package Genesis
*
- * @method static string getUsername() Get the Username, set in configuration
- * @method static string getPassword() Get the Password, set in the configuration
- * @method static string getToken() Get the Terminal Token, set in configuration
+ * @method static string getUsername() Get the Username, set in configuration
+ * @method static string getPassword() Get the Password, set in the configuration
+ * @method static string getToken() Get the Terminal Token, set in configuration
+ * @method static bool getForceSmartRouting() Get whether Smart Routing endpoint will be used for Financial types
*
- * @method static \Genesis\Config setUsername($value) Set the Username
- * @method static \Genesis\Config setPassword($value) Set the Password
- * @method static \Genesis\Config setToken($value) Set the Terminal
+ * @method static null setUsername($value) Set the Username
+ * @method static null setPassword($value) Set the Password
+ * @method static null setToken($value) Set the Terminal
*/
final class Config
{
/**
* Library Version
*/
- const VERSION = '1.23.0';
+ const VERSION = '1.24.2';
/**
* Core configuration settings
@@ -52,11 +55,12 @@ final class Config
* @var array
*/
public static $vault = [
- 'endpoint' => null,
- 'username' => null,
- 'password' => null,
- 'token' => null,
- 'environment' => \Genesis\API\Constants\Environments::STAGING
+ 'endpoint' => null,
+ 'username' => null,
+ 'password' => null,
+ 'token' => null,
+ 'environment' => \Genesis\API\Constants\Environments::STAGING,
+ 'force_smart_routing' => false
];
/**
@@ -77,17 +81,21 @@ final class Config
* @var array
*/
public static $domains = [
- 'gateway' => [
+ 'gateway' => [
'production' => 'gate.',
'sandbox' => 'staging.gate.'
],
- 'wpf' => [
+ 'wpf' => [
'production' => 'wpf.',
'sandbox' => 'staging.wpf.'
],
- 'kyc' => [
+ 'kyc' => [
'production' => 'kyc.',
'sandbox' => 'staging.kyc.'
+ ],
+ 'smart_router' => [
+ 'production' => 'prod.api.',
+ 'sandbox' => 'staging.api.'
]
];
@@ -101,9 +109,9 @@ final class Config
*/
public static function __callStatic($method, $args)
{
- $keySetting = strtolower(substr($method, 3));
+ list($action, $keySetting) = CommonUtils::resolveDynamicMethod($method);
- switch (substr($method, 0, 3)) {
+ switch ($action) {
case 'get':
if (isset(self::$vault[$keySetting])) {
return self::$vault[$keySetting];
@@ -117,26 +125,6 @@ public static function __callStatic($method, $args)
return null;
}
- /**
- * Get the CA PEM
- *
- * @return string - Path to the Genesis CA Bundle; false otherwise
- *
- * @throws \Genesis\Exceptions\InvalidArgument
- */
- public static function getCertificateBundle()
- {
- $bundle = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Certificates' . DIRECTORY_SEPARATOR . 'ca-bundle.pem';
-
- if (!file_exists($bundle)) {
- throw new \Genesis\Exceptions\InvalidArgument(
- 'CA Bundle file is missing or inaccessible'
- );
- }
-
- return $bundle;
- }
-
/**
* Get configuration for an interface
*
@@ -312,6 +300,17 @@ public static function getVersion()
return self::VERSION;
}
+ /**
+ * Set Force Smart Routing endpoint for Financial types
+ *
+ * @param $value
+ * @return bool
+ */
+ public static function setForceSmartRouting($value)
+ {
+ return self::$vault['force_smart_routing'] = CommonUtils::toBoolean($value);
+ }
+
/**
* Load settings from an ini File
*
@@ -331,7 +330,9 @@ public static function loadSettings($iniFile)
foreach ($settings['Genesis'] as $option => $value) {
if (array_key_exists($option, self::$vault)) {
- self::$vault[$option] = $value;
+ $method = 'set' . CommonUtils::snakeCaseToCamelCase($option);
+
+ self::{$method}($value);
}
}