Como migrar da API de Pedidos presenciais V2 para a API de Orders
A API de Orders unifica o processamento de pagamentos com Código QR no Mercado Pago, oferecendo endpoints padronizados, um modelo de status consolidado e novos recursos nativos que não existiam na API de Pedidos presenciais V2. Além disso, todas as novas funcionalidades do Mercado Pago serão desenvolvidas sobre a API de Orders.
A migração da API de Pedidos presenciais V2 para a API de Orders 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 API de Orders 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 API de Pedidos presenciais V2, cada operação utilizava uma URL com o identificador do usuário, da loja e da caixa no path. A API de Orders consolida essas operações em endpoints padronizados identificados pelo order_id.
| Operação | API de Pedidos presenciais V2 | API de Orders |
| 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 API de Pedidos presenciais V2) | POST /v1/orders/{order_id}/refundAPI |
Atualizar o modelo de status e notificações
Uma das mudanças mais significativas entre a API de Pedidos presenciais V2 e a API de Orders é o modelo de status. Na API de Pedidos presenciais V2, 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 API de Orders unifica esse comportamento em um único campo status na order. Consulte o mapeamento completo abaixo.
Além disso, a API de Orders 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 API de Pedidos presenciais V2, 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 API de Orders, 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) | API de Orders (status) | Observação |
| — | opened (sem pagamento ou com pagamento rejeitado) | created | Na API de Pedidos presenciais V2, opened indicava que o pedido ainda não tinha um pagamento aprovado. Na API de Orders, 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 API de Orders, o estado é autocontido. |
rejected | opened (a merchant_order não muda de estado e permanece aberta) | Sem equivalente | Na API de Pedidos presenciais V2, um pagamento rejeitado deixava a merchant_order em opened aguardando uma nova tentativa. Na API de Orders, 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 API de Pedidos presenciais V2, era necessário inspecionar o status_detail do pagamento dentro da merchant_order. Na API de Orders, o estado é o mesmo do reembolso total, mas o status_detail indica partially_refunded. |
| — | — | canceled | Novo status sem equivalente na API de Pedidos presenciais V2. |
| — | — | expired | Novo status sem equivalente na API de Pedidos presenciais V2. |
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 API de Orders, 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 API de Orders 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 API de Orders. 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 API de Orders retorna 201 Created com o objeto completo da order. O campo id do response é necessário para consultas, cancelamentos e reembolsos posteriores.Na API de Orders, 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.
| API de Pedidos presenciais V2 | API de Orders | Descrição | Alteração |
{user_id} (path param) | Não existe | Identificador do usuário de Mercado Pago. Na API de Orders, 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 API de Pedidos presenciais V2, era enviado no path. Na API de Orders, é 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 API de Orders, é 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 API de Orders, a descrição é suficiente. | Removido. |
description | description | Descrição da compra. Na API de Pedidos presenciais V2, existia tanto no nível raiz quanto dentro de items[]. Na API de Orders, 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 API de Orders, 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 API de Pedidos presenciais V2, era uma data absoluta (ex.: 2020-08-22T16:34:56.559-04:00). Na API de Orders, é 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 API de Orders. |
items[].title | items[].title | Nome do item. Na API de Orders, máx. 150 caracteres. | Passa a ser obrigatório. |
items[].unit_price | items[].unit_price | Preço unitário do item. Na API de Pedidos presenciais V2, era number. Na API de Orders, é string decimal. Não aceita decimais (ex.: "15"). | Muda de number para string decimal e passa a ser obrigatório. |
items[].quantity | items[].quantity | Quantidade de itens. Na API de Pedidos presenciais V2, era number. Na API de Orders, é 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 API de Orders. |
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 API de Pedidos presenciais V2, era number. Na API de Orders, é string decimal. Não aceita decimais (ex.: "15"). Exclusivo para integrações com OAuth. | Muda de number para string decimal. |
total_amount | transactions.payments[].amount | Valor total da transação. Na API de Pedidos presenciais V2, era o campo total_amount no nível raiz. Na API de Orders, o valor do pagamento é enviado dentro de transactions.payments[]. Não aceita decimais (ex.: "15"). | Passa para o nó transactions.payments. Muda de number para string decimal. |
A API de Orders também introduz os seguintes campos sem equivalente na API de Pedidos presenciais V2.
| 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. Não aceita decimais (ex.: "15"). |
config.qr.mode | Modo de QR. Valores: static (QR estático associado à caixa, equivalente ao comportamento da API de Pedidos presenciais V2), 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. Não aceita decimais (ex.: "15"). 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 API de Pedidos presenciais V2 retornava HTTP 204 No Content sem body na criação. A API de Orders 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 API de Pedidos presenciais V2, 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 API de Pedidos presenciais V2, 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 API de Pedidos presenciais V2, 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 API de Pedidos presenciais V2, 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 API de Pedidos presenciais V2, o ID do pagamento chegava apenas via webhook do tópico payments. |
transactions.payments[].amount | Valor do pagamento. Na API de Pedidos presenciais V2, 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 API de Orders 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 API de Orders.
| HTTP | API de Pedidos presenciais V2 | API de Orders | 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 API de Orders 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 API de Orders 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 API de Pedidos presenciais V2, autenticação falha retornava 400. Na API de Orders, é 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 API de Orders
Os seguintes erros não têm equivalência na API de Pedidos presenciais V2.
| 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 API de Pedidos presenciais V2, a consulta era realizada por caixa (external_pos_id), retornando a order ativa naquela caixa sem expor o estado da transação. A API de Orders 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 API de Pedidos presenciais V2, essas informações chegavam apenas por notificação.
curl
curl -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.
| API de Pedidos presenciais V2 | API de Orders | Descrição | Alteração |
| Não existe | id | Identificador da order. Na API de Pedidos presenciais V2, 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 API de Pedidos presenciais V2, 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 API de Pedidos presenciais V2, era data absoluta. Na API de Orders, é 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 API de Pedidos presenciais V2, era number. Na API de Orders, é 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 API de Pedidos presenciais V2, era number. Na API de Orders, é string decimal. | Muda de number para string decimal. |
sponsor.id | integration_data.sponsor.id | USER_ID do sistema integrador. Na API de Pedidos presenciais V2, era integer. Na API de Orders, é 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 API de Pedidos presenciais V2, era number. Na API de Orders, é 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 API de Orders, 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 API de Orders. |
items[].currency_id | Removido. A moeda é exposta a nível de order no campo currency. |
items[].total_amount | Removido. Não tem equivalente na API de Orders. |
items[].discount | Removido. A estrutura de descontos migrou para discounts.payment_methods[]. |
A API de Orders 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 API de Pedidos presenciais V2, 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 API de Pedidos presenciais V2, 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 API de Pedidos presenciais V2 mas não têm equivalência na API de Orders.
| HTTP | API de Pedidos presenciais V2 | Observação |
400 | invalid_collectorId | Removido na API de Orders. 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 API de Orders. |
403 | forbidden | Removido na API de Orders. |
Erros renomeados
Os seguintes erros foram renomeados na API de Orders.
| HTTP | API de Pedidos presenciais V2 | API de Orders | 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 API de Orders.
| HTTP | API de Pedidos presenciais V2 | API de Orders | Observação |
400 → 401 | autenticação via middleware | unauthorized | Na API de Pedidos presenciais V2, era 400. Na API de Orders, é 401 explícito. |
Erros introduzidos pela API de Orders
Os seguintes erros não têm equivalência na API de Pedidos presenciais V2.
| 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 API de Pedidos presenciais V2, o cancelamento apagava a order ativa associada à caixa, uma operação sobre a caixa e não sobre a transação individual. Na API de Orders, 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 API de Pedidos presenciais V2, 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 API de Pedidos presenciais V2 mas não têm equivalência na API de Orders.
| HTTP | API de Pedidos presenciais V2 | Observação |
400 | invalid_collector_id | Removido na API de Orders. |
400 | pos_deleted_error | Removido na API de Orders. |
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 API de Orders.
| HTTP | API de Pedidos presenciais V2 | API de Orders | Observação |
400 → 404 | pos_obtainment_by_external_id_error e in_store_order_delete_error | order_not_found | Na API de Pedidos presenciais V2, era 400. Na API de Orders, é 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 API de Orders.
| HTTP | API de Pedidos presenciais V2 | API de Orders | Observação |
400 → 401 | invalid_access_token | unauthorized | Na API de Pedidos presenciais V2, era 400. Na API de Orders, é 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 API de Orders
Os seguintes erros não têm equivalência na API de Pedidos presenciais V2.
| 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 API de Orders introduz o endpoint dedicado POST /v1/orders/{order_id}/refundAPI para reembolsos, que não existia na API de Pedidos presenciais V2. 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.
curl
curl -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.