Подтвердить что ты не робот

Как добавить пользовательский платежный шлюз в Social Engine

Мне нужно интегрировать новый платежный шлюз на наш корпоративный сайт, основанный на Social Engine. Для этого CMS существует расширение под названием Advanced Payment Gateways, которое позволяет интегрировать новые шлюзы. Фактически, он получает имя вашего шлюза и генерирует скелетную структуру, упакованную в файл, чтобы вы могли разархивировать и загрузить на свой сервер и таким образом объединить с каталогом приложения.

Я собираюсь объяснить, как я реализую свой шлюз без Social Engine, и я надеюсь, что кто-то подскажет мне, как я могу включить это в Social Engine.

  1. Сначала я подключаюсь к своему сервису PSP:

    $client = new nusoap_client('https://example.com/pgwchannel/services/pgw?wsdl');
    
  2. Я подготавливаю следующие параметры в массиве для отправки в bpPayRequest:

    $parameters = array(
        'terminalId' => $terminalId,
        'userName' => $userName,
        'userPassword' => $userPassword,
        'orderId' => $orderId,
        'amount' => $amount,
        'localDate' => $localDate,
        'localTime' => $localTime,
        'additionalData' => $additionalData,
        'callBackUrl' => $callBackUrl,
        'payerId' => $payerId);
    
    // Call the SOAP method
    $result = $client->call('bpPayRequest', $parameters, $namespace);
    
  3. Если запрос платежа принят, результатом является строка, разделенная запятыми, с первым элементом 0 0.
    Затем мы можем отправить второй элемент (ссылочный идентификатор) для оплаты шлюз следующим образом с помощью метода POST:

    echo "<script language='javascript' type='text/javascript'>postRefId('" . $res[1] . "');</script>";
    
    <script language="javascript" type="text/javascript">    
        function postRefId (refIdValue) {
            var form = document.createElement("form");
            form.setAttribute("method", "POST");
            form.setAttribute("action", "https://example.com/pgwchannel/startpay");         
            form.setAttribute("target", "_self");
            var hiddenField = document.createElement("input");              
            hiddenField.setAttribute("name", "RefId");
            hiddenField.setAttribute("value", refIdValue);
            form.appendChild(hiddenField);
    
            document.body.appendChild(form);         
            form.submit();
            document.body.removeChild(form);
        }
        </script>
    
  4. Шлюз вернет следующие параметры с помощью метода POST для обратного вызова URL, который мы указали в запросе на оплату:
    RefId (ссылочный идентификатор, созданный на предыдущих шагах)
    ResCode (Результат платежа: 0 означает успех)
    saleOrderId (идентификатор заказа, переданный во время запроса на оплату)
    SaleReferenceId (ссылочный код продажи предоставляется PSP продавцу)

  5. Если ResCode на предыдущем шаге было 0 0, то для подтверждения платежа нам нужно было бы передать вызов bpVerifyRequest со следующими параметрами, в противном случае платеж будет отменен.

     $parameters = array(
        'terminalId' => $terminalId,
        'userName' => $userName,
        'userPassword' => $userPassword,
        'orderId' => $orderId,
        'saleOrderId' => $verifySaleOrderId,
        'saleReferenceId' => $verifySaleReferenceId);
    
    // Call the SOAP method
    $result = $client->call('bpVerifyRequest', $parameters, $namespace);
    
  6. В случае, если результат bpVerifyRequest равен нулю, оплата определена, и продавец должен предоставить приобретенные товары или услуги. Однако существует необязательный метод bpSettleRequest, который используется для запроса расчета. Это называется следующим образом:

    $parameters = array(
        'terminalId' => $terminalId,
        'userName' => $userName,
        'userPassword' => $userPassword,
        'orderId' => $orderId,
        'saleOrderId' => $settleSaleOrderId,
        'saleReferenceId' => $settleSaleReferenceId);

    // Call the SOAP method
    $result = $client->call('bpSettleRequest', $parameters, $namespace);

Я запутался, посмотрев на шлюзы по умолчанию в плагине Payment Gateways, например, PayPal, Stripe, 2Checkout и т.д. Как мне включить эту кодовую логику в недавно созданный каркас шлюза? (структура показана ниже):
enter image description here

Вы можете проверить полный исходный код здесь:
default.php
callback.php

4b9b3361

Ответ 1

Я решил эту проблему, добавив код оплаты в класс Engine_Payment_Gateway_MyGateway:

Как только пользователь подтверждает на странице SocialEngine, что он хочет заплатить, вызывается метод processTransaction() внутри упомянутого класса, и пользователь перенаправляется на защищенную страницу оплаты PSP. Как только они выполнят платеж, то есть оплатят успешно, потерпят неудачу или отменили транзакцию, они перенаправляют страницу PSP на страницу, которую мы отправили ранее, в качестве параметра с именем callBackUrl. Там вы получите параметры, специфичные для PSP, которые помогут вам определить, был ли платеж успешным, и попросить PSP с помощью другого вызова SOAP подтвердить платеж, а затем при необходимости попросить его произвести расчет (внесите деньги как можно скорее на счет продавца):

Добавить в processTransaction():

        $data = array();
        $rawData = $transaction->getRawData();

        //Save order ID for later
        $this->_orderId = $rawData['vendor_order_id'];
        $this->_grandTotal = $rawData['AMT'];


        $client = new nusoap_client('https://example.com/pgwchannel/services/pgw?wsdl');
        $namespace = 'http://interfaces.core.sw.example.com/';


        // Check for an error
        $err = $client->getError();
        if ($err) {
            echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
            die();
        }


        /* Set variables */

