-
Notifications
You must be signed in to change notification settings - Fork 7
Correções de Bugs do Plugin Pagar.me para WooCommerce v3.6.1 #582
Description
Sumário Executivo
Este documento descreve as correções necessárias para resolver os warnings PHP identificados via Sentry no plugin pagarme-payments-for-woocommerce. Os erros não quebram a funcionalidade do plugin, mas indicam código defensivo insuficiente e violação de boas práticas do WordPress.
Índice de Erros
| ID Sentry | Arquivo | Erro | Prioridade |
|---|
- | Checkout.php / Core.php | Translation loading too early | Média
PM-STORE-3, 4, 5 | Gateway.php:179 | WC()->cart->total on null | Alta
PM-STORE-37 | WoocommercePlatformOrderDecorator.php:118 | Undefined array key "completed" | Alta
PM-STORE-36 | Webhooks.php:64 | $body->data->order->metadata on null | Alta
Erro 1: Translation Loading Too Early
Descrição
O WordPress 6.7+ emite um aviso quando funções de tradução (__(), _e(), etc.) são chamadas antes do hook init. O plugin Pagar.me carrega traduções no construtor do Checkout.php durante plugins_loaded.
Stack Trace
plugins_loaded → Core::instance() → Core::initialize() → load_controllers()
→ Checkout::__construct() → __() ← PROBLEMA
Causa Raiz
// Checkout.php - Construtor original (PROBLEMÁTICO)
public function __construct() {
// ...
$this->payment_methods = [
'credit_card' => __('Credit card', 'woo-pagarme-payments'), // Muito cedo!
// ...
];
}
Solução
- Core.php: Mover
initialize()para o hookinitem vez de chamar diretamente no construtor - Checkout.php: Adiar o carregamento das traduções para um callback no
init
Arquivos Afetados
/wp-content/plugins/pagarme-payments-for-woocommerce/src/Core.php/wp-content/plugins/pagarme-payments-for-woocommerce/src/Controller/Checkout.php
Mudanças em Core.php
// ANTES (linha 25) private function __construct() { // ... self::initialize(); // Chamado diretamente }
// DEPOIS
private function __construct()
{
// ...
add_action('init', array(CLASS, 'initialize'), 5); // Adiado para init
}
Mudanças em Checkout.php
// ANTES - No construtor $this->payment_methods = [ 'credit_card' => __('Credit card', 'woo-pagarme-payments'), // ... ];// DEPOIS - Método separado chamado via hook
public function __construct() {
// ...
add_action('init', array($this, 'load_payment_methods_translations'), 20);
}
public function load_payment_methods_translations() {
$this->payment_methods = [
'credit_card' => __('Credit card', 'woo-pagarme-payments'),
// ...
];
}
Erro 2: WC()->cart->total on null (PM-STORE-3, 4, 5)
Descrição
O método getCartTotals() em Gateway.php tenta acessar WC()->cart->total no contexto do admin (/wp-admin/post.php), onde o carrinho não existe.
Stack Trace
enqueue_editor_assets → enqueue_data → do_action('woocommerce_blocks_cart_enqueue_data')
→ add_payment_method_script_data → get_all_registered_script_data
→ get_payment_method_data → getAdditionalPaymentMethodData → getInstallments
→ render → getCartTotals → WC()->cart->total ← NULL
Causa Raiz
// Gateway.php linha 179 (PROBLEMÁTICO)
public function getCartTotals()
{
global $wp;
if (!isset($wp->query_vars['order-pay'])) {
return WC()->cart->total; // WC()->cart é NULL no admin!
}
// ...
}
Solução
Adicionar verificações defensivas antes de acessar o carrinho:
public function getCartTotals() { global $wp;// 1. Verificar contexto admin if (is_admin() && !wp_doing_ajax()) { return 0; } // 2. Verificar página order-pay if (isset($wp->query_vars['order-pay'])) { $orderId = absint($wp->query_vars['order-pay']); $order = wc_get_order($orderId); return ($order && is_a($order, 'WC_Order')) ? $order->get_total() : 0; } // 3. Verificar WooCommerce disponível if (!function_exists('WC')) { return 0; } $wc = WC(); if (!$wc || !isset($wc->cart) || !is_object($wc->cart)) { return 0; } return $wc->cart->get_total('edit');
}
Arquivo Afetado
/wp-content/plugins/pagarme-payments-for-woocommerce/src/Block/Checkout/Gateway.php
Erro 3: Undefined array key "completed" (PM-STORE-37)
Descrição
O método getState() em WoocommercePlatformOrderDecorator.php usa um array de mapeamento que não contém a chave "completed", causando warning quando um pedido tem esse status.
Causa Raiz
// WoocommercePlatformOrderDecorator.php linha 118 (PROBLEMÁTICO) $statusToState = [ 'pending' => 'stateNew', 'paid' => 'complete', // ... outras entradas // FALTA: 'completed' => 'complete' ];
$state = $statusToState[$status] ? // ERRO: chave não existe
$statusToState[$status] : 'processing';
Solução
- Adicionar todos os status possíveis do WooCommerce ao mapa
- Usar null coalescing operator (
??) para fallback seguro
private const STATUS_TO_STATE_MAP = [ 'pending' => 'stateNew', 'paid' => 'complete', 'pending_payment' => 'pending_payment', 'failed' => 'closed', 'processing' => 'processing', 'on_hold' => 'holded', 'on-hold' => 'holded', // Variação com hífen 'canceled' => 'canceled', 'cancelled' => 'canceled', // Grafia UK 'refunded' => 'complete', 'completed' => 'complete', // ADICIONADO 'authentication_required' => 'processing', ];
public function getState()
{
$status = $this->getStatus();
$state = self::STATUS_TO_STATE_MAP[$status] ?? 'processing'; // Null coalescing
return OrderState::$state();
}
Arquivo Afetado
/wp-content/plugins/pagarme-payments-for-woocommerce/src/Concrete/WoocommercePlatformOrderDecorator.php
Erro 4: Webhook metadata on null (PM-STORE-36)
Descrição
O método handle_requests() em Webhooks.php assume que todos os webhooks têm a estrutura $body->data->order->metadata, mas alguns tipos de webhook (como card.updated) não possuem essa estrutura.
Estrutura Esperada vs Real
Esperada (charge.paid):
{
"type": "charge.paid",
"data": {
"code": "4575",
"order": {
"metadata": { "platformVersion": "Woocommerce" }
}
}
}
Real (card.updated):
{
"type": "card.updated",
"data": {
"id": "card_xxx",
"last_four_digits": "1234"
// NÃO TEM "order" nem "code"
}
}
Causa Raiz
// Webhooks.php linha 64 (PROBLEMÁTICO)
if (!$this->orderByWoocommerce($body->data->code, $body->data->order->metadata, $body->id)) {
// Para card.updated, $body->data->order não existe!
}
Solução
- Definir lista de tipos de webhook que não têm estrutura de order
- Verificar tipo antes de acessar propriedades
- Usar acesso defensivo com null coalescing
const NON_ORDER_WEBHOOK_TYPES = [ 'card.created', 'card.updated', 'card.deleted', 'customer.created', 'customer.updated', 'recipient.created', 'recipient.updated', 'balance.available', ];public function handle_requests()
{
// ... validação de assinatura ...// Verificar tipo primeiro $webhookType = $body->type ?? ''; if (in_array($webhookType, self::NON_ORDER_WEBHOOK_TYPES, true)) { $this->config->log()->info("Webhook ignorado (tipo sem order): {$webhookType}"); return; } // Acesso defensivo $code = $body->data->code ?? null; $order = $body->data->order ?? null; $metadata = $order->metadata ?? null; if (!$code) { $this->config->log()->warning("Webhook sem code: {$webhookType}"); return; } if (!$this->orderByWoocommerce($code, $metadata, $body->id)) { return; } // ...
}
Arquivo Afetado
/wp-content/plugins/pagarme-payments-for-woocommerce/src/Controller/Webhooks.php
Instruções de Aplicação
Pré-requisitos
- Acesso SSH ou FTP ao servidor
- Backup completo do site (arquivos + banco de dados)
- Ambiente de staging para testes (recomendado)
Passos
- Fazer backup dos arquivos originais:
cd /var/www/store.pericialmed.com/htdocs/wp-content/plugins/pagarme-payments-for-woocommerce/src
cp Controller/Checkout.php Controller/Checkout.php.bak
cp Core.php Core.php.bak
cp Block/Checkout/Gateway.php Block/Checkout/Gateway.php.bak
cp Concrete/WoocommercePlatformOrderDecorator.php Concrete/WoocommercePlatformOrderDecorator.php.bak
cp Controller/Webhooks.php Controller/Webhooks.php.bak
-
Substituir os arquivos com as versões corrigidas
-
Limpar caches:
# Se usando WP-CLI wp cache flush wp transient delete --allSe usando plugins de cache
Limpar via painel do WordPress
-
Testar funcionalidades:
- Checkout com cartão de crédito
- Checkout com PIX
- Checkout com Boleto
- Webhooks (fazer uma compra teste)
- Painel admin (editar pedidos)
-
Monitorar Sentry por 24-48h para confirmar que os erros não reaparecem
Notas Importantes
Atualizações do Plugin
Essas correções serão sobrescritas quando o plugin for atualizado. Opções:
- Reportar ao Pagar.me: Abrir issue no GitHub https://github.com/pagarme/woocommerce
- Criar mu-plugin: Usar filtros/hooks para interceptar antes do código problemático
- Manter patches: Reaplicar após cada atualização do plugin
Compatibilidade
- Testado com WordPress 6.7+
- Testado com WooCommerce 9.x
- Testado com PHP 8.3
Riscos
- Baixo: As mudanças são defensivas e adicionam verificações de null
- Impacto: Nenhuma alteração de comportamento funcional esperada
- Rollback: Restaurar arquivos
.bakse houver problemas
Contato
Para dúvidas sobre estas correções, consulte a documentação oficial do Pagar.me ou abra um ticket de suporte.
Última atualização: Janeiro 2026 Versão do Plugin: 3.6.1