This document lists the PHP hooks (filters/actions) and JS events to extend Flow POS without modifying the core.
Hooks in PHP #
Products #
flow_pos_product_categories(filter)- When: after loading product categories for the POS.
- Args:
array $categories,array $terms. - Example:
add_filter('flow_pos_product_categories', function ($categories, $terms) { return array_values(array_filter($categories, function ($category) { return $category['slug'] !== 'uncategorized'; })); }, 10, 2);
- When: after loading product categories for the POS.
- Args:
array $categories,array $terms. - Example:
add_filter('flow_pos_product_categories', function ($categories, $terms) { return array_values(array_filter($categories, function ($category) { return $category['slug'] !== 'uncategorized'; })); }, 10, 2); flow_pos_products_query_args(filter)- When: before running
WC_Product_Queryfor the product listing. - Args:
array $query_args,array $context. - Context:
search,search_mode,category,page,per_page,hide_out_of_stock,is_search. - Example:
add_filter('flow_pos_products_query_args', function ($args, $context) { if (!empty($context['category'])) { $args['orderby'] = 'menu_order'; $args['order'] = 'ASC'; } return $args; }, 10, 2);
- When: before running
- When: before running
WC_Product_Queryfor the product listing. - Args:
array $query_args,array $context. - Context:
search,search_mode,category,page,per_page,hide_out_of_stock,is_search. - Example:
add_filter('flow_pos_products_query_args', function ($args, $context) { if (!empty($context['category'])) { $args['orderby'] = 'menu_order'; $args['order'] = 'ASC'; } return $args; }, 10, 2); flow_pos_product_data(filter)- When: after formatting a product for the POS.
- Args:
array $product_data,WC_Product $product. - Example:
add_filter('flow_pos_product_data', function ($data, $product) { $data['sku'] = $product->get_sku(); return $data; }, 10, 2);
- When: after formatting a product for the POS.
- Args:
array $product_data,WC_Product $product. - Example:
add_filter('flow_pos_product_data', function ($data, $product) { $data['sku'] = $product->get_sku(); return $data; }, 10, 2); flow_pos_products_response(filter)- When: before returning the product listing response.
- Args:
array $response,array $context. - Response:
products,page,total_pages. - Example:
add_filter('flow_pos_products_response', function ($response, $context) { $response['has_more'] = $response['page'] < $response['total_pages']; return $response; }, 10, 2);
- When: before returning the product listing response.
- Args:
array $response,array $context. - Response:
products,page,total_pages. - Example:
add_filter('flow_pos_products_response', function ($response, $context) { $response['has_more'] = $response['page'] < $response['total_pages']; return $response; }, 10, 2);
Customers #
flow_pos_customers_search_args(filter)- When: before each
WP_User_Queryin the search for clients. - Args:
array $query_args,array $context. - Context:
term,limit,exclude,type(search,phone,recent). - Example:
add_filter('flow_pos_customers_search_args', function ($args, $context) { if ($context['type'] === 'search') { $args['meta_query'] = isset($args['meta_query']) ? $args['meta_query'] : []; $args['meta_query'][] = [ 'key' => 'billing_country', 'value' => 'MX', ]; } return $args; }, 10, 2);
- When: before each
- When: before each
WP_User_Queryin the search for clients. - Args:
array $query_args,array $context. - Context:
term,limit,exclude,type(search,phone,recent). - Example:
add_filter('flow_pos_customers_search_args', function ($args, $context) { if ($context['type'] === 'search') { $args['meta_query'] = isset($args['meta_query']) ? $args['meta_query'] : []; $args['meta_query'][] = [ 'key' => 'billing_country', 'value' => 'MX', ]; } return $args; }, 10, 2); flow_pos_customers_search_response(filter)- When: before returning the search result.
- Args:
array $response,array $context. - Response:
customers,has_more. - Example:
add_filter('flow_pos_customers_search_response', function ($response, $context) { $response['total'] = count($response['customers']); return $response; }, 10, 2);
- When: before returning the search result.
- Args:
array $response,array $context. - Response:
customers,has_more. - Example:
add_filter('flow_pos_customers_search_response', function ($response, $context) { $response['total'] = count($response['customers']); return $response; }, 10, 2); flow_pos_customer_create_payload(filter)- When: before validating/creating a customer from POS.
- Args:
array $payload,int $user_id. - Payload:
yam,phone,e-mail,billing,shipping,shipping_different. - Example:
add_filter('flow_pos_customer_create_payload', function ($payload, $user_id) { $payload['billing']['country'] = 'MX'; return $payload; }, 10, 2);
- When: before validating/creating a customer from POS.
- Args:
array $payload,int $user_id. - Payload:
yam,phone,e-mail,billing,shipping,shipping_different. - Example:
add_filter('flow_pos_customer_create_payload', function ($payload, $user_id) { $payload['billing']['country'] = 'MX'; return $payload; }, 10, 2); flow_pos_customer_response(filter)- When: before returning the created client payload.
- Args:
array $customer_response,int $user_id,array $payload. - Example:
add_filter('flow_pos_customer_response', function ($customer, $user_id, $payload) { $customer['billing_email'] = $payload['billing']['email'] ?? ''; return $customer; }, 10, 3);
- When: before returning the created client payload.
- Args:
array $customer_response,int $user_id,array $payload. - Example:
add_filter('flow_pos_customer_response', function ($customer, $user_id, $payload) { $customer['billing_email'] = $payload['billing']['email'] ?? ''; return $customer; }, 10, 3); flow_pos_customer_created(action)- When: after creating a client.
- Args:
int $user_id,array $payload,array $customer_response. - Example:
add_action('flow_pos_customer_created', function ($user_id, $payload, $customer_response) { update_user_meta($user_id, '_flow_pos_created', '1'); }, 10, 3);
- When: after creating a client.
- Args:
int $user_id,array $payload,array $customer_response. - Example:
add_action('flow_pos_customer_created', function ($user_id, $payload, $customer_response) { update_user_meta($user_id, '_flow_pos_created', '1'); }, 10, 3);
Boxes / sessions #
flow_pos_register_open_response(filter)- When: before returning the cash register opening response.
- Args:
array $response,int $session_id,int $store_id,int $register_id,int $user_id. - Example:
add_filter('flow_pos_register_open_response', function ($response, $session_id, $store_id, $register_id, $user_id) { $response['timezone'] = wp_timezone_string(); return $response; }, 10, 5);
- When: before returning the cash register opening response.
- Args:
array $response,int $session_id,int $store_id,int $register_id,int $user_id. - Example:
add_filter('flow_pos_register_open_response', function ($response, $session_id, $store_id, $register_id, $user_id) { $response['timezone'] = wp_timezone_string(); return $response; }, 10, 5); flow_pos_register_opened(action)- When: after opening a box.
- Args:
int $session_id,int $store_id,int $register_id,int $user_id,string $opening_cash. - Example:
add_action('flow_pos_register_opened', function ($session_id, $store_id, $register_id, $user_id, $opening_cash) { // custom log }, 10, 5);
- When: after opening a box.
- Args:
int $session_id,int $store_id,int $register_id,int $user_id,string $opening_cash. - Example:
add_action('flow_pos_register_opened', function ($session_id, $store_id, $register_id, $user_id, $opening_cash) { // custom log }, 10, 5); flow_pos_register_close_summary(filter)- When: before returning or using the closing summary.
- Args:
array $summary,array $open_session,int $user_id. - Example:
add_filter('flow_pos_register_close_summary', function ($summary, $open_session, $user_id) { $summary['expected_cash'] = max(0, (float) $summary['expected_cash']); return $summary; }, 10, 3);
- When: before returning or using the closing summary.
- Args:
array $summary,array $open_session,int $user_id. - Example:
add_filter('flow_pos_register_close_summary', function ($summary, $open_session, $user_id) { $summary['expected_cash'] = max(0, (float) $summary['expected_cash']); return $summary; }, 10, 3); flow_pos_register_close_response(filter)- When: before returning the closing response.
- Args:
array $response,array $open_session,int $user_id. - Example:
add_filter('flow_pos_register_close_response', function ($response, $open_session, $user_id) { $response['closed_at'] = current_time('mysql'); return $response; }, 10, 3);
- When: before returning the closing response.
- Args:
array $response,array $open_session,int $user_id. - Example:
add_filter('flow_pos_register_close_response', function ($response, $open_session, $user_id) { $response['closed_at'] = current_time('mysql'); return $response; }, 10, 3); flow_pos_register_closed(action)- When: after closing a box.
- Args:
array $open_session,array $summary,float $closing_cash,float $cash_difference,string $notes,int $user_id. - Example:
add_action('flow_pos_register_closed', function ($open_session, $summary, $closing_cash, $cash_difference, $notes, $user_id) { // custom log }, 10, 6);
- When: after closing a box.
- Args:
array $open_session,array $summary,float $closing_cash,float $cash_difference,string $notes,int $user_id. - Example:
add_action('flow_pos_register_closed', function ($open_session, $summary, $closing_cash, $cash_difference, $notes, $user_id) { // custom log }, 10, 6);
Suspended carts #
flow_pos_suspend_cart_data(filter)- When: before storing a cart as suspended.
- Args:
array $cart_data,array $open_session,int $user_id. - Example:
add_filter('flow_pos_suspend_cart_data', function ($cart_data, $open_session, $user_id) { $cart_data['meta']['source'] = 'pos'; return $cart_data; }, 10, 3);
- When: before storing a cart as suspended.
- Args:
array $cart_data,array $open_session,int $user_id. - Example:
add_filter('flow_pos_suspend_cart_data', function ($cart_data, $open_session, $user_id) { $cart_data['meta']['source'] = 'pos'; return $cart_data; }, 10, 3); flow_pos_cart_suspended(action)- When: after suspending a cart.
- Args:
string $cart_key,array $cart_data,array $open_session,int $user_id. - Example:
add_action('flow_pos_cart_suspended', function ($cart_key, $cart_data, $open_session, $user_id) { // custom log }, 10, 4);
- When: after suspending a cart.
- Args:
string $cart_key,array $cart_data,array $open_session,int $user_id. - Example:
add_action('flow_pos_cart_suspended', function ($cart_key, $cart_data, $open_session, $user_id) { // custom log }, 10, 4); flow_pos_suspended_carts_list(filter)- When: before returning the list of suspended students.
- Args:
array $rows,array $open_session,int $user_id. - Example:
add_filter('flow_pos_suspended_carts_list', function ($rows, $open_session, $user_id) { return array_slice($rows, 0, 10); }, 10, 3);
- When: before returning the list of suspended students.
- Args:
array $rows,array $open_session,int $user_id. - Example:
add_filter('flow_pos_suspended_carts_list', function ($rows, $open_session, $user_id) { return array_slice($rows, 0, 10); }, 10, 3); flow_pos_resume_cart_data(filter)- When: before returning a resumed cart to the POS.
- Args:
array $cart_data,array $row,array $open_session,int $user_id. - Example:
add_filter('flow_pos_resume_cart_data', function ($cart_data, $row, $open_session, $user_id) { unset($cart_data['meta']['internal_flag']); return $cart_data; }, 10, 4);
- When: before returning a resumed cart to the POS.
- Args:
array $cart_data,array $row,array $open_session,int $user_id. - Example:
add_filter('flow_pos_resume_cart_data', function ($cart_data, $row, $open_session, $user_id) { unset($cart_data['meta']['internal_flag']); return $cart_data; }, 10, 4); flow_pos_cart_resumed(action)- When: after resuming a cart.
- Args:
string $cart_key,array $cart_data,array $open_session,int $user_id. - Example:
add_action('flow_pos_cart_resumed', function ($cart_key, $cart_data, $open_session, $user_id) { // custom log }, 10, 4);
- When: after resuming a cart.
- Args:
string $cart_key,array $cart_data,array $open_session,int $user_id. - Example:
add_action('flow_pos_cart_resumed', function ($cart_key, $cart_data, $open_session, $user_id) { // custom log }, 10, 4); flow_pos_cart_voided(action)- When: after canceling a suspended cart.
- Args:
string $cart_key,array $open_session,int $user_id. - Example:
add_action('flow_pos_cart_voided', function ($cart_key, $open_session, $user_id) { // custom log }, 10, 3);
- When: after canceling a suspended cart.
- Args:
string $cart_key,array $open_session,int $user_id. - Example:
add_action('flow_pos_cart_voided', function ($cart_key, $open_session, $user_id) { // custom log }, 10, 3);
Checkout #
flow_pos_checkout_cart_data(filter)- When: before validating and processing the cart.
- Args:
array $cart_data,array $open_session,int $user_id. - Example:
add_filter('flow_pos_checkout_cart_data', function ($cart_data, $open_session, $user_id) { foreach ($cart_data['items'] as &$item) { $item['qty'] = min(99, (int) $item['qty']); } return $cart_data; }, 10, 3);
- When: before validating and processing the cart.
- Args:
array $cart_data,array $open_session,int $user_id. - Example:
add_filter('flow_pos_checkout_cart_data', function ($cart_data, $open_session, $user_id) { foreach ($cart_data['items'] as &$item) { $item['qty'] = min(99, (int) $item['qty']); } return $cart_data; }, 10, 3); flow_pos_checkout_payments_payload(filter)- When: before payments are normalized.
- Args:
array $payments_payload,array $cart_data,array $open_session,int $user_id. - Example:
add_filter('flow_pos_checkout_payments_payload', function ($payments, $cart_data, $open_session, $user_id) { return array_map(function ($payment) { $payment['reference'] = isset($payment['reference']) ? trim($payment['reference']) : ''; return $payments }, $payments }, 10, 4);
- When: before payments are normalized.
- Args:
array $payments_payload,array $cart_data,array $open_session,int $user_id. - Example:
add_filter('flow_pos_checkout_payments_payload', function ($payments, $cart_data, $open_session, $user_id) { return array_map(function ($payment) { $payment['reference'] = isset($payment['reference']) ? trim($payment['reference']) : ''; return $payments }, $payments }, 10, 4); flow_pos_checkout_order_args(filter)- When: before creating the order in WooCommerce.
- Args:
array $order_args,array $cart_data,array $payments,array $open_session,int $user_id. - Example:
add_filter('flow_pos_checkout_order_args', function ($order_args, $cart_data, $payments, $open_session, $user_id) { $order_args['created_via'] = 'flow-pos'; return $order_args; }, 10, 5);
- When: before creating the order in WooCommerce.
- Args:
array $order_args,array $cart_data,array $payments,array $open_session,int $user_id. - Example:
add_filter('flow_pos_checkout_order_args', function ($order_args, $cart_data, $payments, $open_session, $user_id) { $order_args['created_via'] = 'flow-pos'; return $order_args; }, 10, 5); flow_pos_checkout_completed(action)- When: after creating the order and the transaction.
- Args:
int $order_id,int $transaction_id,array $cart_data,array $payments,array $open_session,int $user_id. - Example:
add_action('flow_pos_checkout_completed', function ($order_id, $transaction_id, $cart_data, $payments, $open_session, $user_id) { update_post_meta($order_id, '_flow_pos_custom_flag', '1'); }, 10, 6);
- When: after creating the order and the transaction.
- Args:
int $order_id,int $transaction_id,array $cart_data,array $payments,array $open_session,int $user_id. - Example:
add_action('flow_pos_checkout_completed', function ($order_id, $transaction_id, $cart_data, $payments, $open_session, $user_id) { update_post_meta($order_id, '_flow_pos_custom_flag', '1'); }, 10, 6); flow_pos_checkout_response(filter)- When: before returning the checkout response.
- Args:
array $response,WC_Order $order,array $cart_data,array $payments,array $open_session,int $user_id. - Example:
add_filter('flow_pos_checkout_response', function ($response, $order, $cart_data, $payments, $open_session, $user_id) { $response['receipt_url'] = $order->get_checkout_order_received_url(); return $response; }, 10, 6);
- When: before returning the checkout response.
- Args:
array $response,WC_Order $order,array $cart_data,array $payments,array $open_session,int $user_id. - Example:
add_filter('flow_pos_checkout_response', function ($response, $order, $cart_data, $payments, $open_session, $user_id) { $response['receipt_url'] = $order->get_checkout_order_received_url(); return $response; }, 10, 6);
Events in JS #
All JS hooks are broadcast as CustomEvent in window.
Example:
window.addEventListener('flowPos:customer:selected', (event) => { console.log('Customer selected', event.detail.customer); });
Products #
flowPos:productsLoaded- Detail:
{ products, page, totalPages, hasMore, search, searchMode, category }. - Example:
window.addEventListener('flowPos:productsLoaded', (event) => { const { products, hasMore } = event.detail; console.log(products.length, hasMore); });
- Detail:
- Detail:
{ products, page, totalPages, hasMore, search, searchMode, category }. - Example:
window.addEventListener('flowPos:productsLoaded', (event) => { const { products, hasMore } = event.detail; console.log(products.length, hasMore); }); flowPos:productsLoadFailed- Detail:
{ error, page, search, searchMode, category }. - Example:
window.addEventListener('flowPos:productsLoadFailed', (event) => { console.error(event.detail.error); });
- Detail:
- Detail:
{ error, page, search, searchMode, category }. - Example:
window.addEventListener('flowPos:productsLoadFailed', (event) => { console.error(event.detail.error); });
Cart #
flowPos:cartChanged- Detail:
{ cart, reason }. - Reasons:
add,increase,decrease,remove,clear. - Example:
window.addEventListener('flowPos:cartChanged', (event) => { const { cart, reason } = event.detail; console.log(reason, cart?.items?.length || 0); });
- Detail:
- Detail:
{ cart, reason }. - Reasons:
add,increase,decrease,remove,clear. - Example:
window.addEventListener('flowPos:cartChanged', (event) => { const { cart, reason } = event.detail; console.log(reason, cart?.items?.length || 0); }); flowPos:cartCleared- Detail:
{ cart }. - Example:
window.addEventListener('flowPos:cartCleared', (event) => { console.log('cart cleared', event.detail.cart); });
- Detail:
- Detail:
{ cart }. - Example:
window.addEventListener('flowPos:cartCleared', (event) => { console.log('cart cleared', event.detail.cart); });
Customers #
flowPos:customer:selected- Detail:
{ customer }. - Example:
window.addEventListener('flowPos:customer:selected', (event) => { console.log(event.detail.customer); });
- Detail:
- Detail:
{ customer }. - Example:
window.addEventListener('flowPos:customer:selected', (event) => { console.log(event.detail.customer); }); flowPos:customer:cleared- Detail:
{ customer }. - Example:
window.addEventListener('flowPos:customer:cleared', (event) => { console.log(event.detail.customer); });
- Detail:
- Detail:
{ customer }. - Example:
window.addEventListener('flowPos:customer:cleared', (event) => { console.log(event.detail.customer); }); flowPos:customer:created- Detail:
{ customer }. - Example:
window.addEventListener('flowPos:customer:created', (event) => { console.log('created', event.detail.customer); });
- Detail:
- Detail:
{ customer }. - Example:
window.addEventListener('flowPos:customer:created', (event) => { console.log('created', event.detail.customer); }); flowPos:customer:searchResults- Detail:
{ term, customers, hasMore, append }. - Example:
window.addEventListener('flowPos:customer:searchResults', (event) => { const { term, customers } = event.detail; console.log(term, customers.length); });
- Detail:
- Detail:
{ term, customers, hasMore, append }. - Example:
window.addEventListener('flowPos:customer:searchResults', (event) => { const { term, customers } = event.detail; console.log(term, customers.length); }); flowPos:customer:searchFailed- Detail:
{ term, message }. - Example:
window.addEventListener('flowPos:customer:searchFailed', (event) => { console.error(event.detail.term, event.detail.message); });
- Detail:
- Detail:
{ term, message }. - Example:
window.addEventListener('flowPos:customer:searchFailed', (event) => { console.error(event.detail.term, event.detail.message); });
Checkout #
flowPos:checkout:before- Detail:
{ cart, payments }. - Example:
window.addEventListener('flowPos:checkout:before', (event) => { console.log(event.detail.cart, event.detail.payments); });
- Detail:
- Detail:
{ cart, payments }. - Example:
window.addEventListener('flowPos:checkout:before', (event) => { console.log(event.detail.cart, event.detail.payments); }); flowPos:checkout:after- Detail:
{ orderId, summary }. - Example:
window.addEventListener('flowPos:checkout:after', (event) => { console.log(event.detail.orderId); });
- Detail:
- Detail:
{ orderId, summary }. - Example:
window.addEventListener('flowPos:checkout:after', (event) => { console.log(event.detail.orderId); });
Suspended carts #
flowPos:suspended:created- Detail:
{ cartKey, cart }. - Example:
window.addEventListener('flowPos:suspended:created', (event) => { console.log(event.detail.cartKey); });
- Detail:
- Detail:
{ cartKey, cart }. - Example:
window.addEventListener('flowPos:suspended:created', (event) => { console.log(event.detail.cartKey); }); flowPos:suspended:list- Detail:
{ carts }. - Example:
window.addEventListener('flowPos:suspended:list', (event) => { console.log(event.detail.carts.length); });
- Detail:
- Detail:
{ carts }. - Example:
window.addEventListener('flowPos:suspended:list', (event) => { console.log(event.detail.carts.length); }); flowPos:suspended:resume- Detail:
{ cartKey, cart }. - Example:
window.addEventListener('flowPos:suspended:resumed', (event) => { console.log(event.detail.cartKey); });
- Detail:
- Detail:
{ cartKey, cart }. - Example:
window.addEventListener('flowPos:suspended:resumed', (event) => { console.log(event.detail.cartKey); }); flowPos:suspended:voided- Detail:
{ cartKey }. - Example:
window.addEventListener('flowPos:suspended:voided', (event) => { console.log(event.detail.cartKey); });
- Detail:
- Detail:
{ cartKey }. - Example:
window.addEventListener('flowPos:suspended:voided', (event) => { console.log(event.detail.cartKey); });
Sessions #
flowPos:session:contextLoaded- Detail:
{ hasSession, sessionContext, stores, registers }. - Example:
window.addEventListener('flowPos:session:contextLoaded', (event) => { console.log(event.detail.hasSession); });
- Detail:
- Detail:
{ hasSession, sessionContext, stores, registers }. - Example:
window.addEventListener('flowPos:session:contextLoaded', (event) => { console.log(event.detail.hasSession); }); flowPos:session:opened- Detail:
{ sessionId, sessionContext }. - Example:
window.addEventListener('flowPos:session:opened', (event) => { console.log(event.detail.sessionId); });
- Detail:
- Detail:
{ sessionId, sessionContext }. - Example:
window.addEventListener('flowPos:session:opened', (event) => { console.log(event.detail.sessionId); }); flowPos:session:closed- Detail:
{ sessionId, summary, closingCash, cashDifference }. - Example:
window.addEventListener('flowPos:session:closed', (event) => { console.log(event.detail.sessionId, event.detail.summary); });
- Detail:
- Detail:
{ sessionId, summary, closingCash, cashDifference }. - Example:
window.addEventListener('flowPos:session:closed', (event) => { console.log(event.detail.sessionId, event.detail.summary); }); flowPosSessionContextChanged- Detail:
{ storeId, registerId, sessionId, hasSession, defaultPrimaryColor, ... }. - Example:
window.addEventListener('flowPosSessionContextChanged', (event) => { console.log(event.detail.hasSession); });
- Detail:
- Detail:
{ storeId, registerId, sessionId, hasSession, defaultPrimaryColor, ... }. - Example:
window.addEventListener('flowPosSessionContextChanged', (event) => { console.log(event.detail.hasSession); });