How to migrate from the Dynamic QR Model API to the Orders API
The Orders API unifies payment processing with QR Code in Mercado Pago, consolidating the two creation methods of the Dynamic QR Model API into a single endpoint and extending query and cancellation resources to both modes. In addition, all new Mercado Pago features will be developed on the Orders API.
The Dynamic QR Model API had two creation methods with distinct behaviors:
POST /qrs, dynamic QR mode: creates an order and returns a unique QR string per transaction in theqr_datafield, without associating it with any checkout. The application is responsible for convertingqr_datainto a QR Code and displaying it to the customer.PUT /qrs, hybrid QR mode: creates an order, associates it with the checkout identified by{external_pos_id}, updating the linked static QR, and also returns the dynamic QR in theqr_datafield.
The Orders API unifies these two methods into a single endpoint POST /v1/ordersAPI, differentiating behavior via the config.qr.mode parameter: the dynamic value corresponds to the legacy POST flow and the hybrid value corresponds to the legacy PUT flow.
This distinction also affected query and cancellation resources, which were available in the Dynamic QR Model API only for the PUT flow. In the Orders API, these resources become available for both flows via order_id.
To migrate your integration from the Dynamic QR Model API to the Orders API, follow the steps below.
Map endpoint changes
Before starting the migration steps, review the table below for an overview of all endpoint changes. The Orders API unifies the two creation methods into a single POST /v1/ordersAPI and extends query and cancellation resources to both modes.
| Operation | Dynamic QR Model API | Orders API |
| Create order (dynamic mode) | POST /instore/orders/qr/seller/collectors/{user_id}/pos/{external_pos_id}/qrsAPI | POST /v1/ordersAPI with config.qr.mode: dynamic |
| Create order (hybrid mode) | PUT /instore/orders/qr/seller/collectors/{user_id}/pos/{external_pos_id}/qrsAPI | POST /v1/ordersAPI with config.qr.mode: hybrid |
| Get order | GET /instore/qr/seller/collectors/{user_id}/pos/{external_pos_id}/ordersAPI (PUT flow only) | GET /v1/orders/{order_id}API (both modes) |
| Cancel order | DELETE /instore/orders/qr/seller/collectors/{user_id}/pos/{external_pos_id}/qrsAPI (PUT flow only) | POST /v1/orders/{order_id}/cancelAPI (both modes) |
| Refund order | Via Payments API (no dedicated endpoint in the Dynamic QR Model API) | POST /v1/orders/{order_id}/refundAPI |
Update the status and notifications model
One of the most significant changes between the Dynamic QR Model API and the Orders API is the status model. In the Dynamic QR Model API, the state of a transaction was determined by monitoring notifications from two independent topics , payments and merchant_orders, with different fields and values for each. The Orders API unifies this behavior into a single status field on the order. See the complete mapping below.
In addition, the Orders API also introduces the status_detail field, which provides greater detail on the transaction state. The possible values are created, canceled, accredited, refunded, and expired.
In the Dynamic QR Model API, the merchant_order is created when the order is generated, so notifications from the merchant_orders topic are available from the start of the flow. The payment object, on the other hand, is only created when a payment attempt is made, whether approved or rejected. Applications that monitored only the payments topic received no notifications until the user initiated the payment process. In the Orders API, this behavior is unified: the status field of the order reflects the complete state from creation, without the need to monitor two independent topics.
payments topic (status) | merchant_orders topic (status / order_status) | Orders API (status) | Note |
| — | opened (no payment or rejected payment) | created | In the Dynamic QR Model API, opened indicated the order had no approved payment yet. In the Orders API, this state is explicit from creation. |
approved | closed + order_status: "paid" | processed | Both topics converged on the same result: approved payment. In the Orders API, the state is self-contained. |
rejected | opened (the merchant_order does not change state and remains open) | No equivalent | In the Dynamic QR Model API, a rejected payment left the merchant_order in opened waiting for a new attempt. In the Orders API, rejected payments are not exposed. The state remains created until an approved payment is received. |
refunded | closed + order_status: "reverted" | refunded | Full refund. In the merchant_orders topic, identifiable by order_status: "reverted". |
refunded (partial, status_detail: "partially_refunded") | closed + payment with status_detail: "partially_refunded" | refunded | Partial refund. In the Dynamic QR Model API, it was necessary to inspect the status_detail of the payment within the merchant_order. In the Orders API, the status_detail indicates partially_refunded. |
| — | — | canceled | New status with no equivalent in the Dynamic QR Model API. |
| — | — | expired | New status with no equivalent in the Dynamic QR Model API. |
Regarding notifications, in the Legacy API they could be configured via the notification_url field in the request body (IPN model) or via webhooks with the payments and merchant_orders topics. In the Orders API, the notification_url field does not exist and the payments and merchant_orders topics are not compatible. Configure notifications in Your integrations, subscribing to the "Order (Mercado Pago)" (orders) topic, before going to production. For more information, see the notifications documentation.
Adapt headers
The Orders API introduces a mandatory header change that affects all endpoints. The Access Token must be sent via the Authorization header. Apply the following change before testing any other resource.
The X-Idempotency-Key header is required for order creation, cancellation, and refund operations. It ensures that a repeated request with the same key returns the original result without processing the operation again. Send a UUID v4 or a unique random string per request. GET operations do not require this header.
X-Idempotency-Key is reused with a different body, the API will return the idempotency_key_already_used error. Generate a new key for each distinct operation.Migrate order creation
The Orders API unifies the two creation methods into a single POST /v1/ordersAPI, differentiating behavior via the config.qr.mode parameter. The POST /qrs endpoint, dynamic QR mode, is equivalent to config.qr.mode: dynamic, and the PUT /qrs endpoint, hybrid QR mode, is equivalent to config.qr.mode: hybrid. In both cases, {user_id} is no longer a path parameter, {external_pos_id} moves to the body, and the type: "qr" field becomes required. Follow the steps below to adapt the request, the response, and error handling for each mode.
in_store_order_id field. In the Orders API, that identifier moves to the id field, with an alphanumeric format (e.g., ORD00001111222233334444555566). Capture the id value from the creation response, as it is required for subsequent queries, cancellations, and refunds.The table below shows the body field mapping for both creation modes. The Dynamic QR Model API column indicates the behavior of each field in the POST and PUT flows.
| Dynamic QR Model API (POST / PUT) | Orders API | Description | Change |
{user_id} (path param, both) | Does not exist | User identifier. In the Orders API, identity is obtained directly from the Access Token. | No longer a path parameter. |
{external_pos_id} (path param, both) | config.qr.external_pos_id | External checkout identifier. In the Dynamic QR Model API, it was sent in the path. In the Orders API, it is sent in the body within config.qr. | Moves from path parameter to body. |
external_reference (required in both) | external_reference | Reference that can sync with the point-of-sale system. In the Orders API, max. 64 characters, only letters, numbers, - and _. Cannot contain PII data. | No change in requirement. |
title (required in POST, optional in PUT) | Does not exist | Purchase title. | Removed. The description is sufficient. |
description (required in POST, optional in PUT) | description | Purchase description. In the Dynamic QR Model API, it existed both at the root level and inside items[]. In the Orders API, it exists only at the root level. Max. 150 characters. | In the Orders API, becomes optional and is managed only at the root level. |
items[].description | Does not exist | Item description. | Removed. Description is managed only at the order root level. |
notification_url | Does not exist | URL to receive notifications. | Removed. Configure webhook notifications in your application within Your integrations, selecting the "Order (Mercado Pago)" topic. For more information, see the notifications documentation. |
expiration_date | expiration_time | Order validity. In the Dynamic QR Model API, it was an absolute date. In the Orders API, it is a relative duration in ISO 8601 format. In all modes, the default is 15 minutes and the submitted value is always respected. | Changes from absolute date to relative duration in ISO 8601 format. |
total_amount (required in both) | total_amount | Total order amount. In the Dynamic QR Model API, it was a number. In the Orders API, it is a decimal string representing the sum of all transactions. Does not accept decimal places (e.g., "15"). | Changes from number to decimal string. |
sponsor.id | integration_data.sponsor.id | USER_ID of the Mercado Pago account of the integrating system. | Moves to the integration_data.sponsor node. |
items[].sku_number | items[].external_code | Item code in the external system. | Renamed to items[].external_code. |
items[].category | Does not exist | Item category. | Removed. No equivalent in the Orders API. |
items[].title (required in both) | items[].title | Item name. Max. 150 characters. | No change in requirement. |
items[].unit_price (required in both) | items[].unit_price | Unit price. In the Dynamic QR Model API, it was a number. In the Orders API, it is a decimal string. Does not accept decimal places (e.g., "15"). | Changes from number to decimal string. |
items[].quantity (required in both) | items[].quantity | Item quantity. In the Dynamic QR Model API, it was a number. In the Orders API, it is an integer. | Changes from number to integer. |
items[].unit_measure (required in both) | items[].unit_measure | Item unit of measure. Max. 10 characters. | No change in requirement. |
items[].total_amount (required in both) | Does not exist | Item total (unit price × quantity). | Removed. No equivalent in the Orders API. |
items[].currency_id | Does not exist | Item currency identifier. | Removed. Currency is determined automatically by the seller account. |
items[].external_categories[].id | items[].external_categories[].id | Item category identifier. Enables category-based discounts. Cannot be used together with discounts. | No change. |
discount.total_amount | discounts.payment_methods[].new_total_amount | New total amount when a discount is applied. Does not accept decimal places (e.g., "15"). Cannot be used together with items[].external_categories. | Restructured within discounts.payment_methods[]. Changes from number to decimal string. |
discount.details[] | discounts.payment_methods[].type | Payment method to which the discount applies. Values: debit_card, credit_card, account_money, prepaid_card. Up to 4 methods. | Restructured. The details array now indicates the payment method type. |
taxes[].type | Does not exist | Tax type. | Removed. The new API does not support this field in the request. |
taxes[].value | Does not exist | Tax amount. | Removed. |
taxes[].percentage | Does not exist | Tax percentage. | Removed. |
marketplace | Does not exist | Marketplace identifier. | Removed. The marketplace is identified by the OAuth Access Token. |
internal_metadata | Does not exist | Internal metadata. | Removed. |
customization | Does not exist | Customization object. | Removed. |
The Orders API also introduces the following fields with no equivalent in the Dynamic QR Model API.
| Field | Description |
type | Order type. For QR Code payments, the only valid value is "qr". Required. |
config.qr.mode | QR mode. dynamic for the flow equivalent to the POST legacy (unique QR per transaction). hybrid for the flow equivalent to the PUT legacy. Queues the order at the checkout and returns the dynamic QR in the qr_data field. |
transactions.payments[].amount | Payment amount within the transactions node. Does not accept decimal places (e.g., "15"). Only 1 payment transaction per order. |
marketplace_fee | Marketplace fee amount. Exclusive to OAuth integrations. Does not accept decimal places (e.g., "15"). |
integration_data.platform_id | Platform identifier, assigned by Mercado Pago. |
integration_data.integrator_id | Integrator identifier, assigned by Mercado Pago. Must have the dev_ prefix. |
taxes[].payer_condition | Indicates whether the order is generated with VAT or not. Values: payment_taxable_iva (default) or payment_exempt_iva. |
The table below shows the response field mapping. The columns indicate the origin in each flow of the Dynamic QR Model API.
| Dynamic QR Model API | Orders API | Description | Change |
qr_data (POST and PUT) | type_response.qr_data | EMVCo QR string for conversion into a QR Code. In the Orders API, present only when config.qr.mode is dynamic or hybrid. | Renamed and moved to the type_response node. |
in_store_order_id (POST and PUT) | id | Identifier of the created order. In the Dynamic QR Model API, it was a UUID (e.g., d4e8ca59-...). In the Orders API, it is an alphanumeric ID with the ORD prefix (e.g., ORD00001111222233334444555566). | Renamed from in_store_order_id. Format changes from UUID to alphanumeric ID. |
The Orders API also introduces the following fields in the creation response.
| Field | Description |
user_id | Identifier of the user who created the order. |
type | Order type. For QR Code: always qr. |
external_reference | External reference of the order. |
description | Product or service description. |
expiration_time | Expiration duration in ISO 8601 format. |
processing_mode | Processing mode. For QR Code: always automatic. |
total_amount | Total order amount. |
country_code | Site/country identifier (e.g., "AR"). |
marketplace_fee | Marketplace fee. Exclusive to OAuth integrations. |
status | Current order status. On creation: created. |
status_detail | Current order status detail. The possible values are created, canceled, accredited, refunded, expired. |
currency | Order currency. Values: ARS, BRL, CLP, UYU. |
created_date | Creation date. Format yyyy-MM-ddTHH:mm:ss.sssZ. |
last_updated_date | Last update date. Format yyyy-MM-ddTHH:mm:ss.sssZ. |
config.qr.external_pos_id | External identifier of the checkout associated with the order. |
config.qr.mode | Configured QR mode (dynamic or hybrid). |
transactions.payments[].id | Payment transaction identifier. |
transactions.payments[].amount | Payment amount. |
transactions.payments[].status | Payment status. On creation: created. |
transactions.payments[].status_detail | Payment status detail. On creation: ready_to_process. |
integration_data.application_id | Mercado Pago application identifier. |
integration_data.platform_id | Platform identifier. |
integration_data.integrator_id | Integrator identifier. |
integration_data.sponsor.id | USER_ID of the integrating system. |
taxes[].payer_condition | Indicates whether the order was generated with VAT or not. Values: payment_taxable_iva or payment_exempt_iva. |
POST and PUT flow errors are identical in the Dynamic QR Model API. The Orders API consolidates most field-specific validation errors into the generic codes property_value and property_type, with the field detail in the response body. Additionally, response messages are more descriptive, making it easier to identify and resolve issues. See the tables below for details.
Errors that change behavior
The following errors exist in both APIs but with different behavior in the Orders API.
| HTTP | Dynamic QR Model API | Orders API | Note |
400 | Multiple: invalid_collectorId, invalid_externalPosId, invalid_external_reference, invalid_total_amount, invalid_items.*, invalid_sponsor.* and others | property_value | property_value consolidates field validation errors. The field with the error is indicated in the response detail. |
400 → 401 | (authentication via middleware, 400) | unauthorized | In the Dynamic QR Model API, it was 400. In the Orders API, it is an explicit 401. |
Errors that remain unchanged
The following error has the same behavior in both APIs.
| HTTP | Error | Note |
500 | Generic | Internal error. Check the response and retry the request. |
Errors introduced by the Orders API
The following errors have no equivalent in the Dynamic QR Model API.
| HTTP | Error | Note |
400 | sponsor_id_not_valid | Invalid value for integration_data.sponsor.id. |
400 | marketplace_not_valid | The Access Token was not obtained via OAuth. |
400 | empty_required_header | X-Idempotency-Key is missing. |
400 | unsupported_site | Country not supported. |
400 | unsupported_properties | Unsupported property in the body. The field with the error is indicated in the response detail. |
401 | unauthorized | Invalid or expired Access Token. |
404 | pos_not_found | The external_pos_id does not belong to any checkout. |
404 | marketplace_fee_not_allowed | Sending marketplace_fee is not allowed. The marketplace was not found. |
409 | idempotency_key_already_used | The X-Idempotency-Key was already used with a different request in the last 24 hours. |
Update order queries
The GET /v1/orders/{order_id}API query endpoint is available for both dynamic and hybrid modes in the Orders API. In the Dynamic QR Model API, queries were available only for the PUT flow and queried by checkout, not by order. The POST flow had no query endpoint. State was obtained exclusively via payments and merchant_orders notifications.
The Orders API allows querying the complete order state directly by order_id, including status, payments, refunds, and payment method data.
curl
curl -X GET \ 'https://api.mercadopago.com/v1/orders/{{ORDER_ID}}' \ -H 'Authorization: Bearer {{ACCESS_TOKEN}}'
The legacy fields in this table correspond to the PUT flow query endpoint only. In the POST flow, all response fields are new.
The table below shows the PUT flow fields that existed in both APIs and changed during migration.
| Dynamic QR Model API, PUT flow | Orders API | Description | Change |
| Does not exist | id | Order identifier. | New field. The legacy query endpoint did not return the order ID. |
external_reference | external_reference | External reference of the order. | No change. |
description | description | Purchase description. | No change. |
title | Does not exist | Purchase title. | Removed. |
notification_url | Does not exist | URL configured for notifications. | Removed. |
expiration_date | expiration_time | Order validity. In the Dynamic QR Model API, it was an absolute date. In the Orders API, it is a relative duration in ISO 8601. In all modes, the default is 15 minutes and the submitted value is always respected. | Changes from absolute date to relative duration. |
total_amount | total_amount | Total order amount. In the Dynamic QR Model API, it was a number. In the Orders API, it is a decimal string. | Changes from number to decimal string. |
marketplace_fee | marketplace_fee | Marketplace fee. In the Dynamic QR Model API, it was a number. In the Orders API, it is a decimal string. | Changes from number to decimal string. |
sponsor.id | integration_data.sponsor.id | USER_ID of the integrating system. In the Dynamic QR Model API, it was an integer. In the Orders API, it is a string. | Moves to integration_data.sponsor. Changes from integer to string. |
The Orders API also introduces the following fields in the query response.
| Field | Description |
status | Current order status. Values: created, canceled, processed, refunded, expired. In the POST flow, state was obtained only via webhooks. |
status_detail | Current order status detail. The possible values are created, canceled, accredited, refunded, expired. |
currency | Order currency. Values: ARS, BRL, CLP, UYU. |
created_date / last_updated_date | Creation and last update dates. Format yyyy-MM-ddTHH:mm:ss.sssZ. |
config.qr.external_pos_id | External identifier of the checkout associated with the order. |
config.qr.mode | Configured QR mode. |
transactions.payments[].id | Payment transaction identifier. |
transactions.payments[].amount | Payment amount. |
transactions.payments[].refunded_amount | Refunded amount. Present only when a refund has occurred. |
transactions.payments[].paid_amount | Total amount paid. |
transactions.payments[].status | Current payment status. |
transactions.payments[].status_detail | Detailed payment status. |
transactions.payments[].reference_id | Identifier of the payment associated with the order. |
transactions.payments[].payment_method.type | Selected payment method. |
transactions.payments[].payment_method.installments | Number of installments. |
transactions.payments[].payment_method.id | Payment method or card brand identifier. |
transactions.payments[].discounts.type | Payment method with which the discount was applied. Present only if a discount was applied. |
transactions.refunds[].id | Refund identifier. |
transactions.refunds[].transaction_id | Identifier of the payment being refunded. |
transactions.refunds[].amount | Refund amount. |
transactions.refunds[].status | Refund status. |
Query errors were grouped by type of change. See the tables below for details.
Errors that disappear
The following errors exist in the Dynamic QR Model API PUT flow but have no equivalent in the Orders API.
| HTTP | Dynamic QR Model API | Note |
400 | invalid_collectorId | Removed in the Orders API. The query operates on order_id. |
400 | invalid_externalPosId | Removed. The query operates on order_id, not on the checkout. |
400 | pos_obtainment_by_external_id_error | Removed. The concept of POS as a query parameter disappears. |
400 | pos_deleted_error | Removed in the Orders API. |
403 | forbidden | Removed in the Orders API. |
Renamed errors
The following errors were renamed in the Orders API.
| HTTP | Dynamic QR Model API | Orders API | Note |
404 | point_of_sale_in_store_order_not_found and in_store_order_not_found | order_not_found | Both cases are unified into order_not_found. |
Errors that change behavior
The following errors exist in both APIs but with different behavior in the Orders API.
| HTTP | Dynamic QR Model API | Orders API | Note |
400 → 401 | authentication via middleware | unauthorized | In the Dynamic QR Model API, it was 400. In the Orders API, it is an explicit 401. |
Errors introduced by the Orders API
The following errors have no equivalent in the Dynamic QR Model API.
| HTTP | Error | Note |
400 | invalid_path_param | The order_id has an invalid format. It must start with ORD followed by 26 characters. |
401 | unauthorized | Invalid or expired Access Token. |
404 | order_not_found | The order_id does not correspond to any created order. |
500 | Generic | Internal error. Check the response and retry the request. |
Update order cancellations
The POST /v1/orders/{order_id}/cancelAPI cancellation endpoint is available for both modes in the Orders API. In the Dynamic QR Model API, cancellation was available only for the PUT flow and canceled the order associated with the checkout via DELETE. The POST flow had no cancellation endpoint.
The HTTP method changes from DELETE to POST, {user_id} and {external_pos_id} are removed from the path, and the operation now identifies the order by order_id. The response changed from empty (HTTP 204) to the full order object with status: "canceled" (HTTP 200).
| Header | Requirement | Description |
X-Idempotency-Key | Required | Unique key per request. |
The response includes the following fields of the canceled order.
| Field | Description |
id | Identifier of the canceled order. |
user_id | Identifier of the user who created the order. |
type | Order type. For QR: always qr. |
external_reference | External order reference. |
description | Product or service description. |
expiration_time | Expiration time in ISO 8601 format. |
processing_mode | Processing mode. For QR: always automatic. |
total_amount | Total order amount. |
country_code | Site/country identifier. |
marketplace_fee | Marketplace fee. Exclusive to OAuth integrations. |
integration_data.application_id | Mercado Pago application identifier. |
integration_data.platform_id | Platform identifier, assigned by Mercado Pago. |
integration_data.integrator_id | Integrator identifier, assigned by Mercado Pago. |
integration_data.sponsor.id | USER_ID of the integrating system. |
status | Current order status. On cancellation: canceled. |
status_detail | Status detail. On cancellation: canceled. |
currency | Currency identifier. Values: ARS, BRL, CLP, UYU. |
created_date | Creation date. Format yyyy-MM-ddTHH:mm:ss.sssZ. |
last_updated_date | Last update date. Format yyyy-MM-ddTHH:mm:ss.sssZ. |
config.qr.external_pos_id | External identifier of the checkout associated with the order. |
config.qr.mode | Configured QR mode. |
transactions.payments[].id | Payment transaction identifier. |
transactions.payments[].amount | Payment amount. |
transactions.payments[].status | Payment status. On cancellation: canceled. |
transactions.payments[].status_detail | Payment status detail. On cancellation: canceled_by_api. |
items[].title | Item name. |
items[].unit_price | Item unit price. |
items[].quantity | Item quantity. |
items[].unit_measure | Item unit of measure. |
items[].external_code | External item code. |
items[].external_categories[].id | Item category identifier in the external system. |
discounts.payment_methods[].new_total_amount | New total amount when a discount is applied. |
discounts.payment_methods[].type | Payment method to which the discount applies. |
Cancellation errors were grouped by type of change. See the tables below for details.
Errors that disappear
The following errors exist in the Dynamic QR Model API PUT flow but have no equivalent in the Orders API.
| HTTP | Dynamic QR Model API | Note |
400 | invalid_collectorId | Removed in the Orders API. |
400 | invalid_externalPosId | Removed. {external_pos_id} is no longer a path parameter. |
400 | pos_deleted_error | Removed in the Orders API. |
403 | forbidden | Removed. Identity is validated internally by the Access Token. |
Renamed errors
The following errors were renamed in the Orders API.
| HTTP | Dynamic QR Model API | Orders API | Note |
400 → 404 | pos_obtainment_by_external_id_error and in_store_order_delete_error (order not found) | order_not_found | In the Dynamic QR Model API, it was 400. In the Orders API, it is 404. Cancellation now operates on the order_id. |
409 | in_store_order_delete_error (Cannot delete a locked order) | instore_order_locked_error | Same concept. The error code name changes. |
Errors that change behavior
The following errors exist in both APIs but with different behavior in the Orders API.
| HTTP | Dynamic QR Model API | Orders API | Note |
400 → 401 | authentication via middleware | unauthorized | In the Dynamic QR Model API, it was 400. In the Orders API, it is an explicit 401. |
Errors that remain unchanged
The following error has the same behavior in both APIs.
| HTTP | Error | Note |
500 | Generic | Internal error. Check the response and retry the request. |
Errors introduced by the Orders API
The following errors have no equivalent in the Dynamic QR Model API.
| HTTP | Error | Note |
400 | empty_required_header | X-Idempotency-Key is missing. |
400 | invalid_path_param | The order_id has an invalid format. |
401 | unauthorized | Invalid or expired Access Token. |
404 | order_not_found | The order_id does not correspond to any created order. |
409 | idempotency_key_already_used | The X-Idempotency-Key was already used with a different request. |
409 | order_already_canceled | The order is already canceled. Orders can only be canceled with status: created. |
Implement refunds with the dedicated endpoint
The Orders API introduces the dedicated POST /v1/orders/{order_id}/refundAPI endpoint for refunds, which did not exist in the Dynamic QR Model API in either flow. Previously, it was necessary to receive the payment webhook, obtain the payment_id, and execute the refund through the Payments API separately. Now, the refund is performed directly on the order, for both modes.
Choose between a full or partial refund based on the amount to be returned.
To refund the full order amount, send the request to the POST /v1/orders/{order_id}/refundAPI endpoint without a 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}}'
Refunds are accepted up to 360 days from the payment date.
The refund response varies depending on the type of operation performed.
| Field | Type | Description |
id | string | Identifier of the refunded order. |
status | string | refunded for a full refund. processed for a partial refund (remaining balance still available). |
status_detail | string | refunded for a full refund. partially_refunded for a partial refund. |
transactions.refunds[].id | string | Refund identifier, generated by Mercado Pago. |
transactions.refunds[].transaction_id | string | Identifier of the payment transaction being refunded. |
transactions.refunds[].amount | string | Refund amount. If the payment was made with a discount, reflects that value. |
transactions.refunds[].status | string | processing when a full refund was requested and is being processed. processed when a partial refund was completed successfully. |
transactions.refunds[].reference_id | string | Identifier that associates the payment with its corresponding refund. |
Validate the migration
After applying the changes, verify that the integration operates correctly across all flows before going to production.
The X-Idempotency-Key header must be present in all creation, cancellation, and refund operations.
Orders successfully created via the POST /v1/ordersAPI endpoint with config.qr.mode: dynamic (equivalent to the POST flow of the legacy API).
Orders successfully created via the POST /v1/ordersAPI endpoint with config.qr.mode: hybrid (equivalent to the PUT flow of the legacy API).
The id field was captured from the creation response for use in subsequent queries, cancellations, and refunds.
Orders successfully queried via the GET /v1/orders/{order_id}API endpoint in both modes.
Order status monitored via webhook with the "Order (Mercado Pago)" topic and the new values: created, processed, canceled, refunded, and expired.
Orders successfully canceled via the POST /v1/orders/{order_id}/cancelAPI endpoint in both modes.
Refunds executed via the dedicated POST /v1/orders/{order_id}/refundAPI endpoint.
See the documentation to learn how to test the integration.