Como migrar da Instore Orders V2 API para a Orders API
A migração da Instore Orders V2 API para a Orders API envolve a atualização de endpoints e campos da requisição, a consolidação do modelo de notificações e o aproveitamento de novos recursos nativos, como os endpoints dedicados de cancelamento e reembolso. A principal mudança na criação é que a Orders API retorna 201 Created com o objeto completo da order, em vez de 204 No Content sem body. A migração não implica mudanças no fluxo de negócio: o cliente continua escaneando o QR com o aplicativo do Mercado Pago e confirmando o pagamento.
Veja a seguir como realizar esta migração de forma completa.
Mapear as mudanças de endpoint
Antes de iniciar os passos de migração, consulte a tabela abaixo para ter uma visão geral de todas as mudanças de endpoint. Na Instore Orders V2 API, cada operação utilizava uma URL com o identificador do usuário, da loja e da caixa no path. A Orders API consolida essas operações em endpoints padronizados identificados pelo order_id.
| Operação | Instore Orders V2 API | Orders API |
| Criar order | PUT /instore/qr/seller/collectors/{user_id}/stores/{external_store_id}/pos/{external_pos_id}/ordersAPI | POST /v1/ordersAPI |
| Consultar order | GET /instore/qr/seller/collectors/{user_id}/pos/{external_pos_id}/ordersAPI | GET /v1/orders/{order_id}API |
| Cancelar order | DELETE /instore/qr/seller/collectors/{user_id}/pos/{external_pos_id}/ordersAPI | POST /v1/orders/{order_id}/cancelAPI |
| Reembolsar order | Via API de Payments (sem endpoint dedicado na Instore Orders V2 API) | POST /v1/orders/{order_id}/refundAPI |
Atualizar o modelo de status e notificações
Uma das mudanças mais significativas entre a Instore Orders V2 API e a Orders API é o modelo de status. Na Instore Orders V2 API, o estado de uma transação era determinado pelo monitoramento de notificações de dois tópicos independentes: payments e merchant_orders com campos e valores distintos para cada um. A Orders API unifica esse comportamento em um único campo status na order. Consulte o mapeamento completo abaixo.
Além disso, a Orders API também introduz o campo status_detail, que permite identificar com maior detalhamento o estado da transação. Os valores possíveis são created, canceled, accredited, refunded e expired.
Na Instore Orders V2 API, a merchant_order é criada no momento em que o pedido é gerado, portanto as notificações do tópico merchant_orders estão disponíveis desde o início do fluxo. O objeto payment, por outro lado, só é criado quando existe uma tentativa de pagamento, aprovado ou rejeitado. Quem monitorava apenas o tópico payments não recebia nenhuma notificação até que o usuário iniciasse o processo de pagamento. Na Orders API, esse comportamento é unificado: o campo status da order reflete o estado completo desde a criação, sem necessidade de monitorar dois tópicos independentes.
Tópico payments (status) | Tópico merchant_orders (status / order_status) | Orders API (status) | Observação |
| — | opened (sem pagamento ou com pagamento rejeitado) | created | Na Instore Orders V2 API, opened indicava que o pedido ainda não tinha um pagamento aprovado. Na Orders API, esse estado é explícito desde a criação. |
approved | closed + order_status: "paid" | processed | Ambos os tópicos convergiam no mesmo resultado: pagamento aprovado. Na Orders API, o estado é autocontido. |
rejected | opened (a merchant_order não muda de estado e permanece aberta) | Sem equivalente | Na Instore Orders V2 API, um pagamento rejeitado deixava a merchant_order em opened aguardando uma nova tentativa. Na Orders API, pagamentos rejeitados não são expostos. O estado permanece em created até receber um pagamento aprovado. |
refunded | closed + order_status: "reverted" | refunded | Reembolso total. No tópico merchant_orders, identificável por order_status: "reverted". |
refunded (parcial, status_detail: "partially_refunded") | closed + pagamento com status_detail: "partially_refunded" | refunded | Reembolso parcial. Na Instore Orders V2 API, era necessário inspecionar o status_detail do pagamento dentro da merchant_order. Na Orders API, o estado é o mesmo do reembolso total, mas o status_detail indica partially_refunded. |
| — | — | canceled | Novo status sem equivalente na Instore Orders V2 API. |
| — | — | expired | Novo status sem equivalente na Instore Orders V2 API. |
Quanto às notificações, na API Legacy podiam ser configuradas pelo campo notification_url no body da requisição (modelo IPN) ou por webhooks com os tópicos payments e merchant_orders. Na Orders API, o campo notification_url não existe e os tópicos payments e merchant_orders não são compatíveis. Configure as notificações em Suas integrações, selecionando o tópico "Order (Mercado Pago)" (orders) antes de subir em produção. Para mais informações, acesse a documentação de notificações.
Adaptar os headers
A Orders API introduz uma mudança obrigatória de header que afeta todos os endpoints. O Access Token deve ser enviado via header Authorization. O envio via query param não é permitido na Orders API. Aplique a alteração a seguir antes de testar qualquer outro recurso.
O header X-Idempotency-Key é obrigatório nas operações de criação, cancelamento e reembolso de orders. Ele garante que uma requisição repetida com a mesma chave retorne o resultado original sem processar a operação novamente. Envie um UUID v4 ou string aleatória única por requisição. Operações do tipo GET não requerem este header.
X-Idempotency-Key for reutilizada com um body diferente, a API retornará o erro idempotency_key_already_used. Gere uma nova chave para cada operação distinta.Migrar a criação de orders
O endpoint de criação muda de PUT /instore/qr/seller/collectors/{user_id}/stores/{external_store_id}/pos/{external_pos_id}/ordersAPI para POST /v1/ordersAPI. Além da mudança de método de PUT para POST e da URL, a resposta passa de HTTP 204 No Content sem body para 201 Created com o objeto completo da order. O {user_id} e os parâmetros de path de loja e caixa são removidos. A identidade vem do Access Token e a caixa é identificada pelo campo config.qr.external_pos_id no body. Siga os passos abaixo para adaptar a requisição, a resposta e o tratamento de erros.
204 No Content sem body, o que tornava impossível obter o id do pedido para operações posteriores. A Orders API retorna 201 Created com o objeto completo da order. O campo id do response é necessário para consultas, cancelamentos e reembolsos posteriores.Na Orders API, a identidade do usuário é obtida diretamente do Access Token. O {external_store_id} e o {user_id} deixam de ser parâmetros de path. A caixa passa a ser identificada pelo campo config.qr.external_pos_id no body. Os campos type, com valor "qr", e external_reference passam a ser obrigatórios. A tabela abaixo apresenta os campos que existiam em ambas as APIs e sofreram alterações na migração.
| Instore Orders V2 API | Orders API | Descrição | Alteração |
{user_id} (path param) | Não existe | Identificador do usuário de Mercado Pago. Na Orders API, a identidade é obtida diretamente do Access Token. | Deixa de ser parâmetro de path. |
{external_store_id} (path param) | Não existe | Identificador externo da loja. | Deixa de ser parâmetro de path. A loja é identificada indiretamente pela caixa. |
{external_pos_id} (path param) | config.qr.external_pos_id | Identificador externo da caixa. Na Instore Orders V2 API, era enviado no path. Na Orders API, é enviado no body dentro de config.qr. | Deixa de ser parâmetro de path e passa para o body. |
external_reference | external_reference | Referência que pode sincronizar com o sistema de venda do integrador. Na Orders API, é obrigatório, com no máximo 64 caracteres, apenas letras, números, - e _. Não pode conter dados PII. | Passa a ser obrigatório. |
title | Não existe | Título da compra. Na Orders API, a descrição é suficiente. | Removido. |
description | description | Descrição da compra. Na Instore Orders V2 API, existia tanto no nível raiz quanto dentro de items[]. Na Orders API, existe apenas no nível raiz. Máx. 150 caracteres. Não deve conter dados PII. | Permanece no nível raiz. A versão dentro de items[] foi removida. |
items[].description | Não existe | Descrição do item. | Removido. A descrição é gerenciada apenas no nível raiz da order. |
notification_url | Não existe | URL para receber notificações de pagamento ou merchant_order. Na Orders API, as notificações são configuradas como webhook na sua aplicação em Suas integrações, selecionando o tópico "Order (Mercado Pago)". Para mais informações, acesse a documentação de notificações. | Removido do body. |
expiration_date | expiration_time | Validade do pedido. Na Instore Orders V2 API, era uma data absoluta (ex.: 2020-08-22T16:34:56.559-04:00). Na Orders API, é uma duração relativa em formato ISO 8601 (ex.: PT5M). O valor mínimo é PT30S e o valor máximo é PT3H. Em todos os modos (QR Dinâmico, QR Estático e QR Híbrido), o valor padrão é de 15 minutos e o valor enviado é sempre respeitado. | Muda de data absoluta para duração relativa em formato ISO 8601. |
sponsor.id | integration_data.sponsor.id | USER_ID da conta do Mercado Pago do sistema integrador. | Passa para o nó integration_data.sponsor. |
items[].sku_number | items[].external_code | Código do item no sistema externo. | Renomeado para items[].external_code. |
items[].category | Não existe | Categoria do item. | Removido. Não tem equivalente na Orders API. |
items[].title | items[].title | Nome do item. Na Orders API, máx. 150 caracteres. | Passa a ser obrigatório. |
items[].unit_price | items[].unit_price | Preço unitário do item. Na Instore Orders V2 API, era number. Na Orders API, é string decimal. Aceita dois decimais (ex.: "15.00") ou nenhum. | Muda de number para string decimal e passa a ser obrigatório. |
items[].quantity | items[].quantity | Quantidade de itens. Na Instore Orders V2 API, era number. Na Orders API, é integer. | Muda de number para integer e passa a ser obrigatório. |
items[].unit_measure | items[].unit_measure | Unidade de medida do item. Máx. 10 caracteres. | Passa a ser obrigatório. |
items[].total_amount | Não existe | Total de itens (preço unitário × quantidade). | Removido. Não tem equivalente na Orders API. |
items[].external_categories[].id | items[].external_categories[].id | Identificador de categoria do item no sistema externo. Habilita descontos por categoria. Não pode ser usado junto com discounts. | Sem alteração. |
marketplace_fee | marketplace_fee | Valor da tarifa do marketplace. Na Instore Orders V2 API, era number. Na Orders API, é string decimal. Aceita dois decimais (ex.: "15.00") ou nenhum. Exclusivo para integrações com OAuth. | Muda de number para string decimal. |
total_amount | transactions.payments[].amount | Valor total da transação. Na Instore Orders V2 API, era o campo total_amount no nível raiz. Na Orders API, o valor do pagamento é enviado dentro de transactions.payments[]. Aceita dois decimais (ex.: "15.00") ou nenhum. | Passa para o nó transactions.payments. Muda de number para string decimal. |
A Orders API também introduz os seguintes campos sem equivalente na Instore Orders V2 API.
| Campo | Descrição |
type | Tipo de order. Para pagamentos com QR, o único valor possível é "qr". Obrigatório. |
total_amount | Valor total da order. Representa a soma de todas as transações. Aceita dois decimais (ex.: "15.00") ou nenhum. |
config.qr.mode | Modo de QR. Valores: static (QR estático associado à caixa, equivalente ao comportamento da Instore Orders V2 API), dynamic (QR único por transação, retornado em type_response.qr_data), hybrid (ambos os modos em paralelo). Valor padrão: static. |
discounts.payment_methods[].new_total_amount | Novo valor total da order quando um desconto é aplicado. Aceita dois decimais (ex.: "15.00") ou nenhum. Não pode ser usado junto com items[].external_categories. |
discounts.payment_methods[].type | Meio de pagamento ao qual o desconto se aplica. Valores: debit_card, credit_card, account_money, prepaid_card. Até 4 meios podem ser definidos. |
integration_data.platform_id | Identificador da plataforma, atribuído pelo Mercado Pago. |
integration_data.integrator_id | Identificador do integrador, atribuído pelo Mercado Pago. Deve ter o prefixo dev_. |
A Instore Orders V2 API retornava HTTP 204 No Content sem body na criação. A Orders API retorna 201 Created com o objeto completo da order. A tabela abaixo apresenta os campos do response da nova API.
| Campo | Descrição |
id | Identificador da order criada (ex.: ORD00001111222233334444555566). Na Instore Orders V2 API, não havia body no response de criação. É necessário para consultas, cancelamentos e reembolsos. |
user_id | Identificador do usuário de Mercado Pago que criou a order. Renomeado de collector_id (integer) para user_id (string). |
total_amount | Valor total da order. Muda de number para string decimal. |
external_reference | Referência externa da order. |
description | Descrição do produto ou serviço. Permanece no nível raiz. A versão dentro de items[] foi removida. |
marketplace_fee | Tarifa do marketplace. Muda de number para string decimal. |
integration_data.sponsor.id | USER_ID do sistema integrador. Movido de sponsor_id (integer) para integration_data.sponsor (string). |
country_code | Identificador do site/país (ex.: "AR"). Renomeado de site_id. Formato muda de minúsculas para maiúsculas. |
type | Tipo de order. Para QR: sempre qr. |
expiration_time | Duração de expiração em formato ISO 8601. Substitui expiration_date (data absoluta) por duração relativa. |
processing_mode | Modo de processamento. Para QR: sempre automatic. Substitui o array processing_modes. |
status | Estado atual da order. Ao criar: created. Na Instore Orders V2 API, o estado era obtido apenas via webhooks. |
status_detail | Detalhe do estado atual da order. Os valores possíveis são created, canceled, accredited, refunded, expired. |
currency | Identificador da moeda. Valores: ARS, BRL, CLP, UYU. Na Instore Orders V2 API, a moeda vinha de items[].currency_id. |
created_date | Data de criação. Formato yyyy-MM-ddTHH:mm:ss.sssZ. |
last_updated_date | Data da última atualização. Formato yyyy-MM-ddTHH:mm:ss.sssZ. |
config.qr.external_pos_id | Identificador externo da caixa associada à order. Na Instore Orders V2 API, era parâmetro de path de entrada e não era retornado. |
config.qr.mode | Modo de QR configurado. Valores: static, dynamic, hybrid. |
transactions.payments[].id | Identificador da transação de pagamento. Na Instore Orders V2 API, o ID do pagamento chegava apenas via webhook do tópico payments. |
transactions.payments[].amount | Valor do pagamento. Na Instore Orders V2 API, o valor estava em total_amount no nível do pedido. |
transactions.payments[].status | Estado do pagamento. Ao criar: created. |
transactions.payments[].status_detail | Detalhe do estado do pagamento. Ao criar: ready_to_process. |
type_response.qr_data | Trama QR para conversão em código QR. Presente apenas quando config.qr.mode é dynamic ou hybrid. |
integration_data.application_id | Identificador da aplicação do Mercado Pago. |
integration_data.platform_id | Identificador da plataforma, atribuído pelo Mercado Pago. |
integration_data.integrator_id | Identificador do integrador, atribuído pelo Mercado Pago. |
items[].title | Nome do item. |
items[].unit_price | Preço unitário do item. |
items[].quantity | Quantidade de itens. |
items[].unit_measure | Unidade de medida do item. |
items[].external_categories[].id | Identificador de categoria do item no sistema externo. |
discounts.payment_methods[].new_total_amount | Novo valor total da order quando um desconto é aplicado. |
discounts.payment_methods[].type | Meio de pagamento ao qual o desconto se aplica. |
A Orders API consolida a maioria dos erros de validação específicos por campo nos códigos genéricos property_value e property_type, com o detalhe do campo no corpo da resposta. Além disso, as mensagens de resposta são mais descritivas, facilitando a identificação e resolução de problemas. Consulte as tabelas abaixo para mais detalhes.
Erros que mudam de comportamento
Os seguintes erros existem em ambas as APIs mas com comportamento diferente na Orders API.
| HTTP | Instore Orders V2 API | Orders API | Observação |
400 | Múltiplos: invalid_collectorId, invalid_externalStoreId, invalid_externalPosId, invalid_total_amount, invalid_items.* e outros | property_value | property_value consolida os erros de validação por campo. O campo com erro está indicado no detalhe da resposta. |
400 | error_creating_seller_qr_order (JSON malformado) | property_type | A Orders API distingue JSON malformado com um código próprio em vez do genérico error_creating_seller_qr_order. |
400 | error_creating_seller_qr_order (erros gerais) | bad_request | O código genérico error_creating_seller_qr_order abarcava múltiplos erros. A Orders API usa bad_request para casos não cobertos por outros códigos. |
400 | error_invalid_sponsor_id | sponsor_id_not_valid | O campo migra para integration_data.sponsor.id. |
400 → 401 | autenticação via middleware | unauthorized | Na Instore Orders V2 API, autenticação falha retornava 400. Na Orders API, é 401 explícito. |
404 | pos_obtainment_error | pos_not_found | O external_pos_id deixa de ser parâmetro de path e passa para o body. |
Erros que permanecem iguais
O seguinte erro tem o mesmo comportamento em ambas as APIs.
| HTTP | Erro | Observação |
500 | Genérico | Erro interno. Verifique o retorno e repita a requisição. |
Erros introduzidos pela Orders API
Os seguintes erros não têm equivalência na Instore Orders V2 API.
| HTTP | Erro | Observação |
400 | marketplace_not_valid | O Access Token não foi obtido via OAuth e não é possível identificar um marketplace válido. |
400 | empty_required_header | X-Idempotency-Key ausente. |
400 | unsupported_site | Tentativa de criar a order em um país não suportado. |
400 | unsupported_properties | Propriedade não suportada no body. O campo com erro está indicado no detalhe da resposta. |
404 | marketplace_fee_not_allowed | Não é permitido enviar marketplace_fee porque o marketplace não foi encontrado. |
409 | idempotency_key_already_used | O X-Idempotency-Key já foi utilizado com uma requisição distinta nas últimas 24 horas. |
Atualizar a consulta de orders
O endpoint de consulta muda de GET /instore/qr/seller/collectors/{user_id}/pos/{external_pos_id}/ordersAPI para GET /v1/orders/{order_id}API. Na Instore Orders V2 API, a consulta era realizada por caixa (external_pos_id), retornando a order ativa naquela caixa sem expor o estado da transação. A Orders API substitui o endpoint de consulta por caixa por um endpoint que opera diretamente pelo order_id e retorna o estado completo da transação: status, pagamentos, reembolsos e dados do meio de pagamento. Na Instore Orders V2 API, essas informações chegavam apenas por notificação.
curlcurl -X GET \ 'https://api.mercadopago.com/v1/orders/{{ORDER_ID}}' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}'
A tabela abaixo apresenta os campos do response de consulta que existiam em ambas as APIs e sofreram alterações na migração.
| Instore Orders V2 API | Orders API | Descrição | Alteração |
| Não existe | id | Identificador da order. Na Instore Orders V2 API, o endpoint de consulta não retornava o ID do pedido. | Campo novo. |
| Não existe | user_id | Identificador do usuário que criou a order. Na Instore Orders V2 API, era parâmetro de path mas não era retornado no response. | Campo novo. |
| Não existe | type | Tipo de order. Para QR: sempre qr. | Campo novo. |
external_reference | external_reference | Referência externa da order. | Sem alteração. |
description | description | Descrição da compra. | Sem alteração. |
title | Não existe | Título da compra. | Removido. |
notification_url | Não existe | URL configurada para notificações. | Removido. Configure as notificações webhook na sua aplicação. Para mais informações, acesse a documentação de notificações. |
expiration_date | expiration_time | Validade do pedido. Na Instore Orders V2 API, era data absoluta. Na Orders API, é duração relativa em formato ISO 8601. | Muda de data absoluta para duração relativa. |
| Não existe | processing_mode | Modo de processamento. Para QR: sempre automatic. | Campo novo. |
total_amount | total_amount | Valor total da order. Na Instore Orders V2 API, era number. Na Orders API, é string decimal. | Muda de number para string decimal. |
| Não existe | country_code | Identificador do site/país. | Campo novo. |
marketplace_fee | marketplace_fee | Tarifa do marketplace. Na Instore Orders V2 API, era number. Na Orders API, é string decimal. | Muda de number para string decimal. |
sponsor.id | integration_data.sponsor.id | USER_ID do sistema integrador. Na Instore Orders V2 API, era integer. Na Orders API, é string. | Passa para integration_data.sponsor. Muda de integer para string. |
items[].title | items[].title | Nome do item. | Sem alteração. |
items[].unit_price | items[].unit_price | Preço unitário do item. Na Instore Orders V2 API, era number. Na Orders API, é string decimal. | Muda de number para string decimal. |
items[].quantity | items[].quantity | Quantidade de itens. | Sem alteração. |
items[].unit_measure | items[].unit_measure | Unidade de medida do item. | Sem alteração. |
items[].external_categories[].id | items[].external_categories[].id | Identificador de categoria do item no sistema externo. | Sem alteração. |
Na migração para a Orders API, os seguintes campos de items[] foram removidos e não possuem equivalente direto.
| Campo | Observação |
items[].description | Removido. A descrição é gerenciada apenas no nível raiz da order. |
items[].sku_number | items[].external_code |
items[].category | Removido. Não tem equivalente na Orders API. |
items[].currency_id | Removido. A moeda é exposta a nível de order no campo currency. |
items[].total_amount | Removido. Não tem equivalente na Orders API. |
items[].discount | Removido. A estrutura de descontos migrou para discounts.payment_methods[]. |
A Orders API também introduz os seguintes campos na resposta de consulta.
| Campo | Descrição |
status | Estado atual da order. Valores: created, canceled, processed, refunded, expired. Na Instore Orders V2 API, o estado só era visível via notificações de payments e merchant_orders. |
status_detail | Detalhe do estado atual da order. Os valores possíveis são created, canceled, accredited, refunded, expired. |
currency | Identificador da moeda. Valores: ARS, BRL, CLP, UYU. |
created_date | Data de criação. Formato yyyy-MM-ddTHH:mm:ss.sssZ. |
last_updated_date | Data da última atualização. Formato yyyy-MM-ddTHH:mm:ss.sssZ. |
config.qr.external_pos_id | Identificador externo da caixa associada à order. |
config.qr.mode | Modo de QR configurado. |
integration_data.application_id | Identificador da aplicação do Mercado Pago. |
integration_data.platform_id | Identificador da plataforma, atribuído pelo Mercado Pago. |
integration_data.integrator_id | Identificador do integrador, atribuído pelo Mercado Pago. |
transactions.payments[].id | Identificador da transação de pagamento. Na Instore Orders V2 API, o ID do pagamento chegava apenas via webhook do tópico payments. |
transactions.payments[].amount | Valor do pagamento. |
transactions.payments[].refunded_amount | Valor reembolsado. Presente apenas quando houve um reembolso. |
transactions.payments[].paid_amount | Valor total pago. |
transactions.payments[].status | Estado atual do pagamento. |
transactions.payments[].status_detail | Estado detalhado do pagamento. |
transactions.payments[].reference_id | Identificador do pagamento associado à order. |
transactions.payments[].payment_method.type | Meio de pagamento selecionado. |
transactions.payments[].payment_method.installments | Quantidade de parcelas. |
transactions.payments[].payment_method.id | Identificador do meio de pagamento ou bandeira. |
transactions.payments[].discounts.type | Meio de pagamento com o qual o desconto foi aplicado. Presente apenas se um desconto foi aplicado. |
transactions.refunds[].id | Identificador do reembolso. |
transactions.refunds[].transaction_id | Identificador do pagamento reembolsado. |
transactions.refunds[].reference_id | Identificador que associa a transação ao reembolso. |
transactions.refunds[].amount | Valor do reembolso. |
transactions.refunds[].status | Estado do reembolso. |
discounts.payment_methods[].new_total_amount | Novo valor total da order quando um desconto é aplicado. |
discounts.payment_methods[].type | Meio de pagamento ao qual o desconto se aplica. |
items[].external_code | Código externo do item (ex.: EAN). |
Na consulta, os erros foram agrupados conforme o tipo de alteração. Consulte as tabelas abaixo para mais detalhes.
Erros que desaparecem
Os seguintes erros existem na Instore Orders V2 API mas não têm equivalência na Orders API.
| HTTP | Instore Orders V2 API | Observação |
400 | invalid_collectorId | Removido na Orders API. A consulta opera sobre o order_id. |
400 | invalid_externalPosId | Removido. A consulta opera sobre order_id, não sobre a caixa. |
400 | pos_obtainment_by_external_id_error | Removido. O conceito de POS como parâmetro de consulta desaparece. |
400 | pos_deleted_error | Removido na Orders API. |
403 | forbidden | Removido na Orders API. |
Erros renomeados
Os seguintes erros foram renomeados na Orders API.
| HTTP | Instore Orders V2 API | Orders API | Observação |
404 | point_of_sale_in_store_order_not_found e in_store_order_not_found | order_not_found | Os dois casos de not found são unificados em order_not_found. |
Erros que mudam de comportamento
Os seguintes erros existem em ambas as APIs mas com comportamento diferente na Orders API.
| HTTP | Instore Orders V2 API | Orders API | Observação |
400 → 401 | autenticação via middleware | unauthorized | Na Instore Orders V2 API, era 400. Na Orders API, é 401 explícito. |
Erros introduzidos pela Orders API
Os seguintes erros não têm equivalência na Instore Orders V2 API.
| HTTP | Erro | Observação |
400 | invalid_path_param | O order_id tem formato inválido. Deve começar com ORD seguido de 26 caracteres. |
401 | unauthorized | Access Token inválido ou expirado. |
404 | order_not_found | O order_id não corresponde a nenhuma order criada. |
500 | Genérico | Erro interno. Verifique o retorno e repita a requisição. |
Atualizar o cancelamento de orders
O endpoint de cancelamento muda de DELETE /instore/qr/seller/collectors/{user_id}/pos/{external_pos_id}/ordersAPI para POST /v1/orders/{order_id}/cancelAPI. O método HTTP muda de DELETE para POST, o {user_id} e o {external_id} saem do path, e o cancelamento passa a operar sobre o order_id. O response passou de vazio, código HTTP 204, para o objeto completo da order com status: "canceled", código HTTP 200.
Na Instore Orders V2 API, o cancelamento apagava a order ativa associada à caixa, uma operação sobre a caixa e não sobre a transação individual. Na Orders API, o cancelamento opera diretamente sobre a order pelo order_id, sem depender da caixa no path.
O response retorna o objeto completo da order com status: "canceled". O header necessário nesta operação é:
| Header | Obrigatoriedade | Descrição |
X-Idempotency-Key | Obrigatório | Chave única por requisição. |
O response retorna o objeto completo da order com status: "canceled". Na Instore Orders V2 API, o cancelamento retornava HTTP 204 sem body. A tabela a seguir lista os campos retornados no response de cancelamento.
| Campo | Descrição |
id | Identificador da order cancelada, gerado pelo Mercado Pago. |
user_id | Identificador do usuário do Mercado Pago que criou a order. |
type | Tipo de order. Para QR: sempre qr. |
external_reference | Referência externa da order, atribuída no momento da criação. |
description | Descrição do produto ou serviço, motivo da order. |
expiration_time | Tempo de expiração da order em formato ISO 8601. |
processing_mode | Modo de processamento. Para QR: sempre automatic. |
total_amount | Valor total da order. |
country_code | Identificador do site/país da aplicação do Mercado Pago. |
marketplace_fee | Tarifa do marketplace. Exclusivo para integrações com OAuth. |
integration_data.application_id | Identificador da aplicação do Mercado Pago que criou a order. |
integration_data.platform_id | Identificador da plataforma, atribuído pelo Mercado Pago. |
integration_data.integrator_id | Identificador do integrador, atribuído pelo Mercado Pago. |
integration_data.sponsor.id | USER_ID do sistema integrador. |
status | Estado atual da order. Ao cancelar: canceled. |
status_detail | Detalhe do estado atual da order. Ao cancelar: canceled. |
currency | Identificador da moeda utilizada. Valores: ARS, BRL, CLP, UYU. |
created_date | Data de criação da order. Formato yyyy-MM-ddTHH:mm:ss.sssZ. |
last_updated_date | Data da última atualização da order. Formato yyyy-MM-ddTHH:mm:ss.sssZ. |
config.qr.external_pos_id | Identificador externo da caixa associada à order. |
config.qr.mode | Modo de QR configurado. Valores: static, dynamic, hybrid. |
transactions.payments[].id | Identificador da transação de pagamento, gerado pelo Mercado Pago. |
transactions.payments[].amount | Valor do pagamento. |
transactions.payments[].status | Estado do pagamento. Ao cancelar: canceled. |
transactions.payments[].status_detail | Detalhe do estado do pagamento. Ao cancelar: canceled_by_api. |
transactions.payments[].reference_id | Identificador do pagamento associado à order. |
items[].title | Nome do item. |
items[].unit_price | Preço unitário do item. |
items[].quantity | Quantidade de itens. |
items[].unit_measure | Unidade de medida do item. |
items[].external_code | Código externo do item (ex.: EAN). |
items[].external_categories[].id | Identificador de categoria do item no sistema externo. |
discounts.payment_methods[].new_total_amount | Novo valor total da order quando um desconto é aplicado. |
discounts.payment_methods[].type | Meio de pagamento ao qual o desconto se aplica. |
No cancelamento, os erros foram agrupados conforme o tipo de alteração. Consulte as tabelas abaixo para mais detalhes.
Erros que desaparecem
Os seguintes erros existem na Instore Orders V2 API mas não têm equivalência na Orders API.
| HTTP | Instore Orders V2 API | Observação |
400 | invalid_collector_id | Removido na Orders API. |
400 | pos_deleted_error | Removido na Orders API. |
401 | unauthorized (authorization value not present) | Removido. Ocorria ao enviar {user_id} alfanumérico. A identidade é obtida diretamente do Access Token. |
403 | forbidden | Removido. A identidade é validada internamente pelo Access Token. |
Erros renomeados
Os seguintes erros foram renomeados na Orders API.
| HTTP | Instore Orders V2 API | Orders API | Observação |
400 → 404 | pos_obtainment_by_external_id_error e in_store_order_delete_error | order_not_found | Na Instore Orders V2 API, era 400. Na Orders API, é 404. O cancelamento passa a operar sobre o order_id. |
409 | in_store_order_delete_error (Cannot delete a locked order) | instore_order_locked_error | Mesmo conceito. O nome do código de erro muda. |
Erros que mudam de comportamento
Os seguintes erros existem em ambas as APIs mas com comportamento diferente na Orders API.
| HTTP | Instore Orders V2 API | Orders API | Observação |
400 → 401 | invalid_access_token | unauthorized | Na Instore Orders V2 API, era 400. Na Orders API, é 401. |
Erros que permanecem iguais
O seguinte erro tem o mesmo comportamento em ambas as APIs.
| HTTP | Erro | Observação |
500 | Genérico | Erro interno. Verifique o retorno e repita a requisição. |
Erros introduzidos pela Orders API
Os seguintes erros não têm equivalência na Instore Orders V2 API.
| HTTP | Erro | Observação |
400 | empty_required_header | X-Idempotency-Key ausente. |
400 | invalid_path_param | O order_id tem formato inválido. |
401 | unauthorized | Access Token inválido ou expirado. |
404 | order_not_found | O order_id não corresponde a nenhuma order criada. |
409 | idempotency_key_already_used | O X-Idempotency-Key já foi utilizado com uma requisição distinta. |
409 | order_already_canceled | A order já está cancelada. Orders só podem ser canceladas com status: created. |
Implementar reembolsos com o endpoint dedicado
A Orders API introduz o endpoint dedicado POST /v1/orders/{order_id}/refundAPI para reembolsos, que não existia na Instore Orders V2 API. Anteriormente, era necessário receber o webhook do pagamento, obter o payment_id e executar o reembolso pela API de Payments separadamente. Agora, o reembolso é realizado diretamente sobre a order.
Escolha entre reembolso total ou parcial de acordo com o valor a ser devolvido.
Para reembolsar o valor total da order, envie a requisição ao endpoint POST /v1/orders/{order_id}/refundAPI sem body.
curlcurl -X POST \ 'https://api.mercadopago.com/v1/orders/{{ORDER_ID}}/refund' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \ -H 'X-Idempotency-Key: {{IDEMPOTENCY_KEY}}'
Reembolsos são aceitos em até 360 dias a partir da data do pagamento.
O response do reembolso varia conforme o tipo de operação realizada.
| Campo | Tipo | Descrição |
id | string | Identificador da order reembolsada. |
status | string | refunded para reembolso total. processed para reembolso parcial (ainda há saldo disponível). |
status_detail | string | refunded para reembolso total. partially_refunded para reembolso parcial. |
transactions.refunds[].id | string | Identificador do reembolso, gerado pelo Mercado Pago. |
transactions.refunds[].transaction_id | string | Identificador da transação de pagamento que está sendo reembolsada. |
transactions.refunds[].amount | string | Valor do reembolso. Se o pagamento foi feito com desconto, reflete esse valor. |
transactions.refunds[].status | string | processing quando o reembolso total foi solicitado e está em processamento. processed quando o reembolso parcial foi concluído com sucesso. |
transactions.refunds[].reference_id | string | Identificador que associa o pagamento ao seu respectivo reembolso. |
Validar a migração
Após aplicar as alterações, verifique se a integração opera corretamente em todos os fluxos antes de ir a produção.
O header X-Idempotency-Key deve estar presente em todas as operações de criação, cancelamento e reembolso.
Orders criadas com sucesso com o novo payload no endpoint POST /v1/ordersAPI e o campo id capturado do response.
Orders consultadas com sucesso pelo endpoint GET /v1/orders/{order_id}API.
Status de orders monitorados via webhook com o tópico "Order (Mercado Pago)" e os novos valores: created, processed, canceled, refunded e expired.
Orders canceladas com sucesso pelo endpoint POST /v1/orders/{order_id}/cancelAPI.
Reembolsos executados pelo endpoint dedicado POST /v1/orders/{order_id}/refundAPI.
Acesse a documentação para saber como testar a integração.