ПРОЛОГ
Данная тема создана давно. С тех пор многое менялось, обновлялся woocommerce, отлавливались баги, что-то обсуждалось, были и просто доработки. Тема значительно разрослась, а самая первая версия, описанная в первом посте, практически утратила свою актуальность. Вот несколько ссылок на ключевые посты темы, которые также рекомендованы к обязательному прочтению.
Обнова с WC 2.1 до 2.2
Лечение циклической переадресации
Обнова до WC 2.4
Хочу поделиться своим опытом по совмещению в одно страницы корзины (\cart) и оплаты (\checkout). Во-первых, кому-то может пригодиться, во-вторых, очень хочется услышать мнение более продвинутых сайторазработчиков по этому поводу, так как некоторые мои решения наверняка некорректны и неизящны и можно сделать правильнее и оптимальнее. Хотя вроде немного погонял туба-сюда, проблем не заметил. В общем, жду конструктивной критики.
Зачем?
Прежде всего объясню, зачем я решил лезть в святая святых - функционал и принцип работы интернет-магазина WooCommerce. Функционал конечно классный, отлично заточен под электронную торговлю, особенно - под международную торговлю с кучей вариантов оплаты, доставки товара. Поэтому многое для нашего региона, и в частности для меня неактуально. В частности, я пока вообще не подключаю платежные системы, а сайт должен работать в полуавтоматическом режиме - то есть после заказа в любом случае связь с менеджером и согласование заказа. В итоге имеем кучу похожих малоинформативных страниц, усложняющих процесс заказа, от которых хочется избавиться.
Задача
Сделать одну страничку, на которой будет все необходимое - и корзина, и реквизиты для доставки, и выбор варианта оплаты, причем страничка максимально простая, с минимумом заполняемых полей, которые не напрягают покупателя.
1. Изменение содержания страниц корзины и оплаты
Идея была в том, чтобы запихнуть все содержимое страниц \cart и \checkout в одну. Поскольку изначально весь функционал прописан так, что все менюшки, виджеты, всплывающие сообщения ссылаются на корзину, то основной у нас будет \cart, a \checkout будет висеть скорее на всякий случай, но по идее пользователь не должен на нее попадать, а если вдруг случайно попадет - не отличить от страницы \cart.
Я сделал содержимое обеих страниц идентичным. Заголовок: "Оформление заказа", содержимое:
После такой манипуляции видим страницу, где сначала идет корзина (список выбранных товаров, стоимость, кросс-селл), а потом страница оплаты (реквизиты покупателя, выбор варианта оплаты).
2. Привязка к страницам в настройках WooCommerce
В привязках страниц магазина (WooCommerce - Настройки - Страницы) привязал в качестве страницы оплаты страницу "Оформление заказа" которая "\cart", хотя вроде и без этого работало.
3. Убрать кнопку «перейти к оплате» из корзины и виджета корзины
Чтобы ничто нас не редиректило на \checkout, надо убрать кнопки "перейти к оплате".
Идем в wp-content\plugins\woocommerce\templates\cart\cart.php. Здесь надо начиная со строчки 134 (только не с самого ее начала!!!) удалить следующий код:
То же самое надо сделать и для виджета корзины. Я использую плагин плавающей корзинки
WooCommerce Cart Tab, а он работает на основе виждета. В общем, идем в wp-content\plugins\woocommerce\templates\cart\mini-cart.php, находим 69 строчку и удаляем следующий код:
4. Убрать кнопку «Оформить заказ» из меню
Продолжаем чистить следы. У меня тема Wootique, и в ней в верхнее меню встроены пункты корзины и оплаты, последний нам не нужен.
Открываем wp-content\themes\wootique\custom.css (файл изменения стиля темы) и прописываем туда
Вкладка становится скрытой, хотя из кода не исчезает, просто пользователь ее не увидит.
5. Настройка полей данных о покупателе
На нашей новой страничке оформлния заказа должно быть минимум полей, которые мы расположим в две колонки - первая получится из "Реквизитов для оплаты", вторая из "Адреса доставки".
5.1. Ковыряемся в переводе
Название колонки "реквизиты для оплаты" нам не подходит, открываем poedit и редактируем файл локализации от saphali woocommerce lite. Находим строку 'Billing Address' и меняем ее с "Реквизиты для оплаты" на "Контактные данные".
5.2. Настраиваем доставку.
От системы доставки, которую предлагает Woocommerce пришлось отказаться: во-первых, не очень корректно отображается ajax-расчет в корзине (он не нужен, дублируется), во-вторых, мы не включаем стоимость доставки в стоимость заказа, ее покупатель отдельно оплачивает в зависимости от тарифа почтового курьера (Украина, Новая почта или Гюнсел). В общем, выбор доставки будем позже делать самостоятельно. Пока что на странице настройки доставки в админке убираем все галочки, оставив только "Сбор адреса доставки, даже если не требуется".
5.3. Прячем чекбокс «отправка по реквизитам оплаты»
Открываем wp-content\themes\wootique\custom.css (файл изменения стиля темы) и прописываем туда
5.4. Редактируем отображаемые поля заказа
В настройках Saphali Woocommerce Lite идем в "Управление полями на странице заказа и на странице профиля". Я поля не удалял, просто поснимал флажок "опубликовать", оставив его только для следующих полей:
Реквизиты оплаты - Имя; Фамилия; Email-адрес; Телефон.
Реквизиты доставки - Область, Район; Населенный пункт; а также shipping_adress_1, содержимое которого я поменял на такой текст:
Дополнительные поля - Заметки к заказу оставляем.
5.4. Добавляем радио-кнопки для способов доставки
В последнем обновлении Saphali Woocommerce Lite добавили возможность добавлять поля разного типа - Select, Checkbox, Text, Textarea. Молодцы конечно, но мне хотелось именно радио-кнопки, да и выход из этого положения я нашел еще до обновления, иначе вряд ли бы заморачивался. Порывшись на форумах (англоязычных), в техдокументации woocommerce, был сочинен (точнее переработан) и прописан в functions.php следующий код:
Код добавляет поле (радио-кнопки) и на страницу оформления заказа, и в заказ при просмотре его через админку, и в e-mail, который отправляется юзеру.
6. Настройка вариантов оплаты
Ну тут все просто, у меня настроено 3 варианта для оплаты - Безнал ("Предоплата на карту Приватбанка", причем реквизиты будут высылаться менеджером после согласования заказа), Чек ("Оплата наличными при получении"), Наличными ("Наложенный платеж"). По сути, никакой оплаты через сайт нету, просто в заказе будет виден нужный вариант.
7. Подключение скриптов и стилей
Сравнив страницы \cart и \checkout увидел, что в первой некорректно работает выбор вариантов оплаты посредством радио-кнопок (не отображаются выпадающие описания). Поковырявшись в html - коде этих двух страниц, можно увидеть, что в checkout подключено больше скриптов и стилей. Что ж, значит надо подключить их и для \cart.
Идем в wp-content\plugins\woocommerce\woocommerce.php, находим строчку 1177, где подключаются скрипты для \cart, начинается она с "if ( is_cart() )". Ниже видим такую же для чекаута "if ( is_checkout()" , вытягиваем из нее все недостающее и копипастим в "if ( is_cart() )". В итоге строки 1177-1185 имеют следующее содержание:
В итоге
Вот и все. В результате всех манипуляций получилось вот так:
Все работает, насколько я мог потестировать.
Жду конструктивной критики, возможно подсказок, что можно было бы сделать по-другому.
Данная тема создана давно. С тех пор многое менялось, обновлялся woocommerce, отлавливались баги, что-то обсуждалось, были и просто доработки. Тема значительно разрослась, а самая первая версия, описанная в первом посте, практически утратила свою актуальность. Вот несколько ссылок на ключевые посты темы, которые также рекомендованы к обязательному прочтению.
Обнова с WC 2.1 до 2.2
Лечение циклической переадресации
Обнова до WC 2.4
Хочу поделиться своим опытом по совмещению в одно страницы корзины (\cart) и оплаты (\checkout). Во-первых, кому-то может пригодиться, во-вторых, очень хочется услышать мнение более продвинутых сайторазработчиков по этому поводу, так как некоторые мои решения наверняка некорректны и неизящны и можно сделать правильнее и оптимальнее. Хотя вроде немного погонял туба-сюда, проблем не заметил. В общем, жду конструктивной критики.
Зачем?
Прежде всего объясню, зачем я решил лезть в святая святых - функционал и принцип работы интернет-магазина WooCommerce. Функционал конечно классный, отлично заточен под электронную торговлю, особенно - под международную торговлю с кучей вариантов оплаты, доставки товара. Поэтому многое для нашего региона, и в частности для меня неактуально. В частности, я пока вообще не подключаю платежные системы, а сайт должен работать в полуавтоматическом режиме - то есть после заказа в любом случае связь с менеджером и согласование заказа. В итоге имеем кучу похожих малоинформативных страниц, усложняющих процесс заказа, от которых хочется избавиться.
Задача
Сделать одну страничку, на которой будет все необходимое - и корзина, и реквизиты для доставки, и выбор варианта оплаты, причем страничка максимально простая, с минимумом заполняемых полей, которые не напрягают покупателя.
1. Изменение содержания страниц корзины и оплаты
Идея была в том, чтобы запихнуть все содержимое страниц \cart и \checkout в одну. Поскольку изначально весь функционал прописан так, что все менюшки, виджеты, всплывающие сообщения ссылаются на корзину, то основной у нас будет \cart, a \checkout будет висеть скорее на всякий случай, но по идее пользователь не должен на нее попадать, а если вдруг случайно попадет - не отличить от страницы \cart.
Я сделал содержимое обеих страниц идентичным. Заголовок: "Оформление заказа", содержимое:
Код:
Для того, чтобы оформить заказ, прежде всего проверьте, все ли товары, которые Вас интересуют, попали в корзину, а также проверьте количество. Введите свои контактные данные и реквизиты для доставки, выберите способ оплаты и доставки - и смело нажимайте "Разместить заказ". В ближайшее время наши сотрудники свяжутся с Вами. [woocommerce_cart][hr][woocommerce_checkout]
2. Привязка к страницам в настройках WooCommerce
В привязках страниц магазина (WooCommerce - Настройки - Страницы) привязал в качестве страницы оплаты страницу "Оформление заказа" которая "\cart", хотя вроде и без этого работало.
3. Убрать кнопку «перейти к оплате» из корзины и виджета корзины
Чтобы ничто нас не редиректило на \checkout, надо убрать кнопки "перейти к оплате".
Идем в wp-content\plugins\woocommerce\templates\cart\cart.php. Здесь надо начиная со строчки 134 (только не с самого ее начала!!!) удалить следующий код:
PHP:
<input type="submit" class="checkout-button button alt" name="proceed" value="<?php _e( 'Proceed to Checkout →', 'woocommerce' ); ?>" />
<?php do_action('woocommerce_proceed_to_checkout'); ?>
WooCommerce Cart Tab, а он работает на основе виждета. В общем, идем в wp-content\plugins\woocommerce\templates\cart\mini-cart.php, находим 69 строчку и удаляем следующий код:
PHP:
<a href="<?php echo $woocommerce->cart->get_checkout_url(); ?>" class="button checkout"><?php _e( 'Checkout →', 'woocommerce' ); ?></a>
Продолжаем чистить следы. У меня тема Wootique, и в ней в верхнее меню встроены пункты корзины и оплаты, последний нам не нужен.
Открываем wp-content\themes\wootique\custom.css (файл изменения стиля темы) и прописываем туда
HTML:
a.checkout-link, a.checkout-link:hover {display: none}
5. Настройка полей данных о покупателе
На нашей новой страничке оформлния заказа должно быть минимум полей, которые мы расположим в две колонки - первая получится из "Реквизитов для оплаты", вторая из "Адреса доставки".
5.1. Ковыряемся в переводе
Название колонки "реквизиты для оплаты" нам не подходит, открываем poedit и редактируем файл локализации от saphali woocommerce lite. Находим строку 'Billing Address' и меняем ее с "Реквизиты для оплаты" на "Контактные данные".
5.2. Настраиваем доставку.
От системы доставки, которую предлагает Woocommerce пришлось отказаться: во-первых, не очень корректно отображается ajax-расчет в корзине (он не нужен, дублируется), во-вторых, мы не включаем стоимость доставки в стоимость заказа, ее покупатель отдельно оплачивает в зависимости от тарифа почтового курьера (Украина, Новая почта или Гюнсел). В общем, выбор доставки будем позже делать самостоятельно. Пока что на странице настройки доставки в админке убираем все галочки, оставив только "Сбор адреса доставки, даже если не требуется".
5.3. Прячем чекбокс «отправка по реквизитам оплаты»
Открываем wp-content\themes\wootique\custom.css (файл изменения стиля темы) и прописываем туда
HTML:
#shiptobilling {display:none;}
В настройках Saphali Woocommerce Lite идем в "Управление полями на странице заказа и на странице профиля". Я поля не удалял, просто поснимал флажок "опубликовать", оставив его только для следующих полей:
Реквизиты оплаты - Имя; Фамилия; Email-адрес; Телефон.
Реквизиты доставки - Область, Район; Населенный пункт; а также shipping_adress_1, содержимое которого я поменял на такой текст:
HTML:
№ склада (при доставке до склада перевозчика); <br> Адрес доставки (при доставке до дверей)
5.4. Добавляем радио-кнопки для способов доставки
В последнем обновлении Saphali Woocommerce Lite добавили возможность добавлять поля разного типа - Select, Checkbox, Text, Textarea. Молодцы конечно, но мне хотелось именно радио-кнопки, да и выход из этого положения я нашел еще до обновления, иначе вряд ли бы заморачивался. Порывшись на форумах (англоязычных), в техдокументации woocommerce, был сочинен (точнее переработан) и прописан в functions.php следующий код:
PHP:
/**
* Outputs a radio button form field - Вывод формы с радио-кнопками
*/
function woocommerce_form_field_radio( $key, $args, $value = '' ) {
global $woocommerce;
$defaults = array(
'type' => 'radio',
'label' => '',
'placeholder' => '',
'required' => false,
'class' => array( ),
'label_class' => array( ),
'return' => false,
'options' => array( )
);
$args = wp_parse_args( $args, $defaults );
if ( ( isset( $args[ 'clear' ] ) && $args[ 'clear' ] ) )
$after = '<div class="clear"></div>';
else
$after = '';
$required = ( $args[ 'required' ] ) ? ' <abbr class="required" title="' . esc_attr__( 'required', 'woocommerce' ) . '">*</abbr>' : '';
switch ( $args[ 'type' ] ) {
case "select":
$options = '';
if ( !empty( $args[ 'options' ] ) )
foreach ( $args[ 'options' ] as $option_key => $option_text )
$options .= '<input type="radio" name="' . $key . '" id="' . $key . '" value="' . $option_key . '" ' . selected( $value, $option_key, false ) . 'class="select">' . $option_text . '' . "\r\n";
$field = '<p class="form-row ' . implode( ' ', $args[ 'class' ] ) . '" id="' . $key . '_field">
<label for="' . $key . '" class="' . implode( ' ', $args[ 'label_class' ] ) . '">' . $args[ 'label' ] . $required . '</label>
' . $options . '
</p>' . $after;
break;
} //$args[ 'type' ]
if ( $args[ 'return' ] )
return $field;
else
echo $field;
}
/**
* Add the field to the checkout - Добавляем поле в оплату
**/
add_action( 'woocommerce_after_checkout_billing_form', 'shipping_type_field', 10 );
function shipping_type_field( $checkout ) {
echo '<div id="shipping_type_field" >' . '';
woocommerce_form_field_radio( 'shipping_type', array(
'type' => 'select',
'class' => array(
'shipping_type form-row-wide'
),
'label' => __( 'Способ доставки' ),
'placeholder' => __( '' ),
'required' => true,
'options' => array(
'Самовывоз' => 'Самовывоз<br/>',
'Новая почта склад' => 'Новая Почта, доставка до склада<br/>',
'Новая почта двери' => 'Новая Почта, доставка до адреса<br/>',
'Гюнсел' => 'Гюнсел'
)
), $checkout->get_value( 'shipping_type' ) );
echo '</div>';
}
/**
* Process the checkout - проверка на обязательность поля
**/
add_action( 'woocommerce_checkout_process', 'my_custom_checkout_field_process' );
function my_custom_checkout_field_process( ) {
global $woocommerce;
// Check if set, if its not set add an error.
if ( !$_POST[ 'shipping_type' ] )
$woocommerce->add_error( __( 'Пожалуйста, выберите способ доставки' ) );
}
/**
* Update the order meta with field value - обновление данных заказа с учетом нового поля
**/
add_action( 'woocommerce_checkout_update_order_meta', 'shipping_type_field_update_order_meta' );
function shipping_type_field_update_order_meta( $order_id ) {
if ( $_POST[ 'shipping_type' ] )
update_post_meta( $order_id, 'Shipping type', esc_attr( $_POST[ 'shipping_type' ] ) );
}
/**
* Display field value on the order edition page - отображение нового поля в админке
**/
add_action( 'woocommerce_admin_order_data_after_billing_address', 'shipping_type_field_display_admin_order_meta', 10, 1 );
function shipping_type_field_display_admin_order_meta($order){
echo '<p><strong>'.__('Способ доставки').':</strong> ' . $order->order_custom_fields['Shipping type'][0] . '</p>';
}
/**
* Add the field to order emails - добавить новое поле в e-mail-сообщение
**/
add_filter('woocommerce_email_order_meta_keys', 'my_woocommerce_email_order_meta_keys');
function my_woocommerce_email_order_meta_keys( $keys ) {
$keys['Способ доставки'] = 'shipping_type';
return $keys;
}
6. Настройка вариантов оплаты
Ну тут все просто, у меня настроено 3 варианта для оплаты - Безнал ("Предоплата на карту Приватбанка", причем реквизиты будут высылаться менеджером после согласования заказа), Чек ("Оплата наличными при получении"), Наличными ("Наложенный платеж"). По сути, никакой оплаты через сайт нету, просто в заказе будет виден нужный вариант.
7. Подключение скриптов и стилей
Сравнив страницы \cart и \checkout увидел, что в первой некорректно работает выбор вариантов оплаты посредством радио-кнопок (не отображаются выпадающие описания). Поковырявшись в html - коде этих двух страниц, можно увидеть, что в checkout подключено больше скриптов и стилей. Что ж, значит надо подключить их и для \cart.
Идем в wp-content\plugins\woocommerce\woocommerce.php, находим строчку 1177, где подключаются скрипты для \cart, начинается она с "if ( is_cart() )". Ниже видим такую же для чекаута "if ( is_checkout()" , вытягиваем из нее все недостающее и копипастим в "if ( is_cart() )". В итоге строки 1177-1185 имеют следующее содержание:
PHP:
if ( is_cart() ) {
wp_enqueue_script( 'wc-cart', $frontend_script_path . 'cart' . $suffix . '.js', array( 'jquery' ), $this->version, true );
if ( $chosen_en ) {
wp_enqueue_script( 'wc-chosen', $frontend_script_path . 'chosen-frontend' . $suffix . '.js', array( 'chosen' ), $this->version, true );
wp_enqueue_style( 'woocommerce_chosen_styles', $this->plugin_url() . '/assets/css/chosen.css' );
}
wp_enqueue_script( 'wc-checkout', $frontend_script_path . 'checkout' . $suffix . '.js', array( 'jquery', 'woocommerce' ), $this->version, true );
}
В итоге
Вот и все. В результате всех манипуляций получилось вот так:
Все работает, насколько я мог потестировать.
Жду конструктивной критики, возможно подсказок, что можно было бы сделать по-другому.
Последнее редактирование: