Como Desenvolver uma Extensão para WooCommerce Bookings: Arquitetura e Hooks em PHP
Sistemas de agendamento e reserva nativos para WordPress frequentemente atendem às necessidades básicas de clínicas, consultorias e empresas de locação. No entanto, à medida que a operação ganha escala, surgem regras de negócio que os plugins convencionais não suportam nativamente: precificação dinâmica multidimensional, validações de disponibilidade cruzada entre diferentes instrutores ou recursos compartilhados, e integração direta com ERPs legados.
Quando esse limite é atingido, a solução técnica correta não é alterar os arquivos centrais do plugin ou criar um ecossistema isolado fora do WordPress, mas sim construir uma extensão desacoplada em PHP utilizando os hooks e a arquitetura orientada a objetos do ecossistema WooCommerce.
Por que Desenvolver uma Extensão Própria?
Modificar arquivos de plugins de terceiros impede atualizações de segurança e quebra a compatibilidade futura. Ao criar uma extensão dedicada em formato de plugin satélite (mu-plugin ou plugin padrão):
- Preservação de atualizações: O núcleo do WooCommerce e da ferramenta de reservas (como WooCommerce Bookings, Bookly ou Amelia) permanece intocado.
- Isolamento de escopo: A lógica de negócios customizada reside em sua própria camada de serviço.
- Performance: Evita o acúmulo de dezenas de plugins secundários com excesso de assets não otimizados no front-end.
Arquitetura de uma Extensão de Agendamento
Em implementações que realizo para plataformas com alta densidade de transações, a estrutura de pastas recomendada separa claramente regras de validação, cálculo e integrações externas:
text
custom-booking-extension/
├── custom-booking-extension.php
├── includes/
│ ├── class-booking-validator.php
│ ├── class-pricing-engine.php
│ └── class-resource-sync.php
└── assets/
├── js/booking-scripts.js
└── css/booking-styles.css
1. Interceptando a Validação de Disponibilidade
Para impedir reservas conflitantes sob regras complexas (por exemplo, um intervalo obrigatório de 30 minutos entre consultas que não existe nativamente no plugin), interceptamos o ciclo de validação antes da adição ao carrinho.
No WooCommerce Bookings, podemos utilizar o filtro woocommerce_add_to_cart_validation:
php
addfilter(‘woocommerceaddtocartvalidation’, ‘validarconflitopersonalizadoreserva’, 10, 3);
function validarconflitopersonalizadoreserva($passed, $productid, $quantity) {
$product = wcgetproduct($product_id);
if (!$product || !$product->is_type('booking')) {
return $passed;
}
$booking_date = isset($_POST['wc_bookings_field_start_date_year'])
? sanitize_text_field($_POST['wc_bookings_field_start_date_year']) . '-' .
sanitize_text_field($_POST['wc_bookings_field_start_date_month']) . '-' .
sanitize_text_field($_POST['wc_bookings_field_start_date_day'])
: null;
// Exemplo: checar regra de intervalo customizada em base de dados externa
if ($booking_date && !Booking_Validator::verificar_janela_limpeza($booking_date, $product_id)) {
wc_add_notice(__('Este horário exige uma janela de preparação técnica indisponível no momento.', 'custom-booking'), 'error');
return false;
}
return $passed;
}
2. Customização de Preços em Tempo Real
Regras de preço variáveis conforme o perfil do cliente (B2B vs. B2C) ou reserva em lote exigem modificação do custo calculado antes da criação do pedido. O hook woocommerce_bookings_calculated_booking_cost permite essa manipulação de maneira elegante:
php
addfilter(‘woocommercebookingscalculatedbookingcost’, ‘ajustarcustoreservacustomizado’, 20, 3);
function ajustarcustoreservacustomizado($cost, $bookinghook, $posteddata) {
if (isuserloggedin()) {
$user = wpgetcurrentuser();
if (inarray(‘corporateclient’, (array) $user->roles)) {
// Aplica desconto corporativo negociado via metadados
$discountpercentage = floatval(getusermeta($user->ID, ‘corporatediscount’, true));
if ($discountpercentage > 0) {
$cost = $cost – ($cost * ($discountpercentage / 100));
}
}
}
return max(0, $cost);
}
Tratamento de Concorrência e Race Conditions
Um dos pontos mais críticos em sistemas de agendamento customizados é a reserva simultânea do mesmo slot por dois usuários. Para evitar double-booking:
- Lock Temporário via Transients: Ao iniciar o checkout, bloqueie o slot com um
set_transientassociado ao ID do recurso com validade curta (ex: 10 minutos). - Validação Atômica no Checkout: Use a action
woocommerce_checkout_create_order_line_itempara verificar novamente o status de disponibilidade antes de persistir o pedido. - Transações no Banco de Dados: Para operações que envolvam tabelas customizadas de agenda, utilize
$wpdb->query('START TRANSACTION')e$wpdb->query('COMMIT')para assegurar integridade referencial.
Fluxo Recomendado de Implementação
- Mapeamento de Hooks: Identifique os pontos de injeção exatos da extensão de agendamento utilizada (filtros de cálculo de custo, verificação de disponibilidade, criação de status).
- Criação da Camada de Validação: Estabeleça classes puras de lógica antes de tocar nos hooks do WooCommerce.
- Testes de Borda: Simule fusos horários divergentes, viradas de lote, cancelamentos e tentativas de reserva simultânea.
- Monitoramento e Logs: Integre chamadas a
wc_get_logger()para rastrear qualquer inconsistência de cálculo ou disponibilidade.
Conclusão e Próximos Passos
Estender um plugin de agendamentos no WordPress requer conhecimento sólido de PHP, ciclo de vida do WooCommerce e mecanismos de prevenção de concorrência. Quando executado com as práticas corretas de engenharia de software, o sistema suporta altos volumes operacionais sem riscos de instabilidade.
Se o seu projeto demanda lógica de agendamento personalizada, integrações complexas ou otimização de arquitetura no WooCommerce, entre em contato para estruturarmos uma consultoria técnica especializada.


