Просмотр исходного кода

Ticket #5006 - Stripe Connect: Update integration.

AntonLV 1 год назад
Родитель
Сommit
fdf854a103

+ 20 - 35
modules/boonex/russian/data/langs/bx_stripe_connect/ru.xml

@@ -1,49 +1,34 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources name="ru" flag="ru" title="Russian">
-	<string name="_bx_stripe_connect"><![CDATA[Stripe Connect]]></string>
+    <string name="_bx_stripe_connect"><![CDATA[Stripe Connect]]></string>
 
-	<!-- OPTIONS -->
-	<string name="_bx_stripe_connect_option_mode"><![CDATA[Режим]]></string>
+    <!-- OPTIONS -->
+    <string name="_bx_stripe_connect_option_mode"><![CDATA[Режим]]></string>
     <string name="_bx_stripe_connect_option_mode_live"><![CDATA[рабочий]]></string>
     <string name="_bx_stripe_connect_option_mode_test"><![CDATA[тестовый]]></string>
-    <string name="_bx_stripe_connect_option_api_id_live"><![CDATA[ID клиента (рабочий)]]></string>
     <string name="_bx_stripe_connect_option_api_public_live"><![CDATA[Открытый ключ (рабочий)]]></string>
     <string name="_bx_stripe_connect_option_api_secret_live"><![CDATA[Секретный ключ (рабочий)]]></string>
-    <string name="_bx_stripe_connect_option_api_id_test"><![CDATA[ID клиента (тестовый)]]></string>
     <string name="_bx_stripe_connect_option_api_public_test"><![CDATA[Открытый ключ (тестовый)]]></string>
     <string name="_bx_stripe_connect_option_api_secret_test"><![CDATA[Секретный ключ (тестовый)]]></string>
-    <string name="_bx_stripe_connect_option_api_scope"><![CDATA[Область действия]]></string>
-    <string name="_bx_stripe_connect_option_api_scope_read_only"><![CDATA[Только чтение]]></string>
-    <string name="_bx_stripe_connect_option_api_scope_read_write"><![CDATA[Чтение и запись]]></string>
-    <string name="_bx_stripe_connect_option_pmode_single"><![CDATA[Режим обработки единовременных выплат]]></string>
-    <string name="_bx_stripe_connect_option_fee_single"><![CDATA[Комиссия с единовременных выплат (в центах, процент)]]></string>
-    <string name="_bx_stripe_connect_option_pmode_recurring"><![CDATA[Режим обработки выплат по подписке]]></string>
+    <string name="_bx_stripe_connect_option_pmode"><![CDATA[Режим обработки выплат]]></string>
     <string name="_bx_stripe_connect_option_pmode_direct"><![CDATA[Прямой]]></string>
     <string name="_bx_stripe_connect_option_pmode_platform"><![CDATA[Платформа]]></string>
-    <string name="_bx_stripe_connect_option_fee_recurring"><![CDATA[Комиссия с выплат по подписке (только процент)]]></string>
-    <string name="_bx_stripe_connect_option_redirect_url"><![CDATA[URL перенаправления]]></string>
 
-	<!-- PAGES and BLOCKS -->
-	<string name="_bx_stripe_connect_page_title_sys_result"><![CDATA[Stripe Connect: Результаты]]></string>
-	<string name="_bx_stripe_connect_page_title_result"><![CDATA[Stripe Connect: Результаты]]></string>
-	<string name="_bx_stripe_connect_page_block_title_result"><![CDATA[Stripe Connect: Результаты]]></string>
-	<string name="_bx_stripe_connect_page_block_title_connect"><![CDATA[Stripe Connect]]></string>
+    <!-- GRIDS -->
+    <string name="_bx_stripe_connect_grid_column_title_profile_id"><![CDATA[Профиль]]></string>
+    <string name="_bx_stripe_connect_grid_column_title_live_account_id"><![CDATA[ID учетной записи (действующий)]]></string>
+    <string name="_bx_stripe_connect_grid_column_title_live_details"><![CDATA[Подробности (live)]]></string>
+    <string name="_bx_stripe_connect_grid_column_title_test_account_id"><![CDATA[ID учетной записи (тестовый)]]></string>
+    <string name="_bx_stripe_connect_grid_column_title_test_details"><![CDATA[Подробности (тестовый)]]></string>
+    <string name="_bx_stripe_connect_grid_column_title_added"><![CDATA[Добавлен]]></string>
+    <string name="_bx_stripe_connect_grid_column_title_changed"><![CDATA[Изменен]]></string>
+    <string name="_bx_stripe_connect_action_title_delete"><![CDATA[Удалить]]></string>
 
-	<!-- MENUS -->
-	<string name="_bx_stripe_connect_menu_item_title_accounts"><![CDATA[Аккаунты]]></string>
-
-	<!-- GRIDS -->
-	<string name="_bx_stripe_connect_grid_column_title_author"><![CDATA[Автор]]></string>
-	<string name="_bx_stripe_connect_grid_column_title_user_id"><![CDATA[Stripe Клиент ID]]></string>
-	<string name="_bx_stripe_connect_grid_column_title_public_key"><![CDATA[Публичный ключ]]></string>
-	<string name="_bx_stripe_connect_grid_column_title_access_token"><![CDATA[Секретный ключ]]></string>
-	<string name="_bx_stripe_connect_grid_column_title_added"><![CDATA[Присоединен]]></string>
-	<string name="_bx_stripe_connect_action_title_delete"><![CDATA[Отсоединиться]]></string>
-	
-	<!-- OTHER -->
-	<string name="_bx_stripe_connect_btn_connect"><![CDATA[Присоединиться]]></string>
-	<string name="_bx_stripe_connect_msg_connected"><![CDATA[Вы были успешно присоединены.]]></string>
-	<string name="_bx_stripe_connect_wrn_disconnect"><![CDATA[Вы уверены, что хотите отсоединиться?]]></string>
-	<string name="_bx_stripe_connect_err_perform"><![CDATA[Не удается выполнить действие. Пожалуйста сообщите.]]></string>
-	<string name="_bx_stripe_connect_log"><![CDATA[Stripe Connect]]></string>
+    <!-- OTHER -->
+    <string name="_bx_stripe_connect_btn_account_create"><![CDATA[Создать подключенную учетную запись]]></string>
+    <string name="_bx_stripe_connect_btn_account_delete"><![CDATA[Удалить подключенную учетную запись]]></string>
+    <string name="_bx_stripe_connect_btn_account_continue"><![CDATA[Продолжить создание учетной записи]]></string>
+    <string name="_bx_stripe_connect_err_delete"><![CDATA[Невозможно удалить аккаунт.]]></string>
+    <string name="_bx_stripe_connect_err_perform"><![CDATA[Не удается выполнить действие. Пожалуйста сообщите.]]></string>
+    <string name="_bx_stripe_connect_log"><![CDATA[Stripe Connect]]></string>
 </resources>

+ 95 - 0
modules/boonex/stripe_connect/classes/BxStripeConnectApi.php

@@ -0,0 +1,95 @@
+<?php defined('BX_DOL') or die('hack attempt');
+/**
+ * Copyright (c) UNA, Inc - https://una.io
+ * MIT License - https://opensource.org/licenses/MIT
+ *
+ * @defgroup    StripeConnect Stripe Connect
+ * @ingroup     TridentModules
+ *
+ * @{
+ */
+
+class BxStripeConnectApi extends BxDol
+{
+    protected $_sModule;
+    protected $_oModule;
+
+    protected $_oStripe;
+
+    public function __construct()
+    {
+        if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
+            trigger_error ('Multiple instances are not allowed for the class: ' . get_class($this), E_USER_ERROR);
+
+        parent::__construct();
+
+        $this->_sModule = 'bx_stripe_connect';
+    	$this->_oModule = BxDolModule::getInstance($this->_sModule);
+
+        $this->_oStripe = null;
+    }
+
+    public function __clone()
+    {
+        if (isset($GLOBALS['bxDolClasses'][get_class($this)]))
+            trigger_error('Clone is not allowed for the class: ' . get_class($this), E_USER_ERROR);
+    }
+    
+    public static function getInstance()
+    {
+        if(!isset($GLOBALS['bxDolClasses'][__CLASS__]))
+            $GLOBALS['bxDolClasses'][__CLASS__] = new BxStripeConnectApi();
+
+        return $GLOBALS['bxDolClasses'][__CLASS__];
+    }
+    
+    public function getStripe()
+    {
+        if(empty($this->_oStripe))
+            $this->_oStripe = new \Stripe\StripeClient($this->_oModule->_oConfig->getApiSecretKey());
+
+        return $this->_oStripe;
+    }
+
+    public function retrieveAccount($sAccountId)
+    {
+        try {
+            $oAccount = $this->getStripe()->accounts->retrieve($sAccountId, []);
+        }
+        catch (Exception $oException) {
+            return $this->_processException('Retrieve Account Error: ', $oException);
+        }
+
+        return $oAccount;
+    }
+
+    protected function _processException($sMessage, &$oException)
+    {
+        if(method_exists($oException, 'getError')) {
+            $sError = $oException->getError()->message;
+            $aError = $oException->getError()->toArray();
+        }
+        else { 
+            $sError = $oException->getMessage();
+            $aError = array();
+        }
+
+        $this->_log($sMessage . $sError);
+        if(!empty($aError))
+            $this->_log($aError);
+
+        return false;
+    }
+
+    protected function _log($sContents)
+    {
+        if (is_array($sContents))
+            $sContents = var_export($sContents, true);	
+        else if (is_object($sContents))
+            $sContents = json_encode($sContents);
+
+        bx_log('bx_stripe_connect', $sContents);
+    }
+}
+
+/** @} */

+ 65 - 67
modules/boonex/stripe_connect/classes/BxStripeConnectConfig.php

@@ -15,57 +15,67 @@ class BxStripeConnectConfig extends BxBaseModConnectConfig
 
     protected $_sMode;
 
-    protected $_sApiId;
     protected $_sApiPublicKey;
     protected $_sApiSecretKey;
+    protected $_sAccountType;
+    
+    protected $_sPayMode;
 
