Cómo migrar de la API de Intención de Pago a la API de Orders
La API de Orders unifica el procesamiento de pagos presenciales en Mercado Pago Point, ofreciendo endpoints estandarizados, un modelo de status más completo y nuevos recursos nativos que no existían en la API de Intención de Pago. Además, todas las nuevas funcionalidades de Mercado Pago se desarrollarán sobre la API de Orders.
La migración de la integración de Mercado Pago Point de la API de Intención de Pago a la API de Orders implica la actualización de endpoints y campos de la solicitud, la adaptación del modelo de status y el aprovechamiento de nuevos recursos nativos. La nueva API incorpora status autocontenidos, validez configurable de la order (expiration_time) y endpoint dedicado de reembolso. La migración no implica cambios en el flujo de negocio: la terminal sigue recibiendo las orders creadas por el backend y procesando los pagos de forma autónoma.
A continuación, te explicamos cómo realizar esta migración de forma completa.
Mapear los cambios de endpoint
Antes de iniciar los pasos de migración, consulta la tabla a continuación para tener una visión general de todos los cambios de endpoint. En la API de Intención de Pago, cada operación utilizaba una estructura de URL propia con el identificador del dispositivo en el path. La API de Orders consolida estas operaciones en endpoints estandarizados y elimina el {deviceid} del path en todas las operaciones.
| Operación | API de Intención de Pago | API de Orders |
| Listar terminales | GET /point/integration-api/devicesAPI | GET /terminals/v1/listAPI |
| Actualizar modo de operación de la terminal | PATCH /point/integration-api/devices/{device_id}API | PATCH /terminals/v1/setupAPI |
| Crear intención de pago vs. Crear order | POST /point/integration-api/devices/{deviceid}/payment-intentsAPI | POST /v1/ordersAPI |
| Obtener intención de pago vs. Obtener order | GET /point/integration-api/payment-intents/{paymentintentid}API | GET /v1/orders/{orderid}API |
| Cancelar intención de pago vs. Cancelar order | DELETE /point/integration-api/devices/{deviceid}/payment-intents/{paymentintentid}API | POST /v1/orders/{orderid}/cancelAPI |
| Reembolsar order | No existe endpoint dedicado | POST /v1/orders/{orderid}/refundAPI |
Adaptar los headers
La API de Orders introduce dos cambios obligatorios de headers que afectan a todos los endpoints: el mecanismo de sandbox fue eliminado y un nuevo control de idempotencia fue introducido. Aplica los cambios a continuación antes de probar cualquier otro recurso.
El header x-test-scope: sandbox era utilizado en la API de Intención de Pago para identificar solicitudes de prueba. En la API de Orders, el mecanismo de sandbox fue reestructurado y ese header ya no existe. Elimínalo de todas las solicitudes de la integración. Para operar en ambiente de prueba en la API de Orders, utiliza usuarios de prueba. Consulta la documentación de pruebas para más información.
El header X-Idempotency-Key es obligatorio en las operaciones de creación, cancelación y reembolso de orders. Garantiza que una solicitud repetida con la misma clave devuelva el resultado original sin procesar la operación nuevamente. Envía un UUID v4 o string aleatorio único por solicitud. Las operaciones de tipo GET no requieren este header.
X-Idempotency-Key con un body diferente, la API devolverá el error idempotency_key_already_used. Genera una clave distinta para cada nueva operación.Actualizar el listado y configuración de terminales
Los endpoints de terminales cambiaron de URL: el listado pasa de GET /point/integration-api/devices a GET /terminals/v1/list y la actualización de modo pasa de PATCH /point/integration-api/devices/{device_id} a PATCH /terminals/v1/setup. En la actualización de modo, el identificador de la terminal también deja el path y pasa al body, lo que permite actualizar múltiples terminales en una única llamada.
En la API de Intención de Pago, los dispositivos eran devueltos en el array devices. En la API de Orders, pasan a data.terminals. Los query params store_id, pos_id, limit y offset se mantienen iguales. La tabla a continuación describe los cambios en la respuesta.
| API de Intención de Pago | API de Orders | Descripción | Cambio |
devices[] | data.terminals[] | Lista de terminales asociadas a la cuenta. En la API de Intención de Pago, era devuelto como array directo en devices. En la API de Orders, es movido dentro del objeto data y renombrado a terminals. | Renombrado y movido dentro del objeto data. |
devices[].id | data.terminals[].id | Identificador único de la terminal. Los últimos caracteres coinciden con el serial en la etiqueta trasera de la terminal. | Mismo concepto. El formato del ID puede variar según el modelo de la terminal. |
devices[].pos_id | data.terminals[].pos_id | Identificador de la caja asociada a la terminal. | Sin cambios. |
devices[].store_id (integer) | data.terminals[].store_id (string) | Identificador de la sucursal asociada a la terminal. En la API de Intención de Pago, era devuelto como entero. En la API de Orders, es devuelto como string. | Cambia de integer a string. |
devices[].external_pos_id | data.terminals[].external_pos_id | Identificador externo de caja, definido por el integrador. | Sin cambios. |
devices[].operating_mode | data.terminals[].operating_mode | Modo de operación de la terminal. En la API de Intención de Pago, los valores posibles son PDV y STANDALONE. En la API de Orders, el valor UNDEFINED es añadido para configuraciones no reconocidas. | Incorpora el valor UNDEFINED para configuración no reconocida. |
paging.total / paging.offset / paging.limit | paging.total / paging.offset / paging.limit | Datos de paginación del listado: total de registros, punto de inicio y límite. | Sin cambios. |
En el listado de terminales, los errores fueron agrupados según el tipo de cambio. Consulta las tablas a continuación para más detalles.
Errores no documentados en la API de Orders
Los siguientes errores existen en la API de Intención de Pago pero no están documentados en la API de Orders.
| HTTP | API de Intención de Pago | Observación |
400 | bad_request | Parámetro obligatorio ausente o con formato incorrecto. |
400 | bad_request | Formato de solicitud inválido. |
403 | forbidden | Presente en la API de Intención de Pago. |
Errores que permanecen igual
Los siguientes errores tienen el mismo comportamiento en ambas APIs.
| HTTP | Error | Observación |
401 | unauthorized | Token inválido o expirado. |
500 | internal_error | Error interno. Verificar el retorno y reintentar. |
En la API de Intención de Pago, solo era posible actualizar una terminal por llamada y su identificador se enviaba en el path. En la API de Orders, el identificador migra al body dentro del array terminals[], lo que permite actualizar múltiples terminales en una única llamada.
A continuación, un ejemplo comparativo de actualización de modo de operación.
Actualización del modo de operación vía API de Intención de Pago. El identificador de la terminal se envía como path param.
curlcurl -X PATCH \ 'https://api.mercadopago.com/point/integration-api/devices/{{DEVICE_ID}}' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \ -d '{ "operating_mode": "PDV" }'
En la API de Intención de Pago, la respuesta devuelve solo el campo operating_mode. En la API de Orders, la respuesta devuelve el array terminals[] con id y operating_mode, identificando cada terminal actualizada. Consulta la tabla a continuación para el mapeo completo.
| API de Intención de Pago | API de Orders | Descripción | Cambio |
operating_mode | terminals[].operating_mode | Modo de operación definido para la terminal. En la API de Intención de Pago, era devuelto como campo único. En la API de Orders, es devuelto dentro del array terminals[]. Los valores posibles son PDV y STANDALONE. | Pasa al interior del array terminals[]. |
La API de Orders también introduce el siguiente campo sin equivalente en la API de Intención de Pago.
| Campo | Descripción |
terminals[].id | Identificador único de la terminal actualizada. Es devuelto solo en la API de Orders. |
En la actualización del modo de operación, los errores fueron agrupados según el tipo de cambio. Consulta las tablas a continuación para más detalles.
Errores que desaparecen
El siguiente error existe en la API de Intención de Pago pero fue eliminado en la API de Orders.
| HTTP | API de Intención de Pago | Observación |
424 | failed_dependency | Código eliminado en la API de Orders. |
Errores renombrados
El siguiente error fue renombrado en la API de Orders.
| HTTP | API de Intención de Pago | API de Orders | Observación |
403 | forbidden | store_pos_not_found | Terminal sin sucursal o caja asociada. |
Errores que cambian de comportamiento
El siguiente error existe en ambas APIs pero con un significado diferente en la API de Orders.
| HTTP | API de Intención de Pago | API de Orders | Observación |
400 | bad_request | property_value | device_id u operating_mode con valor inválido. |
Errores que permanecen igual
Los siguientes errores tienen el mismo comportamiento en ambas APIs.
| HTTP | Error | Observación |
401 | unauthorized | Token inválido o expirado. |
500 | internal_error | Error interno. Reintentar la solicitud. |
Errores introducidos por la API de Orders
Los siguientes errores no tienen equivalente en la API de Intención de Pago.
| HTTP | Error | Observación |
400 | unsupported_site | Site inválido. |
400 | required_properties | Propiedad obligatoria ausente. |
400 | unsupported_properties | Campo no soportado enviado. |
400 | invalid_payload | Payload inválido. Verificar los campos enviados. |
403 | terminal_not_allowed_action | Acción no permitida para este modelo de terminal. |
404 | not_found | Recurso no encontrado o ID inválido. |
412 | (sin código string) | Operación no permitida: ya existe una terminal asociada a la caja en modo PDV. Solo se permite una terminal por caja en modo PDV. |
Migrar la creación de intenciones de pago a la creación de orders
El endpoint de creación cambia de POST /point/integration-api/devices/{deviceid}/payment-intents a POST /v1/orders. Además del cambio de URL, la estructura de la solicitud fue significativamente reorganizada: el identificador de la terminal deja el path y pasa al body, se introdujeron nuevos campos obligatorios y la API de Orders posee una estructura distinta. Sigue los pasos a continuación para adaptar la solicitud, la respuesta y el tratamiento de errores.
curlcurl -X POST \ 'https://api.mercadopago.com/v1/orders' \ -H 'Content-Type: application/json' \ -H 'X-Idempotency-Key: {{IDEMPOTENCY_KEY}}' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \ -d '{ "type": "point", "external_reference": "ext_ref_1234", "transactions": { "payments": [ { "amount": "24.00" } ] }, "config": { "point": { "terminal_id": "{{TERMINAL_ID}}", "print_on_terminal": "no_ticket" } }, "description": "Point Smart 2" }'
La API de Orders posee una estructura distinta a la de Intención de Pago: el identificador de la terminal debe enviarse en el body, los campos de configuración de pago e impresión se ubican en nuevos nodos, y los headers de identificación forman parte del body. Los nuevos campos obligatorios son type (con valor "point") y external_reference. Consulta la tabla a continuación para el mapeo completo de campos.
A continuación, un ejemplo comparativo entre la creación de una intención de pago y la creación de una order, seguido de la tabla de mapeo completo de campos.
Solicitud para crear una intención de pago. El identificador de la terminal se envía como path param y el amount es un valor entero.
curlcurl -X POST \ 'https://api.mercadopago.com/point/integration-api/devices/{{DEVICE_ID}}/payment-intents' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \ -H 'x-test-scope: sandbox' \ -d '{ "amount": 1500, "additional_info": { "external_reference": "order-ref-001", "print_on_terminal": true }, "description": "Producto de prueba" }'
| API de Intención de Pago | API de Orders | Descripción | Cambio |
{deviceid} (path param) | config.point.terminal_id | Identifica la terminal que recibirá la order. En la API de Intención de Pago, se envía en el path. En la API de Orders, se envía en el body con el formato {tipo_terminal}__{serial_terminal}. | Pasa de path param a campo en el body. |
amount (integer) | transactions.payments[].amount (string) | Monto a cobrar. En la API de Intención de Pago, se representa como entero con dos decimales implícitos (ej.: 1500 para $15,00). En la API de Orders, se representa como string dentro del array transactions.payments. Acepta dos decimales (ej.: "15.00") o ninguno. Solo se permite 1 transacción por order cuando type es point. | Cambia de entero a string y pasa al array transactions.payments. |
additional_info.external_reference | external_reference | Identificador alfanumérico de la transacción en el sistema del integrador, devuelto en las notificaciones de webhook. En la API de Orders, es obligatorio, con un máximo de 64 caracteres, solo letras, números, - y _. Debe ser único por order y no puede contener datos PII. | Sube al nivel raíz y pasa a ser obligatorio. |
additional_info.print_on_terminal (boolean) | config.point.print_on_terminal (string) | Controla la impresión del ticket en la terminal. En la API de Intención de Pago, acepta los valores booleanos true y false. En la API de Orders, acepta los valores seller_ticket (imprime) y no_ticket (no imprime). Valor por defecto: seller_ticket. | Cambia de booleano a enum string. |
payment.type | config.payment_method.default_type | Define el medio de pago aceptado por la terminal. En la API de Intención de Pago, los valores posibles son credit_card, debit_card. En la API de Orders, los valores posibles son credit_card, debit_card y qr. Si no se envía, la terminal acepta todos los medios de pago. | Cambia de nodo y pasa a aceptar también qr. |
description | description | Describe el producto, servicio o motivo del pago. En la API de Orders, acepta hasta 150 caracteres. | Sin cambios. |
X-platform-id (header) | integration_data.platform_id | Identifica la plataforma de la integración, asignado por Mercado Pago. En la API de Intención de Pago, se enviaba como header. En la API de Orders, se envía en el body dentro de integration_data. | Deja de ser header y pasa al body. |
X-integrator-id (header) | integration_data.integrator_id | Identifica al integrador de la integración, asignado por Mercado Pago. En la API de Intención de Pago, se enviaba como header. En la API de Orders, se envía en el body dentro de integration_data. | Deja de ser header y pasa al body. |
additional_info.ticket_number | config.point.ticket_number | Valor alfanumérico para identificar el número de factura o ticket, impreso en la terminal cuando la impresión está habilitada. | Pasa a config.point. |
La API de Orders también introduce los siguientes campos sin equivalente en la API de Intención de Pago.
| Campo | Descripción |
integration_data.sponsor.id | USER_ID de la cuenta de Mercado Pago del sistema integrador. |
type | Tipo de order. Para Point, el único valor aceptado es "point". Obligatorio. |
expiration_time | Define el tiempo de validez de la order desde su creación, en formato ISO 8601. El valor mínimo es PT30S (30 segundos), el valor máximo es PT3H (3 horas) y el valor por defecto es PT15M (15 minutos). Ejemplos: PT30S para 30 segundos, PT10M para 10 minutos, PT1H15M para 1 hora y 15 minutos. Si la order expira sin ser procesada, se cancela automáticamente. Opcional. |
El formato del ID de la order cambia de UUID (ej.: 7f25f9aa-eea6-...) a alfanumérico (ej.: ORD00001111222233334444555566). Actualiza cualquier lógica de almacenamiento o consulta que dependa del formato del ID antes de continuar.
La tabla a continuación presenta los campos de la respuesta de creación que existían en ambas APIs y sufrieron cambios en la migración.
| API de Intención de Pago | API de Orders | Descripción | Cambio |
id (UUID) | id (alfanumérico) | Identificador de la order creada, generado por Mercado Pago. En la API de Intención de Pago, se devuelve en formato UUID. En la API de Orders, se devuelve en formato alfanumérico con prefijo ORD. | El formato del ID cambia a ORD.... |
device_id | config.point.terminal_id | Identificador de la terminal que recibió la order. | Pasa a config.point. |
amount (integer) | transactions.payments[].amount (string) | Valor del pago. En la API de Intención de Pago, se devuelve como entero. En la API de Orders, se devuelve como string decimal dentro del array de pagos. | Pasa al array de pagos. |
additional_info.external_reference | external_reference | Referencia externa de la order en el sistema del integrador. | Sube al nivel raíz. |
additional_info.print_on_terminal (boolean) | config.point.print_on_terminal (string) | Indica si la terminal imprimió el ticket. En la API de Intención de Pago, se devuelve como booleano. En la API de Orders, se devuelve como enum string: seller_ticket o no_ticket. | Cambia de booleano a enum string. |
additional_info.ticket_number | config.point.ticket_number | Valor alfanumérico para identificar el número de factura o ticket, impreso en la terminal cuando la impresión está habilitada. | Pasa a config.point. |
La API de Orders también introduce los siguientes campos sin equivalente en la API de Intención de Pago.
| Campo | Descripción |
status | Estado actual de la order. Al crear: created. |
status_detail | Detalle del estado de la order. Al crear: created. |
type | Tipo de order. Para Point: siempre point. |
expiration_time | Tiempo de validez de la order en formato ISO 8601. Si la order expira sin ser procesada, se cancela automáticamente. |
created_date / last_updated_date | Registra las fechas de creación y última actualización de la order en formato yyyy-MM-ddTHH:mm:ss.sssZ. |
transactions.payments[].id | Identificador de la transacción de pago, generado por Mercado Pago. Necesario para reembolsos parciales. |
transactions.payments[].status | Estado de la transacción de pago. Al crear: created. |
user_id | Identificador del usuario de Mercado Pago que creó la order. |
processing_mode | Modo de procesamiento de la order. Para Point: siempre automatic. |
country_code | Identificador del site/país de la aplicación. |
integration_data.application_id | Identificador de la aplicación de Mercado Pago. |
integration_data.platform_id | Identificador de la plataforma, asignado por Mercado Pago. |
integration_data.integrator_id | Identificador del integrador, asignado por Mercado Pago. |
integration_data.sponsor.id | USER_ID del sistema integrador. |
En la creación, los errores fueron agrupados según el tipo de cambio. Consulta las tablas a continuación para más detalles.
Errores que cambian de comportamiento
En la API de Intención de Pago, los siguientes errores devolvían el código genérico bad_request. En la API de Orders, son reemplazados por códigos específicos.
| HTTP | API de Intención de Pago | API de Orders | Observación |
400 | bad_request | required_properties | Propiedad obligatoria ausente. |
400 | bad_request | property_value | Valor inválido en una propiedad. |
400 | bad_request | property_type | Tipo incorrecto. Por ejemplo: integer en vez de string. |
400 | bad_request | json_syntax_error | JSON inválido. |
400 | bad_request | unsupported_properties | Propiedad no soportada enviada. |
Errores renombrados
Los siguientes errores fueron renombrados en la API de Orders.
| HTTP | API de Intención de Pago | API de Orders | Observación |
403 | forbidden | forbidden_checking_terminal_owner | Terminal no vinculada a la cuenta. |
409 | conflict_error | already_queued_order_for_terminal | Ya existe una order en espera para este terminal. |
Errores que desaparecen
El siguiente error existe en la API de Intención de Pago pero fue eliminado en la API de Orders.
| HTTP | API de Intención de Pago | Observación |
424 | failed_dependency | Código eliminado en la API de Orders. |
Errores que permanecen igual
El siguiente error tiene el mismo comportamiento en ambas APIs.
| HTTP | Error | Observación |
401 | unauthorized | Token inválido o expirado. |
500 | internal_error | Error interno. Verifica el retorno y repite la solicitud. |
Errores introducidos por la API de Orders
Los siguientes errores no tienen equivalente en la API de Intención de Pago.
| HTTP | Error | Observación |
400 | empty_required_header | X-Idempotency-Key ausente. |
400 | minimum_properties | Número mínimo de propiedades obligatorias no enviado. |
400 | minimum_items / maximum_items | Número inválido de ítems en el array transactions.payments. |
409 | idempotency_key_already_used | Clave de idempotencia reutilizada con body diferente. |
500 | idempotency_validation_failed | Falla en la validación de idempotencia. Reintenta la solicitud. |
Actualizar el mecanismo de consulta de Intención de Pago a Orders
El endpoint de consulta cambia de GET /point/integration-api/payment-intents/{paymentintentid}API a GET /v1/orders/{orderid}API. El identificador de la order en el path también cambia de formato UUID a alfanumérico. La respuesta incluye campos nuevos con información sobre el resultado del pago, reembolsos y datos de la tarjeta utilizada.
curlcurl -X GET \ 'https://api.mercadopago.com/v1/orders/{{ORDER_ID}}' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}'
Además de los campos documentados en la respuesta de creación, la respuesta del GET incluye campos adicionales relevantes para la migración. Consulta la tabla a continuación para el detalle.
| API de Intención de Pago | API de Orders | Descripción | Cambio |
state | status | Estado de la order. En la API de Intención de Pago, campo state con valores en mayúsculas. En la API de Orders, campo status con valores en minúsculas y conjunto de estados expandido. | Renombrado. Consulta el mapeo completo en Actualizar el tratamiento de status. |
payment.id (integer) | transactions.payments[].reference_id (string) | Identificador del pago procesado, disponible cuando el flujo se completa con éxito. En la API de Intención de Pago, era devuelto como entero en payment.id. En la API de Orders, es devuelto como string en transactions.payments[].reference_id. | Identificador del pago procesado. Cambia de integer a string. |
La API de Orders también introduce los siguientes campos sin equivalente en la API de Intención de Pago.
| Campo | Descripción |
status_detail | Detalle del estado de la order. Valores posibles: accredited, canceled_by_api, bad_filled_card_data, insufficient_amount, entre otros. Consulta la Referencia de API para la lista completa. |
transactions.payments[].paid_amount | Valor efectivamente pagado en la transacción. |
transactions.payments[].refunded_amount | Valor reembolsado en la transacción. |
transactions.payments[].status | Estado de la transacción de pago. |
transactions.payments[].status_detail | Detalle del estado de la transacción. Mismos valores posibles de status_detail de la order. |
transactions.payments[].payment_method.type | Medio de pago utilizado en la transacción (ej.: credit_card, debit_card). |
transactions.payments[].payment_method.installments | Cantidad de cuotas seleccionada en la transacción. |
transactions.payments[].payment_method.id | Identificador del medio de pago o marca de tarjeta. Consulta en GET /v1/payment_methodsAPI. |
transactions.payments[].card.first_digits / last_digits | Primeros y últimos dígitos de la tarjeta utilizada en la transacción, disponibles cuando el pago se realizó con tarjeta. |
transactions.refunds[] | Array con los datos de los reembolsos realizados en la order (id, transaction_id, reference_id, amount, status). |
En la consulta, los errores fueron agrupados según el tipo de cambio. Consulta las tablas a continuación para más detalles.
Errores que desaparecen
Los siguientes errores existen en la API de Intención de Pago pero no tienen equivalente en la API de Orders.
| HTTP | API de Intención de Pago | Observación |
401 | unauthorized (Unauthorized use of live credentials) | El header x-test-scope fue eliminado en la API de Orders. |
403 | forbidden | La validación de propiedad de la terminal ocurre solo en la creación. |
429 | too_many_requests | Presente en la API de Intención de Pago. No documentado en la API de Orders. |
Errores renombrados
El siguiente error fue renombrado en la API de Orders.
| HTTP | API de Intención de Pago | API de Orders | Observación |
404 | not_found | order_not_found | Order no encontrada. Verificar si el ID enviado es correcto. |
Errores que cambian de comportamiento
El siguiente error existe en ambas APIs pero con un significado diferente en la API de Orders.
| HTTP | API de Intención de Pago | API de Orders | Observación |
400 | bad_request | bad_request | Formato del order_id inválido. El ID cambia de UUID a alfanumérico. |
Errores que permanecen igual
Los siguientes errores tienen el mismo comportamiento en ambas APIs.
| HTTP | Error | Observación |
401 | unauthorized | Token inválido o expirado. |
500 | internal_error | Error interno. Reintentar la solicitud. |
Actualizar el tratamiento de status
Uno de los cambios más significativos entre la API de Intención de Pago y la API de Orders es el del campo state, que pasa a llamarse status en la nueva API y recibe nuevos valores. En la API de Intención de Pago, el estado FINISHED requería llamadas adicionales para determinar el resultado real del pago. En la API de Orders, los status processed y failed son autocontenidos y eliminan esa necesidad. Actualiza todas las verificaciones de status de la integración conforme a la tabla a continuación.
API de Intención de Pago (state) | API de Orders (status) | Observación |
OPEN | created | Renombrado |
ON_TERMINAL | at_terminal | Renombrado |
PROCESSING | Absorbido | No hay estado intermedio en la API de Orders |
PROCESSED | Absorbido | No hay estado intermedio en la API de Orders |
FINISHED (pago aprobado) | processed | El resultado del pago aprobado está contenido en la propia order, sin necesidad de consultas adicionales. |
FINISHED (pago rechazado) | failed | El resultado del pago rechazado está contenido en la propia order, sin necesidad de consultas adicionales. |
CONFIRMATION_REQUIRED | action_required | Renombrado |
ERROR | failed | Renombrado |
ABANDONED | expired | Renombrado (basado en timeout) |
CANCELED | canceled | Mismo significado. Ahora en minúsculas |
| No existe | refunded | Nuevo status. Debe tratarse explícitamente en todos los flujos |
En la API de Intención de Pago, para confirmar el resultado de un pago con state: FINISHED, era necesario inspeccionar payment.state en el webhook, llamar a GET /v1/payments/{id} o buscar por external_reference. En la API de Orders, los status processed y failed son autocontenidos: el resultado del pago está disponible directamente en la order, sin consultas adicionales.
Actualizar el tópico de notificaciones de webhook
En la API de Intención de Pago, las notificaciones se enviaban con el tópico point_integration_wh. En la API de Orders, pasan al tópico Order (Mercado Pago) (orders).
Antes de ir a producción, actualiza la configuración de tu aplicación en Tus integraciones. Para ello, selecciona el tópico "Order (Mercado Pago)" y desactiva el tópico point_integration_wh. Para más información, consulta la documentación Configurar notificaciones.
Actualizar la cancelación de orders
El nuevo endpoint para cancelar una order es POST /v1/orders/{orderid}/cancel, reemplazando el DELETE de la API de Intención de Pago. El {deviceid} desaparece del path y la cancelación pasa a identificarse únicamente por el {orderid}.
Con la API de Intención de Pago, solo era posible cancelar intenciones de pago que aún no habían llegado a la terminal. En la API de Orders, es posible cancelar una order incluso después de que haya llegado a la terminal, mediante un nuevo header específico.
curlcurl -X POST \ 'https://api.mercadopago.com/v1/orders/{{ORDER_ID}}/cancel' \ -H 'Content-Type: application/json' \ -H 'X-Idempotency-Key: {{IDEMPOTENCY_KEY}}' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}'
La respuesta pasa a devolver el objeto completo de la order con status: "canceled", en lugar de solo el id. Los headers necesarios en esta operación son:
| Header | Obligatoriedad | Descripción |
X-Idempotency-Key | Obligatorio | Clave única por solicitud |
x-allow-cancelable-status | Condicional | Obligatorio para cancelar orders en at_terminal. Valor: "at_terminal" |
Para cancelar orders en status at_terminal, envía el header x-allow-cancelable-status: at_terminal. Sin este header, solo se cancelarán orders con status: created.
En la cancelación, los errores fueron agrupados según el tipo de cambio. Consulta las tablas a continuación para más detalles.
Errores que desaparecen
Los siguientes errores existen en la API de Intención de Pago pero no tienen equivalente en la API de Orders.
| HTTP | API de Intención de Pago | Observación |
400 | bad_request (deviceID format) | deviceid fue eliminado del path en la API de Orders. |
429 | too_many_requests | Presente en la API de Intención de Pago. No documentado en la API de Orders. |
Errores renombrados
El siguiente error fue renombrado en la API de Orders.
| HTTP | API de Intención de Pago | API de Orders | Observación |
409 | conflict_error | cannot_cancel_order | El estado de la order no permite la cancelación. Para at_terminal, enviar x-allow-cancelable-status: at_terminal. |
Errores que cambian de comportamiento
Los siguientes errores existen en ambas APIs pero con comportamiento diferente en la API de Orders.
| HTTP | API de Intención de Pago | API de Orders | Observación |
400 | bad_request | bad_request | Formato del order_id inválido. El ID cambia de UUID a alfanumérico. |
404 | 101 | order_not_found | Order no encontrada. En la API de Intención de Pago, el campo error usa el código numérico "101". |
409 | 101 | order_already_canceled | En la API de Intención de Pago, order inexistente y order ya cancelada devolvían el mismo error "101". En la API de Orders se diferencian en dos errores distintos: 404 para order no encontrada y 409 para order ya cancelada. |
500 | internal_error | idempotency_validation_failed | Falla en la validación de idempotencia. Reintentar la solicitud. |
Errores que permanecen igual
El siguiente error tiene el mismo comportamiento en ambas APIs.
| HTTP | Error | Observación |
401 | unauthorized | Token inválido o expirado. |
Errores introducidos por la API de Orders
Los siguientes errores no tienen equivalente en la API de Intención de Pago.
| HTTP | Error | Observación |
400 | empty_required_header | X-Idempotency-Key ausente. |
409 | idempotency_key_already_used | Clave de idempotencia reutilizada. |
Implementar reembolsos con el endpoint dedicado
La API de Orders introduce el endpoint dedicado POST /v1/orders/{orderid}/refund para reembolsos, que no existía en la API de Intención de Pago. Antes, era necesario recibir el webhook del pago, obtener el payment_id y ejecutar el reembolso a través de la API de Payments por separado. Ahora, el reembolso se realiza directamente sobre la order.
Elige entre reembolso total o parcial de acuerdo con el valor a devolver.
Para reembolsar el valor total de la order, envía la solicitud al endpoint POST /v1/orders/{orderid}/refundAPI sin body.
curlcurl -X POST \ 'https://api.mercadopago.com/v1/orders/{{ORDER_ID}}/refund' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}' \ -H 'X-Idempotency-Key: {{IDEMPOTENCY_KEY}}'
Los reembolsos se aceptan hasta 90 días a partir de la fecha del pago.
La respuesta del reembolso varía según el tipo de operación realizada.
| Campo | Tipo | Descripción |
id | string | Identificador de la order reembolsada |
status | string | refunded para reembolso total. processed para reembolso parcial (aún hay saldo disponible) |
status_detail | string | refunded para reembolso total. partially_refunded para reembolso parcial |
transactions.refunds[].id | string | Identificador del reembolso, generado por Mercado Pago |
transactions.refunds[].transaction_id | string | Identificador de la transacción de pago que está siendo reembolsada |
transactions.refunds[].reference_id | string | Identificador que asocia el pago y su respectivo reembolso |
transactions.refunds[].amount | string | Valor del reembolso |
transactions.refunds[].status | string | processing cuando el reembolso total fue solicitado y está en procesamiento. processed cuando el reembolso parcial fue concluido con éxito |
Validar la migración
Después de aplicar los cambios, verifica que la integración funcione correctamente en todos los flujos antes de ir a producción.
El header x-test-scope fue eliminado de todas las solicitudes de la integración.
El header X-Idempotency-Key debe estar presente en todas las operaciones de creación, cancelación y reembolso.
Terminales listadas con el endpoint GET /terminals/v1/listAPI y modo de operación actualizado con PATCH /terminals/v1/setupAPI.
Orders creadas correctamente con el nuevo payload en el endpoint POST /v1/ordersAPI y recibidas en la terminal.
Orders consultadas correctamente a través del endpoint GET /v1/orders/{orderid}API.
Tópico "Order (Mercado Pago)" (orders) configurado en Tus integraciones sustituyendo point_integration_wh, y status de orders monitoreados con los nuevos valores: created, at_terminal, processed, failed, canceled y refunded.
Orders canceladas correctamente a través del endpoint POST /v1/orders/{orderid}/cancelAPI.
Reembolsos realizados a través del endpoint dedicado POST /v1/orders/{orderid}/refundAPI.
Accede a la documentación para saber cómo probar la integración.