Como migrar da API QR Modelo Dinâmico para a API de Orders
A API de Orders unifica o processamento de pagamentos com Código QR no Mercado Pago, consolidando em um único endpoint os dois métodos de criação da API QR Modelo Dinâmico e estendendo os recursos de consulta e cancelamento para ambos os modos. Além disso, todas as novas funcionalidades do Mercado Pago serão desenvolvidas sobre a API de Orders.
A API QR Modelo Dinâmico possuía dois métodos de criação com comportamentos distintos:
POST /qrs, modo QR dinâmico: cria um pedido e retorna uma trama QR única por transação no campoqr_data, sem associá-la a nenhuma caixa. A aplicação é responsável por converterqr_dataem código QR e exibi-lo ao cliente.PUT /qrs, modo QR híbrido: cria um pedido, o associa à caixa indicada com o{external_pos_id}, atualizando o QR estático vinculado, e retorna também o QR dinâmico no campoqr_data.
A API de Orders unifica esses dois métodos em um único endpoint POST /v1/ordersAPI, diferenciando o comportamento pelo parâmetro config.qr.mode: o valor dynamic corresponde ao fluxo POST legacy e o valor hybrid corresponde ao fluxo PUT legacy.
Essa distinção impactava também os recursos de consulta e cancelamento, disponíveis na API QR Modelo Dinâmico apenas para o fluxo PUT. Na API de Orders, esses recursos passam a estar disponíveis para os dois fluxos via order_id.
Para realizar a migração da sua integração da API QR Modelo Dinâmico para a API de Orders, siga as instruções a seguir.
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. A API de Orders unifica os dois métodos de criação em um único POST /v1/ordersAPI e estende os recursos de consulta e cancelamento para ambos os modos.
| Operação | API QR Modelo Dinâmico | API de Orders |
| Criar order (modo dinâmico) | POST /instore/orders/qr/seller/collectors/{user_id}/pos/{external_pos_id}/qrsAPI | POST /v1/ordersAPI com config.qr.mode: dynamic |
| Criar order (modo híbrido) | PUT /instore/orders/qr/seller/collectors/{user_id}/pos/{external_pos_id}/qrsAPI | POST /v1/ordersAPI com config.qr.mode: hybrid |
| Consultar order | GET /instore/qr/seller/collectors/{user_id}/pos/{external_pos_id}/ordersAPI (apenas fluxo PUT) | GET /v1/orders/{order_id}API (ambos os modos) |
| Cancelar order | DELETE /instore/orders/qr/seller/collectors/{user_id}/pos/{external_pos_id}/qrsAPI (apenas fluxo PUT) | POST /v1/orders/{order_id}/cancelAPI (ambos os modos) |
| Reembolsar order | Via API de Payments (sem endpoint dedicado na API QR Modelo Dinâmico) | POST /v1/orders/{order_id}/refundAPI |
Atualizar o modelo de status e notificações
Uma das mudanças mais significativas entre a API QR Modelo Dinâmico e a API de Orders é o modelo de status. Na API QR Modelo Dinâmico, 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 QR Modelo Dinâmico, 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 QR Modelo Dinâmico, 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 QR Modelo Dinâmico, 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 QR Modelo Dinâmico, era necessário inspecionar o status_detail do pagamento dentro da merchant_order. Na API de Orders, o status_detail indica partially_refunded. |
| — | — | canceled | Novo status sem equivalência na API QR Modelo Dinâmico. |
| — | — | expired | Novo status sem equivalência na API QR Modelo Dinâmico. |
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. 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
A API de Orders unifica os dois métodos de criação em um único POST /v1/ordersAPI, diferenciando o comportamento pelo parâmetro config.qr.mode. O endpoint POST /qrs, modo QR dinâmico, equivale a config.qr.mode: dynamic, e o endpoint PUT /qrs, modo QR híbrido, equivale a config.qr.mode: hybrid. Em ambos os casos, o {user_id} deixa de ser parâmetro de path, o {external_pos_id} passa para o body, e o campo type: "qr" passa a ser obrigatório. Siga os passos abaixo para adaptar a requisição, a resposta e o tratamento de erros de cada modo.
in_store_order_id. Na API de Orders, esse identificador passa para o campo id, com formato alfanumérico, por exemplo ORD00001111222233334444555566. Capture o valor de id do response de criação, pois é necessário para consultas, cancelamentos e reembolsos posteriores.A tabela abaixo apresenta o mapeamento de campos do body para ambos os modos de criação. A coluna da API QR Modelo Dinâmico indica o comportamento de cada campo nos fluxos POST e PUT.
| API QR Modelo Dinâmico (POST / PUT) | API de Orders | Descrição | Alteração |
{user_id} (path param, ambos) | Não existe | Identificador do usuário. Na API de Orders, a identidade é obtida diretamente do Access Token. | Deixa de ser parâmetro de path. |
{external_pos_id} (path param, ambos) | config.qr.external_pos_id | Identificador externo da caixa. Na API QR Modelo Dinâmico, 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 (obrigatório em ambos) | external_reference | Referência que pode sincronizar com o sistema de venda. Na API de Orders, máx. 64 caracteres, apenas letras, números, - e _. Não pode conter dados PII. | Sem alteração na obrigatoriedade. |
title (obrigatório no POST, opcional no PUT) | Não existe | Título da compra. | Removido. A descrição é suficiente. |
description (obrigatório no POST, opcional no PUT) | description | Descrição da compra. Na API QR Modelo Dinâmico, existia tanto no nível raiz quanto dentro de items[]. Na API de Orders, existe apenas no nível raiz. Máx. 150 caracteres. | Na API de Orders, passa a ser opcional e gerenciado apenas no nível raiz. |
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. | Removido. Configure as notificações 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. |
expiration_date | expiration_time | Validade do pedido. Na API QR Modelo Dinâmico, era uma data absoluta. Na API de Orders, é uma duração relativa em formato ISO 8601. Em todos os modos, 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. |
total_amount (obrigatório em ambos) | total_amount | Valor total da order. Na API QR Modelo Dinâmico, era number. Na API de Orders, é string decimal e representa a soma de todas as transações. Não aceita decimais (ex.: "15"). | Muda de number para string decimal. |
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 (obrigatório em ambos) | items[].title | Nome do item. Máx. 150 caracteres. | Sem alteração na obrigatoriedade. |
items[].unit_price (obrigatório em ambos) | items[].unit_price | Preço unitário. Na API QR Modelo Dinâmico, era number. Na API de Orders, é string decimal. Não aceita decimais (ex.: "15"). | Muda de number para string decimal. |
items[].quantity (obrigatório em ambos) | items[].quantity | Quantidade de itens. Na API QR Modelo Dinâmico, era number. Na API de Orders, é integer. | Muda de number para integer. |
items[].unit_measure (obrigatório em ambos) | items[].unit_measure | Unidade de medida do item. Máx. 10 caracteres. | Sem alteração na obrigatoriedade. |
items[].total_amount (obrigatório em ambos) | Não existe | Total do item (preço unitário × quantidade). | Removido. Não tem equivalente na API de Orders. |
items[].currency_id | Não existe | Identificador da moeda do item. | Removido. A moeda é determinada automaticamente pela conta do vendedor. |
items[].external_categories[].id | items[].external_categories[].id | Identificador de categoria do item. Habilita descontos por categoria. Não pode ser usado junto com discounts. | Sem alteração. |
discount.details[] | 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. | Reestruturado. O array de detalhes passa a indicar o tipo de meio de pagamento. |
taxes[].type | Não existe | Tipo de imposto. | Removido. A nova API não suporta este campo no request. |
taxes[].value | Não existe | Valor do imposto. | Removido. |
taxes[].percentage | Não existe | Percentual do imposto. | Removido. |
marketplace | Não existe | Identificador do marketplace. | Removido. O marketplace é identificado pelo Access Token OAuth. |
internal_metadata | Não existe | Metadata interna. | Removido. |
customization | Não existe | Objeto de customização. | Removido. |
A API de Orders também introduz os seguintes campos sem equivalência na API QR Modelo Dinâmico.
| Campo | Descrição |
type | Tipo de order. Para pagamentos com QR, o único valor possível é "qr". Obrigatório. |
config.qr.mode | Modo de QR. dynamic para o fluxo equivalente ao POST legacy (QR único por transação). hybrid para o fluxo equivalente ao PUT legacy. Enfileira o pedido na caixa e retorna o QR dinâmico no campo qr_data. |
transactions.payments[].amount | Valor do pagamento dentro do nó transactions. Não aceita decimais (ex.: "15"). Apenas 1 transação de pagamento por order. |
marketplace_fee | Valor da tarifa do marketplace. Exclusivo para integrações com OAuth. Não aceita decimais (ex.: "15"). |
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_. |
taxes[].payer_condition | Indica se a order é gerada com IVA ou não. Valores: payment_taxable_iva (padrão) ou payment_exempt_iva. |
A tabela abaixo apresenta o mapeamento dos campos do response. As colunas indicam a origem em cada fluxo da API QR Modelo Dinâmico.
| API QR Modelo Dinâmico | API de Orders | Descrição | Alteração |
qr_data (POST e PUT) | type_response.qr_data | Trama QR EMVCo para conversão em código QR. Na API de Orders, presente apenas quando config.qr.mode é dynamic ou hybrid. | Renomeado e movido para o nó type_response. |
in_store_order_id (POST e PUT) | id | Identificador da order criada. Na API QR Modelo Dinâmico, era um UUID (ex.: d4e8ca59-...). Na API de Orders, é um ID alfanumérico com prefixo ORD (ex.: ORD00001111222233334444555566). | Renomeado de in_store_order_id. O formato muda de UUID para ID alfanumérico. |
A API de Orders também introduz os seguintes campos no response de criação.
| Campo | Descrição |
user_id | Identificador do usuário que criou a order. |
type | Tipo de order. Para QR: sempre qr. |
external_reference | Referência externa da order. |
description | Descrição do produto ou serviço. |
expiration_time | Duração de expiração 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 (ex.: "AR"). |
marketplace_fee | Tarifa do marketplace. Exclusivo para integrações com OAuth. |
status | Estado atual da order. Ao criar: created. |
status_detail | Detalhe do estado atual da order. Os valores possíveis são created, canceled, accredited, refunded, expired. |
currency | Moeda da order. 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 (dynamic ou hybrid). |
transactions.payments[].id | Identificador da transação de pagamento. |
transactions.payments[].amount | Valor do pagamento. |
transactions.payments[].status | Estado do pagamento. Ao criar: created. |
transactions.payments[].status_detail | Detalhe do estado do pagamento. Ao criar: ready_to_process. |
integration_data.application_id | Identificador da aplicação do Mercado Pago. |
integration_data.platform_id | Identificador da plataforma. |
integration_data.integrator_id | Identificador do integrador. |
integration_data.sponsor.id | USER_ID do sistema integrador. |
taxes[].payer_condition | Indica se a order foi gerada com IVA ou não. Valores: payment_taxable_iva ou payment_exempt_iva. |
Os erros do fluxo POST e PUT são idênticos na API QR Modelo Dinâmico. 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 QR Modelo Dinâmico | API de Orders | Observação |
400 | Múltiplos: invalid_collectorId, invalid_externalPosId, invalid_external_reference, invalid_total_amount, invalid_items.*, invalid_sponsor.* 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 | (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 → 401 | (autenticação via middleware, 400) | unauthorized | Na API QR Modelo Dinâmico, era 400. Na API de Orders, é 401 explícito. |
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 equivalente na API QR Modelo Dinâmico.
| HTTP | Erro | Observação |
400 | sponsor_id_not_valid | Valor inválido como integration_data.sponsor.id. |
400 | marketplace_not_valid | O Access Token não foi obtido via OAuth. |
400 | empty_required_header | X-Idempotency-Key ausente. |
400 | unsupported_site | País não suportado. |
400 | unsupported_properties | Propriedade não suportada no body. O campo com erro está indicado no detalhe da resposta. |
401 | unauthorized | Access Token inválido ou expirado. |
404 | pos_not_found | O external_pos_id não pertence a nenhuma caixa. |
404 | marketplace_fee_not_allowed | Não é permitido enviar marketplace_fee. 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 GET /v1/orders/{order_id}API está disponível para os modos dinâmico e híbrido na API de Orders. Na API QR Modelo Dinâmico, a consulta existia apenas para o fluxo PUT e consultava por caixa, não por order. O fluxo POST não tinha endpoint de consulta. O estado era obtido exclusivamente via notificações de payments e merchant_orders.
A API de Orders permite consultar o estado completo da order diretamente pelo order_id, incluindo status, pagamentos, reembolsos e dados do meio de pagamento.
curl
curl -X GET \ 'https://api.mercadopago.com/v1/orders/{{ORDER_ID}}' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}'
Os campos legacy desta tabela correspondem ao endpoint de consulta do fluxo PUT apenas. No fluxo POST, todos os campos do response são novos.
A tabela abaixo apresenta os campos do fluxo PUT que existiam em ambas as APIs e sofreram alterações na migração.
| API QR Modelo Dinâmico, fluxo PUT | API de Orders | Descrição | Alteração |
| Não existe | id | Identificador da order. | Campo novo. O endpoint de consulta legacy não retornava o ID do pedido. |
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. |
expiration_date | expiration_time | Validade do pedido. Na API QR Modelo Dinâmico, era data absoluta. Na API de Orders, é duração relativa em ISO 8601. Em todos os modos, o valor padrão é de 15 minutos e o valor enviado é sempre respeitado. | Muda de data absoluta para duração relativa. |
total_amount | total_amount | Valor total da order. Na API QR Modelo Dinâmico, era number. Na API de Orders, é string decimal. | Muda de number para string decimal. |
marketplace_fee | marketplace_fee | Tarifa do marketplace. Na API QR Modelo Dinâmico, 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 QR Modelo Dinâmico, era integer. Na API de Orders, é string. | Passa para integration_data.sponsor. Muda de integer para string. |
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. No fluxo POST, 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 | Moeda da order. Valores: ARS, BRL, CLP, UYU. |
created_date / last_updated_date | Datas de criação e ú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. |
transactions.payments[].id | Identificador da transação de pagamento. |
transactions.payments[].amount | Valor do pagamento. |
transactions.payments[].refunded_amount | Valor reembolsado. Presente apenas quando houve 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 que está sendo reembolsado. |
transactions.refunds[].reference_id | Identificador que associa o pagamento ao seu respectivo 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. |
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 QR Modelo Dinâmico no fluxo PUT, mas não têm equivalência na API de Orders.
| HTTP | API QR Modelo Dinâmico | 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 QR Modelo Dinâmico | 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 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 QR Modelo Dinâmico | API de Orders | Observação |
400 → 401 | autenticação via middleware | unauthorized | Na API QR Modelo Dinâmico, 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 QR Modelo Dinâmico.
| 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 POST /v1/orders/{order_id}/cancelAPI está disponível para ambos os modos na API de Orders. Na API QR Modelo Dinâmico, o cancelamento existia apenas para o fluxo PUT e cancelava a order associada à caixa via DELETE. O fluxo POST não tinha endpoint de cancelamento.
O método HTTP muda de DELETE para POST, o {user_id} e o {external_pos_id} saem do path, e a operação passa a identificar a order pelo order_id. O response passou de vazio, código HTTP 204, para o objeto completo da order com status: "canceled", código HTTP 200.
| Header | Obrigatoriedade | Descrição |
X-Idempotency-Key | Obrigatório | Chave única por requisição. |
O response inclui os seguintes campos da order cancelada.
| Campo | Descrição |
id | Identificador da order cancelada. |
user_id | Identificador do usuário que criou a order. |
type | Tipo de order. Para QR: sempre qr. |
external_reference | Referência externa da order. |
description | Descrição do produto ou serviço. |
expiration_time | Tempo de expiração 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. |
marketplace_fee | Tarifa do marketplace. Exclusivo para integrações com OAuth. |
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. |
integration_data.sponsor.id | USER_ID do sistema integrador. |
status | Estado atual da order. Ao cancelar: canceled. |
status_detail | Detalhe do estado. Ao cancelar: canceled. |
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. |
transactions.payments[].id | Identificador da transação de pagamento. |
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. |
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. |
items[].external_categories[].id | Identificador de categoria do item no sistema externo. |
discounts.payment_methods[].new_total_amount | Novo valor total 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 QR Modelo Dinâmico no fluxo PUT, mas não têm equivalência na API de Orders.
| HTTP | API QR Modelo Dinâmico | Observação |
400 | invalid_collectorId | Removido na API de Orders. |
400 | invalid_externalPosId | Removido. O {external_pos_id} deixa de ser parâmetro de path. |
400 | pos_deleted_error | Removido na API de Orders. |
403 | forbidden | Removido. A identidade é validada internamente pelo Access Token. |
Erros renomeados
Os seguintes erros foram renomeados na API de Orders.
| HTTP | API QR Modelo Dinâmico | API de Orders | Observação |
400 → 404 | pos_obtainment_by_external_id_error e in_store_order_delete_error (order não encontrada) | order_not_found | Na API QR Modelo Dinâmico, 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 QR Modelo Dinâmico | API de Orders | Observação |
400 → 401 | autenticação via middleware | unauthorized | Na API QR Modelo Dinâmico, era 400. Na API de Orders, é 401 explícito. |
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 equivalente na API QR Modelo Dinâmico.
| 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 QR Modelo Dinâmico em nenhum dos dois fluxos. 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, para ambos os modos.
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 pelo endpoint POST /v1/ordersAPI com config.qr.mode: dynamic (equivalente ao fluxo POST da API legacy).
Orders criadas com sucesso pelo endpoint POST /v1/ordersAPI com config.qr.mode: hybrid (equivalente ao fluxo PUT da API legacy).
O campo id foi capturado do response de criação para uso em consultas, cancelamentos e reembolsos posteriores.
Orders consultadas com sucesso pelo endpoint GET /v1/orders/{order_id}API em ambos os modos.
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 em ambos os modos.
Reembolsos executados pelo endpoint dedicado POST /v1/orders/{order_id}/refundAPI.
Acesse a documentação para saber como testar a integração.