Como migrar da Payments API para a Orders API
A Orders API unifica o processamento de pagamentos online de Checkout Transparente , oferecendo endpoints padronizados, um modelo de status consolidado por transação e novos recursos nativos que não existiam na Payments API.
Entre eles, estão: múltiplas transações por order, processamento manual ou automático, endpoint dedicado de captura, autenticação 3DS 2.0 integrada nativamente e lista consolidada de erros de validação.
A migração envolve a atualização de endpoints e campos da requisição, a consolidação do modelo de status e notificações e o aproveitamento de novos recursos nativos. Isso não implica mudanças no fluxo de negócio percebido pelo comprador: o cliente continua preenchendo o checkout dentro do site do vendedor, sem redirecionamentos.
Veja a seguir como realizar esta migração de forma completa, endpoint por endpoint e campo por campo, incluindo as particularidades de cada meio de pagamento.
Antes de implementar, classifique cada fluxo ativo da Payments API em uma destas situações:
- Tem equivalente direto: quando é um recurso obrigatório que tem uma equivalência direta entre as APIs, migre o seu fluxo seguindo as etapas obrigatórias deste guia.
- Exige adaptação técnica: quando é um recurso opcional que já faz parte da sua integração atual, implemente também as etapas conforme seu fluxo.
- Não tem equivalente documentado: mantenha o fluxo na Payments API até que haja suporte na Orders API.
A Payments API continua funcionando normalmente após o lançamento da Orders API. O Mercado Pago não desativou essa API, apenas deixou de adicionar novas funcionalidades a ela, mantendo correções de segurança e estabilidade. Tecnicamente, é possível manter as duas APIs ativas ao mesmo tempo, cada uma processando parte do seu volume.
Recomendamos a seguinte estratégia:
- Migre por meio de pagamento, não tudo de uma vez. Mova cartão para a Orders API primeiro e migre os demais meios de pagamento um a um, após validar a estabilidade.
- Faça a divisão de tráfego no seu próprio checkout. Como cada API usa endpoints, credenciais e chaves de idempotência independentes, é seguro rotear parte das novas transações para /v1/ordersPOST e o restante para /v1/paymentsPOST.
- Separe o tratamento de notificações. Configure o Webhook para escutar os tópicos
ordersepaymentem paralelo durante a transição, direcionando cada payload ao tratamento correto. Só desativepaymentdepois de migrar o tráfego novo e monitorar as transações e notificações pendentes da Payments API. - Defina como interromper a migração. Se for necessário voltar a usar a Payments API, redirecione apenas as novas transações. As transações já criadas devem continuar sendo consultadas, capturadas, canceladas ou reembolsadas na API em que foram processadas, pois não podem nem precisam ser transferidas de uma API para a outra.
- Acompanhe a taxa de aprovação e a qualidade da integração separadamente para cada API durante a coexistência, como critério para decidir quando desligar o tráfego da Payments API.
Antes de iniciar a migração, confirme se todos os meios de pagamento da sua integração já têm equivalente na Orders API.
| Meio de pagamento | Payments API | Orders API |
| Cartão de crédito | Suportado | Suportado |
| Cartão de débito | Suportado (todas as bandeiras) | Suportado (Elo e débito virtual Caixa) |
| Pix | Suportado | Suportado |
| Boleto bancário | Suportado | Suportado |
| Conta Mercado Pago | Suportado | Suportado |
| Linha de Crédito | Suportado | Suportado |
Além da disponibilidade por meio de pagamento, verifique se a sua integração utiliza recursos de Marketplace ou Split de Pagamentos 1:1. Na Payments API, essas integrações retêm comissões por meio de application_fee; a Orders API ainda não tem um campo equivalente documentado para essa mecânica. Trate esse ponto como bloqueio antes de migrar o fluxo.
Na Payments API, cada operação usava um recurso próprio sobre /v1/payments/{id}. A Orders API consolida a maior parte dessas operações em sub-recursos do mesmo /v1/orders/{order_id} e introduz endpoints dedicados que não existiam antes: captura explícita, adição, remoção e atualização de transações, e processamento em modo manual.
O header Authorization é obrigatório em ambas as APIs e não muda. A principal alteração está na obrigatoriedade do header de idempotência em praticamente todas as operações de escrita.
| Header | Payments API | Orders API |
Authorization | Obrigatório em todas as requisições | Obrigatório em todas as requisições |
X-Idempotency-Key | Obrigatório apenas em /v1/paymentsPOST e /v1/payments/{id}/refundsPOST | Obrigatório em /v1/ordersPOST, /v1/orders/{order_id}/capturePOST, /v1/orders/{order_id}/transactionsPOST, /v1/orders/{order_id}/processPOST, /v1/orders/{order_id}/cancelPOST e /v1/orders/{order_id}/refundPOST |
X-Idempotency-Key for reutilizada com um body diferente, a Orders API retorna o erro 409 (idempotency_key_already_used). Gere sempre uma chave nova por tentativa de transação, preferencialmente um UUID v4. Para mais detalhes sobre todos os headers aceitos na Orders API, acesse a Referência de APIAPI.Na Payments API, o status e o status_detail existem em um único nível. Na Orders API, o mesmo conceito existe em dois níveis: o status da order, como visão consolidada, e o status de cada transação em transactions.payments[] — o que passa a ser essencial quando uma order tem mais de uma transação.
A tabela a seguir mapeia os valores de status entre o pagamento na Payments API e os níveis de order e transação na Orders API.
| Payments API | Orders API (order) | Orders API (transação) | Observação |
pending | action_required | action_required | Aguardando ação do pagador ou do vendedor. |
approved | processed | processed | Pagamento aprovado e creditado. |
authorized | action_required (waiting_capture) | action_required (waiting_capture) | Valor reservado, aguardando captura. |
in_process | processing | processing | Em análise ou processamento. |
in_mediation | charged_back (in_process) | charged_back (in_process) | Contestação em andamento. |
rejected | failed | failed | Recusado. O status_detail traz o motivo. |
cancelled | canceled | canceled | Cancelado pelo vendedor, pelo comprador ou por expiração. |
refunded | refunded | refunded | Reembolsado integralmente. |
charged_back | charged_back (settled / reimbursed) | charged_back (settled/reimbursed) | Contestação recebida e resolvida. |
cancelled, com dois L, e a Orders API usa canceled, com um L. Se a sua integração compara esse valor de status como string literal, atualize a grafia.O endpoint de criação muda de /v1/paymentsPOST para /v1/ordersPOST. Além da URL, a estrutura da requisição foi reorganizada: o valor e o meio de pagamento migram para dentro do nó transactions.payments[], um array que permite múltiplas transações por order. Os campos type, com valor fixo online, e o nó config passam a existir sem equivalência direta no legado.
A tabela a seguir mapeia, campo a campo, a estrutura da requisição de criação entre as duas APIs.
| Payments API | Orders API | Mudança |
transaction_amount | transactions.payments[].amount / total_amount | Migra para dentro do array de transações e passa a ser string. O total_amount deve corresponder à soma das transações. |
payment_method_id | transactions.payments[].payment_method.id | Passa a ficar aninhado em payment_method. |
token | transactions.payments[].payment_method.token | Passa a ficar aninhado em payment_method. |
installments | transactions.payments[].payment_method.installments | Passa a ficar aninhado em payment_method. |
statement_descriptor | transactions.payments[].payment_method.statement_descriptor | Passa a ficar aninhado em payment_method. |
description | description | Sem alteração. Permanece no nível raiz. |
external_reference | external_reference | Sem alteração de nome. Passa a ser obrigatório em alguns meios de pagamento. |
notification_url | Não existe. | Removido do body. As notificações passam a ser configuradas em Suas integrações. Veja mais informações em Notificações. |
capture | capture_mode | Muda de booleano para os valores manual, automatic e automatic_async, no nível raiz da order. |
date_of_expiration | transactions.payments[].expiration_time / date_of_expiration | Passa a aceitar duração no formato ISO 8601, além de data absoluta. |
payer.email | payer.email | Sem alteração. |
payer.identification.type / .number | payer.identification.type / .number | Sem alteração. |
payer.first_name / .last_name | payer.first_name / .last_name | Sem alteração. |
payer.address.* | payer.address.* | Sem alteração de estrutura. |
three_d_secure_mode | config.online.transaction_security.validation e .liability_shift | Reestruturado. Veja mais informações em Integrar 3DS. |
items[].id | items[].external_code | Renomeado. |
items[].title / .unit_price / .quantity / .description / .picture_url / .category_id | Mesmos nomes | Sem alteração de nome. |
| Não existe | type | Campo novo e obrigatório. Para pagamentos online, o valor é online. |
| Não existe | processing_mode | Campo novo. Define se a order é processada em uma etapa ou depois, via /process. |
| Não existe | integration_data.{integrator_id, platform_id, sponsor.id} | Campo novo. Substitui parcialmente o sponsor_id do legado. |
issuer_id | transactions.payments[].payment_method.id (de forma implícita) | Não há campo issuer_id direto documentado. Valide a necessidade caso a caso. |
binary_mode | Não documentado como campo da Orders API | Restringia o resultado a aprovado ou recusado. Sem equivalente direto encontrado. |
application_fee | Não documentado na Orders API. Valide com a equipe responsável por sua integração antes de migrar integrações com Split de Pagamentos 1:1. | |
fee_details[] | Sem equivalente direto documentado | Detalhamento de taxas. Valide o cálculo a partir dos relatórios de liberação de dinheiro. |
A tabela a seguir mapeia os principais campos da resposta de criação entre as duas APIs.
| Payments API | Orders API | Mudança |
id | id | O formato muda de numérico para alfanumérico com prefixo ORD. |
status | status / transactions.payments[].status | Passa a existir em dois níveis. |
status_detail | status_detail / transactions.payments[].status_detail | Passa a existir em dois níveis. |
transaction_amount | total_amount / transactions.payments[].amount | Passa a existir em dois níveis e muda para string. |
transaction_amount_refunded | transactions.refunds[].amount / status_detail: partially_refunded | Reestruturado como array de reembolsos. |
date_created | created_date | Renomeado. |
date_last_updated | last_updated_date | Renomeado. |
payment_method_id | transactions.payments[].payment_method.id | Passa a ficar aninhado. |
payment_type_id | transactions.payments[].payment_method.type | Renomeado e aninhado. |
collector_id | Não existe | Removido da resposta de criação. |
point_of_interaction.transaction_data.* | transactions.payments[].payment_method.{qr_code, qr_code_base64, ticket_url} | Reestruturado para dentro de payment_method. |
transaction_details.external_resource_url | transactions.payments[].payment_method.ticket_url | Renomeado. |
| Não existe | total_paid_amount | Campo novo. Total efetivamente pago. |
| Não existe | capture_mode | Campo novo. Modo de captura configurado. |
| Não existe | processing_mode | Campo novo. Modo de processamento configurado. |
| Não existe | country_code | Campo novo. Código do país. |
card.{...} | Não retornado na criação. A resposta traz apenas o token e o identificador do pagamento. | Reduzido. Use os endpoints de Salvar Cartões para dados persistidos do cartão. |
| Não existe | client_token | Campo novo. Token de acompanhamento client-side. |
A Payments API retorna um erro por vez, o primeiro encontrado. A Orders API retorna uma lista com todos os erros de validação da requisição em uma única resposta, o que agiliza a correção.
A tabela a seguir lista os erros da Payments API que foram renomeados ou consolidados em códigos mais genéricos na Orders API.
| HTTP | Payments API | Orders API | Observação |
400 | 3000 a 3032 | property_value / property_type / required_properties | Consolidados em códigos genéricos de validação por campo. |
400 | 4000 a 4051 | required_properties / unsupported_properties / minimum_properties | Consolidados. |
400 | 23 | property_value | Formato inválido de date_of_expiration. |
400 | 2072 | invalid_total_amount | Renomeado. Passa a validar a soma de transactions.payments[].amount contra total_amount. |
400 | 2131 | invalid_order_type / property_value | Consolidado. |
400 | 4292 | empty_required_header | Renomeado. |
401 | Unauthorized use of live credentials | invalid_credentials | Renomeado. |
409 | 2001 | idempotency_key_already_used | Consolidado no mecanismo de idempotência. |
403 | 4 (caller not authorized) | Não documentado como erro 403 específico na Orders API | Valide o comportamento em ambiente de teste. |
O endpoint de consulta muda de /v1/payments/{id}GET para /v1/orders/{id}GET. A resposta traz o objeto completo da order, incluindo todas as transações associadas, seus reembolsos e eventuais contestações — informação que no legado exigia consultas separadas.
| Informação | Payments API | Orders API |
| Reembolsos | Consulta separada em /v1/payments/{id}/refundsGET. | Incluído em transactions.refunds[] |
| Contestações | Consulta separada em /v1/chargebacks/{id}GET. | Referenciado em transactions.chargebacks[], com id, transaction_id, case_id, status e references. |
| Dados do 3DS | payment_method.data.threeds | transactions.payments[].payment_method.transaction_security |
| Parcelamento sem cartão e condições de parcelas | Não aplicável neste endpoint. | config.payment_method.{default_type, installments_cost, installments.interest_free, installments.available} |
Erros de consulta
| HTTP | Erro | Observação |
400 | invalid_path_param | O order_id enviado tem formato inválido. |
401 | invalid_credentials | Access Token inválido ou expirado. |
404 | order_not_found | O order_id não corresponde a nenhuma order criada. |
500 | internal_error | Erro genérico. Tente novamente e, se persistir, contate o suporte com o x-request-id. |
O endpoint de busca muda de /v1/payments/searchGET para /v1/orders/searchGET, com filtros e paginação reestruturados. Os intervalos de data passam a ser obrigatórios e a paginação usa page e page_size em vez de offset e limit.
| Payments API | Orders API | Observação |
sort | sort_by | Renomeado. O padrão é created_date. |
criteria | sort_order | Renomeado. O padrão é desc. |
begin_date / end_date | begin_date / end_date | Passam a ser obrigatórios, no formato RFC3339. |
external_reference | external_reference | Sem alteração. |
collector.id / payer.id | Não documentado como filtro. | A identidade é obtida do Access Token. |
offset / limit | page / page_size | Paginação por página. O page_size tem máximo de 100 e padrão de 20. |
| Não existe | status / status_detail / payment_method_id / payment_method_type | Novos filtros diretos. |
A reserva de valor muda de um campo booleano (capture) para um modo de captura configurado na criação da order (capture_mode), combinado com um endpoint dedicado de captura.
A tabela a seguir compara como reservar um valor sem captura imediata nas duas APIs.
| Payments API | Orders API |
/v1/paymentsPOST com "capture": "false". | /v1/ordersPOST com "capture_mode": "manual". |
Resultado: "status": "authorized". | Resultado: "status": "action_required" e "status_detail": "waiting_capture". |
Assim como na Payments API, é possível cancelar uma order antes da conclusão do pagamento ou reembolsá-la, total ou parcialmente, após a aprovação. Veja a seguir como cada fluxo muda na Orders API.
Só é possível cancelar uma order com status action_required ou created, ou seja, com o pagamento ainda não concluído. O endpoint muda de /v1/payments/{id}PUT para o endpoint dedicado /v1/orders/{order_id}/cancelPOST.
Os endpoints da API de Clientes são compartilhados entre as duas APIs e não sofrem alteração de estrutura na migração. Apenas a forma de usar o cartão salvo em uma nova cobrança muda, já que o pagamento passa a ser criado como order.
| Recurso | Endpoint sem alteração entre as APIs |
| Criar cliente | /v1/customersPOST |
| Buscar clientes | /v1/customers/searchGET |
| Obter cliente | /v1/customers/{id}GET |
| Atualizar cliente | /v1/customers/{id}PUT |
| Salvar cartão | /v1/customers/{customer_id}/cardsPOST |
| Listar cartões do cliente | /v1/customers/{customer_id}/cardsGET |
| Obter cartão | /v1/customers/{customer_id}/cards/{id}GET |
| Atualizar cartão | /v1/customers/{customer_id}/cards/{id}PUT |
| Excluir cartão | /v1/customers/{customer_id}/cards/{id}DELETE |
| Endereços do cliente | /v1/customers/{id}/addressesPOST, /v1/customers/{id}/addressesGET, /v1/customers/{id}/addresses/{address_id}PUT e /v1/customers/{id}/addresses/{address_id}DELETE |
O que muda ao pagar com um cartão salvo:
| Payments API | Orders API |
"payer.type": "customer"/ "payer.id": "<customer_id>" / token (gerado apenas com o código de segurança) | "payer.customer_id": "<customer_id>" / transactions.payments[].payment_method.token |
| /v1/paymentsPOST | /v1/ordersPOST |
Na Payments API, integrações de marketplace usam OAuth para obter o Access Token do vendedor conectado e enviam o campo application_fee, com o valor retido pelo integrador, no corpo da criação do pagamento.
application_fee documentado. O nó integration_data.sponsor.id existe, mas não substitui a mecânica de retenção de comissão. Se a sua integração depende de Split de Pagamentos 1:1 ou Marketplace, valide esse ponto antes de migrar esse fluxo específico e não assuma paridade.A autenticação 3D Secure 2.0 passa de um campo simples para um nó de configuração dedicado em config.online.transaction_security, com controle explícito de responsabilidade por contestação.
| Payments API | Orders API | Descrição |
"three_d_secure_mode": "optional" | "config.online.transaction_security.validation": "on_fraud_risk" | Executa o 3DS quando o motor de risco identificar necessidade. Recomendado. |
"three_d_secure_mode": "not_supported" | config.online.transaction_security.validation: "never" | Desativa o 3DS explicitamente. É o valor padrão. |
| Não existe | config.online.transaction_security.liability_shift: "required" | Transfere ao emissor a responsabilidade por contestação. Obrigatório quando validation for diferente de never. |
Resposta com desafio: "status": "pending", campos creq e external_resource_url. | Resposta com desafio: "status = action_required", "status_detail" = "pending_challenge" e URL em transactions.payments[].payment_method.transaction_security.url. | Renomeado e reestruturado. |
| Tempo limite do desafio não documentado | Tempo limite do desafio de 40 minutos. | Prazo definido explicitamente. |
Restrição: "capture": "true" e "binary_mode": "false" obrigatórios. | Sem restrições equivalentes documentadas. | Confirme o comportamento com capture_mode diferente de automatic em ambiente de teste. |
Status possíveis após o fluxo de 3DS na Orders API:
status | status_detail | Descrição |
processed | accredited | Aprovado, com ou sem autenticação. |
failed | failed | Recusado, sem autenticação ou com falha nela. |
action_required | pending_challenge | Pendente de autenticação, por até 40 minutos. |
canceled | expired | O desafio expirou. É necessário criar uma nova order. |
cardholder_name usados para simular cada cenário diferem entre as duas APIs, então utilize a tabela específica da Orders API. Para mais informações sobre esse fluxo, acesse Integrar 3DS.O mecanismo de assinatura e validação HMAC-SHA256 é idêntico entre as duas APIs. O que muda é o tópico de notificação e a origem da configuração.
| Payments API | Orders API | Observação |
Tópico payment | Tópico orders | Principal mudança. Reconfigure o Webhook para o novo tópico. |
Configurável via notification_url no body ou no painel. | Configurável apenas no painel, em Suas integrações | Eliminada a opção de configurar por requisição. |
| Recurso a consultar: /v1/payments/{id}GET. | Recurso a consultar: /v1/orders/{id}GET. | O endpoint muda. |
| IPN disponível e sem validação de assinatura. | Não disponível. | Utilize exclusivamente Webhooks na nova integração. |
| Prazo de resposta de 22 segundos e com reenvio a cada 15 minutos. | Prazo de resposta de 22 segundos e com reenvio a cada 15 minutos. | Sem alteração. |
O endpoint de consulta de contestação /v1/chargebacks/{id}GET é idêntico entre as duas APIs. A diferença está no evento de notificação e nos novos campos expostos diretamente na order.
| Payments API | Orders API | Observação |
Notificação via tópico topic_chargebacks_wh | Notificação pelo evento Contestações, no tópico chargebacks, com "action": "order.charged_back". | Configure esse evento além de Order (Mercado Pago). |
Status do pagamento: charged_back | Status da order e da transação: charged_back, com "status_detail": "in_process", "settled" ou "reimbursed". | Detalhamento adicional de status_detail. |
| Consulta via /v1/chargebacks/{id}GET. | Consulta via /v1/chargebacks/{id}GET. | Sem alteração. |
payment_id, /v1/chargebacks/{id}/documentationPOST para enviar a documentação comprobatória; e /v1/chargebacks/documentation/{type}/{uuid}GET para recuperar um arquivo já enviado.Os campos de resolução são idênticos nas duas APIs.
| Campo | Valor | Descrição |
coverage_applied | true | Decisão a favor do vendedor. O valor é devolvido a ele. |
coverage_applied | false | Decisão contra o vendedor. O valor é descontado dele. |
As boas práticas de prevenção à fraude permanecem conceitualmente iguais. O que muda é onde os dados adicionais são enviados no corpo da requisição.
| Prática | Payments API | Orders API |
| Device ID | Script de segurança e header X-meli-session-id no /v1/paymentsPOST | /v1/ordersPOST (mesmo mecanismo) |
| Dados adicionais do comprador e do produto | additional_info.{items[], payer, shipments} | Distribuídos entre items[] / payer / shipment (sem o nó additional_info consolidado) |
| Texto identificável na fatura | statement_descriptor (no nível raiz) | transactions.payments[].payment_method.statement_descriptor |
| Dados de indústria | additional_info.travel.{passengers, routes} | Os dados são enviados na estrutura da order. Consulte Dados de indústria; os exemplos, incluindo category_id, não formam uma lista fechada de valores. |
O uso de credenciais, usuários e cartões de teste segue o mesmo conceito. A principal diferença está no e-mail exigido para o pagador e na tabela de nomes de titular usada para simular cada cenário.
| Item | Payments API | Orders API |
| E-mail de teste com cartão | Padrão de usuário de teste | test@testuser.com (o único aceito) |
| E-mail de teste com Pix e boleto | Padrão de usuário de teste | test_user_br@testuser.com |
| Simulação de cenários pelo nome do titular | APRO / OTHE / CONT / CALL / FUND / SECU / EXPI / FORM | CARD / INST / DUPL / LOCK / CTNA / ATTE / BLAC / UNSU / TEST (conjunto ampliado) |
| Verificação do resultado | /v1/payments/{id}GET | /v1/orders/{id}GET |
cardholder_name da Orders API, acesse Cartões de teste. Para mais detalhes sobre o fluxo, acesse Testar a integração.A avaliação da Orders API considera os seguintes aspectos para medir a qualidade da integração migrada.
| Aspecto avaliado | Payments API | Orders API |
| Uso do SDK oficial na tokenização | Avaliado | Avaliado |
| Device ID | Avaliado | Avaliado |
Tratamento de status e status_detail | Avaliado | Avaliado (incluindo o nível de transação) |
Uso da X-Idempotency-Key | Avaliado (apenas na criação e no reembolso) | Avaliado (em todas as operações de escrita) |
| Conciliação com múltiplas transações | Não aplicável | Avaliado |
| Uso de 3DS quando aplicável | Não avaliado | Avaliado |
Antes de subir em produção, confirme os seguintes pontos:
- Ativar as credenciais de produção em Suas integrações.
- Substituir a Public Key e o Access Token de teste pelos de produção.
- Implementar certificado SSL/HTTPS, obrigatório em produção.
- Reconfigurar o Webhook para o tópico
orders. Desative o tópicopaymentapenas depois de migrar o tráfego novo e concluir o monitoramento das transações e notificações pendentes da Payments API. - Garantir o tratamento de todos os valores de
statusestatus_detailnos dois níveis, order e transação.
Depois de aplicar as mudanças, verifique se a integração funciona corretamente em todos os fluxos antes de ir para produção. Use os checkboxes abaixo para confirmar cada ponto.