Pular para o conteúdo
Documentação API Reference FAQ Changelog Status
Otimizações API Magento 1 Openmage

Endpoint SOAP para leitura em lote de preço e estoque

PDF

Endpoint SOAP do módulo MageShop_BatchProductInfo que retorna preço e estoque de uma lista de SKUs em uma única chamada — para integrações ERP em Magento 1.

L Lucas Steinbach 24/05/2026 Atualizado 28/05/2026 9 min de leitura

Orientações de Integração — SOAP API Magento 1

Leitura em lote de preço e estoque (módulo MageShop_BatchProductInfo)

Documento de referência para integrações ERP ↔ Magento 1 que precisam coletar preço e estoque de muitos produtos em poucas chamadas. Expõe um método SOAP v2 customizado que substitui o par clássico catalogProductInfo + cataloginventoryStockItemList.


1. Contexto

Em integrações ERP ↔ Magento 1, é comum coletar preço e estoque de centenas ou milhares de SKUs para conferência, reconciliação ou sincronização periódica. O caminho ingênuo — uma chamada por SKU em catalogProductInfo + outra em cataloginventoryStockItemList — gera 2N requisições, cada uma com seu custo de hidratação de model, round-trip SOAP e parsing XML.

Este módulo expõe um único método SOAP que retorna preço, estoque e dados básicos de catálogo de uma lista arbitrária de SKUs em uma única chamada, lendo direto dos índices catalog_product_index_price e cataloginventory_stock_item via PDO — sem hidratar models Magento.

Este caminho é específico do Magento 1 (sem MSI). Para Magento 2, ver os endpoints REST documentados em Endpoints de API com/sem MSI nesta mesma seção.


2. Convenções e Autenticação

2.1. Convenções

  • Endpoint WSDL (SOAP v2): https://<dominio>/api/v2_soap/?wsdl
  • Endpoint WSDL (SOAP v1 RPC encoded): https://<dominio>/api/?wsdl
  • Login obrigatório: toda chamada ao método exige um sessionId obtido previamente via login(API_USER, API_KEY).
  • Numéricos retornados como stringprice, qty, special_price vêm como string no XML; converter no consumidor (floatval / Decimal).

2.2. Autenticação

ACL exigida

Item Valor
Resource mageshop_batchProductInfo
ACL mageshop_batchproductinfo/info/get
Nome legível no admin Batch Product Info → Info → Get Info

Configuração do role da API

  1. Admin → System → Web Services → SOAP/XML-RPC - Roles.
  2. Editar (ou criar) o role que o usuário da API utiliza.
  3. Em Role Resources, marcar Batch Product Info → Info → Get Info.
  4. Salvar e vincular ao usuário da API em System → Web Services → SOAP/XML-RPC - Users.

Sem essa ACL marcada, o método retorna fault SOAP código 2 ("Access denied") — independentemente das credenciais estarem corretas.


3. Endpoint — mageshopBatchProductInfoGetInfo

3.1. Identificação

Campo Valor
Nome do método (SOAP v2) mageshopBatchProductInfoGetInfo
Resource mageshop_batchProductInfo
Alias batchProductInfo
ACL mageshop_batchproductinfo/info/get

3.2. Parâmetros

Parâmetro Tipo Obrigatório Default Descrição
sessionId string sim Token retornado pelo login.
identifiers array de string sim Lista de SKUs ou entity_id. Sem limite explícito de quantidade, ver nota abaixo.
filterBy string não sku sku ou entity_id.
store string não default store view Store code ou store id. Afeta campos com override por store.

Notas sobre os parâmetros

  • identifiers — sem limite declarado pelo módulo. Há dedupe automático (valores repetidos contam uma vez na resposta). A ordem do input é preservada na resposta.
  • filterBy = sku busca pela coluna sku da tabela catalog_product_entity. filterBy = entity_id busca pela coluna entity_id.
  • store afeta price, status, visibility, special_price e suas datas — todos campos com override por store no Magento. Se omitido, usa a default store view. Estoque é global no Magento 1 e não depende da store.

Embora o módulo não imponha limite, lotes muito grandes (10k+ SKUs em uma única chamada) podem estourar timeout do PHP-FPM ou limites de tamanho de resposta SOAP. Sweet spot recomendado: Sugestão inicial: 500–2000 SKUs por chamada.

3.3. Exemplo de request — SOAP v1 RPC encoded

<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                  xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                  xmlns:urn="urn:OpenMage"
                  xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
   <soapenv:Header/>
   <soapenv:Body>
      <urn:mageshopBatchProductInfoGetInfo soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
         <sessionId xsi:type="xsd:string">{token}</sessionId>
         <identifiers xsi:type="urn:mageshopBatchProductInfoIdentifierArray" soapenc:arrayType="xsd:string[3]">
            <item xsi:type="xsd:string">SKU-001</item>
            <item xsi:type="xsd:string">SKU-002</item>
            <item xsi:type="xsd:string">SKU-INEXISTENTE</item>
         </identifiers>
         <filterBy xsi:type="xsd:string">sku</filterBy>
         <store xsi:type="xsd:string"></store>
      </urn:mageshopBatchProductInfoGetInfo>
   </soapenv:Body>
