Integração
Tudo o que o time de tecnologia precisa para conectar o seu sistema à loja que roda no BCX-Brain: catálogo, estoque, preço, pedidos, nota fiscal e rastreio.
Visão geral
O BCX-Brain, a plataforma de vendas da BCX Capital and Holding, tem uma API REST v3 em JSON, no formato que o mercado de comércio eletrônico já usa: produto, variação, pedido, cliente e aviso por webhook. Se o seu ERP já integra com loja virtual, o trabalho é de de-para: apontar para o endereço da loja, usar a chave que entregamos e seguir os campos desta página.
A divisão é simples: o ERP é a fonte do catálogo (produto, preço e estoque) e a loja é a fonte da venda (pedido e cliente). A nota fiscal e o rastreio voltam do ERP para o pedido.
ERP
- Cadastro de produto
- Estoque por filial
- Tabelas de preço
- Faturamento e NF-e
- Expedição
Loja no BCX-Brain
- Vitrine e checkout
- Mesa de atendimento
- Pagamento (Pix e cartão)
- Avisos ao cliente
- Painel de vendas
O ERP manda
Produto, preço e estoque saem do ERP. Quem cadastra na loja é a integração, nunca a mão.
O ERP busca
O ERP lê os pedidos pagos pela API, de tempo em tempo, e recebe o aviso imediato pelo webhook.
O ERP devolve
Chave da NF-e, DANFE e código de rastreio voltam para o pedido, e o cliente é avisado.
Primeiros passos
- Receba o ambiente de teste. Toda integração começa numa loja de homologação, com o catálogo real da empresa e pagamento simulado. Nada do que acontece ali chega ao cliente final.
- Receba a chave de acesso. Entregamos uma chave por loja:
bcx_test_…na homologação ebcx_live_…na loja no ar. - Faça a primeira chamada. Liste os produtos para testar o acesso.
- Monte o de-para. Use as tabelas de Produtos e Campos de extensão.
- Rode a homologação. Siga o roteiro de homologação. Com tudo aprovado, entregamos a chave da loja no ar.
curl https://{sua-loja}/api/v3/products?per_page=5 \ -H "Authorization: Bearer $BCX_CHAVE"
O mesmo conector serve para qualquer loja no BCX-Brain. O que muda de uma empresa para outra é só o endereço da loja e a chave. Por isso recomendamos guardar endereço e chave como configuração por empresa no ERP.
Autenticação
Toda chamada leva a chave de acesso no cabeçalho Authorization, no formato Bearer, sempre sobre HTTPS. Chamada sem chave, com chave revogada ou sem HTTPS volta 401.
Authorization: Bearer bcx_test_SUA_CHAVE Content-Type: application/json; charset=utf-8
| Permissão | O que libera | Uso recomendado |
|---|---|---|
read | Consultar produtos, pedidos e clientes | Painéis e relatórios |
write | Criar e alterar produtos, pedidos e notas | Envio de carga sem consulta |
read_write | As duas | Conector do ERP |
| Exclusão | Nunca liberada para a chave de integração | Use "status": "private" ou estoque zero |
A chave aparece uma vez só, na entrega, e nunca vai em URL, log, e-mail ou planilha. Se vazar, avise o nosso time: revogamos a chave e emitimos outra na hora, sem parar a loja.
Convenções
| Item | Padrão |
|---|---|
| Endereço base | https://{sua-loja}/api/v3 |
| Formato | JSON em UTF-8, com acentos normais (sem conversão) |
| Datas | ISO 8601. Campos *_gmt em UTC; os demais no horário de São Paulo |
| Valores | Texto com ponto decimal: "189.90". Nunca vírgula |
| Medidas | Peso em kg, dimensões em cm |
| Paginação | per_page (até 100) e page. Total nos cabeçalhos X-Total-Count e X-Total-Pages |
| Lote | Até 100 itens por chamada em /batch |
| Ritmo | Recomendamos até 5 chamadas por segundo por loja. Acima de 10 por segundo a loja responde 429. Prefira lote a chamadas soltas |
| Versão | Toda resposta traz o cabeçalho X-Bcx-Api com a versão da API (hoje 1.7) |
| Chave do produto | sku (código do ERP), único por loja |
Criar produto
/productsCria o produto na loja. O produto nasce como draft (rascunho) até ter foto e descrição aprovadas pelo nosso time; preço e estoque já valem desde o primeiro envio. Todo produto criado pela integração tem controle de estoque ligado.
Campos
| Campo | Tipo | Descrição | |
|---|---|---|---|
sku | texto | obrigatório | Código do produto no ERP. É a chave da integração |
name | texto | obrigatório | Nome comercial, com marca e medida. Ex.: Cimento CP II-E-32 Votoran 50 kg |
regular_price | texto | obrigatório | Preço de venda no varejo |
sale_price | texto | opcional | Preço promocional. Vazio remove a promoção |
manage_stock | booleano | obrigatório | Sempre true (a loja liga sozinha se vier vazio) |
stock_quantity | número | obrigatório | Saldo disponível para venda (já descontado o reservado) |
weight | texto | obrigatório | Peso bruto da embalagem de venda, em kg |
dimensions | objeto | obrigatório | length, width, height em cm, da embalagem de venda |
categories | lista | opcional | IDs de categoria da loja. Se vier vazio, o nosso time classifica |
description | texto | opcional | Descrição técnica. HTML simples é aceito |
meta_data | lista | opcional | Campos de extensão do BCX-Brain. Veja a tabela |
curl -X POST https://{sua-loja}/api/v3/products \ -H "Authorization: Bearer $BCX_CHAVE" \ -H "Content-Type: application/json" \ -d '{ "sku": "100245", "name": "Cimento CP II-E-32 Votoran 50 kg", "regular_price": "38.90", "manage_stock": true, "stock_quantity": 420, "weight": "50.2", "dimensions": { "length": "60", "width": "40", "height": "12" }, "meta_data": [ { "key": "bcx_ean", "value": "7891234567895" }, { "key": "bcx_ncm", "value": "25232910" }, { "key": "bcx_marca", "value": "Votoran" }, { "key": "bcx_unidade_venda", "value": "saco" } ] }'
{
"id": 48213,
"sku": "100245",
"name": "Cimento CP II-E-32 Votoran 50 kg",
"status": "draft",
"regular_price": "38.90",
"stock_quantity": 420,
"stock_status": "instock",
"date_created_gmt": "2026-10-20T18:42:10"
}A resposta traz o id do produto na loja. Grave esse número no cadastro do ERP: as próximas atualizações ficam mais rápidas com ele, e ele é o vínculo oficial entre os dois sistemas.
Buscar produto por SKU
/products?sku={sku}Use antes de criar, para não duplicar. Se a lista voltar vazia, o produto ainda não existe na loja.
curl "https://{sua-loja}/api/v3/products?sku=100245" \ -H "Authorization: Bearer $BCX_CHAVE"
Quando o ERP manda um nome muito diferente para um produto que já está à venda, a loja mantém o nome atual, aplica o resto (preço e estoque) e marca o produto para conferência do nosso time, com o motivo sku_nome_divergente. Isso evita que um código reaproveitado no ERP troque o produto que está à venda.
Atualizar em lote
/products/batchCria, atualiza e despublica até 100 produtos numa chamada só. É o caminho recomendado para a carga inicial e para a sincronização periódica.
{
"create": [ { "sku": "100246", "name": "Argamassa AC-II Quartzolit 20 kg", "regular_price": "32.50", … } ],
"update": [ { "id": 48213, "stock_quantity": 380 } ],
"delete": []
}Não apague. Atualize com "status": "private" ou zere o estoque. O histórico de vendas e a página no Google ficam preservados. A chave de integração não exclui: um lote com a lista delete preenchida volta 403 inteiro, sem aplicar nada.
Estoque e preço
/products/{id}Atualização leve, só com o que mudou. Para muitos itens, use o lote.
{
"regular_price": "39.90",
"sale_price": "36.90",
"stock_quantity": 355
}| Dado | Frequência recomendada | Por quê |
|---|---|---|
| Estoque | A cada movimento, ou no máximo a cada 15 minutos | Evita vender o que já saiu no balcão |
| Preço | A cada alteração no ERP | O preço da loja precisa bater com o da nota |
| Cadastro | Na criação e na alteração do item | Nome, medida e categoria mudam pouco |
| Conferência geral | Uma vez por dia, de madrugada | Corrige qualquer diferença que tenha escapado |
Estoque por filial: envie em stock_quantity o saldo das filiais que atendem a loja on-line, e o detalhe por filial em bcx_estoque_filiais.
Variações
/products/{id}/variationsPara o mesmo produto em versões diferentes (voltagem 110V e 220V, cor, tamanho). O produto pai é criado com "type": "variable" e cada variação tem o seu SKU, preço e estoque.
{
"sku": "200871-220",
"regular_price": "1249.00",
"manage_stock": true,
"stock_quantity": 6,
"attributes": [ { "name": "Voltagem", "option": "220V" } ]
}Campos de extensão
Dados do ERP que o padrão não tem campo próprio vão em meta_data, sempre com o prefixo bcx_. A plataforma usa esses campos na vitrine, na busca, no frete e no painel de vendas.
| Chave | Exemplo | Para que serve |
|---|---|---|
bcx_ean | 7891234567895 | Código de barras (GTIN) da embalagem de venda |
bcx_ncm | 25232910 | Classificação fiscal |
bcx_marca | Votoran | Marca do fabricante |
bcx_unidade_venda | saco, m², metro, caixa, milheiro | Como o produto é vendido. Aparece na página do produto: «Vendido por saco» |
bcx_qtd_por_unidade | 2.5 | Conteúdo da unidade. Ex.: caixa de piso com 2,5 m², exibido como «Vendido por caixa (2,5 m² por caixa)» |
bcx_multiplo_venda | 1 | Quantidade mínima e múltiplo. A loja só aceita múltiplos desse número, na página e no carrinho |
bcx_nao_fracionavel | sim | Item que não divide em volumes. Sinaliza ao nosso time que o frete é por cotação |
bcx_estoque_filiais | [{"filial":"01","qtd":300}] | Saldo por filial, em JSON. A página do produto mostra em quais lojas há saldo |
bcx_tabelas_preco | [{"tabela":"revenda","preco":"35.10"}] | Preços de revenda e construtora, em JSON. Vale para o cliente ligado à tabela (veja Clientes) |
bcx_erp_id | 100245 | Código interno do ERP, quando diferente do SKU |
bcx_conferencia | só leitura | Preenchido pela loja quando o produto está em conferência, com o motivo |
Listar pedidos
/orders?status=processing&bcx_pendente_erp=trueO ERP busca os pedidos pagos que ainda não importou. processing quer dizer pagamento confirmado: é o momento de faturar e separar. Com bcx_pendente_erp=true, a loja devolve só os pedidos que ainda não têm o número do ERP gravado (veja Registrar a importação).
curl "https://{sua-loja}/api/v3/orders?status=processing&bcx_pendente_erp=true&per_page=50&orderby=date&order=asc" \ -H "Authorization: Bearer $BCX_CHAVE"
Use as duas coisas juntas: o webhook avisa na hora, e a consulta a cada 5 minutos garante que nenhum pedido fica para trás se o aviso falhar. Na prática, é a consulta que dá a segurança.
Objeto do pedido
Os campos que o ERP precisa para faturar. O pedido traz CPF ou CNPJ, inscrição estadual, número e bairro em campos separados.
{
"id": 10582,
"number": "10582",
"status": "processing",
"date_paid_gmt": "2026-10-20T19:05:44",
"payment_method": "asaas-pix",
"transaction_id": "pay_8f2k1x0q",
"total": "1027.80",
"discount_total": "54.10",
"shipping_total": "49.90",
"billing": {
"first_name": "Marcos", "last_name": "Almeida",
"company": "Almeida Reformas Ltda",
"persontype": "2", "cnpj": "12.345.678/0001-90", "ie": "123.456.789.110",
"address_1": "Rua das Palmeiras", "number": "120",
"neighborhood": "Jabaquara", "city": "São Paulo",
"state": "SP", "postcode": "04321-000",
"email": "compras@exemplo.com.br", "phone": "(11) 90000-0000"
},
"line_items": [
{ "sku": "100245", "name": "Cimento CP II-E-32 Votoran 50 kg", "quantity": 20, "price": 38.90, "total": "778.00" }
],
"shipping_lines": [ { "method_title": "Entrega própria", "total": "49.90" } ],
"meta_data": [
{ "key": "bcx_canal", "value": "mesa" },
{ "key": "bcx_filial", "value": "01" }
]
}| Campo | Valores |
|---|---|
billing.persontype | 1 pessoa física (vem cpf) · 2 pessoa jurídica (vem cnpj e ie) |
payment_method | asaas-pix, asaas-credit-card, asaas-ticket |
bcx_canal | site, mesa (venda feita pelo vendedor), loja_fisica |
bcx_filial | Filial que atende o pedido, no código do ERP |
O valor que o ERP fatura é sempre o total do pedido. Taxas e divisões de pagamento ficam na plataforma de pagamento e não entram na nota.
Status do pedido
| Status | Significado | Ação do ERP |
|---|---|---|
pending | Aguardando pagamento | Não importar |
processing | Pago | Importar, faturar e separar |
on-hold | Em análise | Aguardar |
completed | Faturado e enviado | O ERP marca ao devolver a nota e o rastreio |
cancelled | Cancelado | Cancelar no ERP e devolver o estoque |
refunded | Estornado | Emitir nota de devolução, se já faturado |
Registrar a importação no ERP
/orders/{id}Logo depois de importar, grave o número do pedido no ERP. A partir daí o pedido sai da lista bcx_pendente_erp=true, e o número aparece no painel da loja, para o nosso time encontrar o pedido nos dois lados.
{
"meta_data": [
{ "key": "bcx_erp_pedido", "value": "PV-558120" },
{ "key": "bcx_erp_importado_em", "value": "2026-10-20T16:07:02-03:00" }
]
}Nota fiscal e rastreio
/orders/{id}Quando a NF-e for autorizada e o pedido sair, devolva os dados e mude o status para completed. O cliente recebe o aviso por e-mail, uma vez só, com o número da nota, o link do DANFE e o rastreio, e passa a ver tudo na conta dele, em «Nota fiscal e entrega».
{
"status": "completed",
"meta_data": [
{ "key": "bcx_nfe_chave", "value": "35261012345678000190550010000123451000123456" },
{ "key": "bcx_nfe_numero", "value": "12345" },
{ "key": "bcx_nfe_serie", "value": "1" },
{ "key": "bcx_nfe_danfe_url", "value": "https://…/danfe.pdf" },
{ "key": "bcx_nfe_xml_url", "value": "https://…/nfe.xml" },
{ "key": "bcx_rastreio_codigo", "value": "AB123456789BR" },
{ "key": "bcx_rastreio_transportadora", "value": "Correios" },
{ "key": "bcx_volumes", "value": "3" }
]
}A chave da NF-e tem 44 dígitos, sem espaço nem ponto. Os links do DANFE e do XML começam com https://. Fora disso o pedido volta 400 com o motivo, sem gravar nada.
Se a entrega é com caminhão da loja, mande bcx_rastreio_transportadora como entrega_propria e, no lugar do código, a data prevista em bcx_entrega_prevista (AAAA-MM-DD).
Clientes
/customers?email={email}Os dados do cliente já chegam completos dentro do pedido. Esta rota serve para quem quer manter o cadastro do ERP sincronizado com as contas da loja, como construtoras e revendas com tabela de preço própria.
Para ligar uma conta a uma tabela de preço, grave bcx_tabela_preco (ex.: revenda) no meta_data do cliente com PUT /customers/{id}. Logado, esse cliente vê e paga o preço da tabela dele em todo produto que tiver a tabela em bcx_tabelas_preco, e a página avisa que o preço da tabela foi aplicado.
Webhooks
A loja avisa o ERP no momento em que algo acontece, com um POST em JSON para o endereço que o ERP informar. Nós cadastramos os avisos na homologação. O corpo é o mesmo objeto que a API devolve, e o remetente se identifica como BCX-Brain-Webhook/1.7.
| Evento | Quando dispara |
|---|---|
order.created | Pedido criado (ainda pode estar aguardando pagamento) |
order.updated | Mudança de status, incluindo pagamento confirmado e cancelamento |
customer.created | Conta nova na loja |
product.updated | Alteração feita pela loja num produto (ex.: despublicação) |
| Cabeçalho | Conteúdo |
|---|---|
X-Bcx-Event | Evento, ex.: order.updated |
X-Bcx-Resource | Recurso, ex.: order |
X-Bcx-Source | Endereço da loja que mandou o aviso |
X-Bcx-Delivery-Id | Identificador da entrega, para não processar duas vezes |
X-Bcx-Signature | Assinatura HMAC-SHA256 do corpo, em base64 |
O ERP deve responder 200 em até 5 segundos e processar o pedido em fila. Depois de 5 falhas seguidas o aviso é pausado até o nosso time reativar, e a consulta periódica de pedidos continua cobrindo.
Validar a assinatura
Calcule o HMAC-SHA256 do corpo recebido, sem alterar nada, com o segredo do webhook, e compare com o cabeçalho. Se não bater, descarte.
const crypto = require('crypto'); const esperado = crypto.createHmac('sha256', SEGREDO_WEBHOOK) .update(corpoBruto).digest('base64'); if (esperado !== req.headers['x-bcx-signature']) return res.status(401).end();
$esperado = base64_encode(hash_hmac('sha256', $corpoBruto, SEGREDO_WEBHOOK, true)); if (!hash_equals($esperado, $_SERVER['HTTP_X_BCX_SIGNATURE'] ?? '')) { http_response_code(401); exit; }
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(segredoWebhook)); var esperado = Convert.ToBase64String(hmac.ComputeHash(corpoBruto)); if (esperado != Request.Headers["X-Bcx-Signature"]) return Unauthorized();
Padrão de cadastro
O frete, a busca e o Google Shopping dependem do cadastro. Um produto sem peso, por exemplo, é cotado como se pesasse 1 kg, e a diferença aparece depois na conta da transportadora. Por isso o padrão abaixo é obrigatório.
| Regra | Certo | Errado |
|---|---|---|
| Dimensões em centímetro | "length": "60" | "0.6" (metro) |
| Peso bruto em quilo | "50.2" | "50200" (grama) |
| Ponto decimal | "38.90" | "38,90" |
| Medida da embalagem de venda | Caixa de piso fechada | Uma peça solta |
| Nome com marca e medida | Tinta Acrílica Suvinil Fosco Branco 18 L | TINTA ACR BCO 18 |
| Estoque já descontado | Saldo livre para venda | Saldo físico com reservas |
Portão de entrada
Toda carga passa por uma conferência automática. O que é recusado volta 400 com a lista de motivos, e o produto mantém os dados anteriores. No lote, cada item tem o seu resultado: um item recusado não trava os outros. O que fica em conferência é gravado e marcado em bcx_conferencia.
| Condição | Resultado | Motivo devolvido |
|---|---|---|
| Peso vazio ou zero | Recusado | peso_ausente |
| Alguma dimensão vazia ou zero | Recusado | dimensao_ausente |
| As três dimensões abaixo de 3 | Recusado | dimensao_em_metro |
| Vírgula em campo numérico | Recusado | separador_decimal |
| SKU igual com nome diferente | Em conferência | sku_nome_divergente |
| Mais de 30 kg em caixa pequena | Em conferência | peso_suspeito |
Acima de 30 kg, de 100 cm no maior lado ou de 200 cm na soma dos lados, os Correios não levam. Esses produtos devem vir com bcx_nao_fracionavel = sim.
Homologação
A integração vai para a loja no ar depois de passar por este roteiro na loja de teste, com o nosso time acompanhando.
- Carga do catálogo. Todos os produtos ativos do ERP entram pelo lote, sem recusa no portão.
- Estoque e preço. Uma alteração feita no ERP aparece na loja dentro da frequência combinada.
- Pedido pago no Pix. O pedido entra no ERP com cliente, itens, frete e desconto corretos.
- Pedido de pessoa jurídica. CNPJ e inscrição estadual chegam nos campos certos.
- Nota e rastreio. A NF-e e o código voltam para o pedido e o status vira
completed. - Cancelamento. O pedido cancelado na loja é cancelado no ERP e o estoque volta.
- Falha do aviso. Com o webhook desligado, a consulta periódica importa o pedido mesmo assim.
Erros
| Código | Significado | O que fazer |
|---|---|---|
200 · 201 | Certo | Seguir |
400 | Dado inválido | Ler o campo message e corrigir o envio |
401 | Chave ausente, inválida ou revogada | Conferir o cabeçalho Authorization e o HTTPS |
403 | Sem permissão | A chave não tem a permissão da operação (ex.: exclusão) |
404 | Recurso não existe | Conferir o id ou buscar pelo SKU |
429 | Ritmo acima do limite | Esperar e reenviar, de preferência em lote |
500 · 503 | Instabilidade | Reenviar com espera crescente (1, 5, 30 segundos) |
{
"code": "bcx_cadastro_recusado",
"message": "Cadastro recusado no portão de entrada: As três dimensões estão abaixo de 3: provável metro. Envie em centímetros.",
"data": {
"status": 400,
"sku": "100245",
"motivos": [ { "motivo": "dimensao_em_metro", "mensagem": "As três dimensões estão abaixo de 3: provável metro. Envie em centímetros." } ]
}
}Novidades da versão
Toda mudança na API entra numa versão nova e fica registrada aqui.
v1.7atual20/10/2026
- Campos de extensão para material de construção: unidade de venda, conteúdo por unidade, múltiplo de venda e item não fracionável.
- Estoque por filial e tabelas de preço de revenda e construtora.
- Devolução de NF-e, DANFE, XML e rastreio no pedido, com aviso automático ao cliente.
- Entrega própria com data prevista.
- Portão de entrada com os motivos de recusa.
- Roteiro de homologação em sete passos.
v1.613/07/2026
- Registro da importação do pedido no ERP.
- Filtro
bcx_pendente_erppara buscar só o que falta importar. - Canal de venda e filial informados no pedido.
v1.516/03/2026
- Exclusão bloqueada pela API: produto sai de venda pelo status, nunca é apagado.
- Produto criado pela API nasce como rascunho, para conferência antes de ir para a loja.
- Códigos de erro com prefixo
bcx_.
v1.424/11/2025
- Busca de produto por SKU.
- Paginação com os cabeçalhos
X-Total-CounteX-Total-Pages. - Limite de 10 chamadas por segundo, com resposta
429quando passa.
v1.315/09/2025
- Dados fiscais do comprador no pedido: tipo de pessoa, CPF ou CNPJ, inscrição estadual, número e bairro.
- Consulta de clientes.
v1.230/06/2025
- Avisos automáticos (webhooks) de pedido e produto.
- Assinatura em todo aviso, no cabeçalho
X-Bcx-Signature, para o ERP conferir a origem.
v1.114/04/2025
- Variações de produto (cor, tamanho, embalagem), cada uma com SKU, preço e estoque próprios.
- Atualização de produtos em lote.
v1.010/02/2025
- Primeira versão: produtos, estoque, preço e pedidos em API REST, no formato JSON.
- Endereço
/api/v3, chave de acesso própria (Bearer) e chamada só por HTTPS.
Suporte técnico
O nosso time acompanha a integração do primeiro teste até a loja no ar. Para dúvida técnica, credencial ou ambiente de teste, fale com o nosso time pelo mesmo canal em que você recebeu esta documentação, informando a empresa e o endereço da loja.