-    function __construct($aModule)
+    public function __construct($aModule)
     {
         parent::__construct($aModule);
 
-        $this->CNF = array (
-	        // module icon
+        $this->CNF = [
+            // module icon
             'ICON' => 'cc-stripe col-blue1',
 
             // database tables
             'TABLE_ENTRIES' => $aModule['db_prefix'] . 'accounts',
 
-        	// page URIs
-        	'URL_API_AUTHORIZE' => 'https://connect.stripe.com/oauth/authorize',
-        	'URL_API_DEAUTHORIZE' => 'https://connect.stripe.com/oauth/deauthorize',
-        	'URL_API_TOKEN' => 'https://connect.stripe.com/oauth/token',
-
-        	'URI_REDIRECT' => 'result',
-        	'URI_NOTIFY' => 'notify',
-
-	        // some params
-	        'PARAM_MODE' => 'bx_stripe_connect_mode',
-            'PARAM_API_ID_LIVE' => 'bx_stripe_connect_api_id_live',
-        	'PARAM_API_PUBLIC_LIVE' => 'bx_stripe_connect_api_public_live',
-        	'PARAM_API_SECRET_LIVE' => 'bx_stripe_connect_api_secret_live',
-        	'PARAM_API_ID_TEST' => 'bx_stripe_connect_api_id_test',
-        	'PARAM_API_PUBLIC_TEST' => 'bx_stripe_connect_api_public_test',
-        	'PARAM_API_SECRET_TEST' => 'bx_stripe_connect_api_secret_test',
-        	'PARAM_API_SCOPE' => 'bx_stripe_connect_api_scope',
-        	'PARAM_PMODE_SINGLE' => 'bx_stripe_connect_pmode_single',
-        	'PARAM_FEE_SINGLE' => 'bx_stripe_connect_fee_single',
-        	'PARAM_PMODE_RECURRING' => 'bx_stripe_connect_pmode_recurring',
-        	'PARAM_FEE_RECURRING' => 'bx_stripe_connect_fee_recurring',
-
-	        // objects
-        	'OBJECT_GRID_ACCOUNTS' => 'bx_stripe_connect_accounts',
-
-	        // Related Stripe payment provider name in Payments module 
-        	'STRIPE' => 'stripe',
-        );
-
-        $this->_aJsClasses = array(
-        	'main' => 'BxStripeConnectMain',
-        );
-
-        $this->_aJsObjects = array(
-        	'main' => 'oStripeConnectMain',
-        );
+            // database fields
+            'FIELD_ID' => 'id',
+            'FIELD_ADDED' => 'added',
+            'FIELD_CHANGED' => 'changed',
+            'FIELD_PROFILE_ID' => 'profile_id',
+            'FIELD_LIVE_ACCOUNT_ID' => 'live_account_id',
+            'FIELD_LIVE_DETAILS' => 'live_details',
+            'FIELD_TEST_ACCOUNT_ID' => 'test_account_id',
+            'FIELD_TEST_DETAILS' => 'test_details',
+
+            // page URIs
+            'URL_API_AUTHORIZE' => 'https://connect.stripe.com/oauth/authorize',
+            'URL_API_DEAUTHORIZE' => 'https://connect.stripe.com/oauth/deauthorize',
+            'URL_API_TOKEN' => 'https://connect.stripe.com/oauth/token',
+
+            'URI_REDIRECT' => 'result',
+            'URI_NOTIFY' => 'notify',
+
+            // some params
+            'PARAM_MODE' => 'bx_stripe_connect_mode',
+            'PARAM_API_PUBLIC_LIVE' => 'bx_stripe_connect_api_public_live',
+            'PARAM_API_SECRET_LIVE' => 'bx_stripe_connect_api_secret_live',
+            'PARAM_API_PUBLIC_TEST' => 'bx_stripe_connect_api_public_test',
+            'PARAM_API_SECRET_TEST' => 'bx_stripe_connect_api_secret_test',
+            'PARAM_PMODE' => 'bx_stripe_connect_pmode',
+            'PARAM_FEE_SINGLE' => 'bx_stripe_connect_fee_single',
+            'PARAM_FEE_RECURRING' => 'bx_stripe_connect_fee_recurring',
+
+            // objects
+            'OBJECT_GRID_ACCOUNTS' => 'bx_stripe_connect_accounts',
+
+            // Related Stripe payment provider name in Payments module 
+            'STRIPE' => 'stripe_connect',
+        ];
+
+        $this->_aJsClasses = [
+            'main' => 'BxStripeConnectMain',
+        ];
+
+        $this->_aJsObjects = [
+            'main' => 'oStripeConnectMain',
+        ];
+
+        $this->_sAccountType = 'standard'; //'express'
     }
 
     public function init(&$oDb)
@@ -74,9 +84,9 @@ class BxStripeConnectConfig extends BxBaseModConnectConfig
         $sOptionPrefix = $this->getName();
 
     	$this->_sMode = $this->_oDb->getParam($this->CNF['PARAM_MODE']);
-    	$this->_sApiId = $this->_oDb->getParam($this->CNF['PARAM_API_ID_' . ($this->_sMode == BX_STRIPE_CONNECT_MODE_LIVE ? 'LIVE' : 'TEST')]);
     	$this->_sApiPublicKey = $this->_oDb->getParam($this->CNF['PARAM_API_PUBLIC_' . ($this->_sMode == BX_STRIPE_CONNECT_MODE_LIVE ? 'LIVE' : 'TEST')]);
     	$this->_sApiSecretKey = $this->_oDb->getParam($this->CNF['PARAM_API_SECRET_' . ($this->_sMode == BX_STRIPE_CONNECT_MODE_LIVE ? 'LIVE' : 'TEST')]);
+        $this->_sPayMode = getParam($this->CNF['PARAM_PMODE']);
     }
 
     public function getMode()
@@ -84,36 +94,24 @@ class BxStripeConnectConfig extends BxBaseModConnectConfig
         return $this->_sMode;
     }
 
-    public function getApiId()
-	{
-		return $this->_sApiId;
-	}
-
     public function getApiPublicKey()
-	{
-		return $this->_sApiPublicKey;
-	}
-
-	public function getApiSecretKey()
-	{
-		return $this->_sApiSecretKey;
-	}
-
-    public function getPayMode($sType)
     {
-        $sResult = '';
+        return $this->_sApiPublicKey;
+    }
 
-        switch($sType) {
-            case BX_PAYMENT_TYPE_SINGLE:
-                $sResult = getParam($this->CNF['PARAM_PMODE_SINGLE']);
-                break;
+    public function getApiSecretKey()
+    {
+        return $this->_sApiSecretKey;
+    }
 
-            case BX_PAYMENT_TYPE_RECURRING:
-                $sResult = getParam($this->CNF['PARAM_PMODE_RECURRING']);
-                break;
-        }
+    public function getAccountType()
+    {
+        return $this->_sAccountType;
+    }
 
-        return $sResult;
+    public function getPayMode()
+    {
+        return $this->_sPayMode;
     }
 
     public function getFee($sType, $fAmount = 0)
@@ -124,7 +122,7 @@ class BxStripeConnectConfig extends BxBaseModConnectConfig
             case BX_PAYMENT_TYPE_SINGLE:
                 $mixedValue = getParam($this->CNF['PARAM_FEE_SINGLE']);
                 if(is_numeric($mixedValue))
-                    $iResult = (int)$mixedValue;
+                    $iResult = (int)(100 * (float)$mixedValue);
                 else if(strpos($mixedValue, '%') !== false)
                     $iResult = (int)round($fAmount * (int)trim($mixedValue, '%') / 100);
                 break;

+ 61 - 30
modules/boonex/stripe_connect/classes/BxStripeConnectDb.php

@@ -11,70 +11,101 @@
 
 class BxStripeConnectDb extends BxBaseModConnectDb
 {
-    function __construct(&$oConfig)
+    public function __construct(&$oConfig)
     {
         parent::__construct($oConfig);
     }
 
-	public function getAccount($aParams = array())
+    public function getAccount($aParams = [])
     {
     	$CNF = &$this->_oConfig->CNF;
-    	$aMethod = array('name' => 'getAll', 'params' => array(0 => 'query'));
+
+    	$aMethod = ['name' => 'getAll', 'params' => [0 => 'query']];
 
     	$sJoinClause = $sWhereClause = "";
-        switch($aParams['type']) {
+        switch($aParams['sample']) {
             case 'id':
             	$aMethod['name'] = 'getRow';
-            	$aMethod['params'][1] = array(
-                	'id' => $aParams['id']
-                );
+            	$aMethod['params'][1] = [
+                    'id' => $aParams['id']
+                ];
 
                 $sWhereClause = " AND `te`.`id`=:id";
                 break;
 
-			case 'author':
-				$aMethod['name'] = 'getRow';
-				$aMethod['params'][1] = array(
-                	'author' => $aParams['author']
-                );
+            case 'profile_id':
+                $aMethod['name'] = 'getRow';
+                $aMethod['params'][1] = [
+                    'profile_id' => $aParams['profile_id']
+                ];
+
+                $sWhereClause = " AND `te`.`profile_id`=:profile_id";
+                break;
+            
+            case 'account_id':
+                $aMethod['name'] = 'getRow';
+                
+                if(!empty($aParams['live_account_id'])) {
+                    $aMethod['params'][1] = [
+                        'live_account_id' => $aParams['live_account_id']
+                    ];
+
+                    $sWhereClause = " AND `te`.`live_account_id`=:live_account_id";
+                }
+
+                if(!empty($aParams['test_account_id'])) {
+                    $aMethod['params'][1] = [
+                        'test_account_id' => $aParams['test_account_id']
+                    ];
 
-				$sWhereClause = " AND `te`.`author`=:author";
-				break;
+                    $sWhereClause = " AND `te`.`test_account_id`=:test_account_id";
+                }
+                break;
         }
 
-        $aMethod['params'][0] = "SELECT
-        		`te`.*
-            FROM `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` AS `te`" . $sJoinClause . "
+        $aMethod['params'][0] = "SELECT `te`.*
+            FROM `" . $CNF['TABLE_ENTRIES'] . "` AS `te`" . $sJoinClause . "
             WHERE 1" . $sWhereClause;
 
-        return call_user_func_array(array($this, $aMethod['name']), $aMethod['params']);
+        return call_user_func_array([$this, $aMethod['name']], $aMethod['params']);
     }
 
-	public function insertAccount($aSet)
+    public function insertAccount($aSet)
     {
-        $sQuery = "REPLACE INTO `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` SET " . $this->arrayToSQL($aSet);
-        return (int)$this->query($sQuery) > 0;
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!isset($aSet[$CNF['FIELD_ADDED']]))
+            $aSet[$CNF['FIELD_ADDED']] = time();
+
+        if(!isset($aSet[$CNF['FIELD_CHANGED']]))
+            $aSet[$CNF['FIELD_CHANGED']] = time();
+
+        return (int)$this->query("REPLACE INTO `" . $CNF['TABLE_ENTRIES'] . "` SET " . $this->arrayToSQL($aSet)) > 0;
     }
 
-	public function updateAccount($aSet, $aWhere)
+    public function updateAccount($aSet, $aWhere)
     {
-        $sQuery = "UPDATE `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` SET " . $this->arrayToSQL($aSet) . " WHERE " . (!empty($aWhere) ? $this->arrayToSQL($aWhere, ' AND ') : "1");
-        return (int)$this->query($sQuery) > 0;
+        $CNF = &$this->_oConfig->CNF;
+
+        if(!isset($aSet[$CNF['FIELD_CHANGED']]))
+            $aSet[$CNF['FIELD_CHANGED']] = time();
+
+        return (int)$this->query("UPDATE `" . $CNF['TABLE_ENTRIES'] . "` SET " . $this->arrayToSQL($aSet) . " WHERE " . (!empty($aWhere) ? $this->arrayToSQL($aWhere, ' AND ') : "1")) > 0;
     }
 
-	public function deleteAccount($aWhere)
+    public function deleteAccount($aWhere)
     {
     	if(empty($aWhere))
-    		return false;
+            return false;
 
         return $this->query("DELETE FROM `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` WHERE " . $this->arrayToSQL($aWhere, ' AND ')) !== false;
     }
 
-    public function hasAccount($iAuthor)
+    public function hasAccount($iProfileId, $sMode)
     {
-        return (int)$this->getOne("SELECT `id` FROM `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` WHERE `author` = :author LIMIT 1", array(
-    		'author' => $iAuthor,
-    	)) > 0;
+        return (int)$this->getOne("SELECT `id` FROM `" . $this->_oConfig->CNF['TABLE_ENTRIES'] . "` WHERE `profile_id` = :profile_id AND `" . $sMode . "_account_id` <> '' LIMIT 1", [
+            'profile_id' => $iProfileId,
+    	]) > 0;
     }
 }
 