</soapenv:Envelope>

Variações

Buscando por entity_id:

<identifiers xsi:type="urn:mageshopBatchProductInfoIdentifierArray" soapenc:arrayType="xsd:string[3]">
   <item xsi:type="xsd:string">4521</item>
   <item xsi:type="xsd:string">4522</item>
   <item xsi:type="xsd:string">999999</item>
</identifiers>
<filterBy xsi:type="xsd:string">entity_id</filterBy>

Para store específica:

<store xsi:type="xsd:string">default</store>

4. Resposta

4.1. Exemplo

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
                   xmlns:ns1="urn:OpenMage"
                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                   xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                   xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
   <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
      <ns1:mageshopBatchProductInfoGetInfoResponse>
         <result xsi:type="ns1:mageshopBatchProductInfoEntityArray" SOAP-ENC:arrayType="ns1:mageshopBatchProductInfoEntity[3]">
            <item xsi:type="ns1:mageshopBatchProductInfoEntity">
               <found xsi:type="xsd:int">1</found>
               <sku xsi:type="xsd:string">SKU-001</sku>
               <product_id xsi:type="xsd:string">4521</product_id>
               <type_id xsi:type="xsd:string">simple</type_id>
               <status xsi:type="xsd:int">1</status>
               <visibility xsi:type="xsd:int">4</visibility>
               <price xsi:type="xsd:string">199.9000</price>
               <special_price xsi:type="xsd:string">159.9000</special_price>
               <special_from_date xsi:type="xsd:string">2026-05-01 00:00:00</special_from_date>
               <special_to_date xsi:type="xsd:string">2026-05-31 23:59:59</special_to_date>
               <qty xsi:type="xsd:string">42.0000</qty>
               <is_in_stock xsi:type="xsd:int">1</is_in_stock>
               <manage_stock xsi:type="xsd:int">1</manage_stock>
            </item>
            <item xsi:type="ns1:mageshopBatchProductInfoEntity">
               <found xsi:type="xsd:int">1</found>
               <sku xsi:type="xsd:string">SKU-002</sku>
               <product_id xsi:type="xsd:string">4522</product_id>
               <type_id xsi:type="xsd:string">simple</type_id>
               <status xsi:type="xsd:int">1</status>
               <visibility xsi:type="xsd:int">4</visibility>
               <price xsi:type="xsd:string">89.9000</price>
               <qty xsi:type="xsd:string">0.0000</qty>
               <is_in_stock xsi:type="xsd:int">0</is_in_stock>
               <manage_stock xsi:type="xsd:int">1</manage_stock>
            </item>
            <item xsi:type="ns1:mageshopBatchProductInfoEntity">
               <found xsi:type="xsd:int">0</found>
               <sku xsi:type="xsd:string">SKU-INEXISTENTE</sku>
            </item>
         </result>
      </ns1:mageshopBatchProductInfoGetInfoResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

4.2. Campos da resposta

Cada item retornado segue a estrutura abaixo. Campos com valor nulo ou não aplicável podem ser omitidos do XML — o consumidor deve tratar a ausência do nó como "campo não informado".

Campo Tipo Quando vem Descrição
found int sempre 1 se encontrou o produto, 0 se não.
sku string sempre SKU do produto (echo do request quando found=0).
product_id string found=1 entity_id do produto no Magento.
type_id string found=1 simple, configurable, grouped, virtual, bundle, etc.
status int found=1 1 = Enabled, 2 = Disabled.
visibility int found=1 1 = Not Visible, 2 = Catalog, 3 = Search, 4 = Both.
price string found=1 Preço cadastrado do produto (EAV), já com override por store quando aplicável.
special_price string se houver Preço promocional cru, mesmo fora da janela special_from_datespecial_to_date.
special_from_date string se houver Início da promoção (YYYY-MM-DD HH:MM:SS).
special_to_date string se houver Fim da promoção.
qty string found=1 Quantidade em estoque.
is_in_stock int found=1 1 em estoque, 0 fora de estoque.
manage_stock int found=1 1 se o estoque é controlado pelo Magento, 0 se não.

4.3. Pontos importantes

  • Ordem da resposta — segue a ordem dos identifiers no request (depois do dedupe). Isso facilita correlação direta com o pedido sem precisar indexar por SKU no consumidor.
  • Itens não encontrados — vêm com found=0 e apenas sku preenchido (ou product_id, se o filtro era entity_id). É echo do valor do request, para correlação. Não gera fault SOAP, é resposta normal.

