Código Para Reembolsar Status - Descubra o Novo Código de Reset de Status em Blox Fruits e Domine o Jogo!
Descubra o Novo Código de Reset de Status em Blox Fruits e Domine o Jogo!

Como funciona o reembolso programático no WordPress

A maioria das pessoas que precisa refundir pedidos ou assinaturas no WordPress vai parar na interface do WooCommerce e clica nos botões manualmente. Funciona até você ter cinquenta transações para processar de uma vez ou até o cliente reclamar que o dinheiro não voltou e você precisa provar que o reembolso foi realizado. O código entra exatamente nessa brecha entre o que a UI permite e o que o sistema consegue fazer.

Código para reembolsar status e lidar com ordenações em lote

O WooCommerce expõe uma API relativamente tranquila para reembolsos. A função central é a wc_create_refund(), que recebe um array de argumentos e devolve um ID de reembolso ou um objeto WP_Error. O que muita gente não percebe de cara é que o status do pedido muda automaticamente para "refunded" quando o reembolso cobre o valor total, e fica em "partially refunded" se for parcial. Isso acontece sem você precisar tocar em nada. Vejo um erro recorrente todo dia em fóruns: alguém chama wc_create_refund() passando apenas o order_id e espera que tudo volte. O código não funciona assim. Ele precisa saber pelo menos o motivo do reembolso via reason, e idealmente passar os itens e quantidades se quiser registrar o reembolso contra linhas específicas do pedido. Se você pular isso, o WooCommerce cria o reembolso, mas o histórico fica incompleto e a conciliação bancária vira bagunça.

Um exemplo real. Há algum tempo precisei processar reembolsos para um cliente que migrou dados de uma plataforma antiga. Os pedidos vinham com status inconsistente porque a importação tinha fallido no meio do processo. Metade dos pedidos aparecia como "processing" mas já tinha confirmado pagamento, e a outra metade estava "on-hold". Se eu rodasse o código de reembolso sem checar o status primeiro, o WooCommerce rejeitaria a operação. A solução foi simples: antes de chamar wc_create_refund(), eu validava se o order->get_status() era um dos permitidos para reembolso. Usei um array com processing, completed e completed com meta_field personalizado. Se o status não batia, eu atualizava para completed via update_post_meta primeiro e só então criava o reembolso. O código básico segue esse padrão:

👉 Clique no botão abaixo para saber mais sobre o assunto!

$order = wc_get_order( $order_id );

$refund = wc_create_refund( array(
    'order_id'  => $order_id,
    'amount'    => 99.90,
    'reason'    => 'Solicitação do cliente',
    'restock_items' => false,
) );

if ( is_wp_error( $refund ) ) {
    error_log( 'Erro no reembolso: ' . $refund->get_error_message() );
}

Se você precisa reembolsar apenas itens específicos, a coisa muda um pouco. Você constrói um array de itens mapeando o order_item_id pelo order->get_items(). Isso evita reembolso equivocado de produtos que já foram substituídos ou cancelados anteriormente. Lembre-se de que itens com status de devolução anterior podem travar o refund se o valor já tiver sido parcialmente estornado. Isso é um detalhe que o WooCommerce não avisa de forma clara. Ele só falha silenciosamente e você perde tempo debugando.

Limitações e o que esse código não resolve

Reembolso via código não significa dinheiro voltando magicamente. O WooCommerce apenas registra a ação no banco. A transferência real depende do gateway configurado. Stripe, PayPal e Mercado Pago têm comportamentos diferentes. Com Stripe, por exemplo, o reembolso é criado na API do gateway quase que automaticamente se você usar a integração nativa, mas com gateways mais antigos ou customizados, você precisa chamar a função de reembolso do provedor separadamente. Já passei por um caso em que o registro aparecia como refunded no painel, mas o cliente ainda via "payment pending" na fatura porque o gateway não tinha sido notificado. A correção foi forçar uma chamada à API do gateway antes de dar crédito ao usuário. Outro problema comum: cobranças recorrentes em assinaturas. Se o pedido fizer parte de um subscription do WooCommerce Subscriptions, reembolsar o pedido pai não cancela os renovações futuras. Você precisa chamar a função específica de cancellation ou modificar o status do subscription. Não fazer isso gera duplicidade de cobrança no mês seguinte, e ninguém gosta de lidar com isso.

Se o seu cenário envolve muitos reembolsos recorrentes ou integrações múltiplas, considere usar a API REST do WooCommerce em vez de funções síncronas. Ela permite tratamento de erros mais granular, rate limiting configurável e batch operations. O código direto no functions.php do tema funciona para operações pontuais, mas vira dor de cabeça quando o volume sobe. Eu prefiro construir um script separado fora do tema, rodando via WP-CLI, para não depender do ciclo de vida da request e evitar timeouts em servidores com timeout baixo. Abaixo deixo o link oficial da documentação do WooCommerce sobre reembolsos, que é onde a maior parte das informações técnicas está documentada e atualizada. É mais confiável do que tutoriais de terceiros que às vezes usam funções depreciadas.

WooCommerce Developer Docs – Orders & Refunds