Повторный заказ без входа на сайт

Борюсь сейчас с оформлением заказа без входа на сайт с привязкой к учетке покупателя
Сценарий таков:

  • Быстрая регистрация включена
  • Пользователь уже оформлял заказы раньше
  • Сессия закончилась и покупатель пришел как гость.
    Что сейчас делаю: в контроллере app/controllers/frontend/checkout.php в ПОСТ секции моде update_steps проверяю есть ли пользователь с введенным мейлом.
    Если есть - устанавливаю $auth[‘user_id’].
    Проблема после этого пользователя авторизирует, он получает доступ к кабинету итд, а то вообще не секьюрно))))

Может у кого есть какие либо варианты как то решить другими путями?

Не делайте вот это - автологин по email. Это очень очень плохая методика, вы верно пишите про не секьюрно.

Пока надо увеличить время жизни куки логина - сейчас стоит неделя.

Вот тут поставьте

// Live time for permanent cookies (currency, language, etc…)
define(‘COOKIE_ALIVE_TIME’, SECONDS_IN_DAY * 7); // one week

Самый хороший для вас вариант судя по всему- вечный логин (по аналогии например с вконтакте или facebook)
Если человек вернулся на сайт - обновлять куку логина (делать ее рефреш автоматически, продлевать срок жизни). Мы так делали, в целом если ставить COOKIE_ALIVE_TIME = 28 days и человек достаточно часто возвращается, его будет редко разлогинивать.

2 лайка

Автологин получился случайно, я просто описал свои наработки в этом направлении.
Проблема в том, что пользователь мог и не заходить к нам еще(магазин новый, пользователи старые).

Просто убрать проверку email на учетку? Получится гость оформит заказ с email уже регистрированного покупателя. А заказ сам назначится учетке по email.

Да, в целом к этому и стремимся

Через Хук is_user_exists_post
if(Registry::get(‘runtime.controller’) == ‘checkout’ && Registry::get(‘runtime.mode’) != ‘create_profile’){
$is_exist = false;
}

2 лайка

И можно добавить данный заказ клиенту, если у клиента уже есть учетка. Но все заказы клиент увидит после авторизации. А до авторизации только заказы в рамках своей сессии.

function fn_[ADDON]_place_order($order_id, $action, $order_status, $cart, $auth)
{
     if($order_id != false){
         $email = $cart['user_data']['email'] ? $cart['user_data']['email'] : $cart['user_data']['s_email'];
         $user_data = array(
             'email' => $email
             );
         $user_id = fn_is_user_exists(0,$user_data);
         
         if($user_id != false){
            db_query('UPDATE ?:orders SET user_id = ?i WHERE order_id = ?i', $user_id, $order_id);
         }
     }
}
2 лайка

@developstores @sweetcode
Спасибо за участие, просветили, всё заплясало

Так что уже работает такое решение? А при оформлении заказа зарегистрированным пользователем не выдает ошибку о том что эта почта уже используется- получается зарегистрированному пользователю оформить заказ как гость?

Да, работает.
Заказа оформляется и привязывается к клиенту. Ошибка не возникает т.к. хук в функции is_user_exists возвращает ложь

1 лайк

Добрый день.

Извините за ламерский вопрос, каким образом заставить сей функционал работать? Добавить код в app/…/…?

Включаете модуль Мои изменения
в файле app/addons/my_changes/func.php

function fn_my_changes_place_order($order_id, $action, $order_status, $cart, $auth)
{
     if($order_id != false){
         $email = $cart['user_data']['email'] ? $cart['user_data']['email'] : $cart['user_data']['s_email'];
         $user_data = array(
             'email' => $email
             );
         $user_id = fn_is_user_exists(0,$user_data);
         
         if($user_id != false){
            db_query('UPDATE ?:orders SET user_id = ?i WHERE order_id = ?i', $user_id, $order_id);
         }
     }
}

И вторая функция

function fn_my_changes_is_user_exists_post($user_id, $user_data, &$is_exist){
if(Registry::get(‘runtime.controller’) == ‘checkout’ && Registry::get(‘runtime.mode’) != ‘create_profile’){
$is_exist = false;
}
}

В файле app/addons/my_changes/init.php (Привёдён весь текст файла)

<?php

if (!defined('BOOTSTRAP')) { die('Access denied'); }

fn_register_hooks(
    'place_order',
    'is_user_exists_post'
);

1 лайк

У вас заказы привязываются к существующим аккаунтам? Потому что я проверил и именно этот момент не работает

1 лайк

В целом у меня немного не так всё, так что копипастил код на странице.
Можно попробовать вот так, думаю заработает у Вас

!!!Не проверял

function fn_my_changes_place_order($order_id, $action, $order_status, $cart, $auth)
{
     if($order_id != false){
         $email = $cart['user_data']['email'] ? $cart['user_data']['email'] : $cart['user_data']['s_email'];

        $user_id = db_get_field("SELECT user_id FROM ?:users WHERE email= ?s", $email);
         
         if($user_id != false){
            db_query('UPDATE ?:orders SET user_id = ?i WHERE order_id = ?i', $user_id, $order_id);
         }
     }
}
1 лайк

Ваш вариант рабочий, большое спасибо :slightly_smiling_face:

А проверка может быть не по Емейл, а по номеру телефона?

В целом может, но только если у вас на сайте это(регистрация по номеру) реализовано уже.
У нас именно так

Файл app/addons/my_changes/func.php

    <?php

use Tygh\Registry;
use Tygh\Navigation\LastView;
use Tygh\Http;

function fn_my_changes_place_order($order_id, $action, $order_status, $cart, $auth)
{
     if($order_id != false){
         $email = $cart['user_data']['email'] ? $cart['user_data']['email'] : $cart['user_data']['s_email'];

        $user_id = db_get_field("SELECT user_id FROM ?:users WHERE email= ?s", $email);
         
         if($user_id != false){
            db_query('UPDATE ?:orders SET user_id = ?i WHERE order_id = ?i', $user_id, $order_id);
         }
     }
}


function fn_my_changes_is_user_exists_post($user_id, $user_data, &$is_exist){
if(Registry::get(‘runtime.controller’) == ‘checkout’ && Registry::get(‘runtime.mode’) != ‘create_profile’){
$is_exist = false;
}
}

Файл app/addons/my_changes/init.php

    <?php

use Tygh\Registry;
use Tygh\Navigation\LastView;
use Tygh\Http;

if (!defined('BOOTSTRAP')) { die('Access denied'); }

fn_register_hooks(
    'place_order',
    'is_user_exists_post'
);

К сожалению, все еще показывается надпись, что пользователь уже зарегистрирован, и оформление заказа не продолжается.
Подскажите, пожалуйста, что может быть не так.

Ошиблись с файлом)
снизу должен быть init.php
Может и сделано у вас так?

Чтоб по телефону тоже шла проверка, надо добавить к коду:

if($order_id != false){
    $phone = $cart['user_data']['s_phone'] ? $cart['user_data']['s_phone'] : $cart['user_data']['s_phone'];

    $user_id = db_get_field("SELECT user_id FROM ?:users WHERE phone= ?s", $phone);
     
    if($user_id != false){
        db_query("UPDATE ?:orders SET user_id = ?i WHERE order_id = ?i", $user_id, $order_id);
    }
}

Не обязательно должна быть регистрация по телефону, кстати.

Тестил способ, привязывает заказ к учетке, даже если покупатель указал другой email, но телефон соответствует.

И самое главное, желательно маска телефона на сайте. Потому что если телефон в базе у учетки +79991234567, а покупатель в заказе укажет +7(999)123-45-67, то заказ не привяжется.

1 лайк