SKUs inexistentes não retornam erro SOAP — retornam um item com found=0 dentro do array de resposta. O consumidor precisa inspecionar o campo found de cada item, não confiar apenas no status HTTP/SOAP.

  • Special price cruspecial_price traz o valor cadastrado mesmo se a data atual estiver fora do período special_from_datespecial_to_date. Cabe ao consumidor decidir se o aplica como ativo ou não, comparando com a data corrente.

O Magento aplica a janela de datas na vitrine, mas a API entrega o valor cru para não impor decisão de negócio ao integrador. Se o ERP quer usar exatamente o preço efetivo do dia, precisa replicar a lógica: se now ∈ [from, to], usar special_price; senão, usar price.

  • Estoque global no Magento 1 — não há MSI no M1. Os campos qty, is_in_stock e manage_stock não dependem da store informada. O parâmetro store afeta apenas preço, status e visibility.

5. Erros — Faults SOAP

Código Quando ocorre
2001 filterBy inválido — usar sku ou entity_id (ou os apelidos id / product_id).
2002 identifiers inválido — esperado: array não vazio.
2003 Falha de query no banco. Ver logs do Magento (var/log/system.log / var/log/exception.log).
5 Sessão expirada. Refazer login e tentar novamente.
2 Sem permissão no ACL para o método. Revisar configuração de role descrita em 2.2.

A diferença entre SKU inexistente e falha de query: SKU inexistente é resposta normal (item com found=0), nunca fault. Fault 2003 é problema de infraestrutura/banco e deve ser escalado ao time de devs com o trecho relevante do log.


6. Receita prática — cliente PHP

$client = new SoapClient('https://sualoja.com.br/api/v2_soap/?wsdl', [
    'trace'      => true,
    'cache_wsdl' => WSDL_CACHE_NONE,
]);

$session = $client->login('API_USER', 'API_KEY');

$result = $client->mageshopBatchProductInfoGetInfo(
    $session,
    ['SKU-001', 'SKU-002', 'SKU-INEXISTENTE'],
    'sku',
    null
);

foreach ($result as $item) {
    if ($item->found) {
        echo "{$item->sku}: R\$ {$item->price} | estoque: {$item->qty}\n";
    } else {
        echo "{$item->sku}: não encontrado\n";
    }
}

7. Características técnicas

Para o time de N2 entender por que este endpoint é mais barato que o caminho ingênuo:

  • 1 única query SQL com LEFT JOIN em tabelas indexadas (catalog_product_entity, catalog_product_index_price, cataloginventory_stock_item, EAV de status/visibility/special_price). Mesmo com milhares de SKUs, é 1 round-trip ao banco.
  • Sem hidratação de model — usa core_read PDO direto. Não há custo de Mage::getModel('catalog/product')->load() por item, que sozinho instanciaria objetos completos e dispararia events.
  • Preço lido do índicecatalog_product_index_price já contém o preço com regras de catálogo aplicadas no reindex. Não recalcula nada na hora da chamada.
  • Estoque lido do índicecataloginventory_stock_item direto.
  • Sem cache de resposta — preço e estoque mudam com frequência alta; cachear a resposta poderia entregar dado defasado ao ERP. O cache fica por conta do consumidor, com janela curta se for o caso.

8. Boas práticas e resultado esperado

Recomendações

  • Use este endpoint sempre que precisar de mais de 1 SKU. Para um único SKU, catalogProductInfo continua adequado — mas a partir de ~5 SKUs, este método já compensa pelo overhead reduzido.
  • Dedupe do lado do cliente é dispensável — o módulo já deduplica identifiers internamente. Não precisa pré-processar.
  • Inspecione found por item — não basta verificar que a chamada retornou sem fault. Cada item pode ter found=0 mesmo quando a chamada como um todo deu certo.
  • Reaproveite o sessionId — o login SOAP tem custo. Manter uma sessão viva e renovar só quando vier fault 5 (sessão expirada) é mais eficiente que logar a cada batch.
  • Replique a lógica de janela de promoção no ERPspecial_price vem cru. Se o ERP precisa do preço efetivo do dia, comparar now com special_from_date / special_to_date.

Resultado esperado da adoção

  • Redução significativa do número total de chamadas SOAP (de 2N para 1 por lote).
  • Menor consumo de CPU e banco de dados na aplicação Magento — uma query única indexada substitui N hidratações de model.
  • Sincronizações de catálogo mais rápidas e previsíveis.
  • Menor risco de timeouts em ERPs que sincronizam catálogos grandes.

Em caso de dúvidas sobre a implementação ou sobre limites adequados de tamanho de lote para o ambiente, fica à disposição o time de integração.

Copiar para usar com IA

Este artigo foi útil?

Obrigado pelo seu feedback!