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

Ticket #4558 - Build-in API support: Payments. Stripe V3.

AntonLV 2 лет назад
Родитель
Сommit
efd2410eea

+ 11 - 1
modules/boonex/payment/classes/BxPaymentConfig.php

@@ -234,7 +234,17 @@ class BxPaymentConfig extends BxBaseModPaymentConfig
     {
         return unserialize(base64_decode($s));
     }
-            
+
+    public function urlEncode($s)
+    {
+        return urlencode(base64_encode($s));
+    }
+
+    public function urlDecode($s)
+    {
+        return base64_decode(urldecode($s));
+    }
+
     public function descriptorA2S($a) 
     {
     	return implode($this->getDivider('DIVIDER_DESCRIPTOR'), $a);

+ 73 - 12
modules/boonex/payment/classes/BxPaymentModule.php

@@ -177,6 +177,9 @@ class BxPaymentModule extends BxBaseModPaymentModule
             'GetBlockCartHistory' => 'BxPaymentCart',
             'GetBlockListMy' => 'BxPaymentSubscriptions',
             'GetBlockHistory' => 'BxPaymentSubscriptions',
+
+            'InitializeCheckoutApi' => '',
+            'StripeV3CreateSessionApi' => ''
         ));
     }
 
@@ -1067,17 +1070,49 @@ class BxPaymentModule extends BxBaseModPaymentModule
         return $oProvider->initializeCheckout($iPendingId, $aInfo, $sRedirect);
     }
 
+    public function serviceInitializeCheckoutApi($sType, $iSellerId, $sProvider, $aItems = [], $sRedirect = '', $aCustoms = [])
+    {
+        $mixedResult = $this->serviceInitializeCheckout($sType, $iSellerId, $sProvider, $aItems, $sRedirect, $aCustoms);
+        if(is_string($mixedResult))
+            return [bx_api_get_msg($mixedResult)];
+        
+        if(is_array($mixedResult)) {
+            if(isset($mixedResult['redirect'])) {
+                header('Location: ' . bx_api_get_relative_url($mixedResult['redirect']));
+                exit;
+            }
+
+            if(isset($mixedResult['message']))
+                return [bx_api_get_msg($mixedResult)];
+        }
+
+        return [];
+    }
+
     public function actionFinalizeCheckout($sProvider, $mixedVendorId = "")
     {
         $aData = &$_REQUEST;
 
+        $aResult = $this->serviceFinalizeCheckout($sProvider, $mixedVendorId, $aData);
+        if(isset($aResult['error']))
+            return $this->_oTemplate->displayPageCodeError($aResult['error']);
+        else if(isset($aResult['redirect'])) {
+            header('Location: ' . $aResult['redirect']);
+            exit;
+        }
+        else
+            $this->_oTemplate->displayPageCodeResponse($aResult['message']);
+    }
+    
+    public function serviceFinalizeCheckout($sProvider, $mixedVendorId = "", $aData = [])
+    {
         $oProvider = $this->getObjectProvider($sProvider, $mixedVendorId);
         if($oProvider === false || !$oProvider->isActive())
-            return $this->_oTemplate->displayPageCodeError($this->_sLangsPrefix . 'err_incorrect_provider');
+            return ['error' => $this->_sLangsPrefix . 'err_incorrect_provider'];
 
         $aResult = $oProvider->finalizeCheckout($aData);
         if((int)$aResult['code'] != BX_PAYMENT_RESULT_SUCCESS) 
-            return $this->_oTemplate->displayPageCodeError($aResult['message']);
+            return ['error' => $aResult['message']];
 
         $aPending = $this->_oDb->getOrderPending(['type' => 'id', 'id' => (int)$aResult['pending_id']]);
         $bTypeRecurring = $aPending['type'] == BX_PAYMENT_TYPE_RECURRING;
@@ -1100,7 +1135,7 @@ class BxPaymentModule extends BxBaseModPaymentModule
             );
 
             if(!$this->getObjectSubscriptions()->register($aPending, $aSubscription))
-                return $this->_oTemplate->displayPageCodeError($this->_sLangsPrefix . 'err_already_registered');
+                return ['error' => $this->_sLangsPrefix . 'err_already_registered'];
         }
 
         $this->onPaymentRegisterBefore($aPending);
@@ -1128,17 +1163,13 @@ class BxPaymentModule extends BxBaseModPaymentModule
             'result' => &$aResult,
         ));
 
-        if($oProvider->needRedirect()) {
-            header('Location: ' . $oProvider->getReturnUrl());
-            exit;
-        }
+        if($oProvider->needRedirect()) 
+            return ['redirect' => $oProvider->getReturnUrl()];
 
-        if(!empty($aResult['redirect'])) {
-            header('Location: ' . base64_decode(urldecode($aResult['redirect'])));
-            exit;
-        }
+        if(!empty($aResult['redirect'])) 
+            return ['redirect' => $this->_oConfig->urlDecode($aResult['redirect'])];
 
-        $this->_oTemplate->displayPageCodeResponse($aResult['message']);
+        return ['message' => $aResult['message']];
     }
 
     public function actionFinalizedCheckout($sProvider, $mixedVendorId = "")
@@ -1967,6 +1998,36 @@ class BxPaymentModule extends BxBaseModPaymentModule
     	return true;
     }
 
+    public function serviceStripeV3CreateSessionApi($mixedParams)
+    {
+        $aParams = is_array($mixedParams) ? $mixedParams : json_decode($mixedParams, true);
+        if(!isset($aParams['type'], $aParams['seller_id'], $aParams['items']))
+            return [bx_api_get_msg(_t($this->_sLangsPrefix . 'err_wrong_data'))];
+            
+        $sProvider = 'stripe_v3';
+        $iClientId = $this->getProfileId();
+        $iSellerId = (int)$aParams['seller_id'];
+        $sItems = $aParams['items'];
+
+        $oProvider = $this->getObjectProvider($sProvider, $iSellerId);
+        if($oProvider === false || !$oProvider->isActive())
+            return [bx_api_get_msg(_t($this->_sLangsPrefix . 'err_incorrect_provider'))];
+
+        $aSessionParams = [];
+        if(!empty($aParams['return_url']))
+            $aSessionParams['return_url'] = $aParams['return_url'] . '/api.php?r=' . $this->getName() . '/initialize_checkout_api&' . http_build_query([
+                'params' => [$aParams['type'], $iSellerId, $sProvider, $sItems, $this->_oConfig->urlEncode($this->_oConfig->getUrl('URL_HISTORY'))]
+            ]);
+
+        $minxedSession = $oProvider->createSessionPaymentEmbedded($aParams['type'], $iClientId, $iSellerId, $sItems, $aSessionParams);
+        if($minxedSession === false)
+            return [bx_api_get_msg(_t($this->_sLangsPrefix . 'err_cannot_perform'))];
+
+        return [
+            'clientSecret' => $minxedSession
+        ];
+    }
+
     public function serviceConvert($fAmount, $sCurrencyFrom, $sCurrencyTo, $fRate = false)
     {
         $sCurrencyDefault = $this->_oConfig->getDefaultCurrencyCode();

+ 56 - 14
modules/boonex/payment/classes/BxPaymentProviderStripeV3.php

@@ -75,8 +75,8 @@ class BxPaymentProviderStripeV3 extends BxPaymentProviderStripeBasic implements
             )), false)
         );
 
-        $sSessionId = $this->_createSession(BX_PAYMENT_TYPE_RECURRING, $aSessionParams, $aClient, $aCartInfo);
-        if($sSessionId === false)
+        $mixedSession = $this->_createSession(BX_PAYMENT_TYPE_RECURRING, $aSessionParams, $aClient, $aCartInfo);
+        if($mixedSession === false)
             return echoJson(array('msg' => _t('_bx_payment_err_cannot_perform')));
 
         $sJsObject = $this->getJsObject(array(
@@ -87,7 +87,7 @@ class BxPaymentProviderStripeV3 extends BxPaymentProviderStripeBasic implements
 
         return echoJson(array(
             'code' => 0, 
-            'session_id' => $sSessionId,
+            'session_id' => $mixedSession['id'],
             'eval' => $sJsObject . '.onSubscribe(oData);'
         ));
     }
@@ -203,13 +203,18 @@ class BxPaymentProviderStripeV3 extends BxPaymentProviderStripeBasic implements
         if(!empty($aProcessed) && is_array($aProcessed) && (int)$aProcessed['processed'] != 0 && $aProcessed['id'] != $iPendingId)
             return $this->_sLangsPrefix . 'err_already_processed';
 
-        header("Location: " . $this->getReturnDataUrl($aVendor['id'], array(
+        $aData = [
             'mode' => $mixedResult['mode'],
             'order_id' => $mixedResult['order_id'],
             'customer_id' => $mixedResult['customer_id'], 
             'pending_id' => $aPending['id'],
             'redirect' => $sRedirect
-        )));
+        ];
+
+        if(bx_is_api())
+            return $this->_oModule->serviceFinalizeCheckout($this->_sName, $aVendor['id'], $aData);
+
+        header("Location: " . $this->getReturnDataUrl($aVendor['id'], $aData));
         exit;
     }
 
@@ -354,16 +359,19 @@ class BxPaymentProviderStripeV3 extends BxPaymentProviderStripeBasic implements
             )), false)
         );
 
-        $sSessionId = $this->_createSession(BX_PAYMENT_TYPE_SINGLE, $aSessionParams, $aClient, $aCartInfo);
-        if($sSessionId === false)
+        $mixedSession = $this->_createSession(BX_PAYMENT_TYPE_SINGLE, $aSessionParams, $aClient, $aCartInfo);
+        if($mixedSession === false)
             return array('msg' => _t('_bx_payment_err_cannot_perform'));
 
         return array(
             'eval' => $this->_oModule->_oConfig->getJsObject($this->_sName) . '.onCartCheckout(oData);', 
-            'session_id' => $sSessionId
+            'session_id' => $mixedSession['id']
         );
     }
 
+    /**
+     * Note. Isn't used for now in default version.
+     */
     public function createSessionAuthorize($sType, $iClientId, $iSellerId, $sItems, $aSessionParams = [])
     {
         $aClient = $this->_oModule->getProfileInfo($iClientId);
@@ -383,7 +391,43 @@ class BxPaymentProviderStripeV3 extends BxPaymentProviderStripeBasic implements
             ], false)
         ], $aSessionParams);
 
-        return $this->_createSession('authorize', $aSessionParams, $aClient, $aCartInfo);
+        $mixedSession = $this->_createSession('authorize', $aSessionParams, $aClient, $aCartInfo);
+        if($mixedSession === false)
+            return false;
+
+        return $mixedSession['id'];
+    }
+
+    /*
+     * https://stripe.com/docs/checkout/embedded/quickstart?client=react&lang=php
+     */
+    public function createSessionPaymentEmbedded($sType, $iClientId, $iSellerId, $sItems, $aSessionParams = [])
+    {
+        $aClient = $this->_oModule->getProfileInfo($iClientId);
+
+        $oCart = $this->_oModule->getObjectCart();
+        $aCartInfo = $oCart->getInfo($sType, $aClient['id'], $iSellerId, $sItems);
+        if(empty($aCartInfo) || !is_array($aCartInfo))
+            return false;
+
+        $aSessionParams = array_merge([
+            'ui_mode' => 'embedded',
+            'return_url' => bx_append_url_params($this->_oModule->_oConfig->getUrl('URL_CART_CHECKOUT'), [
+                'provider' => $this->_sName,
+                'seller_id' => $iSellerId,
+                'items' => $sItems,
+                'session_id' => '{CHECKOUT_SESSION_ID}'
+            ], false)
+        ], $aSessionParams);
+
+        if(strpos($aSessionParams['return_url'], 'session_id') === false)
+            $aSessionParams['return_url'] .= '&session_id={CHECKOUT_SESSION_ID}';
+
+        $mixedSession = $this->_createSession(BX_PAYMENT_TYPE_SINGLE, $aSessionParams, $aClient, $aCartInfo);
+        if($mixedSession === false)
+            return false;
+
+        return $mixedSession['client_secret'];
     }
 
     public function createTax($sName, $fPercentage, $bInclusive = false)
@@ -602,11 +646,9 @@ class BxPaymentProviderStripeV3 extends BxPaymentProviderStripeBasic implements
 
         $oSession = null;
         $aSession = array_merge([
-            'payment_method_types' => ['card'],
-            'customer_email' => !empty($aClient['email']) ? $aClient['email'] : '',
             'mode' => $sMode,
-            'success_url' => '',
-            'cancel_url' => '',
+            'payment_method_types' => ['card'],
+            'customer_email' => !empty($aClient['email']) ? $aClient['email'] : ''
         ], $aParams);
 
         $bLineItems = !empty($aLineItems);
@@ -647,7 +689,7 @@ class BxPaymentProviderStripeV3 extends BxPaymentProviderStripeBasic implements
         if($bVerify && !$this->checkVerificationCodeSession($aCartInfo['vendor_id'], $aClient['id'], $aResult))
             return false;
 
-        return $aResult['id'];
+        return $aResult;
     }
 
     protected function _getSession($sType, $sId)