//Get price from SEAO 
//$order_ids = Engine_Api::_()->getDbTable('orders','sitestoreproduct')->getOrderIds($this->parent_id);
//$price = Engine_Api::_()->getDbTable('orders','sitestoreproduct')->getGrandTotal($this->parent_id);


        $terminalId = '1111111';
        $userName = 'username';
        $userPassword = '1111111';
        $orderId = $rawData['vendor_order_id'];

        $amount = $rawData['AMT'];
        $localDate = date("Y") . date("m") . date("d");
        $localTime = date("h") . date("i") . date("s");
        $additionalData = $rawData['return_url'];
        $callBackUrl = 'https://example.com/pgateway/pay/callback';
        $payerId = '0';







        /* Define parameters array   */

        $parameters = array(
            'terminalId' => $terminalId,
            'userName' => $userName,
            'userPassword' => $userPassword,
            'orderId' => $orderId,
            'amount' => $amount,
            'localDate' => $localDate,
            'localTime' => $localTime,
            'additionalData' => $additionalData,
            'callBackUrl' => $callBackUrl,
            'payerId' => $payerId
        );



        $result = $client->call('bpPayRequest', $parameters, $namespace);



        if ($client->fault) {
            echo '<h2>Fault</h2><pre>';
            print_r($result);
            echo '</pre>';
            die();
        } else { //Check for errors
            $error = $client->getError();
            if ($error) {
                echo "An error occurred: ";
                print_r($error);
                die();
            } else {
                //break the code
                $resultSegmts = explode(',', $result);
                $ResCode = $resultSegmts [0];


                if ($ResCode == "0") {
                    //Notify admin of the order                    
                    echo '<h3>Redirecting you to the payment page. Please wait...</h3><br/>';
                    echo '<script language="javascript" type="text/javascript">
                      postRefId("' . $resultSegmts[1] . '");
                    </script>';
                } elseif ($ResCode == "25") {
                    echo "<h3>Purchase successful</h3>";
                } else {
                    echo "<h3>PSP response is: $ResCode</h3>";
                } 
            }
        }

Добавьте к своему действию обратного вызова:

    $this->view->message = 'This is callback action for PayController';
    $RefId = $_POST['RefId'];
    $ResCode = $_POST['ResCode'];
    $saleOrderId = $_POST['SaleOrderId'];
    $saleReferenceId = $_POST['SaleReferenceId'];

    $this->_orderId = $saleOrderId;

        $this->view->RefId = $RefId;
        $this->view->saleOlderId = $saleOrderId;
        $this->view->saleReferenceId = $saleReferenceId;
    }
    if ($ResCode == "0") {
        try {
            $client = new nusoap_client('https://example.com/pgwchannel/services/pgw?wsdl');
        } catch (Exception $e) {
            die($e->getMessage());
        }

        $namespace = 'http://interfaces.core.sw.example.com/';
        $terminalId = "111111";
        $userName = "username";
        $userPassword = "11111111";


        $parameters = array(
            'terminalId' => $terminalId,
            'userName' => $userName,
            'userPassword' => $userPassword,
            'orderId' => $saleOrderId,
            'saleOrderId' => $saleOrderId,
            'saleReferenceId' => $saleReferenceId
        );
        $resVerify = $client->call('bpVerifyRequest', $parameters, $namespace);



        if ($resVerify->fault) { //Check for fault 
            echo "<h1>Fault: </h1>";
            print_r($result);
            die();
        } else { //No fault: check for errors now 
            $err = $client->getError();
            if ($err) {
                echo "<h1>Error: " . $err . " </h1>";
            } else {
                if ($resVerify == "0") {//Check verification response: if 0, then purchase was successful. 
                    echo "<div class='center content green'>Payment successful. Thank you for your order.</div>";
                    $this->view->message = $this->_translate('Thanks for your purchase.');
                    $this->dbSave(); //update database table
                } else
                    echo "<script language='javascript' type='text/javascript'>alert(    'Verification Response: " . $resVerify . "');</script>";
            }
        }

        //Note that we need to send bpSettleRequest to PSP service to request settlement once we have verified the payment 
        if ($resVerify == "0") {
            // Update table, Save RefId
            //Create parameters array for settle
            $this->sendEmail();
            $this->sendSms();

            $resSettle = $client->call('bpSettleRequest', $parameters, $namespace);
            //Check for fault 
            if ($resSettle->fault) {
                echo "<h1>Fault: </h1><br/><pre>";
                print_r($resSettle);
                echo "</pre>";
                die();
            } else { //No fault in bpSettleRequest result 
                $err = $client->getError();
                if ($err) {
                    echo "<h1>Error: </h1><pre>" . $err . "</pre>";
                    die();
                } else {
                    if ($resSettle == "0" || $resSettle == "45") {//Settle request successful 
                        // echo "<script language='javascript' type='text/javascript'>alert('Payment successful');</script>";
                    }
                }
            }
        }
    } else {
        echo "<div class='center content error'>Payment failed. Please try again later.</div> ";
        // log error in app
        // Update table, log the error
        // Show proper message to user
    }
    $returnUrl = 'https://example.com/stores/products'; //Go to store home for now. Later I'll set this to the last page 
    echo "<div class='center'>";
    echo "<form action=$returnUrl method='POST'>";
    echo "<input class='center' id='returnstore' type='submit' value='Return to store'/>";
    echo "</form>";
    echo "</div>";