плагин для Wordpress

Начинаем понемногу разбираться как сделать свой плагин фискализации чеков для wordpress. 

Режим товароучетки

Нас интересует режим товароучетки. То есть продавец сам пробивает чек при оплате за наличные или по банковской карте, для чего используется локально подключенное оборудование. Для этого он работает через браузер в облачной программе на сайте с движком ворпресса. 

Поизучав терминологию выяснилось, что нас интересует pickup плагины, то есть самовывоз. Вот примерные ключевые слова:
ручная оплата
manual payment
payment gateaway 
WooCommerce наличными при самовывозе
pickup - самовывоз
WooCommerce Cash On Pickup

Код движка wordpress открыт, апи плагинов и куча примеров плагинов имеется, так в чем проблема?

Xampp

Итак для быстрой установки всего необходимого для wordpress на локальный компьютер используем xampp (apache+mysql+php+phpmyadmin). Устанавливаемся все просто и все с разу готово для установки вордпресс.

Но это всего лишь по сути создание базы данных через phpmyadmin.  В общем все идет просто. Но реальные проблемы есть и будут.

Откат на php 8.1.28

Установили мы WooCommerce (это магазин).  (PHP Version 8.1.28.) Накатили плагин payanyway и получили ошибку: Deprecated: Creation of dynamic property.

Откатились на PHP Version 8.1.28. , пришлось потом поработать с php.ini, раскомментировали многие extensions и
добавили extension_dir = "C:\xampp\php\ext"

Мораль такова - php это не С++, тут люди вольности позволяют - вчера работал функционал, сегодня нет и переписывай свой код на php во всех рабочих проектах (как я понял, но могу ошибаться), в общем сигнал тревожный на будущее.

Ищем плагины

Для начала сделаем неправильно. Попробуем просто установить какой-нибудь плагин, например payanyway. В результате woocommerce_payanyway активировался нормально. 

Другой затык например был с Robokassa. Забыли раскомментировать: extension=openssl. Из за этого не устанавливался Robokassa (надо сначала зарегистрироваться, процесс не быстрый) . Ошибка  Загрузка не удалась. No working transports found.

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

В общем довольно приличный облом. И хочется даже плюнуть на wordpress, но первое впечатление всегда обманчиво, будем надеяться...

На самом деле нас интересует Woocommerce Manual Payment, как выяснится намного позже. На основе этого плагина мы создадим свой Woocommerce BIT Manual Payment.

Способы оплаты

Далее разбираемся почему в способах оплаты не появляется payanyway, хотя вроде бы установлен и активирован.

Итак добавление новых способов оплаты не приводит к добавлению их на странице оформления заказа новых способов оплаты (на странице checkout у пользователя). 

Именно по слову checkout находим некий плагин Woocommerce checkout manager. Он настраивает поля для оформления заказа и тут проблем нет. Не в этом дело.

Но никаким способом не удается добавить оплаты. И тут выясняется, что при установке некоторых иностранных плагинов оплаты страны Россия нет в списке, санкции не иначе как... И это не правда.

Где включаются способы оплаты?

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

Находим включение способов оплаты (как все банально) здесь: Woocommerce Настройки Платежи!

Как раскручиваем работу скриптов плагинов

Допустим надо понять как работает какой-нибудь плагин или наоборот почему он не работает вроде бы как надо. Что мы делаем. 

Самый верный способ идем отладчиком по коду самого WooCommerce и самих работающих и не очень плагинов и сравниваем поведение. Как настроить отладку смотрите здесь: xDebug.

Первый метод, который нам попался get_available_payment_gateways(). Он проверяем включенные плагины и возвращает их списком объектов ($_available_gateways).

Допустим не работает у наспдагин wc-cash-on-pickup (как мы думаем), но в списке $_available_gateways он есть. В общем плагин cash on pickup нам пока не нужен, потому что мы нашли то что искали.

Разворот на WooCommerce Manual Payment

