0
<< предыдущая заметкаследующая заметка >>
29 февраля 2024
Друзья-программисты, а кто-то писал плагины под WooCommerce?

UPD: Друзья, спасибо всем за советы, вопрос решен. Правильный ответ (с вашими подсказками) нашел мудрый Кирилл. Итак, вопрос был, как в магазине WooCommerce фронтенд JS может обратиться к бэкенду по Ajax и получить доступ к сессии, пользователю, его корзине и номеру заказа. Правильный ответ:

1. В магазине WooCommerce (в отличие от прочих магазинов типа OpenCart и PrestaShop) нельзя узнать номер заказа до нажатия кнопки Checkout: заказа не существует, хоть корзина уже зарегистрирована в сессии. Заказ будет создан и получит номер только в момент выполнения Checkout.

2. Даже если вы зарегистрировали отдельный rest-эндпоинт и гоняете туда запросы аяксом, WooCommerce не сможет опознать сессию и проигнорирует авторизационные куки WooCommerce и WordPress. Чтобы сессия была опознана, необходимо при запросе делать специальные манипуляции: в дополнение к авторизационным кукам разместить в хедерах некие загадочные ключи Nonce и X-WP-Nonce. Искать их надо столь же неочевидным способом: X-WP-Nonce доступен в объекте wp.apiFetch.nonceMiddleware, а Nonce передается при загрузке страницы и затем обновляется по React, так что его актуальная версия лежит в LocalStorage 'storeApiNonce'.

Чтобы не париться, для своих Аякс-запросов можно использовать даже тот эндпоинт, что использует кнопка Checkout, дописав туда свои процедуры на случай запроса аяксом. Сам запрос в итоге такой:

var data={
 
"shipping_address"args.cart.shippingAddress,
 
"billing_address"args.cart.billingAddress,
 
// "customer_note": document.querySelector("DIV.wc-block-checkout__add-note TEXTAREA").value,
 
"payment_method""myplugin",
 
"payment_data": [{"key":"wc-myplugin-new-payment-method","value":false}],
};

const 
result await fetch(
    
"https://my_store.ru/wp-json/wc/store/v1/checkout?_locale=user&myparameters=123
    
,{ method:'POST'mode:'cors'credentials:'include'headers: [
        [
"Content-Type""application/json"],
        [
"X-WP-Nonce"wp.apiFetch.nonceMiddleware.nonce ],
        [
"Nonce"JSON.parse(window.localStorage.getItem('storeApiNonce')).nonce ],
     ],
     
bodyJSON.stringify(data)
    }
);
if(
result.okconsole.log('OK: '+result.text());
else 
console.log("Error" + result.status);

При этом, разумеется, мы понимаем, что в нагромождении граблей этого магазина (React над плагином WooCommerce над WordPress) может существовать и другой путь, каким фронтенд может обратиться к бэкенду дабы зарегистрировать заказ и узнать его уникальный номер. Возможно, есть специальная процедура wc.SpecialMagic[666].FuckingSecretApi(wp_Shit), но разбираться в этом не вижу смысла — все равно разработчики всё поменяют через полгода, чтобы ваши плагины отвалились и потребовали серьезной переделки. Сейчас, например, все написанные миром плагины и документации прежних лет уже не работают с новыми версиями типа WooCommerce 8.5.2 (WordPress 6.4.2) — изменилось всё, включая даже метод регистрации плагина. Так что, вполне возможно, именно прямой запрос с подстановкой Nonce продолжит работать, когда всё прочее изменится.

По личным ощущениям: с благодарностью вспоминаю магазины OpenCart3, OpenCart4 и PrestaShop, написание плагинов для которых потребовало неделю-две напряженной работы на каждый. По сравнению с ними WooCommerce — невероятно запутанная йобань, с которой я провозился уже месяц, и без помощи Кирилла и ваших советов точно бы не осилил. Сложнее, вероятно, окажется лишь Magento — насколько я уже успел видеть, это закупленное пафосным Adobe удивительное поделие девяностых: в 2024 году его админят из терминала набором текстовых команд в консоли...

[ БЫЛО ]
БЫЛО:

Третью неделю бьюсь, не могу заставить фронтенд правильно получать order при ajax-запросе. Может кто чего посоветовать? Сам callback по кнопке checkout задается легко:


<?php
add_action
'woocommerce_store_api_checkout_order_processed''my_callback' );

function 
my_callback$order ) {
    
$order->add_order_note'blabla' );
    
$order->save();
    
$order->payment_complete();
    return 
true;
}

Проблема в том, что вместо checkout мне нужно выполнить ряд своих взаимодействий с бэкендом по ajax. Я регистрирую rest-эндпоинт, успешно делаю ajax-запросы, вместе с ними прилетают даже авторизационные куки, но получаю-то я в функции не $order, а какой-то загадочный $request, и что дальше? Кто-нибудь знает, как из этой мишуры получить доступ к объекту $order, чтобы пользоваться его функциями и данными о заказе?


<?php
add_action
('rest_api_init', function () {
    
register_rest_route('my/v1''/checkout-data/', array(
        
'methods' => 'POST',
        
'callback' => 'my_ajax',
        
'permission_callback' => function () { return true; },
    ));
});

function 
my_ajax(WP_REST_Request $request) {
    
$order = ... ???
}

Я бы просто хаком перехватывал саму кнопку checkout на фронтенде, но там же адова смесь движков react+wp+woo, всё это уходит куда-то в глубины движков, обрастает авторизационными данными и само парсит ответы, меня туда не подпуская. Буду очень благодарен за советы.

<< предыдущая заметка следующая заметка >>
пожаловаться на эту публикацию администрации портала
архив понравившихся мне ссылок

Комментарии к этой заметке скрываются - они будут видны только вам и мне.

Оставить комментарий