+ 30 - 5
modules/boonex/stripe_connect/classes/BxStripeConnectGridAccounts.php

@@ -11,8 +11,8 @@
 
 class BxStripeConnectGridAccounts extends BxTemplGrid
 {
-	protected $_sModule;
-	protected $_oModule;
+    protected $_sModule;
+    protected $_oModule;
 	
     public function __construct ($aOptions, $oTemplate = false)
     {
@@ -22,17 +22,42 @@ class BxStripeConnectGridAccounts extends BxTemplGrid
         parent::__construct ($aOptions, $oTemplate);
     }
 
-	protected function _isVisibleGrid ($a)
+    protected function _isVisibleGrid ($a)
     {
         return isAdmin();
     }
 
-	protected function _getCellAuthor($mixedValue, $sKey, $aField, $aRow)
+    protected function _getCellProfileId($mixedValue, $sKey, $aField, $aRow)
     {
     	return parent::_getCellDefault($this->_oModule->_oTemplate->displayProfileLink($mixedValue), $sKey, $aField, $aRow);
     }
 
-	protected function _getCellAdded($mixedValue, $sKey, $aField, $aRow)
+    protected function _getCellLiveDetails($mixedValue, $sKey, $aField, $aRow)
+    {
+        return $this->__getCellDetails($mixedValue, $sKey, $aField, $aRow);
+    }
+
+    protected function _getCellTestDetails($mixedValue, $sKey, $aField, $aRow)
+    {
+        return $this->__getCellDetails($mixedValue, $sKey, $aField, $aRow);
+    }
+
+    protected function __getCellDetails($mixedValue, $sKey, $aField, $aRow)
+    {
+    	return parent::_getCellDefault(_t((int)$mixedValue != 0 ? '_Yes' : '_No'), $sKey, $aField, $aRow);
+    }
+
+    protected function _getCellAdded($mixedValue, $sKey, $aField, $aRow)
+    {
+    	return $this->__getCellDate($mixedValue, $sKey, $aField, $aRow);
+    }
+
+    protected function _getCellChanged($mixedValue, $sKey, $aField, $aRow)
+    {
+    	return $this->__getCellDate($mixedValue, $sKey, $aField, $aRow);
+    }
+
+    protected function __getCellDate($mixedValue, $sKey, $aField, $aRow)
     {
     	return parent::_getCellDefault(bx_time_js($mixedValue), $sKey, $aField, $aRow);
     }

+ 249 - 211
modules/boonex/stripe_connect/classes/BxStripeConnectModule.php

@@ -43,208 +43,269 @@ class BxStripeConnectModule extends BxBaseModConnectModule
      */
     public function serviceGetOptionsMode()
     {
-        return array(
-        	BX_STRIPE_CONNECT_MODE_LIVE => _t('_bx_stripe_connect_option_mode_live'),
-        	BX_STRIPE_CONNECT_MODE_TEST => _t('_bx_stripe_connect_option_mode_test'),
-        );
+        return [
+            BX_STRIPE_CONNECT_MODE_LIVE => _t('_bx_stripe_connect_option_mode_live'),
+            BX_STRIPE_CONNECT_MODE_TEST => _t('_bx_stripe_connect_option_mode_test'),
+        ];
     }
 
     /**
      * @page service Service Calls
      * @section bx_stripe_connect Stripe Connect
      * @subsection bx_stripe_connect-other Other
-     * @subsubsection bx_stripe_connect-get_options_api_scope get_options_api_scope
+     * @subsubsection bx_stripe_connect-get_options_pmode get_options_pmode
      * 
-     * @code bx_srv('bx_stripe_connect', 'get_options_api_scope', [...]); @endcode
+     * @code bx_srv('bx_stripe_connect', 'get_options_pmode', [...]); @endcode
      * 
-     * Get an array with available API scopes. Is used in forms.
+     * Get an array with available processing modes for payments. Is used in forms.
      *
-     * @return an array with available scopes represented as key => value pairs.
+     * @return an array with available modes represented as key => value pairs.
      * 
-     * @see BxStripeConnectModule::serviceGetOptionsApiScope
+     * @see BxStripeConnectModule::serviceGetOptionsPmode
      */
     /** 
-     * @ref bx_stripe_connect-get_options_api_scope "get_options_api_scope"
+     * @ref bx_stripe_connect-get_options_pmode "get_options_pmode"
      */
-    public function serviceGetOptionsApiScope()
+    public function serviceGetOptionsPmode()
     {
-        return array(
-        	'read_only' => _t('_bx_stripe_connect_option_api_scope_read_only'),
-            'read_write' => _t('_bx_stripe_connect_option_api_scope_read_write'),
-        );
+        return [
+            BX_STRIPE_CONNECT_PMODE_DIRECT => _t('_bx_stripe_connect_option_pmode_direct'),
+            //BX_STRIPE_CONNECT_PMODE_PLATFORM => _t('_bx_stripe_connect_option_pmode_platform'),
+        ];
     }
 
-    /**
-     * @page service Service Calls
-     * @section bx_stripe_connect Stripe Connect
-     * @subsection bx_stripe_connect-other Other
-     * @subsubsection bx_stripe_connect-get_options_pmode_single get_options_pmode_single
-     * 
-     * @code bx_srv('bx_stripe_connect', 'get_options_pmode_single', [...]); @endcode
-     * 
-     * Get an array with available processing modes for single time payments. Is used in forms.
-     *
-     * @return an array with available modes represented as key => value pairs.
-     * 
-     * @see BxStripeConnectModule::serviceGetOptionsPmodeSingle
-     */
-    /** 
-     * @ref bx_stripe_connect-get_options_pmode_single "get_options_pmode_single"
-     */
-    public function serviceGetOptionsPmodeSingle()
+    public function serviceGetOptionValueMode($iVendorId, $aParams = [])
     {
-        return array(
-        	BX_STRIPE_CONNECT_PMODE_DIRECT => _t('_bx_stripe_connect_option_pmode_direct'),
-            BX_STRIPE_CONNECT_PMODE_PLATFORM => _t('_bx_stripe_connect_option_pmode_platform'),
-        );
+        return _t('_bx_stripe_connect_option_mode_' . $this->_oConfig->getMode());
     }
 
-    /**
-     * @page service Service Calls
-     * @section bx_stripe_connect Stripe Connect
-     * @subsection bx_stripe_connect-other Other
-     * @subsubsection bx_stripe_connect-get_options_pmode_recurring get_options_pmode_recurring
-     * 
-     * @code bx_srv('bx_stripe_connect', 'get_options_pmode_recurring', [...]); @endcode
-     * 
-     * Get an array with available processing modes for recurring payments. Is used in forms.
-     * Note. Subscriptions (recurring payments) do not currently support the Platform mode.
-     *
-     * @return an array with available modes represented as key => value pairs.
-     * 
-     * @see BxStripeConnectModule::serviceGetOptionsPmodeRecurring
-     */
-    /** 
-     * @ref bx_stripe_connect-get_options_pmode_recurring "get_options_pmode_recurring"
-     */
-    public function serviceGetOptionsPmodeRecurring()
+    public function serviceGetOptionValueLiveAccountId($iVendorId, $aParams = [])
     {
-        return array(
-        	BX_STRIPE_CONNECT_PMODE_DIRECT => _t('_bx_stripe_connect_option_pmode_direct'),
-        );
+        $CNF = &$this->_oConfig->CNF;
+
+        $aAccount = $this->_oDb->getAccount(['sample' => 'profile_id', 'profile_id' => $iVendorId]);
+        if(empty($aAccount) || !is_array($aAccount))
+            return '';
+
+        return $aAccount[$CNF['FIELD_LIVE_ACCOUNT_ID']];
+    }
+
+    public function serviceGetOptionValueTestAccountId($iVendorId, $aParams = [])
+    {
+        $CNF = &$this->_oConfig->CNF;
+
+        $aAccount = $this->_oDb->getAccount(['sample' => 'profile_id', 'profile_id' => $iVendorId]);
+        if(empty($aAccount) || !is_array($aAccount))
+            return '';
+
+        return $aAccount[$CNF['FIELD_TEST_ACCOUNT_ID']];
+    }
+
+    public function serviceGetConnectCode($iVendorId, $aParams = [])
+    {
+        return $this->_oTemplate->getConnectCode($iVendorId, $aParams);
     }
 
     /**
-     * @page service Service Calls
-     * @section bx_stripe_connect Stripe Connect
-     * @subsection bx_stripe_connect-page_blocks Page Blocks
-     * @subsubsection bx_stripe_connect-get_block_connect get_block_connect
-     * 
-     * @code bx_srv('bx_stripe_connect', 'get_block_connect', [...]); @endcode
      * 
-     * Get page block with necessary info and actions to connect/disconnect.
-     *
-     * @return HTML string with block content to display on the site, all necessary CSS and JS files are automatically added to the HEAD section of the site HTML.
+     * ACTION METHODS
      * 
-     * @see BxStripeConnectModule::serviceGetBlockConnect
      */
-    /** 
-     * @ref bx_stripe_connect-get_block_connect "get_block_connect"
-     */
-    public function serviceGetBlockConnect()
+    public function actionNotify()
     {
-    	return $this->_oTemplate->displayBlockConnect();
+        $iResult = $this->_processEvent();
+        http_response_code($iResult);
     }
 
-    public function actionDelete()
+    public function actionAccountCreate()
     {
-    	$sError = _t('_bx_stripe_connect_err_perform');
+        $CNF = &$this->_oConfig->CNF;
 
-    	$iId = (int)bx_get('id');
-    	if(empty($iId))
-    		return echoJson(array('code' => 1, 'message' => $sError));
+        $sError = _t('_bx_stripe_connect_err_perform');
 
-    	if(!$this->deleteAccount($iId))
-    		return echoJson(array('code' => 2, 'message' => $sError));
+        $iId = (int)bx_get('id');
+    	if(empty($iId) || $iId != bx_get_logged_profile_id())
+            return echoJson(['code' => 1, 'message' => $sError]);
 
-    	echoJson(array('code' => 0, 'id' => $iId, 'reload' => 1));
-    }
+        $oProfile = BxDolProfile::getInstance($iId);
+        if(!$oProfile)
+            return echoJson(['code' => 1, 'message' => $sError]);
 
-    public function actionResult()
-    {
-    	if(bx_get('error') !== false)
-    		$this->_oTemplate->displayErrorOccured(bx_process_input(bx_get('error_description')));
+        $sAccIdField = $CNF['FIELD_' . strtoupper($this->_oConfig->getMode()) . '_ACCOUNT_ID'];
+
+        //TODO: Replace with call to $this->_oConfig->getStripe() method.
+        $oStripe = new \Stripe\StripeClient($this->_oConfig->getApiSecretKey());
+        $oAccount = $oStripe->accounts->create([
+            'type' => $this->_oConfig->getAccountType(),
+            'email' => $oProfile->getAccountObject()->getEmail(),
+        ]);
+
+        if(!$oAccount)
+            return echoJson(['code' => 1, 'message' => $sError]);
 
-		$mixedResult = $this->createAccount(bx_process_input(bx_get('code')));
-		if($mixedResult !== true)
-			$this->_oTemplate->displayErrorOccured($mixedResult);
+        $this->_oDb->insertAccount([
+            'profile_id' => $iId,
+            $sAccIdField => $oAccount->id
+        ]);
 
-		$this->_oTemplate->displayMsg('_bx_stripe_connect_msg_connected', true);
+        $sLink = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=payment-details');
+        $oAccountLink = $oStripe->accountLinks->create([
+            'account' => $oAccount->id,
+            'refresh_url' => $sLink,
+            'return_url' => $sLink,
+            'type' => 'account_onboarding',
+        ]);
+
+        return echoJson(['code' => 0, 'redirect' => $oAccountLink->url]);
     }
 
-	public function actionNotify()
+    public function actionAccountContinue()
     {
-		$iResult = $this->_processEvent();
-		http_response_code($iResult);
+        $CNF = &$this->_oConfig->CNF;
+
+        $sError = _t('_bx_stripe_connect_err_perform');
+
+        $iId = (int)bx_get('id');
+    	if(empty($iId) || $iId != bx_get_logged_profile_id())
+            return echoJson(['code' => 1, 'message' => $sError]);
+
+        $sModeUc = strtoupper($this->_oConfig->getMode());
+        $sAccIdField = $CNF['FIELD_' . $sModeUc . '_ACCOUNT_ID'];
+        $sAccDetailsField = $CNF['FIELD_' . $sModeUc . '_DETAILS'];
+
+        $aAccount = $this->_oDb->getAccount(['sample' => 'profile_id', 'profile_id' => $iId]);
+        if(empty($aAccount) || !is_array($aAccount) || $aAccount[$sAccIdField] == '')
+            return echoJson(['code' => 1, 'message' => $sError]);
+
+        if((int)$aAccount[$sAccDetailsField] != 0)
+            return echoJson(['code' => 0]);
+
+        $oStripe = new \Stripe\StripeClient($this->_oConfig->getApiSecretKey());
+
+        $sLink = BX_DOL_URL_ROOT . BxDolPermalinks::getInstance()->permalink('page.php?i=payment-details');
+        $oAccountLink = $oStripe->accountLinks->create([
+            'account' => $aAccount[$sAccIdField],
+            'refresh_url' => $sLink,
+            'return_url' => $sLink,
+            'type' => 'account_onboarding',
+        ]);
+
+        if(empty($oAccountLink))
+            return echoJson(['code' => 1, 'message' => $sError]);
+
+        return echoJson(['code' => 0, 'redirect' => $oAccountLink->url]);
     }
 
-    public function createAccount($sCode)
+    public function actionAccountDelete()
     {
-    	$CNF = $this->_oConfig->CNF;
-
-		$oResult = $this->_request($CNF['URL_API_TOKEN'], array(
-			'client_secret' => $this->_oConfig->getApiSecretKey(),
-			'code' => $sCode,
-			'grant_type' => 'authorization_code'
-		));
-
-		if(!empty($oResult->error))
-			return bx_process_input($oResult->error_description);
-
-		$bResult = $this->_oDb->insertAccount(array(
-			'author' => bx_get_logged_profile_id(),
-			'added' => time(),
-			'user_id' => $oResult->stripe_user_id,
-			'public_key' => $oResult->stripe_publishable_key,
-			'access_token' => $oResult->access_token,
-			'refresh_token' => $oResult->refresh_token
-		));
-
-		return $bResult ? $bResult : _t('_bx_stripe_connect_err_perform');
+        $CNF = &$this->_oConfig->CNF;
+
+        $sError = _t('_bx_stripe_connect_err_perform');
+
+        $iId = (int)bx_get('id');
+    	if(empty($iId) || $iId != bx_get_logged_profile_id())
+            return echoJson(['code' => 1, 'message' => $sError]);
+
+        $aAccount = $this->_oDb->getAccount(['sample' => 'profile_id', 'profile_id' => $iId]);
+        if(empty($aAccount) || !is_array($aAccount))
+            return echoJson(['code' => 1, 'message' => $sError]);
+
+        $sAccIdField = $CNF['FIELD_' . strtoupper($this->_oConfig->getMode()) . '_ACCOUNT_ID'];
+
+        $oStripe = new \Stripe\StripeClient($this->_oConfig->getApiSecretKey());
+        $oAccount = $oStripe->accounts->delete($aAccount[$sAccIdField], []);
+
+        if(!$oAccount || !$oAccount->deleted)
+            return echoJson(['code' => 2, 'message' => _t('_bx_stripe_connect_err_delete')]);
+
+        $this->_oDb->deleteAccount([
+            'profile_id' => $iId,
+            $sAccIdField => $oAccount->id
+        ]);
+
+        return echoJson(['code' => 0, 'reload' => 1]);
     }
 
-    public function deleteAccount($iId)
+    /**
+     * 
+     * OTHER METHODS
+     * 
+     */   
+    public function processAlertStripeV3GetButton($iObject, $iSender, $aParams)
     {
-    	$CNF = $this->_oConfig->CNF;
+        $CNF = &$this->_oConfig->CNF;
 
-		$aAccount = $this->_oDb->getAccount(array('type' => 'id', 'id' => $iId));
-		if(empty($aAccount) || !is_array($aAccount))
-			return false;
+        if(empty($aParams['vendor_id']))
+            return false;
 
-		$oResult = $this->_request($CNF['URL_API_DEAUTHORIZE'], array(
-			'client_id' => $this->_oConfig->getApiId(),
-			'client_secret' => $this->_oConfig->getApiSecretKey(),
-			'stripe_user_id' => $aAccount['user_id'],
-		));
+        $sModeUc = strtoupper($this->_oConfig->getMode());
+        $sAccIdField = $CNF['FIELD_' . $sModeUc . '_ACCOUNT_ID'];
+            
+        $aAccount = $this->_oDb->getAccount(['sample' => 'profile_id', 'profile_id' => (int)$aParams['vendor_id']]);
+        if(empty($aAccount) || !is_array($aAccount) || empty($aAccount[$sAccIdField]))
+            return false;
 
-		if(!empty($oResult->error))
-			return false;
+        $aParams['public_key'] = $this->_oConfig->getApiPublicKey();
+        $aParams['connected_account_id'] = $aAccount[$sAccIdField];
 
-		return $this->_oDb->deleteAccount(array('id' => $iId));
+        return !empty($aParams['public_key']);
     }
 
-    public function processAlertStripeGetButton($iObject, $iSender, $aParams)
+    public function processAlertStripeV3CreateSession($iObject, $iSender, $aParams)
     {
-        if(empty($aParams['type']))
+        $CNF = &$this->_oConfig->CNF;
+
+        if(empty($aParams['session_params']))
             return false;
 
-        $sType = $aParams['type'];
-        $sPayMode = $this->_oConfig->getPayMode($sType);
+        try {
+            $sModeUc = strtoupper($this->_oConfig->getMode());
+            $sAccIdField = $CNF['FIELD_' . $sModeUc . '_ACCOUNT_ID'];
+
+            $iVendorId = (int)$aParams['session_params']['metadata']['vendor'];
+            $aAccount = $this->_oDb->getAccount(['sample' => 'profile_id', 'profile_id' => $iVendorId]);
+            if(empty($aAccount) || !is_array($aAccount) || empty($aAccount[$sAccIdField]))
+                return false;
+
+            switch($aParams['session_params']['mode']) {
+                case 'payment':
+                    $fAmount = 0;
+                    foreach($aParams['session_params']['line_items'] as $aLineItem)
+                        $fAmount += (float)$aLineItem['price_data']['unit_amount'] * (int)$aLineItem['quantity'];
+
+                    $aParams['session_params']['payment_intent_data'] = [
+                        'application_fee_amount' => $this->_oConfig->getFee(BX_PAYMENT_TYPE_SINGLE, $fAmount)
+                    ];
+                    break;
 
-        switch($sType) {
-            case BX_PAYMENT_TYPE_SINGLE:
-                if($sPayMode == BX_STRIPE_CONNECT_PMODE_PLATFORM)
-                    $aParams['public_key'] = $this->_oConfig->getApiPublicKey();
-                break;
+                //TODO: Need to complete create Subscription flow.
+                case 'subscription':
+                    $fAmount = 0;
+                    foreach($aParams['session_params']['line_items'] as $aLineItem)
+                        $fAmount += (float)$aLineItem['price'] * (int)$aLineItem['quantity'];
 
-            case BX_PAYMENT_TYPE_RECURRING:
-                //TODO: Perform necessary actions here !WHEN! 'Platform' mode will be available for recurring payments.
-                break;
+                    $aParams['session_params']['payment_intent_data'] = [
+                        'application_fee_amount' => $this->_oConfig->getFee(BX_PAYMENT_TYPE_SINGLE, $fAmount)
+                    ];
+                    break;
+            }
+
+            $aParams['session_object'] = BxStripeConnectApi::getInstance()->getStripe()->checkout->sessions->create($aParams['session_params'], [
+                'stripe_account' => $aAccount[$sAccIdField]
+            ]);
         }
+        catch (Exception $oException) {
+            $aParams['session_object'] = null;
 
-        return !empty($aParams['public_key']);
+            return $this->_processException('Create Session Error: ', $oException);
+        }
+
+        return !empty($aParams['session_object']);
     }
 
+    /**
+     * Methods related to old Stripe integration (which starts with 'processAlertStripe') are outdated.
+     */
     public function processAlertStripeCreateCustomer($iObject, $iSender, $aParams)
     {
         if(empty($aParams['type']) || empty($aParams['customer_params']['card']))
@@ -401,81 +462,58 @@ class BxStripeConnectModule extends BxBaseModConnectModule
 		return !empty($aParams['subscription_object']);
     }
 
-	protected function _request($sUrl, $aParams = array())
-	{
-	    $sResult = '';
-	    if(!function_exists('curl_init'))
-			return false;
-
-        $rConnect = curl_init();
-
-		curl_setopt($rConnect, CURLOPT_URL, $sUrl);
-		curl_setopt($rConnect, CURLOPT_HEADER, 0);
-		curl_setopt($rConnect, CURLOPT_RETURNTRANSFER, 1);
-		curl_setopt($rConnect, CURLOPT_FOLLOWLOCATION, 1);
-		curl_setopt($rConnect, CURLOPT_POST, 1);
-		curl_setopt($rConnect, CURLOPT_POSTFIELDS, http_build_query($aParams));
-
-        if(bx_mb_strpos($sUrl, 'https') !== false) {
-	        curl_setopt($rConnect, CURLOPT_SSL_VERIFYPEER, 0);
-			curl_setopt($rConnect, CURLOPT_SSL_VERIFYHOST, 0);
-        }
-	
-		$sResult = curl_exec($rConnect);
-		curl_close($rConnect);
-
-	    return json_decode($sResult);
-	}
-
-	protected function _processEvent()
-	{
-    	$sInput = @file_get_contents("php://input");
-		$aEvent = json_decode($sInput, true);
-		if(empty($aEvent) || !is_array($aEvent)) 
-			return 404;
+    protected function _processEvent()
+    {
+        $sInput = @file_get_contents("php://input");
+        $aEvent = json_decode($sInput, true);
+        if(empty($aEvent) || !is_array($aEvent)) 
+            return 404;
 
-		$sType = $aEvent['type'];
-		if(!in_array($sType, array('account.application.deauthorized')))
-			return 200;
+        $sType = $aEvent['type'];
+        if(!in_array($sType, ['account.updated']))
+            return 200;
 
-		$this->_log('Webhooks: ' . (!empty($sType) ? $sType : ''));
-		$this->_log($aEvent);
+        $this->_log('Webhooks: ' . (!empty($sType) ? $sType : ''));
+        $this->_log($aEvent);
 
-		$sMethod = '_processEvent' . bx_gen_method_name($sType, array('.', '_', '-'));
-    	if(!method_exists($this, $sMethod))
-    		return 200;
+        $sMethod = '_processEvent' . bx_gen_method_name($sType, array('.', '_', '-'));
+        if(!method_exists($this, $sMethod))
+            return 200;
 
     	return $this->$sMethod($aEvent) ? 200 : 403;
     }
 
-	protected function _processEventAccountApplicationDeauthorized(&$aEvent)
-	{
-		$CNF = $this->_oConfig->CNF;
+    protected function _processEventAccountUpdated(&$aEvent)
+    {
+        $CNF = $this->_oConfig->CNF;
+
+        $sAccountId = '';
+        if(!isset($aEvent['data']['object']['id']) || !($sAccountId = bx_process_input($aEvent['data']['object']['id'])))
+            return false;
 
-		$sApiId = bx_process_input($aEvent['data']['object']['id']);
-		if(strcmp($sApiId, $this->_oConfig->getApiId()) != 0)
-			return false;
+        $sMode = $this->_oConfig->getMode();
+        $sAccDetailsField = $CNF['FIELD_' . strtoupper($sMode) . '_DETAILS'];
 
-		$sUserId = bx_process_input($aEvent['user_id']);
-		if(empty($sUserId))
-			return false;
+        $aAccount = $this->_oDb->getAccount(['sample' => 'account_id', $sMode . '_account_id' => $sAccountId]);
+        if((int)$aAccount[$sAccDetailsField] == 0 && $aEvent['data']['object']['details_submitted'])
+            return $this->_oDb->updateAccount([$sAccDetailsField => 1], [$CNF['FIELD_ID'] => $aAccount[$CNF['FIELD_ID']]]);
 
-		return $this->_oDb->deleteAccount(array('user_id' => $sUserId));
-	}
+        return true;
+    }
 
     protected function _processException($sMessage, &$oException)
-	{
-		$aError = $oException->getJsonBody();
+    {
+        $aError = $oException->getJsonBody();
 
-		$sMessage = $aError['error']['message'];
-		if(empty($sMessage))
-			$sMessage = $oException->getMessage();
+        $sMessage = $aError['error']['message'];
+        if(empty($sMessage))
+            $sMessage = $oException->getMessage();
 
-		$this->_log($sMessage . $aError['error']['message']);
-		$this->_log($aError);
+        $this->_log($sMessage . $aError['error']['message']);
+        $this->_log($aError);
 
-		return false;
-	}
+        return false;
+    }
 
     protected function _getAccount($iPending, $sType)
     {
@@ -498,15 +536,15 @@ class BxStripeConnectModule extends BxBaseModConnectModule
         return $aAccount;
     }
 
-	protected function _log($sContents)
-	{
-		if (is_array($sContents))
-			$sContents = var_export($sContents, true);	
-		else if (is_object($sContents))
-			$sContents = json_encode($sContents);
-		
-		bx_log('bx_stripe_connect', $sContents);
-	}
+    protected function _log($sContents)
+    {
+        if (is_array($sContents))
+            $sContents = var_export($sContents, true);	
+        else if (is_object($sContents))
+            $sContents = json_encode($sContents);
+
+        bx_log('bx_stripe_connect', $sContents);
+    }
 }
 
 /** @} */

+ 47 - 57
modules/boonex/stripe_connect/classes/BxStripeConnectTemplate.php

@@ -9,79 +9,68 @@
  * @{
  */
 
-class BxStripeConnectTemplate extends BxBaseModConnectTemplate
+require_once('BxStripeConnectApi.php');
+
+class BxStripeConnectTemplate extends BxBaseModGeneralTemplate
 {
-    function __construct($oConfig, $oDb)
+    public function __construct($oConfig, $oDb)
     {
     	$this->MODULE = 'bx_stripe_connect';
 
         parent::__construct($oConfig, $oDb);
     }
 
-    public function displayBlockConnect()
+    public function getConnectCode($iVendorId, $aParams = [])
     {
-    	$CNF = $this->_oConfig->CNF;
-
-    	$sApiId = $this->_oConfig->getApiId();
-    	if(empty($sApiId))
-    		return '';
-
-		$iVendor = bx_get_logged_profile_id();
-		$aVendorAccount = $this->_oDb->getAccount(array('type' => 'author', 'author' => $iVendor));
-		if(!empty($aVendorAccount) && is_array($aVendorAccount))
-			return $this->displayBlockAccount($aVendorAccount);
-
-		$aVendor = BxDolModule::getInstance($this->MODULE)->getProfileInfo($iVendor);
-    	$bVendorStripe = BxDolPayments::getInstance()->isPaymentProvider($iVendor, $CNF['STRIPE']);
+        $CNF = &$this->_oConfig->CNF;
 
-    	$aRequestParams = array(
-			'response_type' => 'code',
-			'client_id' => $sApiId,
-			'scope' => $this->_oDb->getParam($CNF['PARAM_API_SCOPE']),
-			'redirect_uri' => BX_DOL_URL_ROOT . $this->_oConfig->getBaseUri() . $CNF['URI_REDIRECT'],
-			'stripe_landing' => $bVendorStripe ? 'login' : 'register'
-		);
+        $sJsObject = $this->_oConfig->getJsObject('main');        
+ 
+        $sModeUc = strtoupper($this->_oConfig->getMode());
+        $sAccIdField = $CNF['FIELD_' . $sModeUc . '_ACCOUNT_ID'];
+        $sAccDetailsField = $CNF['FIELD_' . $sModeUc . '_DETAILS'];
+ 
+        $bShowContinue = false;
+        $sActionMethod = $sActionTitle = '';
+        if(($aAccount = $this->_oDb->getAccount(['sample' => 'profile_id', 'profile_id' => $iVendorId])) && is_array($aAccount) && $aAccount[$sAccIdField] != '') {
+            if(($bShowContinue = (int)$aAccount[$sAccDetailsField] == 0)) {
+                $oAccount = BxStripeConnectApi::getInstance()->retrieveAccount($aAccount[$sAccIdField]);
+                if($oAccount->details_submitted) {
+                    $this->_oDb->updateAccount([$sAccDetailsField => 1], [$CNF['FIELD_ID'] => $aAccount[$CNF['FIELD_ID']]]);
 
-		if(!$bVendorStripe)
-			$aRequestParams = array_merge($aRequestParams, array(
-				'stripe_user[email]' => $aVendor['email'],
-				'stripe_user[url]' => urlencode($aVendor['link']),
-				'stripe_user[first_name]' => $aVendor['name']
-			));
+                    $bShowContinue = false;
+                }
+            }
 
-    	$this->addCss(array('main.css'));
-    	return $this->parseHtmlByName('block_connect.html', array(
-    		'link' => bx_append_url_params($CNF['URL_API_AUTHORIZE'], $aRequestParams, false)
-    	));
-    }
-    
-    public function displayBlockAccount($aAccount)
-    {
-    	$CNF = $this->_oConfig->CNF;
+            $sActionMethod = 'accountDelete';
+            $sActionTitle = '_bx_stripe_connect_btn_account_delete';
+        }
+        else {
+            $sActionMethod = 'accountCreate';
+            $sActionTitle = '_bx_stripe_connect_btn_account_create';
+        }
 
-    	$sApiId = $this->_oConfig->getApiId();
-    	if(empty($sApiId))
-    		return '';
-
-		$this->addCss(array('main.css'));
-		$this->addJs(array('main.js'));
-    	$this->addJsTranslation(array('_bx_stripe_connect_wrn_disconnect'));
-    	return $this->parseHtmlByName('block_account.html', array(
-    		'js_object' => $this->_oConfig->getJsObject('main'),
-    		'id' => $aAccount['id'],
-    		'user_id' => $aAccount['user_id'],
-    	    'public_key' => $aAccount['public_key'],
-    		'access_token' => $aAccount['access_token'],
-	    	'added' => bx_time_js($aAccount['added']),
-    	    'keys_usage' => _t('_bx_stripe_connect_txt_keys_usage', BxDolPayments::getInstance()->getDetailsUrl()),
-    		'js_code' => $this->getJsCode('main')
-    	));
+        $this->addJs(['main.js']);
+        return $this->parseHtmlByName('connect_code.html', [
+            'js_object' => $sJsObject,
+            'js_code' => $this->getJsCode('main'),
+            'profile_id' => $iVendorId,
+            'action_method' => $sActionMethod,
+            'action_title' => _t($sActionTitle),
+            'bx_if:show_continue' => [
+                'condition' => $bShowContinue,
+                'content' => [
+                    'js_object' => $sJsObject,
+                    'profile_id' => $iVendorId,
+                ]
+            ]
+        ]);
     }
 
-	public function displayProfileLink($mixedProfile)
+    public function displayProfileLink($mixedProfile)
     {
     	if(!is_array($mixedProfile))
-    		$mixedProfile = BxDolModule::getInstance($this->MODULE)->getProfileInfo((int)$mixedProfile);
+            $mixedProfile = BxDolModule::getInstance($this->MODULE)->getProfileInfo((int)$mixedProfile);
 
     	return $this->parseHtmlByName('link.html', array(
             'href' => $mixedProfile['link'],
@@ -89,6 +78,7 @@ class BxStripeConnectTemplate extends BxBaseModConnectTemplate
             'content' => $mixedProfile['name']
         ));
     }
+
 }
 
 /** @} */

+ 23 - 37
modules/boonex/stripe_connect/install/langs/en.xml

@@ -1,50 +1,36 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources name="en" flag="gb" title="English">
-	<string name="_bx_stripe_connect"><![CDATA[Stripe Connect]]></string>
+    <string name="_bx_stripe_connect"><![CDATA[Stripe Connect]]></string>
 
-	<!-- OPTIONS -->
-	<string name="_bx_stripe_connect_option_mode"><![CDATA[Mode]]></string>
-	<string name="_bx_stripe_connect_option_mode_live"><![CDATA[Live]]></string>
-	<string name="_bx_stripe_connect_option_mode_test"><![CDATA[Test]]></string>
-    <string name="_bx_stripe_connect_option_api_id_live"><![CDATA[Client ID (live)]]></string>
+    <!-- OPTIONS -->
+    <string name="_bx_stripe_connect_option_mode"><![CDATA[Mode]]></string>
+    <string name="_bx_stripe_connect_option_mode_live"><![CDATA[Live]]></string>
+    <string name="_bx_stripe_connect_option_mode_test"><![CDATA[Test]]></string>
     <string name="_bx_stripe_connect_option_api_public_live"><![CDATA[Public Key (live)]]></string>
     <string name="_bx_stripe_connect_option_api_secret_live"><![CDATA[Secret Key (live)]]></string>
-    <string name="_bx_stripe_connect_option_api_id_test"><![CDATA[Client ID (test)]]></string>
     <string name="_bx_stripe_connect_option_api_public_test"><![CDATA[Public Key (test)]]></string>
     <string name="_bx_stripe_connect_option_api_secret_test"><![CDATA[Secret Key (test)]]></string>
-    <string name="_bx_stripe_connect_option_api_scope"><![CDATA[Scope]]></string>
-    <string name="_bx_stripe_connect_option_api_scope_read_only"><![CDATA[Read Only]]></string>
-    <string name="_bx_stripe_connect_option_api_scope_read_write"><![CDATA[Read Write]]></string>
-    <string name="_bx_stripe_connect_option_pmode_single"><![CDATA[One-time payments processing mode]]></string>
-    <string name="_bx_stripe_connect_option_fee_single"><![CDATA[One-time fee (in cents, percent)]]></string>
-    <string name="_bx_stripe_connect_option_pmode_recurring"><![CDATA[Subscription payments processing mode]]></string>
+    <string name="_bx_stripe_connect_option_pmode"><![CDATA[Payments processing mode]]></string>
     <string name="_bx_stripe_connect_option_pmode_direct"><![CDATA[Direct]]></string>
     <string name="_bx_stripe_connect_option_pmode_platform"><![CDATA[Platform]]></string>
+    <string name="_bx_stripe_connect_option_fee_single"><![CDATA[One-time fee (in cents, percent)]]></string>
     <string name="_bx_stripe_connect_option_fee_recurring"><![CDATA[Subscription fee (percent only)]]></string>
-    <string name="_bx_stripe_connect_option_redirect_url"><![CDATA[Redirect URL]]></string>  
-
-	<!-- PAGES and BLOCKS -->
-	<string name="_bx_stripe_connect_page_title_sys_result"><![CDATA[Stripe Connect Results]]></string>
-	<string name="_bx_stripe_connect_page_title_result"><![CDATA[Stripe Connect Results]]></string>
-	<string name="_bx_stripe_connect_page_block_title_result"><![CDATA[Stripe Connect Results]]></string>
-	<string name="_bx_stripe_connect_page_block_title_connect"><![CDATA[Stripe Connect]]></string>
 
-	<!-- MENUS -->
-	<string name="_bx_stripe_connect_menu_item_title_accounts"><![CDATA[Accounts]]></string>
+    <!-- GRIDS -->
+    <string name="_bx_stripe_connect_grid_column_title_profile_id"><![CDATA[Profile]]></string>
+    <string name="_bx_stripe_connect_grid_column_title_live_account_id"><![CDATA[Account ID (live)]]></string>
+    <string name="_bx_stripe_connect_grid_column_title_live_details"><![CDATA[Details (live)]]></string>
+    <string name="_bx_stripe_connect_grid_column_title_test_account_id"><![CDATA[Account ID (test)]]></string>
+    <string name="_bx_stripe_connect_grid_column_title_test_details"><![CDATA[Details (test)]]></string>
+    <string name="_bx_stripe_connect_grid_column_title_added"><![CDATA[Added]]></string>
+    <string name="_bx_stripe_connect_grid_column_title_changed"><![CDATA[Changed]]></string>
+    <string name="_bx_stripe_connect_action_title_delete"><![CDATA[Delete]]></string>
 
-	<!-- GRIDS -->
-	<string name="_bx_stripe_connect_grid_column_title_author"><![CDATA[Author]]></string>
-	<string name="_bx_stripe_connect_grid_column_title_user_id"><![CDATA[Stripe User ID]]></string>
-	<string name="_bx_stripe_connect_grid_column_title_public_key"><![CDATA[Public Key]]></string>
-	<string name="_bx_stripe_connect_grid_column_title_access_token"><![CDATA[Secret Key]]></string>
-	<string name="_bx_stripe_connect_grid_column_title_added"><![CDATA[Connected]]></string>
-	<string name="_bx_stripe_connect_action_title_delete"><![CDATA[Disconnect]]></string>
-	
-	<!-- OTHER -->
-	<string name="_bx_stripe_connect_btn_connect"><![CDATA[Connect]]></string>
-	<string name="_bx_stripe_connect_msg_connected"><![CDATA[You were successfully connected.]]></string>
-	<string name="_bx_stripe_connect_wrn_disconnect"><![CDATA[Are you sure you want to disconnect?]]></string>
-	<string name="_bx_stripe_connect_err_perform"><![CDATA[Cannot perform the action. Please report.]]></string>
-	<string name="_bx_stripe_connect_txt_keys_usage"><![CDATA[<b>Note</b>. You should use these <b>Public</b> and <b>Secret</b> keys in configuration settings of your Stripe account <a href="{0}">here</a>.]]></string>
-  <string name="_bx_stripe_connect_log"><![CDATA[Stripe Connect]]></string>
+    <!-- OTHER -->
+    <string name="_bx_stripe_connect_btn_account_create"><![CDATA[Create Connected Account]]></string>
+    <string name="_bx_stripe_connect_btn_account_delete"><![CDATA[Delete Connected Account]]></string>
+    <string name="_bx_stripe_connect_btn_account_continue"><![CDATA[Continue with Account Creation]]></string>
+    <string name="_bx_stripe_connect_err_delete"><![CDATA[Cannot delete account.]]></string>
+    <string name="_bx_stripe_connect_err_perform"><![CDATA[Cannot perform the action. Please report.]]></string>
+    <string name="_bx_stripe_connect_log"><![CDATA[Stripe Connect]]></string>
 </resources>

+ 30 - 43
modules/boonex/stripe_connect/install/sql/enable.sql

@@ -13,50 +13,31 @@ SET @iCategId = LAST_INSERT_ID();
 
 INSERT INTO `sys_options` (`name`, `value`, `category_id`, `caption`, `type`, `check`, `check_error`, `order`, `extra`) VALUES
 ('bx_stripe_connect_mode', 'live', @iCategId, '_bx_stripe_connect_option_mode', 'select', '', '', 10, 'a:2:{s:6:"module";s:17:"bx_stripe_connect";s:6:"method";s:16:"get_options_mode";}'),
-('bx_stripe_connect_api_id_live', '', @iCategId, '_bx_stripe_connect_option_api_id_live', 'digit', '', '', 20, ''),
-('bx_stripe_connect_api_public_live', '', @iCategId, '_bx_stripe_connect_option_api_public_live', 'digit', '', '', 30, ''),
-('bx_stripe_connect_api_secret_live', '', @iCategId, '_bx_stripe_connect_option_api_secret_live', 'digit', '', '', 40, ''),
-('bx_stripe_connect_api_id_test', '', @iCategId, '_bx_stripe_connect_option_api_id_test', 'digit', '', '', 50, ''),
-('bx_stripe_connect_api_public_test', '', @iCategId, '_bx_stripe_connect_option_api_public_test', 'digit', '', '', 60, ''),
-('bx_stripe_connect_api_secret_test', '', @iCategId, '_bx_stripe_connect_option_api_secret_test', 'digit', '', '', 70, ''),
-('bx_stripe_connect_api_scope', 'read_write', @iCategId, '_bx_stripe_connect_option_api_scope', 'select', '', '', 80, 'a:2:{s:6:"module";s:17:"bx_stripe_connect";s:6:"method";s:21:"get_options_api_scope";}'),
-('bx_stripe_connect_pmode_single', 'direct', @iCategId, '_bx_stripe_connect_option_pmode_single', 'select', '', '', 90, 'a:2:{s:6:"module";s:17:"bx_stripe_connect";s:6:"method";s:24:"get_options_pmode_single";}'),
-('bx_stripe_connect_fee_single', '', @iCategId, '_bx_stripe_connect_option_fee_single', 'digit', '', '', 100, ''),
-('bx_stripe_connect_pmode_recurring', 'direct', @iCategId, '_bx_stripe_connect_option_pmode_recurring', 'select', '', '', 110, 'a:2:{s:6:"module";s:17:"bx_stripe_connect";s:6:"method";s:27:"get_options_pmode_recurring";}'),
-('bx_stripe_connect_fee_recurring', '', @iCategId, '_bx_stripe_connect_option_fee_recurring', 'digit', '', '', 120, ''),
-('bx_stripe_connect_redirect_url', '', @iCategId, '_bx_stripe_connect_option_redirect_url', 'value', '', '', 130, '');
-
-
--- PAGE: result
-INSERT INTO `sys_objects_page`(`object`, `uri`, `title_system`, `title`, `module`, `layout_id`, `visible_for_levels`, `visible_for_levels_editable`, `url`, `meta_description`, `meta_keywords`, `meta_robots`, `cache_lifetime`, `cache_editable`, `deletable`, `override_class_name`, `override_class_file`) VALUES 
-('bx_stripe_connect_result', 'stripe-connect-result', '_bx_stripe_connect_page_title_sys_result', '_bx_stripe_connect_page_title_result', @sName, 5, 2147483647, 0, '', '', '', '', 0, 1, 0, 'BxStripeConnectPage', 'modules/boonex/stripe_connect/classes/BxStripeConnectPage.php');
-
-INSERT INTO `sys_pages_blocks`(`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `active`, `order`) VALUES 
-('bx_stripe_connect_result', 1, @sName, '_bx_stripe_connect_page_block_title_result', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:17:"bx_stripe_connect";s:6:"method";s:16:"get_block_result";}', 0, 0, 1, 1);
-
-
--- PAGES: add page block on dashboard
-SET @iPBCellDashboard = 3;
-SET @iPBOrderDashboard = (SELECT IFNULL(MAX(`order`), 0) FROM `sys_pages_blocks` WHERE `object` = 'sys_dashboard' AND `cell_id` = @iPBCellDashboard LIMIT 1);
-INSERT INTO `sys_pages_blocks` (`object`, `cell_id`, `module`, `title`, `designbox_id`, `visible_for_levels`, `type`, `content`, `deletable`, `copyable`, `order`) VALUES
-('sys_dashboard', @iPBCellDashboard, @sName, '_bx_stripe_connect_page_block_title_connect', 11, 2147483647, 'service', 'a:2:{s:6:"module";s:17:"bx_stripe_connect";s:6:"method";s:17:"get_block_connect";}', 0, 1, @iPBOrderDashboard + 1);
-
+('bx_stripe_connect_api_public_live', '', @iCategId, '_bx_stripe_connect_option_api_public_live', 'digit', '', '', 20, ''),
+('bx_stripe_connect_api_secret_live', '', @iCategId, '_bx_stripe_connect_option_api_secret_live', 'digit', '', '', 30, ''),
+('bx_stripe_connect_api_public_test', '', @iCategId, '_bx_stripe_connect_option_api_public_test', 'digit', '', '', 40, ''),
+('bx_stripe_connect_api_secret_test', '', @iCategId, '_bx_stripe_connect_option_api_secret_test', 'digit', '', '', 50, ''),
+('bx_stripe_connect_pmode', 'direct', @iCategId, '_bx_stripe_connect_option_pmode', 'select', '', '', 60, 'a:2:{s:6:"module";s:17:"bx_stripe_connect";s:6:"method";s:17:"get_options_pmode";}'),
+('bx_stripe_connect_fee_single', '', @iCategId, '_bx_stripe_connect_option_fee_single', 'digit', '', '', 70, ''),
+('bx_stripe_connect_fee_recurring', '', @iCategId, '_bx_stripe_connect_option_fee_recurring', 'digit', '', '', 80, '');
 
 -- GRIDS: Manage
 INSERT INTO `sys_objects_grid` (`object`, `source_type`, `source`, `table`, `field_id`, `field_order`, `paginate_url`, `paginate_per_page`, `paginate_simple`, `paginate_get_start`, `paginate_get_per_page`, `filter_fields`, `filter_mode`, `sorting_fields`, `visible_for_levels`, `override_class_name`, `override_class_file`) VALUES
-('bx_stripe_connect_accounts', 'Sql', 'SELECT * FROM `bx_stripe_connect_accounts`', 'bx_stripe_connect_accounts', 'id', '', '', 10, NULL, 'start', '', 'user_id,public_key,access_token', 'auto', 'user_id,public_key,access_token', 128, 'BxStripeConnectGridAccounts', 'modules/boonex/stripe_connect/classes/BxStripeConnectGridAccounts.php');
+('bx_stripe_connect_accounts', 'Sql', 'SELECT * FROM `bx_stripe_connect_accounts`', 'bx_stripe_connect_accounts', 'id', '', '', 20, NULL, 'start', '', 'live_account_id,test_account_id', 'auto', 'live_account_id,test_account_id', 128, 'BxStripeConnectGridAccounts', 'modules/boonex/stripe_connect/classes/BxStripeConnectGridAccounts.php');
 
 INSERT INTO `sys_grid_fields` (`object`, `name`, `title`, `width`, `translatable`, `chars_limit`, `params`, `order`) VALUES
-('bx_stripe_connect_accounts', 'checkbox', 'Select', '2%', 0, '', '', 1),
-('bx_stripe_connect_accounts', 'author', '_bx_stripe_connect_grid_column_title_author', '16%', 0, '18', '', 2),
-('bx_stripe_connect_accounts', 'user_id', '_bx_stripe_connect_grid_column_title_user_id', '18%', 0, '18', '', 3),
-('bx_stripe_connect_accounts', 'public_key', '_bx_stripe_connect_grid_column_title_public_key', '18%', 0, '18', '', 4),
-('bx_stripe_connect_accounts', 'access_token', '_bx_stripe_connect_grid_column_title_access_token', '18%', 0, '18', '', 5),
-('bx_stripe_connect_accounts', 'added', '_bx_stripe_connect_grid_column_title_added', '10%', 0, '18', '', 6),
-('bx_stripe_connect_accounts', 'actions', '', '18%', 0, '', '', 7);
+('bx_stripe_connect_accounts', 'checkbox', '_sys_select', '2%', 0, '', '', 1),
+('bx_stripe_connect_accounts', 'profile_id', '_bx_stripe_connect_grid_column_title_profile_id', '15%', 0, '', '', 2),
+('bx_stripe_connect_accounts', 'live_account_id', '_bx_stripe_connect_grid_column_title_live_account_id', '18%', 0, 32, '', 3),
+('bx_stripe_connect_accounts', 'live_details', '_bx_stripe_connect_grid_column_title_live_details', '5%', 0, '', '', 4),
+('bx_stripe_connect_accounts', 'test_account_id', '_bx_stripe_connect_grid_column_title_test_account_id', '18%', 0, 32, '', 5),
+('bx_stripe_connect_accounts', 'test_details', '_bx_stripe_connect_grid_column_title_test_details', '5%', 0, '', '', 6),
+('bx_stripe_connect_accounts', 'added', '_bx_stripe_connect_grid_column_title_added', '10%', 0, '', '', 7),
+('bx_stripe_connect_accounts', 'changed', '_bx_stripe_connect_grid_column_title_changed', '10%', 0, '', '', 8),
+('bx_stripe_connect_accounts', 'actions', '', '17%', 0, '', '', 9);
 
 INSERT INTO `sys_grid_actions` (`object`, `type`, `name`, `title`, `icon`, `icon_only`, `confirm`, `order`) VALUES
-('bx_stripe_connect_accounts', 'single', 'delete', '_bx_stripe_connect_action_title_delete', 'unlink', 1, 1, 1),
+('bx_stripe_connect_accounts', 'single', 'delete', '_bx_stripe_connect_action_title_delete', 'times', 1, 1, 1),
 ('bx_stripe_connect_accounts', 'bulk', 'delete', '_bx_stripe_connect_action_title_delete', '', 0, 1, 1);
 
 
@@ -66,9 +47,15 @@ INSERT INTO `sys_alerts_handlers` (`name`, `class`, `file`, `service_call`) VALU
 SET @iHandler := LAST_INSERT_ID();
 
 INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
-('bx_payment', 'stripe_get_button', @iHandler),
-('bx_payment', 'stripe_create_customer', @iHandler),
-('bx_payment', 'stripe_retrieve_customer', @iHandler),
-('bx_payment', 'stripe_create_charge', @iHandler),
-('bx_payment', 'stripe_retrieve_charge', @iHandler),
-('bx_payment', 'stripe_create_subscription', @iHandler);
+('bx_payment', 'stripe_v3_get_button', @iHandler),
+('bx_payment', 'stripe_v3_create_session', @iHandler);
+
+-- INSERT INTO `sys_alerts` (`unit`, `action`, `handler_id`) VALUES
+-- ('bx_payment', 'stripe_get_button', @iHandler),
+-- ('bx_payment', 'stripe_create_customer', @iHandler),
+-- ('bx_payment', 'stripe_retrieve_customer', @iHandler),
+-- ('bx_payment', 'stripe_create_charge', @iHandler),
+-- ('bx_payment', 'stripe_retrieve_charge', @iHandler),
+-- ('bx_payment', 'stripe_create_subscription', @iHandler);
+
+

+ 9 - 8
modules/boonex/stripe_connect/install/sql/install.sql

@@ -2,17 +2,18 @@ SET @sName = 'bx_stripe_connect';
 
 
 -- TABLES
-CREATE TABLE `bx_stripe_connect_accounts` (
+CREATE TABLE IF NOT EXISTS `bx_stripe_connect_accounts` (
   `id` int(11) NOT NULL auto_increment,
-  `author` int(11) NOT NULL default '0',
   `added` int(11) NOT NULL default '0',
-  `user_id` varchar(64) NOT NULL default '',
-  `public_key` varchar(128) NOT NULL default '',
-  `access_token` varchar(128) NOT NULL default '',
-  `refresh_token` varchar(128) NOT NULL default '',
+  `changed` int(11) NOT NULL default '0',
+  `profile_id` int(11) NOT NULL default '0',
+  `live_account_id` varchar(64) NOT NULL default '',
+  `live_details` tinyint(4) NOT NULL default '0',
+  `test_account_id` varchar(64) NOT NULL default '',
+  `test_details` tinyint(4) NOT NULL default '0',
   PRIMARY KEY (`id`),
-  UNIQUE KEY `author` (`author`),
-  UNIQUE KEY `user_id` (`user_id`)
+  UNIQUE KEY `profile_id` (`profile_id`),
+  UNIQUE KEY `live_account_id` (`live_account_id`)
 );
 
 -- Logs Objects

+ 65 - 23
modules/boonex/stripe_connect/js/main.js

@@ -1,5 +1,5 @@
 function BxStripeConnectMain(oOptions) {
-	this._sActionsUri = oOptions.sActionUri;
+    this._sActionsUri = oOptions.sActionUri;
     this._sActionsUrl = oOptions.sActionUrl;
     this._sObjName = oOptions.sObjName == undefined ? 'oStripeConnectMain' : oOptions.sObjName;
     this._sAnimationEffect = oOptions.sAnimationEffect == undefined ? 'slide' : oOptions.sAnimationEffect;
@@ -7,28 +7,70 @@ function BxStripeConnectMain(oOptions) {
     this._aHtmlIds = oOptions.aHtmlIds == undefined ? {} : oOptions.aHtmlIds;
 }
 
-BxStripeConnectMain.prototype.disconnect = function(iId, oLink) {
-	var $this = this;
-	var oDate = new Date();
-
-	bx_confirm(_t('_bx_stripe_connect_wrn_disconnect'), function() {
-		$this.loadingInButton(oLink, true);
-
-	    $.get(
-	        this._sActionsUrl + 'delete/',
-	        {
-	        	id: iId,
-	        	_t: oDate.getTime()
-	        },
-	        function(oData) {
-	        	if(parseInt(oData.code) != 0)
-	        		$this.loadingInButton(oLink, false);
-
-	        	processJsonData(oData);
-	        },
-	        'json'
-	    );
-	});    
+BxStripeConnectMain.prototype.accountCreate = function(iId, oLink) {
+    var $this = this;
+    var oDate = new Date();
+
+    this.loadingInButton(oLink, true);
+
+    $.get(
+        this._sActionsUrl + 'account_create/',
+        {
+            id: iId,
+            _t: oDate.getTime()
+        },
+        function(oData) {
+            if(parseInt(oData.code) != 0)
+                $this.loadingInButton(oLink, false);
+
+            processJsonData(oData);
+        },
+        'json'
+    );
+};
+
+BxStripeConnectMain.prototype.accountContinue = function(iId, oLink) {
+    var $this = this;
+    var oDate = new Date();
+
+    this.loadingInButton(oLink, true);
+
+    $.get(
+        this._sActionsUrl + 'account_continue/',
+        {
+            id: iId,
+            _t: oDate.getTime()
+        },
+        function(oData) {
+            if(parseInt(oData.code) != 0)
+                $this.loadingInButton(oLink, false);
+
+            processJsonData(oData);
+        },
+        'json'
+    );
+};
+
+BxStripeConnectMain.prototype.accountDelete = function(iId, oLink) {
+    var $this = this;
+    var oDate = new Date();
+
+    this.loadingInButton(oLink, true);
+
+    $.get(
+        this._sActionsUrl + 'account_delete/',
+        {
+            id: iId,
+            _t: oDate.getTime()
+        },
+        function(oData) {
+            if(parseInt(oData.code) != 0)
+                $this.loadingInButton(oLink, false);
+
+            processJsonData(oData);
+        },
+        'json'
+    );
 };
 
 BxStripeConnectMain.prototype.loadingInButton = function(e, bShow) {

+ 0 - 11
modules/boonex/stripe_connect/template/block_account.html

@@ -1,11 +0,0 @@
-<div class="bx-strp-con-account">
-	<div><bx_text:_bx_stripe_connect_grid_column_title_user_id />: <span class="bx-def-font-grayed">__user_id__</span></div>
-	<div class="bx-def-margin-thd-top"><bx_text:_bx_stripe_connect_grid_column_title_public_key />: <span class="bx-def-font-grayed">__public_key__</span></div>
-	<div class="bx-def-margin-thd-top"><bx_text:_bx_stripe_connect_grid_column_title_access_token />: <span class="bx-def-font-grayed">__access_token__</span></div>
-	<div class="bx-def-margin-thd-top"><bx_text:_bx_stripe_connect_grid_column_title_added />: <span class="bx-def-font-grayed">__added__</span></div>
-	<div class="bx-def-margin-topbottom">__keys_usage__</div>
-	<div>
-		<a class="bx-btn" href="javascript:void(0)" onclick="javascript:__js_object__.disconnect(__id__, this);"><bx_text:_bx_stripe_connect_action_title_delete /></a>
-	</div>
-	__js_code__
-</div>

+ 0 - 3
modules/boonex/stripe_connect/template/block_connect.html

@@ -1,3 +0,0 @@
-<div class="bx-strp-con-connect bx-def-font-align-center">
-	<a class="bx-btn" href="__link__"><bx_text:_bx_stripe_connect_btn_connect /></a>
-</div>

+ 9 - 0
modules/boonex/stripe_connect/template/connect_code.html

@@ -0,0 +1,9 @@
+<div class=" flex flex-wrap py-4">
+    <bx_if:show_continue>
+        <a class="bx-btn mr-4" href="javascript:void(0)" onclick="javascript:__js_object__.accountContinue(__profile_id__, this)">
+            <bx_text:_bx_stripe_connect_btn_account_continue />
+        </a>
+    </bx_if:show_continue>
+    <a class="bx-btn" href="javascript:void(0)" onclick="javascript:__js_object__.__action_method__(__profile_id__, this)">__action_title__</a>
+    __js_code__
+</div>

+ 0 - 5
modules/boonex/stripe_connect/template/css/main.css

@@ -1,5 +0,0 @@
-/*-- Connect Block --*/
-.bx-strp-con-connect .bx-btn {
-	display: inline-block;
-	float: none;
-}

+ 12 - 0
template/scripts/BxBaseCmtsServices.php

@@ -442,9 +442,21 @@ class BxBaseCmtsServices extends BxDol
         $sCmtUrl = str_replace(BX_DOL_URL_ROOT, '{bx_url_root}', $oCmts->serviceGetLink($iCmtId));
         $sCmtCaption = strmaxtextlen($oCmts->serviceGetText($iCmtId), 20, '...');
 
+        //TODO: Add setting in API app and use the same for another comments' related notifications.
+        $sCmtUrlApi = '';
+        if(bx_is_api()) {
+            $aCmt = $oCmts->getCommentsBy(['type' => 'uniq_id', 'uniq_id' => $iCmtIdUnique]);
+            if(!empty($aCmt) && is_array($aCmt)) {
+                $oCmts->init($aCmt['cmt_object_id']);
+
+                $sCmtUrlApi = str_replace(BX_DOL_URL_ROOT, '{bx_url_root}', $oCmts->getBaseUrl() . '#cid=' . $iCmtId);
+            }
+        }
+
         return array(
             'entry_sample' => $oCmts->getLanguageKey('txt_sample_single'),
             'entry_url' => $sCmtUrl,
+            'entry_url_api' => $sCmtUrlApi,
             'entry_caption' => $sCmtCaption,
             'entry_author' => $aCmtInfo['author_id'],
             'subentry_sample' => $oCmts->getLanguageKey('txt_sample_vote_single'),