Что произошло. Напоминаю мы мониторим тему оплаты наличными при самовывозе. Так вот нам надо обратить внимание как сделан плагин WooCommerce Manual Payment. Именно он предлагает в бекенде оплату от покупателя. 

Чтобы можно было принимать оплату при самовывозе надо не забыть: в WooCommerce - Настройки - Доставка - Самовывоз добавить адрес (точку самовывоза).

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

фотка 1

Мы легко догадываемся, что это плагин в папке woo-mp. Начинаем изучать его.

Но сама оплата при самовывозе реализуется в папке бекэнда wp-admin, так как это в интерфейсе сотрудника организации, которая продает.

Интерфейс бекенда и плагин Manual payment (далее MP) (как и все остальное в общем-то) связывается хуками. 

Ключевой момент поиска - это такая строчка в файле C:\xampp\htdocs\wp\wp-content\plugins\woocommerce\src\Internal\Admin\Orders\Edit.php:

do_action( 'add_meta_boxes_' . $this->screen_id, $this->order );
// $this->screen_id = "woocommerce_page_wc-orders" 
// соответственно add_meta_boxes_woocommerce_page_wc-orders и есть наш хук
// который добавит на форму редактирования заказа некий блок оплаты из плагина MP

Файл, который отображает наш блок оплаты, расположен здесь C:\xampp\htdocs\wp\wp-content\plugins\woo-mp\includes\controllers\payment-meta-box-controller.php

Тут надо еще отметить, что изучаемый нами плагин Woo_MP при открытии заказа в бекенде делает некоторые ajax запросы на сайт https://js.stripe.com. Нам этого не понадобится для оплаты налом и для изучения не представляет пока интерес.

Как производится оплата

Как происходит оплата в Woo_MP . Делается это стандартно через ajax запрос, потом обязательно перезагрузка страницы. Так же и мы собираемся фискализировать чеки и принимать банк.карты.

В общем как принять налом оплату уже понятно. Теперь как напечатать состав чека разбираемся. 

Где получить состав заказа для фискализации чека

Ответ очевиден, смотрите GET параметры страницы, у нас например так (id=129):
http://localhost/wp/wp-admin/admin.php?page=wc-orders&action=edit&id=129
id это и есть номер заказа.

Далее надо найти по номеру заказа сам состав заказа. И тут есть нюансы. Сам заказ получаем так:

 $wc_order = wc_get_order( $_REQUEST['id'] );

Проход по позициям заказа получаем тоже через метод get_items():

foreach ($wc_order->get_items() as $item => $arr)
{

Массив $arr это класс WC_Order_Item_Product. И тут тоже оказывается надо знать названия методов для доступа к данным внутри экземпляра класса (WC_Order_Item_Product). Также придется изучить класс WC_Product_Attribute, это экземпляр продаваемой позиции.

Далее мы уже понимаем как сохранить состав чека.

Добавляем глобальные параметры к плагину

Итак мы уже готовы послать по нажатию на кнопку  - ajax post запрос на localhost:44735. Порт 44735 слушает наша программа БИТ драйвер ККТ,  которая управляет локально подключенным оборудованием.

По протоколу АПИ БИТ драйвер ККТ в post пакете надо ещё послать BIT_KKT_TOKEN , это токен кассового аппарата (уникальный идентификатор). Он задаётся глобально на странице свойств плагина.

Выбрасываем лишний функционал

Процесс создания своего плагина проходит по принципу выкидывания из чужого плагина. (донора) лишнего функционала. Это самый простой способ. Так у нас и получается в результате.

Особенности wordpress

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

Подключение js файлов

Для этог имеется специальный метод движка.

jquery-ui

Например, чтобы добавить функционал jquery form dialog, у нас например оказалось достаточно только было добавить подключение:

wp_enqueue_script('jquery-ui-dialog');

Дело в том, что сам jquery ui оказывается уже был подключен в вордпрессе.

Проверить это можно было просто - посмотрев исходный код результата страницы. Ищем те же строчки где есть хххххх.js . Суть в том, что все равно все внешние ресурсы подключаются в результате стандартно единообразно и это видно в исходнике.

admin-ajax.php

Оказалось, что в вордпресс есть такая, я бы сказал хрень, когда страница самостоятельно перезагружается периодически. Это очень непривычно, но отключить это как-то не очень получается. 

Итак мы уже почти завершили плагин для ручной оплаты в бекэнде.

Мы не стали изменять себе и реализовали всплывающую форму для индикации процесса выполнения оплаты через jquery ui form.

JQuery обертка $

Не знаю точно как это называется, но надо как бы оборачивать функции ниже указанным способом. Дело в том, что $ синтаксис у нас не заработал без этого.

jQuery(function($){
    // now you can use jQuery code here with $ shortcut formatting
    // this executes immediately - before the page is finished loading
});

Comet Cache

Отдельное спасибо плагину Comet Cache. переименовали мы папку woo_mp плагина в woo_pa (Payment Acceptance, так будет называться наш плагин), сделали очистку кеша. И вдруг все содержание woo-pa и сама папка пропала и в корзине тоже нет ничего. Восстанавливаем плагин заново...

Но не проблема восстановление занимает 1/10 от первичного вклада варемени.

Как в конце поменять статус заказа на Выполнен

На последнем этапе остается в парадигме вордпресс как-то поменять статус заказа. Внимание функционал этого находится  в WooCommerce, файл plugins\woocommerce\includes\class-wc-order.php:

class WC_Order extends WC_Abstract_Order {


Вот простой метод update_status, который нас избавляет от трудностей:

    public function update_status( $new_status, $note = '', $manual = false ) {
        if ( ! $this->get_id() ) { // Order must exist.
            return false;
        }


        try {
            $this->set_status( $new_status, $note, $manual );
            $this->save();
        } catch ( Exception $e ) {
            $logger = wc_get_logger();
            $logger->error(
                sprintf(
                    'Error updating status for order #%d',
                    $this->get_id()
                ),
                array(
                    'order' => $this,
                    'error' => $e,
                )
            );
            $this->add_order_note( __( 'Update status event failed.', 'woocommerce' ) . ' ' . $e->getMessage() );
            return false;
        }
        return true;
    }

Но перед этим надо понять следующую вещь. А как мы после выполнения оплаты из js (на загруженной странице) переходим опять на php, то есть происходит перезагрузка страницы?

admin-ajax.php

На самом деле происходит так называемый ajax запрос на страницу admin-ajax.php. Страница нашего заказа еще не перезагружается. Вот payload ajax запроса:

action: woo_mp_process_transaction
_wpnonce: 0d294c3877
gateway_id: eway
order_id: 128
transaction_type: charge
amount: 230
currency: RUB
last_4: 1377
sub_action: get_access_code
redirect_url: http://localhost/wp/wp-admin/admin.php?page=wc-orders&action=edit&id=128

Напоминаю, что мы изучаем функционал на примере плагина Manual Payment (все еще).

То есть нам надо реализовать отработку отдельно woo_mp_process_transaction и конце вызвать редирект опять на нашу страницу заказа (чтобы увидеть изменение статуса заказа).

Все как всегда просто и банально в вордпресс, надо добавить экшн wp_ajax_woo_pa_process_transaction, который нам загрузит файл с классом Transaction_Controller, где собственно и будет вызван метод process_transaction:

add_action( 'wp_ajax_woo_pa_process_transaction', [ new Controllers\Transaction_Controller(), 'process_transaction' ] );

Хорошо придумано и удобно. Начинаю полюбливать вордпресс.

Плагин использует единый протокол фискализации чеков и принятия банковских карт БИТ драйвер ККТ. По сути это.программный интерфейс для разработчиков: АПИ для web разработчиков, который можно использовать для плагинов разных движков.

Далее формируется полный пакет, посылаем его на localhost:44735, ждём ответа и отрабатываем результат.


Wordpress-плагин-для-БИТ-драйвер-ККТ.mp4