Cómo migrar de la Instore Orders API a la Orders API
La migración de la Instore Orders API a la Orders API implica la actualización de endpoints y campos de la solicitud, la consolidación del modelo de notificaciones y el aprovechamiento de nuevos recursos nativos que no existían antes: endpoints dedicados de consulta por order_id, cancelación y reembolso.
La migración no implica cambios en el flujo de negocio: el cliente sigue escaneando el Código QR con la aplicación de Mercado Pago y confirmando el pago. Además, en esta modalidad, la Orders API habilita retiro de dinero (extracash y cash-out), descuentos por medio de pago, descuentos por categoría y cuotas sin interés. Para más detalles, consulta la documentación de procesamiento de transacciones.
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 Instore Orders API, cada operación utilizaba una URL con el identificador del usuario y de la caja en el path. La Orders API consolida estas operaciones en endpoints estandarizados e introduce recursos que no existían antes.
| Operación | Instore Orders API | Orders API |
| Crear order | POST /mpmobile/instore/qr/{user_id}/{external_id}API | POST /v1/ordersAPI |
| Consultar order | No existía endpoint dedicado | GET /v1/orders/{order_id}API |
| Cancelar order | DELETE /mpmobile/instore/qr/{user_id}/{external_id}API | POST /v1/orders/{order_id}/cancelAPI |
| Reembolsar order | Vía API de Payments (sin endpoint dedicado en la Instore Orders API) | POST /v1/orders/{order_id}/refundAPI |
En la Instore Orders API, existían dos endpoints válidos para la creación y cancelación: POST /mpmobile/instore/qr/{user_id}/{external_id}API, usando el identificador externo de la caja, y /mpmobile/instore/qr/{pos_id}, usando el identificador interno. Ambos migran al mismo endpoint en la Orders API: POST /v1/ordersAPI, donde la caja se identifica por el campo config.qr.external_pos_id en el body.
Actualizar el modelo de status y notificaciones
Uno de los cambios más significativos entre la Instore Orders API y la Orders API es el modelo de status. En la Instore Orders API, el estado de una transacción se determinaba mediante el monitoreo de notificaciones de dos tópicos independientes: payments y merchant_orders con campos y valores distintos para cada uno. La Orders API unifica este comportamiento en un único campo status en la order. Consulta el mapeo completo a continuación.
Además, la Orders API también introduce el campo status_detail, que permite identificar con mayor detalle el estado de la transacción. Los valores posibles son created, canceled, accredited, refunded y expired.
En la Instore Orders API, la merchant_order se crea en el momento en que se genera el pedido, por lo que las notificaciones del tópico merchant_orders están disponibles desde el inicio del flujo. El objeto payment, en cambio, solo se crea cuando existe un intento de pago, aprobado o rechazado. Quien monitoreaba únicamente el tópico payments no recibía ninguna notificación hasta que el usuario iniciaba el proceso de pago. En la Orders API, este comportamiento está unificado: el campo status de la order refleja el estado completo desde la creación, sin necesidad de monitorear dos tópicos independientes.
Tópico payments (status) | Tópico merchant_orders (status / order_status) | Orders API (status) | Observación |
| — | opened (sin pago o con pago rechazado) | created | En la Instore Orders API, opened indicaba que el pedido aún no tenía un pago aprobado. En la Orders API, este estado es explícito desde la creación. |
approved | closed + order_status: "paid" | processed | Ambos tópicos convergían en el mismo resultado: pago aprobado. En la Orders API, el estado es autocontenido. |
rejected | opened (la merchant_order no cambia de estado y permanece abierta) | Sin equivalente | En la Instore Orders API, un pago rechazado dejaba la merchant_order en opened a la espera de un nuevo intento. En la Orders API, los pagos rechazados no se exponen y el estado permanece en created hasta recibir un pago aprobado. |
refunded | closed + order_status: "reverted" | refunded | Reembolso total. En el tópico merchant_orders, identificable por order_status: "reverted". |
| — | — | canceled | Nuevo status sin equivalencia en la Instore Orders API. |
| — | — | expired | Nuevo status sin equivalencia en la Instore Orders API. |
En cuanto a las notificaciones, en la API Legacy podían configurarse mediante el campo notification_url en el body de la solicitud (modelo IPN) o mediante webhooks con los tópicos payments y merchant_orders. En la Orders API, el campo notification_url no existe y los tópicos payments y merchant_orders no son compatibles. Configura las notificaciones en Tus integraciones, suscribiéndote al tópico "Order (Mercado Pago)" (orders), antes de ir a producción. Para más información, consulta la documentación de notificaciones.
Adaptar los headers
La Orders API introduce dos cambios obligatorios de headers que afectan a todos los endpoints. El Access Token debe enviarse a través del header Authorization. El envío vía query param no está permitido en la Orders API. Aplica los cambios a continuación antes de probar cualquier otro recurso.
El header X-Ttl-Store-Preference era utilizado en la Instore Orders API para definir el tiempo de validez del pedido en segundos. En la Orders API, esta funcionalidad fue reemplazada por el campo expiration_time en el body de la solicitud, en formato ISO 8601, por ejemplo PT5M para 5 minutos. El valor predeterminado es de 15 minutos y el valor enviado siempre se respeta. Elimina este header de todas las solicitudes y migra el control de validez al campo expiration_time.
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.Migrar la creación de orders
Los endpoints de creación POST /mpmobile/instore/qr/{user_id}/{external_id}API y POST /mpmobile/instore/qr/{pos_id} migran a POST /v1/ordersAPI. Además del cambio de URL, la estructura de la solicitud fue significativamente reorganizada: el identificador del usuario y de la caja dejan el path y pasan al body, se introdujeron nuevos campos obligatorios y la Orders API ofrece tres modos de Código QR configurables a través de config.qr.mode. 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": "qr", "total_amount": "50.00", "external_reference": "ext_ref_1234", "config": { "qr": { "external_pos_id": "STORE001POS001", "mode": "static" } }, "transactions": { "payments": [ { "amount": "50.00" } ] }, "items": [ { "title": "Smartphone", "unit_price": "50.00", "quantity": 1, "unit_measure": "unit" } ] }'
En la Orders API, la identidad del usuario se obtiene directamente del Access Token. El {user_id} deja de ser parámetro de path. La caja pasa a identificarse por el campo config.qr.external_pos_id en el body. Los campos type, con valor "qr", y external_reference pasan a ser obligatorios. La tabla a continuación presenta los campos que existían en ambas APIs y sufrieron cambios en la migración.
| Instore Orders API | Orders API | Descripción | Cambio |
{user_id} (path param) | No existe | Identificador del usuario de Mercado Pago. En la Instore Orders API, se enviaba en el path. En la Orders API, la identidad se obtiene directamente del Access Token. | Deja de ser parámetro de path. |
{external_id} (path param) | config.qr.external_pos_id | Identificador externo de la caja, definido por el integrador. En la Instore Orders API, se enviaba en el path. En la Orders API, se envía en el body dentro de config.qr. | Deja de ser parámetro de path y pasa al body. |
external_reference | external_reference | Referencia que puede sincronizar con el sistema de venta del integrador. En la Orders API, es obligatorio, con un máximo de 64 caracteres, solo letras, números, - y _. No puede contener datos PII. | Pasa a ser obligatorio. |
notification_url | No existe | URL para recibir notificaciones de pago o merchant_order. En la Orders API, las notificaciones se configuran como webhook en tu aplicación dentro de Tus integraciones, seleccionando el tópico "Order (Mercado Pago)". Para más información, accede a la documentación de notificaciones. | Eliminado del body. |
sponsor_id | integration_data.sponsor.id | USER_ID de la cuenta de Mercado Pago del sistema integrador. | Pasa al nodo integration_data.sponsor. |
items[].id | items[].external_code | Identificador del ítem en el sistema externo. | Renombrado a items[].external_code. |
items[].title | items[].title | Nombre del ítem. En la Orders API tiene un máximo de 150 caracteres. | Pasa a ser obligatorio. |
items[].currency_id | No existe | Identificador de la moneda del ítem en formato ISO 4217. En la Orders API, la moneda se determina a partir de la cuenta del vendedor. | Eliminado. |
items[].unit_price | items[].unit_price | Precio unitario del ítem. En la Instore Orders API, era number. En la Orders API, es string decimal. Acepta dos decimales (ej.: "15.00") o ninguno. | Cambia de number a string decimal y pasa a ser obligatorio. |
items[].quantity | items[].quantity | Cantidad de ítems. En la Instore Orders API, era number. En la Orders API, es integer. | Cambia de number a integer y pasa a ser obligatorio. |
items[].description | description | Descripción del ítem o motivo de la order. En la Orders API, la descripción existe solo en el nivel raíz de la order, no dentro de items. Máx. 150 caracteres. No debe contener datos PII. | Se mueve del nivel de ítem al nivel raíz de la order. |
items[].picture_url | No existe | URL de la imagen del ítem. | Eliminado. No tiene equivalente en la Orders API. |
marketplace_fee | marketplace_fee | Valor de la tarifa del marketplace. En la Instore Orders API, era number. En la Orders API, es string decimal. Acepta dos decimales (ej.: "15.00") o ninguno. Exclusivo para integraciones con OAuth. | Cambia de number a string decimal. |
X-Ttl-Store-Preference (header) | expiration_time | Tiempo de validez del pedido. En la Instore Orders API, se definía en segundos a través del header. En la Orders API, se define en formato ISO 8601 (ej.: PT5M para 5 minutos) en el body. Mínimo: 30 segundos. Máximo: 3600 horas. En todos los modos, el valor predeterminado es de 15 minutos y el valor enviado siempre se respeta. | Cambia de header en segundos a campo en el body en formato ISO 8601. |
La Orders API también introduce los siguientes campos sin equivalencia en la Instore Orders API.
| Campo | Descripción |
type | Tipo de order. Para pagos con Código QR, el único valor posible es "qr". Obligatorio. |
total_amount | Valor total de la order. Representa la suma de las transacciones. Si hay retiro de dinero, debe ser la suma del monto de pago y del monto de retiro. Acepta dos decimales (ej.: "15.00") o ninguno. |
config.qr.mode | Modo de Código QR. Los valores posibles son static (Código QR estático asociado a la caja, equivalente al comportamiento de la Instore Orders API), dynamic (Código QR único por transacción, devuelto en type_response.qr_data), hybrid (ambos modos en paralelo). El valor por defecto es static. |
transactions.payments[].amount | Valor del pago dentro del nodo transactions. Acepta dos decimales (ej.: "15.00") o ninguno. Solo 1 transacción de pago por order. |
items[].unit_measure | Unidad de medida del ítem. Máx. 10 caracteres. Obligatorio. |
items[].external_categories[].id | Identificador de categoría del ítem en el sistema externo. Habilita descuentos por categoría. No puede usarse junto con discounts. |
discounts.payment_methods[].new_total_amount | Nuevo valor total de la order cuando se aplica un descuento. Acepta dos decimales (ej.: "15.00") o ninguno. No puede usarse junto con items[].external_categories. |
discounts.payment_methods[].type | Medio de pago al que aplica el descuento. Los valores posibles son debit_card, credit_card, account_money, prepaid_card. Se pueden definir hasta 4 medios. |
integration_data.platform_id | Identificador de la plataforma, asignado por Mercado Pago. |
integration_data.integrator_id | Identificador del integrador, asignado por Mercado Pago. Debe tener el prefijo dev_. |
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.
| Instore Orders API | Orders API | Descripción | Cambio |
id | id | Identificador de la order creada. En la Instore Orders API, el formato era {collector_id}-{uuid}. En la Orders API, es un ID alfanumérico propio (ej.: ORD00001111222233334444555566). | El formato del ID cambia de {collector_id}-{uuid} a ID alfanumérico. |
collector_id | user_id | Identificador del vendedor. En la Instore Orders API, era integer. En la Orders API, es string. | Renombrado de collector_id a user_id. Cambia de integer a string |
collector | No existe | Datos del vendedor. | Eliminado. Los datos del vendedor no se devuelven en la order. |
total_amount | total_amount | Valor total de la order. En la Instore Orders API, era number. En la Orders API, es string decimal. | Cambia de number a string decimal. |
amount | No existe | Valor del pedido. Era siempre igual a total_amount. | Eliminado. En la Orders API, el valor del pago está en transactions.payments[].amount. |
external_reference | external_reference | Referencia externa de la order. | Sin cambios. |
notification_url | No existe | URL configurada para recibir notificaciones. | Eliminado del response. Configura las notificaciones webhook en tu aplicación dentro de Tus integraciones. Para más información, accede a la documentación de notificaciones. |
expiration_date_to | No existe | Fecha y hora de expiración del pedido en formato ISO 8601 absoluto. | Eliminado. En la Orders API, la expiración se configura como duración relativa en expiration_time. |
expires | No existe | Indica si el pedido tiene fecha de expiración. | Eliminado. En la Orders API, la order siempre expira. |
marketplace_fee | marketplace_fee | Tarifa del marketplace. En la Instore Orders API, era number. En la Orders API, es string decimal. | Cambia de number a string decimal. |
sponsor_id | integration_data.sponsor.id | USER_ID del sistema integrador. En la Instore Orders API, era integer. En la Orders API, es string. | Pasa a integration_data.sponsor. Cambia de integer a string. |
site_id | country_code | Identificador del site/país. En la Instore Orders API, el formato era en minúsculas (ej.: "mla"). En la Orders API, es el código del país en mayúsculas (ej.: "AR"). | Renombrado de site_id a country_code. El formato cambia de minúsculas a mayúsculas. |
items[].description | description | Descripción del ítem. | Se mueve del nivel de ítem al nivel raíz de la order. |
items[].id | items[].external_code | Identificador del ítem en el sistema externo. | Renombrado a items[].external_code. |
En la migración a la Orders API, los siguientes campos fueron eliminados y no tienen equivalente directo.
| Campo | Observación |
operation_type | Eliminado. No tiene equivalente en la Orders API. |
payment_methods | Eliminado. Las exclusiones de medios de pago no se devuelven a nivel de order. |
payment_methods.included_payment_types | Eliminado junto con el nodo payment_methods. |
marketplace | Eliminado. No tiene equivalente en la Orders API. |
back_urls | Eliminado. No tiene equivalente en la Orders API. |
payer | Eliminado. Los datos del pagador no se devuelven en el response de creación. |
client_id | Eliminado. Redundante con user_id. |
processing_modes | Eliminado. Reemplazado por el campo processing_mode (string) en la Orders API. |
internal_metadata | Eliminado. Campo de uso interno sin equivalencia en la Orders API. |
items[].currency_id | Eliminado. La moneda se expone a nivel de order en el campo currency. |
items[].picture_url | Eliminado. No tiene equivalente en la Orders API. |
La Orders API también introduce los siguientes campos en el response de creación.
| Campo | Descripción |
type | Tipo de order. Para Código QR: siempre qr. |
description | Descripción del producto o servicio, motivo de la order (en Legacy era items[].description). |
expiration_time | Tiempo de expiración de la order en formato ISO 8601. |
processing_mode | Modo de procesamiento. Para Código QR: siempre automatic. |
status | Estado actual de la order. Al crearse es created. |
status_detail | Detalle del estado actual de la order. Los valores posibles son created, canceled, accredited, refunded, expired. |
currency | Identificador de la moneda. Los valores posibles son ARS, BRL, CLP, UYU. |
created_date | Fecha de creación de la order. Formato yyyy-MM-ddTHH:mm:ss.sssZ. |
last_updated_date | Fecha de la última actualización de la order. Formato yyyy-MM-ddTHH:mm:ss.sssZ. |
config.qr.external_pos_id | Identificador externo de la caja asociada a la order. |
config.qr.mode | Modo de Código QR configurado. Los valores posibles son static, dynamic, hybrid. Para integraciones migradas desde la Instore Orders API, el valor es static. |
transactions.payments[].id | Identificador de la transacción de pago. |
transactions.payments[].amount | Valor del pago. |
transactions.payments[].status | Estado del pago. Al crearse es created. |
transactions.payments[].status_detail | Detalle del estado del pago. Al crearse es ready_to_process. |
type_response.qr_data | Trama de Código QR que debe convertirse en código QR para que el pago pueda realizarse. Presente solo cuando config.qr.mode es dynamic o hybrid. |
integration_data.application_id | Identificador de la aplicación de Mercado Pago. |
items[].title | Nombre del ítem. |
items[].unit_price | Precio unitario del ítem. |
items[].quantity | Cantidad de ítems. |
items[].unit_measure | Unidad de medida del ítem. |
items[].external_categories[].id | Identificador de categoría del ítem en el sistema externo. |
discounts.payment_methods[].new_total_amount | Nuevo valor total de la order cuando se aplica un descuento. |
discounts.payment_methods[].type | Medio de pago al que aplica el descuento. |
La Orders API consolida la mayoría de los errores de validación específicos por campo en los códigos genéricos property_value y property_type, con el detalle del campo en el cuerpo de la respuesta. Además, los mensajes de respuesta son más descriptivos, lo que facilita la identificación y resolución de problemas. Consulta las tablas a continuación para más detalles.
Errores que desaparecen
Los siguientes errores existen en la Instore Orders API pero no tienen equivalencia en la Orders API.
| HTTP | Instore Orders API | Observación |
400 | invalid_collector_id | Eliminado. La identidad se obtiene directamente del Access Token. |
Errores renombrados
Los siguientes errores fueron renombrados en la Orders API.
| HTTP | Instore Orders API | Orders API | Observación |
400 | invalid_sponsor_id | sponsor_id_not_valid | El campo migra a integration_data.sponsor.id. |
404 | pos_obtainment_error | pos_not_found | El external_pos_id deja de ser parámetro de path y pasa al body. |
Errores que cambian de comportamiento
Los siguientes errores existen en ambas APIs pero con comportamiento diferente en la Orders API.
| HTTP | Instore Orders API | Orders API | Observación |
400 | invalid_items | property_value | property_value consolida los errores de validación por campo. El campo con error está indicado en el detalle de la respuesta. |
400 | json_syntax_error | property_type | Equivalente más cercano. En la Instore Orders API, también cubría JSON malformado en general. |
400 | invalid_access_token | unauthorized (HTTP 401) | En la Instore Orders API, era 400. En la Orders API, es 401. |
Errores que permanecen iguales
El siguiente error tiene el mismo comportamiento en ambas APIs.
| HTTP | Error | Observación |
500 | Genérico | Error interno. Verifica el retorno y repite la solicitud. |
Errores introducidos por la Orders API
Los siguientes errores no tienen equivalencia en la Instore Orders API.
| HTTP | Error | Observación |
400 | empty_required_header | X-Idempotency-Key ausente. |
400 | unsupported_site | Intento de crear la order en un país no soportado. |
400 | unsupported_properties | Propiedad no soportada en el body. El campo con error está indicado en el detalle de la respuesta. |
400 | bad_request | Campos no soportados o inválidos en general. |
400 | marketplace_not_valid | El Access Token no fue obtenido a través de OAuth y no es posible identificar un marketplace válido. |
400 | seller_configuration | El vendedor no está autorizado para realizar transacciones de retiro de dinero. Comunicarse con el equipo comercial de Mercado Pago para habilitar esta funcionalidad. |
404 | marketplace_fee_not_allowed | No está permitido enviar marketplace_fee porque el marketplace no fue encontrado. |
409 | idempotency_key_already_used | El X-Idempotency-Key ya fue utilizado con una solicitud distinta en las últimas 24 horas. |
Implementar la consulta de orders
El endpoint de consulta GET /v1/orders/{order_id}API es una novedad exclusiva de la Orders API. La Instore Orders API no contaba con un endpoint dedicado para consultar el estado de una transacción. Antes, el estado se obtenía exclusivamente a través de notificaciones de webhook de los tópicos payments y merchant_orders. La Orders API permite consultar el estado completo de la order en cualquier momento, incluyendo status, pagos, reembolsos y datos del medio de pago.
curlcurl -X GET \ 'https://api.mercadopago.com/v1/orders/{{ORDER_ID}}' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}'
El response del GET incluye todos los campos del response de creación, además de los campos adicionales a continuación, disponibles tras el procesamiento del pago.
| Campo | Descripción |
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. |
transactions.payments[].refunded_amount | Valor reembolsado. Presente solo cuando hubo un reembolso. |
transactions.payments[].paid_amount | Valor total pagado. Si el pago fue realizado con descuento, refleja ese valor. |
transactions.payments[].status | Estado actual del pago. Los valores posibles son created, canceled, processed, refunded, expired. |
transactions.payments[].status_detail | Estado detallado del pago. Los valores posibles son created, canceled_by_api, accredited, refunded, expired, in_review. |
transactions.payments[].reference_id | Identificador del pago asociado a la order. |
transactions.payments[].payment_method.type | Medio de pago seleccionado en la transacción. |
transactions.payments[].payment_method.installments | Cantidad de cuotas seleccionadas. |
transactions.payments[].payment_method.id | Identificador del medio de pago o marca de la tarjeta. |
transactions.payments[].discounts.type | Medio de pago con el que se aplicó el descuento. Presente solo si se aplicó un descuento. |
transactions.refunds[].id | Identificador de la transacción de reembolso. |
transactions.refunds[].transaction_id | Identificador del pago que está siendo reembolsado. |
transactions.refunds[].reference_id | Identificador que asocia la transacción a su reembolso. |
transactions.refunds[].amount | Valor devuelto en el reembolso. |
transactions.refunds[].status | Estado del reembolso. Los valores posibles son processing, processed, failed. |
items[].title | Nombre del ítem. |
items[].unit_price | Precio unitario del ítem. |
items[].quantity | Cantidad de ítems. |
items[].unit_measure | Unidad de medida del ítem. |
items[].external_code | Código externo del ítem. |
items[].external_categories[].id | Identificador de categoría del ítem. |
discounts.payment_methods[].new_total_amount | Nuevo valor total cuando se aplica un descuento. |
discounts.payment_methods[].type | Medio de pago al que aplica el descuento. |
Como este es un endpoint nuevo en la Orders API, no tiene equivalente en la Instore Orders API. Los errores documentados a continuación son exclusivos de la nueva API.
| HTTP | Error | Observación |
400 | invalid_path_param | El order_id enviado para la consulta de la order tiene formato inválido. Debe comenzar con el prefijo ORD seguido de 26 caracteres. |
401 | unauthorized | Access Token inválido o expirado. |
404 | order_not_found | El order_id no corresponde a ninguna order creada. |
500 | Genérico | Error interno. Verifica el retorno y repite la solicitud. |
Actualizar la cancelación de orders
El endpoint de cancelación cambia completamente de estructura: de DELETE /mpmobile/instore/qr/{user_id}/{external_id}API a POST /v1/orders/{order_id}/cancelAPI. El método HTTP cambia de DELETE a POST, el {user_id} y el {external_id} salen del path, y la cancelación pasa a operar sobre el identificador único de la order.
En la Instore Orders API, la cancelación eliminaba la order activa asociada a la caja, una operación sobre la caja y no sobre la transacción individual. En la Orders API, la cancelación opera directamente sobre la order por el order_id, sin depender de la caja en el path. El response pasó de vacío (HTTP 204) al objeto completo de la order con status: "canceled" (HTTP 200).
El header necesario en esta operación es:
| Header | Obligatoriedad | Descripción |
X-Idempotency-Key | Obligatorio | Clave única por solicitud. |
En la Instore Orders API, la cancelación devolvía HTTP 204 sin body. El response a la cancelación con la Orders API devuelve el objeto completo de la order con status: "canceled". La tabla a continuación lista los campos devueltos en el response de cancelación.
| Campo | Descripción |
id | Identificador de la order cancelada, generado por Mercado Pago. |
user_id | Identificador del usuario de Mercado Pago que creó la order. |
type | Tipo de order. Para Código QR: siempre qr. |
external_reference | Referencia externa de la order, asignada en el momento de la creación. |
description | Descripción del producto o servicio, motivo de la order. |
expiration_time | Tiempo de expiración de la order en formato ISO 8601. |
processing_mode | Modo de procesamiento. Para Código QR: siempre automatic. |
total_amount | Valor total de la order. |
country_code | Identificador del site/país de la aplicación de Mercado Pago. |
marketplace_fee | Tarifa del marketplace. Exclusivo para integraciones con OAuth. |
integration_data.application_id | Identificador de la aplicación de Mercado Pago que creó la order. |
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. |
status | Estado actual de la order. Al cancelar: canceled. |
status_detail | Detalle del estado actual de la order. Al cancelar: canceled. |
currency | Identificador de la moneda utilizada. Los valores posibles son ARS, BRL, CLP, UYU. |
created_date | Fecha de creación de la order. Formato yyyy-MM-ddTHH:mm:ss.sssZ. |
last_updated_date | Fecha de la última actualización de la order. Formato yyyy-MM-ddTHH:mm:ss.sssZ. |
config.qr.external_pos_id | Identificador externo de la caja asociada a la order. |
config.qr.mode | Modo de Código QR configurado. Los valores posibles son static, dynamic, hybrid. Para integraciones migradas desde la Instore Orders API, el valor es static. |
transactions.payments[].id | Identificador de la transacción de pago, generado por Mercado Pago. |
transactions.payments[].amount | Valor del pago. |
transactions.payments[].status | Estado del pago. Al cancelar: canceled. |
transactions.payments[].status_detail | Detalle del estado del pago. Al cancelar: canceled_by_api. |
transactions.payments[].reference_id | Identificador del pago asociado a la order. |
items[].title | Nombre del ítem. |
items[].unit_price | Precio unitario del ítem. |
items[].quantity | Cantidad de ítems. |
items[].unit_measure | Unidad de medida del ítem. |
items[].external_code | Código externo del ítem (ej.: EAN). |
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 Instore Orders API pero no tienen equivalencia en la Orders API.
| HTTP | Instore Orders API | Observación |
400 | invalid_collector_id | Eliminado en la Orders API. |
401 | unauthorized (authorization value not present) | Eliminado. Ocurría al enviar {user_id} alfanumérico. La identidad se obtiene directamente del Access Token. |
403 | forbidden | Eliminado. Ocurría cuando el {user_id} no pertenecía al dueño del Access Token. |
Errores renombrados
Los siguientes errores fueron renombrados en la Orders API.
| HTTP | Instore Orders API | Orders API | Observación |
400 → 404 | pos_obtainment_by_external_id_error | order_not_found | En la Instore Orders API, era 400. En la Orders API, es 404. La cancelación pasa a operar sobre el order_id. |
Errores que cambian de comportamiento
Los siguientes errores existen en ambas APIs pero con un comportamiento diferente en la Orders API.
| HTTP | Instore Orders API | Orders API | Observación |
400 → 401 | invalid_access_token | unauthorized | En la Instore Orders API, era 400. En la Orders API, es 401. |
Errores que permanecen iguales
El siguiente error tiene el mismo comportamiento en ambas APIs.
| HTTP | Error | Observación |
500 | Genérico | Error interno. Verifica el retorno y repite la solicitud. |
Errores introducidos por la Orders API
Los siguientes errores no tienen equivalencia en la Instore Orders API.
| HTTP | Error | Observación |
400 | empty_required_header | X-Idempotency-Key ausente. |
400 | invalid_path_param | El order_id tiene formato inválido. Debe comenzar con ORD seguido de 26 caracteres. |
404 | order_not_found | El order_id no corresponde a ninguna order creada. |
409 | idempotency_key_already_used | El X-Idempotency-Key ya fue utilizado con una solicitud distinta. |
409 | order_already_canceled | La order ya está cancelada. Las orders solo pueden cancelarse con status: created. |
409 | instore_order_locked_error | No es posible cancelar una order mientras el pago está en curso. |
Implementar reembolsos con el endpoint dedicado
La Orders API introduce el endpoint dedicado POST /v1/orders/{order_id}/refundAPI para reembolsos, que no existía en la Instore Orders API. 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.
Para reembolsar el valor total de la order, envía la solicitud al endpoint POST /v1/orders/{order_id}/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 360 días a partir de la fecha del pago. Para orders con retiro de dinero (cash-out o extracash), el plazo máximo es de 72 horas.
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. |
status_detail | string | refunded para reembolso total. |
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[].amount | string | Valor del reembolso. Si el pago fue realizado con descuento, refleja ese valor. |
transactions.refunds[].status | string | processing cuando el reembolso fue solicitado y está en procesamiento. |
transactions.refunds[].reference_id | string | Identificador que asocia el pago a su respectivo reembolso. |
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-Ttl-Store-Preference fue eliminado y reemplazado por el campo expiration_time en el body de la solicitud.
El header X-Idempotency-Key debe estar presente en todas las operaciones de creación, cancelación y reembolso.
Orders creadas correctamente con el nuevo payload en el endpoint POST /v1/ordersAPI y el campo id capturado del response.
Orders consultadas correctamente a través del endpoint GET /v1/orders/{order_id}API.
Status de orders monitoreados vía webhook con el tópico "Order (Mercado Pago)" y los nuevos valores: created, processed, canceled, refunded y expired.
Orders canceladas correctamente a través del endpoint POST /v1/orders/{order_id}/cancelAPI.
Reembolsos realizados a través del endpoint dedicado POST /v1/orders/{order_id}/refundAPI.
Accede a la documentación para saber cómo probar la integración.