Skip to content

Correções de Bugs do Plugin Pagar.me para WooCommerce v3.6.1 #582

@proteusbr1

Description

@proteusbr1

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

  1. Core.php: Mover initialize() para o hook init em vez de chamar diretamente no construtor
  2. 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

  1. Adicionar todos os status possíveis do WooCommerce ao mapa
  2. 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

  1. Definir lista de tipos de webhook que não têm estrutura de order
  2. Verificar tipo antes de acessar propriedades
  3. 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

  1. Acesso SSH ou FTP ao servidor
  2. Backup completo do site (arquivos + banco de dados)
  3. Ambiente de staging para testes (recomendado)

Passos

  1. 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

  1. Substituir os arquivos com as versões corrigidas

  2. Limpar caches:

# Se usando WP-CLI
wp cache flush
wp transient delete --all

Se usando plugins de cache

Limpar via painel do WordPress

  1. Testar funcionalidades:

    • Checkout com cartão de crédito
    • Checkout com PIX
    • Checkout com Boleto
    • Webhooks (fazer uma compra teste)
    • Painel admin (editar pedidos)
  2. 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:

  1. Reportar ao Pagar.me: Abrir issue no GitHub https://github.com/pagarme/woocommerce
  2. Criar mu-plugin: Usar filtros/hooks para interceptar antes do código problemático
  3. 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 .bak se 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions