OC v3.х Отправить json на сторонний сервер после оформления заказа.

Den_Volt

Разрушитель (V)
Сообщения
62
Симпатии
122
Баллы
4 046
Задача стоит такая, после оформления заказа нужно отправлять информацию о заказе в виде json данных на другой сервак, в данный момент нашел контроллер который редиректит после всех валидаций на страницу успешного заказа (/catalog/controller/extension/payment/cod.php), вставляю туда код отправки и данные улетают, но вот встал вопрос, как сделать это правильно, может есть более правильные способы? Хотел бы узнать мнение специалистов.

PHP:
class ControllerExtensionPaymentCod extends Controller {
    public function index() {
        return $this->load->view('extension/payment/cod');
    }

    public function confirm() {
        $json = array();
        
        if ($this->session->data['payment_method']['code'] == 'cod') {
            $this->load->model('checkout/order');

            $this->model_checkout_order->addOrderHistory($this->session->data['order_id'], $this->config->get('payment_cod_order_status_id'));
            
            $this->load->model('account/order'); /*подключаем модель для получения информации о заказе*/
            
            $order_info = false;
            
            $order_info = $this->model_account_order->getOrderProducts($this->session->data['order_id']); /*order_info содержит информацию о заказе*/
            
            
            $url="http://site.by/metod.php?id=".json_encode($order_info);
            
            $curl = curl_init($url);
            
            curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
            
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            
            curl_setopt($curl, CURLOPT_HEADER, true);
            
            curl_setopt($curl, CURLOPT_NOBODY, true);
            
            curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
            
            $output = curl_exec($curl);
            
            curl_close($curl);
            
            $json['redirect'] = $this->url->link('checkout/success'); /*редирект на успешное оформление*/
        }
        
        $this->response->addHeader('Content-Type: application/json');
        $this->response->setOutput(json_encode($json));       
    }
}
 
1. Чтобы не писать в коде контроллера в OC3 можно использовать события, н-р, как отправляется письмо (админу, клиенту) после создания заказа. События доступны через админку OC и их при необходимости можно отключать / включать.
2. При отправке на ресурс желательно его закрыть хотя бы basic authorization и использовать протокол с шифрованием (https). Если между сайтом и внешним ресурсом проброшен VPN, то можно и без этого.
3. У клиента, в случае недоступности внешнего ресурса, при оформлении заказа будут подвисания (время таймаута curl) и может не очиститься корзина.
Чтобы оформление клиентом заказа на сайте никак не зависело от доступности ресурса для отправки информации о заказе можно разделить процессы оформления заказа и отправки информации о заказе на внешний ресурс , н-р, так. На крон повесить внешний скрипт, который будет мониторить появления новых заказов и отправлять их на внешний сервис. При это внешний сервис должен возвращать ответ об успешном принятии заказа, чтобы его не отправлять повторно.
 
Первым делом нашёл плагин выводящий полную информацию о заказе https://opencart3x.ru/module/order/admin-order-email, решил все настройки делать именно в этом xml, что бы в дальшейнем была возможность выключить этот функционал оправки заявок на сервер (сервер склада).
После добавления в объект $data всех данных пытаюсь отдать его в файл json.php для проверки но ничего не прилетает. Буду благодарен за подсказку

PHP:
//весь код до этого много присвоений $data[..] = 

//стандартный код
$mail->setTo($this->config->get('config_email'));
$mail->setFrom($this->config->get('config_email'));
$mail->setSender(html_entity_decode($order_info['store_name'], ENT_QUOTES, 'UTF-8'));
$mail->setSubject(html_entity_decode(sprintf($this->language->get('text_subject'), $this->config->get('config_name'), $order_info['order_id']), ENT_QUOTES, 'UTF-8'));*/

//после сборки всех данных решил сделать вставку
            
$url="https://site.by/json.php?id=".json_encode($data);
            
$curl = curl_init($url);
            
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
            
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            
curl_setopt($curl, CURLOPT_HEADER, true);
            
curl_setopt($curl, CURLOPT_NOBODY, true);
            
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
            
$output = curl_exec($curl);
            
curl_close($curl);
            

//Далее отправка mail

$mail->setHTML($this->load->view('mail/order_add', $data));
$mail->send();

// Send to additional alert emails
$emails = explode(',', $this->config->get('config_mail_alert_email'));

foreach ($emails as $email) {
    if ($email && filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $mail->setTo($email);
            $mail->send();
    }
}

Файлик json.php выглядит вот так
PHP:
$postData = file_get_contents('php://input');
$data = json_decode($postData, true);

$fp = fopen('data.txt', 'w');
fwrite($fp, serialize($data));
fclose($fp);

echo $data;
var_dump($data);
 
Первым делом нашёл плагин выводящий полную информацию о заказе https://opencart3x.ru/module/order/admin-order-email, решил все настройки делать именно в этом xml, что бы в дальшейнем была возможность выключить этот функционал оправки заявок на сервер (сервер склада).
После добавления в объект $data всех данных пытаюсь отдать его в файл json.php для проверки но ничего не прилетает. Буду благодарен за подсказку

PHP:
//весь код до этого много присвоений $data[..] =

//стандартный код
$mail->setTo($this->config->get('config_email'));
$mail->setFrom($this->config->get('config_email'));
$mail->setSender(html_entity_decode($order_info['store_name'], ENT_QUOTES, 'UTF-8'));
$mail->setSubject(html_entity_decode(sprintf($this->language->get('text_subject'), $this->config->get('config_name'), $order_info['order_id']), ENT_QUOTES, 'UTF-8'));*/

//после сборки всех данных решил сделать вставку
          
$url="https://site.by/json.php?id=".json_encode($data);
          
$curl = curl_init($url);
          
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
          
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
          
curl_setopt($curl, CURLOPT_HEADER, true);
          
curl_setopt($curl, CURLOPT_NOBODY, true);
          
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
          
$output = curl_exec($curl);
          
curl_close($curl);
          

//Далее отправка mail

$mail->setHTML($this->load->view('mail/order_add', $data));
$mail->send();

// Send to additional alert emails
$emails = explode(',', $this->config->get('config_mail_alert_email'));

foreach ($emails as $email) {
    if ($email && filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $mail->setTo($email);
            $mail->send();
    }
}

Файлик json.php выглядит вот так
PHP:
$postData = file_get_contents('php://input');
$data = json_decode($postData, true);

$fp = fopen('data.txt', 'w');
fwrite($fp, serialize($data));
fclose($fp);

echo $data;
var_dump($data);
Вы пытаетесь отправить GET запрос и затем обрабатываете на приемнике как POST.
Попробуйте отправлять запрос как POST (н-р, как-то так) или на принимающей стороне обрабатывайте GET запрос.
 
Для тех кому будет интересно как отправлять post запрос и принимать его:
PHP:
$data_string = json_encode ($data, JSON_UNESCAPED_UNICODE);
$curl = curl_init('https://site.com/json.php');
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($curl, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
   'Content-Type: application/json',
   'Content-Length: ' . strlen($data_string))
);
$result = curl_exec($curl);
curl_close($curl);

Для обработки json на сервере можно использовать эту структуру (файл json.php):
PHP:
/*Принимаем Json*/
$postData = file_get_contents('php://input');

/*Пишем в файл*/
$fp = fopen('data.txt', 'w');
fwrite($fp, $postData);
fclose($fp);
 
Назад
Верх