Atualizado em 19/06/2026
Toda integração séria de uma loja — sincronizar pedidos com um ERP, alimentar um app, despachar para um marketplace, conciliar com a logística — passa pela REST API do WooCommerce. Ela é uma API própria, distinta da REST API do núcleo do WordPress, exposta sob /wp-json/wc/v3/, com a sua própria autenticação por chaves. A grande vantagem: ela conversa com os pedidos pela camada de abstração do WooCommerce, então funciona com o HPOS e te poupa de escrever SQL que quebra na próxima mudança de armazenamento. Este artigo cobre autenticação, os endpoints de pedidos, paginação e as armadilhas de segurança e escala que derrubam integrações apressadas.
Duas APIs diferentes: não confunda
O WordPress tem a sua REST API em /wp-json/wp/v2/ (posts, páginas, usuários). O WooCommerce expõe a dele em /wp-json/wc/v3/ (produtos, pedidos, clientes, cupons, relatórios). Elas rodam sobre a mesma infraestrutura, mas têm autenticações separadas: as chaves geradas no WooCommerce valem para wc/v3, não para wp/v2. Quem está começando às vezes tenta listar pedidos pela API do núcleo e não acha — porque pedido, com HPOS, nem é post. Para a API do WordPress, veja REST API do WordPress.
Autenticação: Consumer key e secret
O acesso é por um par de chaves geradas em WooCommerce › Ajustes › Avançado › REST API › Adicionar chave. Ao criar, você escolhe o usuário dono e a permissão: somente leitura, somente escrita ou leitura/escrita. O WooCommerce então exibe, uma única vez, o Consumer key (ck_...) e o Consumer secret (cs_...).
- Sobre HTTPS (o caso normal): autentique com HTTP Basic Auth, usando a key como usuário e o secret como senha. Simples e seguro, porque o TLS protege as credenciais em trânsito.
- Sobre HTTP (loja sem certificado — evite): use OAuth 1.0a, que assina a requisição sem trafegar o secret em claro. É a exceção para ambientes legados.
As chaves são credenciais críticas. Uma chave de leitura/escrita vazada permite criar e alterar pedidos. Trate-as como senha: nunca as comite no repositório nem as embuta no front-end (JavaScript do navegador); guarde em variáveis de ambiente ou cofre de segredos; conceda o menor privilégio (só leitura quando for só ler); e revogue imediatamente qualquer chave suspeita pelo painel. E sim: HTTPS é obrigatório para Basic Auth.
Endpoints de pedidos
Os pedidos vivem sob /wp-json/wc/v3/orders. O verbo HTTP define a ação:
| Método + endpoint | Ação |
|---|---|
GET /wc/v3/orders | Listar pedidos (com filtros e paginação) |
GET /wc/v3/orders/<id> | Obter um pedido específico |
POST /wc/v3/orders | Criar um pedido |
PUT /wc/v3/orders/<id> | Atualizar um pedido (ex.: mudar status) |
DELETE /wc/v3/orders/<id> | Excluir (ou mover para a lixeira) |
POST /wc/v3/orders/batch | Criar/atualizar/excluir em lote |
Listar pedidos (com filtros)
Um GET em /orders aceita filtros úteis: status, after/before (datas ISO 8601), per_page e page. Com Basic Auth sobre HTTPS, via curl:
curl https://minhaloja.com.br/wp-json/wc/v3/orders \
-u ck_SUA_CONSUMER_KEY:cs_SEU_CONSUMER_SECRET \
-G \
-d status=processing \
-d after=2026-06-01T00:00:00 \
-d per_page=20 \
-d page=1
A resposta é um array JSON de pedidos. Os totais de paginação vêm nos cabeçalhos X-WP-Total e X-WP-TotalPages — adicione -i ao curl para vê-los. Itere page de 1 até X-WP-TotalPages.
Obter um pedido
curl https://minhaloja.com.br/wp-json/wc/v3/orders/456 \
-u ck_SUA_CONSUMER_KEY:cs_SEU_CONSUMER_SECRET
Retorna o objeto completo do pedido #456: itens de linha (line_items), totais, dados de cobrança/entrega, status e metadados — tudo já resolvido pela camada do WooCommerce, independente de o pedido estar no armazenamento legado ou no HPOS.
Criar um pedido
Um POST com corpo JSON cria o pedido. Os itens vão em line_items (referenciando product_id/variation_id e quantity); o WooCommerce calcula os totais:
curl -X POST https://minhaloja.com.br/wp-json/wc/v3/orders \
-u ck_SUA_CONSUMER_KEY:cs_SEU_CONSUMER_SECRET \
-H "Content-Type: application/json" \
-d '{
"payment_method": "bacs",
"payment_method_title": "Transferência",
"set_paid": false,
"status": "pending",
"billing": {
"first_name": "Roger",
"last_name": "Takemiya",
"email": "[email protected]",
"phone": "(43) 99932-9697"
},
"line_items": [
{ "product_id": 123, "quantity": 2 },
{ "variation_id": 456, "quantity": 1 }
]
}'
Repare em set_paid: com true, o WooCommerce marca o pedido como pago e dispara a transição de status correspondente (e os e-mails). Mudar status pela API tem o mesmo efeito de mudar pela CRUD API — os hooks e e-mails rodam. Em integrações que importam histórico, isso pode disparar notificações reais; planeje.
Atualizar status (ex.: marcar como concluído)
curl -X PUT https://minhaloja.com.br/wp-json/wc/v3/orders/456 \
-u ck_SUA_CONSUMER_KEY:cs_SEU_CONSUMER_SECRET \
-H "Content-Type: application/json" \
-d '{ "status": "completed" }'
Consumir a API a partir do próprio WordPress
Às vezes a integração roda dentro de outro WordPress (ou do próprio), e você quer chamar a API com as funções nativas wp_remote_get()/wp_remote_post() em vez de curl. O Basic Auth vai no cabeçalho Authorization; cheque sempre erros e o código HTTP:
<?php
$ck = 'ck_SUA_CONSUMER_KEY';
$cs = 'cs_SEU_CONSUMER_SECRET';
$args = array(
'headers' => array(
'Authorization' => 'Basic ' . base64_encode( $ck . ':' . $cs ),
),
'timeout' => 20,
);
$url = add_query_arg(
array( 'status' => 'processing', 'per_page' => 20 ),
'https://minhaloja.com.br/wp-json/wc/v3/orders'
);
$response = wp_remote_get( $url, $args );
if ( is_wp_error( $response ) ) {
error_log( 'Erro na API: ' . $response->get_error_message() );
} else {
$code = wp_remote_retrieve_response_code( $response );
$total = wp_remote_retrieve_header( $response, 'x-wp-totalpages' );
if ( 200 === (int) $code ) {
$orders = json_decode( wp_remote_retrieve_body( $response ), true );
foreach ( (array) $orders as $order ) {
echo esc_html( '#' . $order['id'] . ' — ' . $order['status'] ) . '<br>';
}
} else {
error_log( "API devolveu HTTP {$code}" );
}
}
Para criar, use wp_remote_post(); para atualizar (PUT), use wp_remote_request() com 'method' => 'PUT' — atenção: wp_remote_post() força POST e ignora um 'method' diferente. Em ambos, envie 'body' => wp_json_encode( $dados ) e o cabeçalho Content-Type: application/json, e cheque erros e código HTTP.
Paginação, escala e webhooks
Três pontos que separam um protótipo de uma integração de produção:
- Pagine sempre. Use
per_page(o padrão é 10; aumente com cautela) epage, e leiaX-WP-Total/X-WP-TotalPagesnos cabeçalhos. Filtre porafter/beforepara puxar só o que mudou. - Respeite a escala. Cada chamada inicializa o WordPress; rajadas de requisições derrubam a loja. Use lotes (
/orders/batch), espaçamento entre chamadas e cache do seu lado. - Eventos por webhook, não por polling. Para reagir a "pedido criado/atualizado", configure webhooks em Ajustes › Avançado › Webhooks: o WooCommerce faz um POST na sua URL no momento do evento. Valide a assinatura no cabeçalho
X-WC-Webhook-Signaturee responda rápido com 200.
Por que a REST API e não o banco? Porque ela abstrai o armazenamento. A mesma chamada GET /orders funciona no modelo legado e no HPOS; um SELECT em wp_postmeta que lia pedidos simplesmente para de funcionar quando a loja migra. Integrar por REST é à prova das mudanças internas do WooCommerce. Se você vai migrar para o HPOS, veja migrar loja WooCommerce e a base em produtos e pedidos via código.
Armadilhas comuns
- Chave no front-end ou no Git. Credenciais expostas = loja comprometida. Use variáveis de ambiente/cofre e o menor privilégio.
- Basic Auth sem HTTPS. Sem TLS, as chaves vazam em claro. HTTPS é obrigatório; OAuth 1.0a só para HTTP legado.
- Confundir as APIs. Pedidos estão em
wc/v3, não emwp/v2; com HPOS, nem são posts. - Puxar tudo sem paginar. Esbarra em limites e sobrecarrega o servidor; pagine e filtre por data.
- Polling agressivo. Ineficiente e arriscado; prefira webhooks para eventos.
- Ignorar o código HTTP. Sempre cheque
is_wp_error()e o status (200/201/4xx) antes de usar o corpo. - Esquecer os efeitos de status.
set_paide mudanças de status disparam hooks e e-mails reais.
Boas práticas
- Menor privilégio. Chave só de leitura quando a integração só lê.
- HTTPS sempre. E rotacione/revogue chaves periodicamente.
- API, não SQL. A abstração garante compatibilidade com HPOS e versões futuras.
- Pagine e filtre.
per_page/page+after/before, lendo os cabeçalhos de total. - Webhooks para eventos. Empurre, não fique perguntando.
- Lotes para volume.
/orders/batchem vez de N requisições isoladas.
A REST API do WooCommerce é a ponte correta entre a sua loja e o mundo externo — ERPs, apps, marketplaces — justamente porque fala a língua da CRUD API de pedidos e por isso convive com o HPOS sem sofrimento. Para o lado WordPress da história, veja a REST API do WordPress. Se a sua loja precisa de uma integração com ERP, app ou marketplace feita com segurança e escala, conheça os serviços de suporte e manutenção WooCommerce ou veja os demais artigos de desenvolvimento.
Perguntas frequentes
A REST API do WooCommerce é a mesma do WordPress?
Não. São duas APIs distintas. A do núcleo do WordPress vive em /wp-json/wp/v2/ e expõe posts, páginas, usuários, etc. A do WooCommerce vive em /wp-json/wc/v3/ e expõe produtos, pedidos, clientes, cupons e relatórios, com a sua própria autenticação por Consumer key/secret. Embora rodem sobre a mesma infraestrutura de REST, você não usa as chaves do WooCommerce na API do núcleo nem vice-versa. Veja REST API do WordPress.
Como gero as chaves de acesso (Consumer key/secret)?
Em WooCommerce › Ajustes › Avançado › REST API › Adicionar chave. Você define uma descrição, o usuário dono da chave e a permissão (somente leitura, somente escrita ou leitura/escrita). Ao salvar, o WooCommerce mostra o Consumer key (ck_...) e o Consumer secret (cs_...) uma única vez — copie e guarde com segurança, porque o secret não é exibido novamente. A permissão segue o princípio do menor privilégio: se a integração só lê pedidos, dê só leitura.
Preciso mesmo de HTTPS?
Para a autenticação simples (Basic Auth, passando ck e cs), sim, é obrigatório HTTPS — sem TLS, as chaves trafegam em texto puro e podem ser capturadas. Só faz sentido usar a alternativa OAuth 1.0a quando a loja está em HTTP (sem certificado), porque ela assina a requisição sem expor o secret na rede. Na prática, toda loja séria roda em HTTPS e usa Basic Auth; trate OAuth como exceção para ambientes legados.
A REST API funciona com HPOS (High-Performance Order Storage)?
Sim, e essa é justamente uma das vantagens de usá-la. A API trabalha por cima da CRUD API do WooCommerce, que abstrai onde o pedido está armazenado. Então a mesma chamada GET /wp-json/wc/v3/orders funciona tanto no armazenamento legado quanto no HPOS, sem você precisar saber a diferença. É exatamente por isso que integrar via REST é preferível a mexer direto no banco: o SQL que funcionava em wp_postmeta quebra no HPOS, a chamada REST não. Veja migrar loja WooCommerce.
Como faço paginação de muitos pedidos?
Com os parâmetros per_page (o padrão é 10; aumente com cautela) e page. Para saber quantas páginas há, leia os cabeçalhos da resposta X-WP-Total (total de itens) e X-WP-TotalPages (total de páginas) — eles vêm na resposta, não no corpo. Não tente puxar tudo de uma vez: além de pesado para o servidor, há limites. Itere página a página até X-WP-TotalPages, e prefira filtrar por data (after/before) para reduzir o volume.
Para reagir a novos pedidos, faço polling na API?
Não faça polling constante — é ineficiente e esbarra em limites. Para reagir a eventos (pedido criado, atualizado, pagamento concluído), use webhooks: o WooCommerce envia um POST para a sua URL no momento do evento. Configure-os em Ajustes › Avançado › Webhooks, valide a assinatura (cabeçalho X-WC-Webhook-Signature) e responda rápido. Reserve as chamadas REST para leituras sob demanda e escritas; deixe os webhooks empurrarem os eventos para você.