# MD for: https://www.mercadopago.com.ar/developers/es/docs/checkout-api-orders/resources/migrate-payments-to-orders.md \# How to migrate from the Payments API to the Orders API The Orders API unifies online payment processing for Checkout API, offering standardized endpoints, a transaction-level consolidated status model, and new native features that were not available in the Payments API. These include multiple transactions per order, manual or automatic processing, a dedicated capture endpoint, natively integrated 3DS 2.0 authentication, and a consolidated list of validation errors. Migration involves \*\*updating request endpoints and fields\*\*, \*\*consolidating the status and notification model\*\*, and taking advantage of \*\*new native features\*\*. Migration does not involve changes to the business flow experienced by the buyer: the customer continues to complete the checkout within the seller's website, without redirects. See below how to complete this migration, endpoint by endpoint and field by field, including the specific characteristics of each payment method. Before implementing, classify each active Payments API flow into one of these situations: - \*\*It has a direct equivalent:\*\* when it is a mandatory feature with a direct equivalent between the APIs, migrate your flow by following the \*\*required\*\* steps in this guide. - \*\*It requires a technical adaptation:\*\* when it is an optional feature already part of your current integration, also implement the \*\*Based on your flow\*\* steps. - \*\*It has no documented equivalent:\*\* keep the flow in the Payments API until the Orders API supports it. ::::::AccordionComponent{title="1\. Plan coexistence" pill="Required"} The Payments API continues to work normally after the launch of the Orders API. Mercado Pago has not deactivated this API; it has simply stopped adding new features to it, while maintaining security and stability fixes. Technically, both APIs can remain active at the same time, each processing part of your volume. We recommend the following strategy: - \*\*Migrate by payment method, not all at once.\*\* Move cards to the Orders API first, then migrate the remaining payment methods one at a time after validating stability. - \*\*Split traffic in your own checkout.\*\* Because each API uses independent endpoints, credentials, and idempotency keys, it is safe to route part of new transactions to :TagComponent{tag="POST" text="/v1/orders" href="/developers/en/reference/online-payments/checkout-api/create-order/post" color="green"} and the rest to :TagComponent{tag="POST" text="/v1/payments" href="/developers/en/reference/online-payments/checkout-api-payments/create-payment/post" color="green"}. - \*\*Handle notifications separately.\*\* Configure the Webhook to listen to the \`orders\` and \`payment\` topics in parallel during the transition, routing each payload to the appropriate handler. Disable \`payment\` only after migrating new traffic and monitoring outstanding Payments API transactions and notifications. - \*\*Define how to interrupt the migration.\*\* If you need to return to the Payments API, redirect only new transactions. Existing transactions must continue to be retrieved, captured, canceled, or refunded through the API in which they were processed, because they cannot and do not need to be transferred from one API to the other. - \*\*Monitor the approval rate and integration quality\*\* separately for each API during coexistence, as a criterion for deciding when to stop sending traffic to the Payments API. > NOTE > > When you are ready to complete the migration, see \[Go to production\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/go-to-production). :::::: ::::::AccordionComponent{title="2\. Verify supported payment methods" pill="Required"} Before starting the migration, confirm that all the payment methods in your integration already have an equivalent in the Orders API. | Payment method | Payments API | Orders API | |---|---|---| | Credit card | Supported | Supported | | Debit card | Supported | Supported | | Rapipago | Supported | Supported | | Pago Fácil | Supported | Supported | | Mercado Pago Wallet | Supported | Supported | | Cuotas sin Tarjeta | Supported | Supported | > NOTE > > In Argentina, Resolution E 51/2017 (\*precios transparentes\*) requires displaying, when offering card installment financing, the cash price, the total financed price, the number and value of each installment, the TEA, and the CFT, with specific typographic rules. This information is obtained through :TagComponent{tag="GET" text="/v1/payment\_methods/installments" href="/developers/en/reference/online-payments/checkout-api/payment-methods/get" color="accent"}, which returns \`payer\_costs\[\].labels\`. Validate the applicable regulatory treatment when building your installment checkout on the Orders API. In addition to payment method availability, check whether your integration uses Marketplace or Split Payments 1:1\. In the Payments API, these integrations withhold commissions through \`application\_fee\`; the Orders API does not yet have a documented equivalent field for this mechanism. Treat this as a blocker before migrating the flow. :::::: ::::::AccordionComponent{title="3\. Map endpoint changes" pill="Required"} In the Payments API, each operation used its own resource under \`/v1/payments/{id}\`. The Orders API consolidates most of these operations into subresources of the same \`/v1/orders/{order\_id}\` and introduces dedicated endpoints that were not available before: explicit capture; adding, removing, and updating transactions; and manual-mode processing. | Operation | Payments API | Orders API | |---|---|---| | Create payment vs. create order | :TagComponent{tag="POST" text="/v1/payments" href="/developers/en/reference/online-payments/checkout-api-payments/create-payment/post" color="green"} | :TagComponent{tag="POST" text="/v1/orders" href="/developers/en/reference/online-payments/checkout-api/create-order/post" color="green"} | | Get payment or order by ID | :TagComponent{tag="GET" text="/v1/payments/{id}" href="/developers/en/reference/online-payments/checkout-api-payments/get-payment/get" color="accent"} | :TagComponent{tag="GET" text="/v1/orders/{id}" href="/developers/en/reference/online-payments/checkout-api/get-order/get" color="accent"} | | Search payments and orders by filters | :TagComponent{tag="GET" text="/v1/payments/search" href="/developers/en/reference/online-payments/checkout-api-payments/search-payments/get" color="accent"} | :TagComponent{tag="GET" text="/v1/orders" href="/developers/en/reference/online-payments/checkout-api/search-order/get" color="accent"} | | Update payment or transaction | :TagComponent{tag="PUT" text="/v1/payments/{id}" href="/developers/en/reference/online-payments/checkout-api-payments/update-payment/put" color="orange"} | :TagComponent{tag="PUT" text="/v1/orders/{order\_id}/transactions/{transaction\_id}" href="/developers/en/reference/online-payments/checkout-api/update-transaction-order/put" color="orange"} | | Capture authorized payment | :TagComponent{tag="PUT" text="/v1/payments/{id}" href="/developers/en/reference/online-payments/checkout-api-payments/update-payment/put" color="orange"} with \`"capture": "true"\` | :TagComponent{tag="POST" text="/v1/orders/{order\_id}/capture" href="/developers/en/reference/online-payments/checkout-api/capture-order/post" color="green"} | | Reserve amount | :TagComponent{tag="POST" text="/v1/payments" href="/developers/en/reference/online-payments/checkout-api-payments/create-payment/post" color="green"} with \`"capture": "false"\` | :TagComponent{tag="POST" text="/v1/orders" href="/developers/en/reference/online-payments/checkout-api/create-order/post" color="green"} with \`"capture\_mode": "manual"\` | | Cancel payment or order | :TagComponent{tag="PUT" text="/v1/payments/{id}" href="/developers/en/reference/online-payments/checkout-api-payments/create-cancellation/put" color="orange"} with \`"status": "cancelled"\` | :TagComponent{tag="POST" text="/v1/orders/{order\_id}/cancel" href="/developers/en/reference/online-payments/checkout-api/cancel-order/post" color="green"} | | Add transaction to order | Not available. | :TagComponent{tag="POST" text="/v1/orders/{order\_id}/transactions" href="/developers/en/reference/online-payments/checkout-api/add-transaction-order/post" color="green"} | | Delete transaction from order | Not available. | :TagComponent{tag="DELETE" text="/v1/orders/{order\_id}/transactions/{transaction\_id}" href="/developers/en/reference/online-payments/checkout-api/delete-transaction-order/delete" color="red"} | | Process order in manual mode | Not available. | :TagComponent{tag="POST" text="/v1/orders/{order\_id}/process" href="/developers/en/reference/online-payments/checkout-api/process-order/post" color="green"} | | Create refund / Refund order | :TagComponent{tag="POST" text="/v1/payments/{id}/refunds" href="/developers/en/reference/online-payments/checkout-api-payments/create-refund/post" color="green"} | :TagComponent{tag="POST" text="/v1/orders/{order\_id}/refund" href="/developers/en/reference/online-payments/checkout-api/refund-order/post" color="green"} | | Get specific refund | :TagComponent{tag="GET" text="/v1/payments/{id}/refunds/{refund\_id}" href="/developers/en/reference/online-payments/checkout-api-payments/get-refund/get" color="accent"} | Included in the response from :TagComponent{tag="GET" text="/v1/orders/{id}" href="/developers/en/reference/online-payments/checkout-api/get-order/get" color="accent"} (under \`transactions.refunds\[\]\`) | | Get payment methods | :TagComponent{tag="GET" text="/v1/payment\_methods" href="/developers/en/reference/online-payments/checkout-api-payments/payment-methods/get" color="accent"} | :TagComponent{tag="GET" text="/v1/payment\_methods" href="/developers/en/reference/online-payments/checkout-api-payments/payment-methods/get" color="accent"} (unchanged) | | Get identification types | :TagComponent{tag="GET" text="/v1/identification\_types" href="/developers/en/reference/online-payments/checkout-api-payments/identification-types/get" color="accent"} | :TagComponent{tag="GET" text="/v1/identification\_types" href="/developers/en/reference/online-payments/checkout-api-payments/identification-types/get" color="accent"} (unchanged) | | Create customers | :TagComponent{tag="POST" text="/v1/customers" href="/developers/en/reference/online-payments/checkout-api/customers/create-customer/post" color="green"} | :TagComponent{tag="POST" text="/v1/customers" href="/developers/en/reference/online-payments/checkout-api/customers/create-customer/post" color="green"} (unchanged) | | Save cards | :TagComponent{tag="POST" text="/v1/customers/{customer\_id}/cards" href="/developers/en/reference/online-payments/checkout-api/cards/save-card/post" color="green"} | :TagComponent{tag="POST" text="/v1/customers/{customer\_id}/cards" href="/developers/en/reference/online-payments/checkout-api/cards/save-card/post" color="green"} (unchanged) | | Get address | :TagComponent{tag="GET" text="/v1/customers/{id}/addresses/{address\_id}" href="/developers/en/reference/online-payments/checkout-api/addresses/get-address/get" color="accent"} | :TagComponent{tag="GET" text="/v1/customers/{id}/addresses/{address\_id}" href="/developers/en/reference/online-payments/checkout-api/addresses/get-address/get" color="accent"} (unchanged) | | Chargeback | :TagComponent{tag="GET" text="/v1/chargebacks/{id}" href="/developers/en/reference/online-payments/checkout-api/chargebacks/get-chargeback/get" color="accent"} | :TagComponent{tag="GET" text="/v1/chargebacks/{id}" href="/developers/en/reference/online-payments/checkout-api/chargebacks/get-chargeback/get" color="accent"} (with a new notification topic) | > NOTE > > To learn about all endpoints and parameters in detail, see the :TagComponent{tag="API" text="API Reference" href="/developers/en/reference/online-payments/checkout-api/overview" color="accent"}. :::::: ::::::AccordionComponent{title="4\. Adapt the headers" pill="Required"} The \`Authorization\` header is required in both APIs and does not change. The main change is that the idempotency header becomes mandatory for almost all write operations. | Header | Payments API | Orders API | |---|---|---| | \`Authorization\` | Required in all requests | Required in all requests | | \`X-Idempotency-Key\` | Required only in :TagComponent{tag="POST" text="/v1/payments" href="/developers/en/reference/online-payments/checkout-api-payments/create-payment/post" color="green"} and :TagComponent{tag="POST" text="/v1/payments/{id}/refunds" href="/developers/en/reference/online-payments/checkout-api-payments/create-refund/post" color="green"} | Required in :TagComponent{tag="POST" text="/v1/orders" href="/developers/en/reference/online-payments/checkout-api/create-order/post" color="green"}, :TagComponent{tag="POST" text="/v1/orders/{order\_id}/capture" href="/developers/en/reference/online-payments/checkout-api/capture-order/post" color="green"}, :TagComponent{tag="POST" text="/v1/orders/{order\_id}/transactions" href="/developers/en/reference/online-payments/checkout-api/add-transaction-order/post" color="green"}, :TagComponent{tag="POST" text="/v1/orders/{order\_id}/process" href="/developers/en/reference/online-payments/checkout-api/process-order/post" color="green"}, :TagComponent{tag="POST" text="/v1/orders/{order\_id}/cancel" href="/developers/en/reference/online-payments/checkout-api/cancel-order/post" color="green"}, and :TagComponent{tag="POST" text="/v1/orders/{order\_id}/refund" href="/developers/en/reference/online-payments/checkout-api/refund-order/post" color="green"} | > NOTE > > If the same \`X-Idempotency-Key\` is reused with a different body, the Orders API returns the \`409\` error (\`idempotency\_key\_already\_used\`). Always generate a new key for each transaction attempt, preferably a UUID v4\. For more details about all headers accepted by the Orders API, see the :TagComponent{tag="API" text="API Reference" href="/developers/en/reference/online-payments/checkout-api/overview" color="accent"}. :::::: ::::::AccordionComponent{title="5\. Update the status model" pill="Required"} In the Payments API, \`status\` and \`status\_detail\` exist at a single level. In the Orders API, the same concept exists at two levels: the order status, as a consolidated view, and the status of each transaction in \`transactions.payments\[\]\`. This distinction becomes essential when an order has more than one transaction. :::::TabsComponent ::::TabComponent{title="Map status values"} The following table maps the \`status\` values between a payment in the Payments API and the order and transaction levels in the Orders API. | Payments API | Orders API (order) | Orders API (transaction) | Note | |---|---|---|---| | \`pending\` | \`action\_required\` | \`action\_required\` | Awaiting action from the payer or seller. | | \`approved\` | \`processed\` | \`processed\` | Payment approved and credited. | | \`authorized\` | \`action\_required\` (\`waiting\_capture\`) | \`action\_required\` (\`waiting\_capture\`) | Amount reserved, awaiting capture. | | \`in\_process\` | \`processing\` | \`processing\` | Under review or processing. | | \`in\_mediation\` | \`charged\_back\` (\`in\_process\`) | \`charged\_back\` (\`in\_process\`) | Chargeback in progress. | | \`rejected\` | \`failed\` | \`failed\` | Rejected. \`status\_detail\` provides the reason. | | \`cancelled\` | \`canceled\` | \`canceled\` | Canceled by the seller, buyer, or due to expiration. | | \`refunded\` | \`refunded\` | \`refunded\` | Fully refunded. | | \`charged\_back\` | \`charged\_back\` (\`settled\` / \`reimbursed\`) | \`charged\_back\` (\`settled\`/\`reimbursed\`) | Chargeback received and resolved. | > WARNING > > Note the spelling: the Payments API uses \`cancelled\`, with two Ls, and the Orders API uses \`canceled\`, with one L. If your integration compares this status value as a literal string, update the spelling. :::: ::::TabComponent{title="Map status\_detail values for card rejections"} The following table maps the main card rejection \`status\_detail\` values between the two APIs. | Payments API | Orders API | Description | |---|---|---| | \`cc\_rejected\_bad\_filled\_card\_number\` | \`bad\_filled\_card\_data\` | Card data entered incorrectly. | | \`cc\_rejected\_bad\_filled\_date\` | \`bad\_filled\_card\_data\` | Incorrect expiration date. | | \`cc\_rejected\_bad\_filled\_security\_code\` | \`bad\_filled\_card\_data\` | Incorrect security code. | | \`cc\_rejected\_call\_for\_authorize\` | \`required\_call\_for\_authorize\` | The issuer requires authorization from the cardholder. | | \`cc\_rejected\_card\_disabled\` | \`card\_disabled\` | Card disabled. | | \`cc\_rejected\_duplicated\_payment\` | \`processing\_error\` | Duplicate payment. In the Orders API, duplicate prevention is handled through \`X-Idempotency-Key\`. | | \`cc\_rejected\_high\_risk\` | \`high\_risk\` | Rejected by fraud prevention. | | \`cc\_rejected\_insufficient\_amount\` | \`insufficient\_amount\` or \`card\_insufficient\_amount\` | Both codes exist and have distinct meanings: \`insufficient\_amount\` indicates insufficient funds generically, while \`card\_insufficient\_amount\` indicates that the card has insufficient funds or credit limit. | | \`cc\_rejected\_invalid\_installments\` | \`invalid\_installments\` | Installment plan not allowed. | | \`cc\_rejected\_max\_attempts\` | \`max\_attempts\_exceeded\` | Number of attempts exceeded. | | \`cc\_rejected\_other\_reason\` | \`rejected\_by\_issuer\` | Generic issuer rejection. | | \`accredited\` | \`accredited\` | Credited successfully. Unchanged. | | \`pending\_waiting\_transfer\` | \`waiting\_transfer\` | Awaiting transfer. | | \`pending\_review\_manual\` | \`pending\_review\_manual\` | Under manual review. Unchanged. | | \`cc\_rejected\_3ds\_challenge\` | \`3ds\_challenge\_expired\` or \`cc\_rejected\_3ds\_challenge\` | 3DS challenge failure or expiration. | > NOTE > > Granular legacy codes, such as the multiple \`cc\_rejected\_bad\_filled\_\*\` codes, are consolidated into a single code in the Orders API. Adapt any buyer-facing message display logic that depends on the exact \`status\_detail\` value. The complete list is available in \[Transaction status\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-management/status/transaction-status). :::: ::::: > NOTE > > For more details about the status models in the Orders API, see \[Order status\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-management/status/order-status) and \[Transaction status\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-management/status/transaction-status). :::::: ::::::AccordionComponent{title="6\. Migrate payment creation to order creation" pill="Required"} The creation endpoint changes from :TagComponent{tag="POST" text="/v1/payments" href="/developers/en/reference/online-payments/checkout-api-payments/create-payment/post" color="green"} to :TagComponent{tag="POST" text="/v1/orders" href="/developers/en/reference/online-payments/checkout-api/create-order/post" color="green"}. In addition to the URL, the request structure has been reorganized: the amount and payment method move into the \`transactions.payments\[\]\` node, an array that allows multiple transactions per order. The \`type\` field, with the fixed value \`online\`, and the \`config\` node are introduced without direct equivalents in the legacy API. :::::TabsComponent ::::TabComponent{title="Map the request body fields"} The following table maps the creation request structure field by field between the two APIs. | Payments API | Orders API | Change | |---|---|---| | \`transaction\_amount\` | \`transactions.payments\[\].amount\` / \`total\_amount\` | Moves into the transactions array and becomes a string. \`total\_amount\` must match the sum of the transactions. | | \`payment\_method\_id\` | \`transactions.payments\[\].payment\_method.id\` | Becomes nested under \`payment\_method\`. | | \`token\` | \`transactions.payments\[\].payment\_method.token\` | Becomes nested under \`payment\_method\`. | | \`installments\` | \`transactions.payments\[\].payment\_method.installments\` | Becomes nested under \`payment\_method\`. | | \`statement\_descriptor\` | \`transactions.payments\[\].payment\_method.statement\_descriptor\` | Becomes nested under \`payment\_method\`. | | \`description\` | \`description\` | Unchanged. Remains at the root level. | | \`external\_reference\` | \`external\_reference\` | Name unchanged. Becomes required for some payment methods. | | \`notification\_url\` | Not available. | Removed from the body. Notifications are now configured in \[Your integrations\](https://www.mercadopago.com.ar/developers/panel/app). Learn more in \[Notifications\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/notifications). | | \`capture\` | \`capture\_mode\` | Changes from a boolean to the values \`manual\`, \`automatic\`, and \`automatic\_async\`, at the order root level. | | \`date\_of\_expiration\` | \`transactions.payments\[\].expiration\_time\` / \`date\_of\_expiration\` | Now accepts a duration in ISO 8601 format, in addition to an absolute date. | | \`payer.email\` | \`payer.email\` | Unchanged. | | \`payer.identification.type\` / \`.number\` | \`payer.identification.type\` / \`.number\` | Unchanged. | | \`payer.first\_name\` / \`.last\_name\` | \`payer.first\_name\` / \`.last\_name\` | Unchanged. | | \`payer.address.\*\` | \`payer.address.\*\` | Structure unchanged. | | \`three\_d\_secure\_mode\` | \`config.online.transaction\_security.validation\` and \`.liability\_shift\` | Restructured. Learn more in \[Integrate 3DS\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-management/integrate-3ds). | | \`items\[\].id\` | \`items\[\].external\_code\` | Renamed. | | \`items\[\].title\` / \`.unit\_price\` / \`.quantity\` / \`.description\` / \`.picture\_url\` / \`.category\_id\` | Same names | Names unchanged. | | Not available | \`type\` | New required field. For online payments, the value is \`online\`. | | Not available | \`processing\_mode\` | New field. Defines whether the order is processed in one step or later, through \`/process\`. | | Not available | \`integration\_data.{integrator\_id, platform\_id, sponsor.id}\` | New field. Partially replaces the legacy \`sponsor\_id\`. | | \`issuer\_id\` | \`transactions.payments\[\].payment\_method.id\` (implicitly) | There is no documented direct \`issuer\_id\` field. Validate the need on a case-by-case basis. | | \`binary\_mode\` | Not documented as an Orders API field | Restricted the result to approved or rejected. No direct equivalent found. | | \`application\_fee\` | Not documented in the Orders API. Validate with the team responsible for your integration before migrating integrations that use Split Payments 1:1\. | | | \`fee\_details\[\]\` | No documented direct equivalent | Fee details. Validate the calculation using money release reports. | > NOTE > > For more details about \`processing\_mode\` and \`capture\_mode\`, see \[Integration model\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/integration-model). :::: ::::TabComponent{title="Migrate credit and debit card creation"} The following table maps the main fields between creating a card payment in the Payments API and creating an equivalent order in the Orders API. | Field | Payments API | Orders API | Requirement | |---|---|---|---| | Card brand | \`payment\_method\_id\` | \`transactions.payments\[\].payment\_method.id\` | Required | | Card type | Inferred from \`payment\_method\_id\` | \`transactions.payments\[\].payment\_method.type\` (\`credit\_card\` / \`debit\_card\`) | Required | | Card token | \`token\` | \`transactions.payments\[\].payment\_method.token\` | Required | | Installments | \`installments\` | \`transactions.payments\[\].payment\_method.installments\` | Required | | Statement descriptor | \`statement\_descriptor\` | \`transactions.payments\[\].payment\_method.statement\_descriptor\` | Optional | > NOTE > > Client-side card tokenization continues to use MercadoPago.js V2, with no change to the flow. Confirm that you are using the latest version before migrating. For new integrations, we recommend Card Payment, which already builds the object in the format expected by the Orders API. For more details about the complete integration with the Orders API, see \[Cards\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-integration/websites/cards) and the :TagComponent{tag="API" text="API Reference" href="/developers/en/reference/online-payments/checkout-api/overview" color="accent"}. :::: ::::TabComponent{title="Compare a complete card request and response"} Use this card payment scenario as a reference to compare the structure of equivalent requests and responses in both APIs. ### Payments API \`\`\`curl curl -X POST 'https://api.mercadopago.com/v1/payments' \\ -H 'Authorization: Bearer {{YOUR\_ACCESS\_TOKEN}}' \\ -H 'Content-Type: application/json' \\ -H 'X-Idempotency-Key: {{SOME\_UNIQUE\_VALUE}}' \\ -d '{ "transaction\_amount": 50, "token": "{{CARD\_TOKEN}}", "description": "Test product", "installments": 1, "payment\_method\_id": "master", "payer": { "email": "test@testuser.com" } }' \`\`\` \`\`\`json { "id": 1234567890, "status": "approved", "status\_detail": "accredited", "transaction\_amount": 50 } \`\`\` ### Orders API \`\`\`curl curl -X POST 'https://api.mercadopago.com/v1/orders' \\ -H 'Authorization: Bearer {{YOUR\_ACCESS\_TOKEN}}' \\ -H 'Content-Type: application/json' \\ -H 'X-Idempotency-Key: {{SOME\_UNIQUE\_VALUE}}' \\ -d '{ "type": "online", "processing\_mode": "automatic", "total\_amount": "50.00", "external\_reference": "ext\_ref\_1234", "payer": { "email": "test@testuser.com" }, "transactions": { "payments": \[{ "amount": "50.00", "payment\_method": { "id": "master", "type": "credit\_card", "token": "{{CARD\_TOKEN}}", "installments": 1 } }\] } }' \`\`\` \`\`\`json { "id": "ORD01JS2V6CM8KJ0EC4H502TGK1WP", "status": "processed", "status\_detail": "accredited", "transactions": { "payments": \[ { "id": "PAY01JS2V6CM8KJ0EC4H504R7YE34", "status": "processed", "status\_detail": "accredited" } \] } } \`\`\` After creation, persist the \`id\`, \`status\`, and \`status\_detail\`. In the Orders API, also persist \`transactions.payments\[\].id\` and handle status values at both the order and transaction levels when retrieving :TagComponent{tag="GET" text="/v1/orders/{id}" href="/developers/en/reference/online-payments/checkout-api/get-order/get" color="accent"}. :::: ::::TabComponent{title="Migrate Rapipago and Pago Fácil creation"} The following table maps the fields and behavior of Rapipago and Pago Fácil between creating a payment in the Payments API and creating an order in the Orders API. | Field | Payments API | Orders API | |---|---|---| | Payment method | \`"payment\_method\_id": "rapipago"\` or \`"pagofacil"\` and without the \`type\` field. | \`"payment\_method.id": "rapipago"\` or \`"pagofacil"\` and \`".type": "ticket"\`, required and not available in the legacy API. | | Payer data | Only \`payer.email\` in the documented example. | \`payer.email\`, \`payer.first\_name\`, \`payer.last\_name\`, and \`payer.identification.{type, number}\` become required. | | Payment slip expiration | \`date\_of\_expiration\` (absolute date, between 1 and 30 days) | \`expiration\_time\` (ISO 8601 duration) | | Instructions link | \`transaction\_details.external\_resource\_url\` | \`transactions.payments\[\].payment\_method.ticket\_url\` | | Barcode | Not documented. | \`transactions.payments\[\].payment\_method.barcode\_content\` (in EAN-13 format) | | Reference | \`payment\_method\_reference\_id\` | \`transactions.payments\[\].payment\_method.reference\` | | Verification code | Not documented. | \`transactions.payments\[\].payment\_method.verification\_code\` | | Initial status | \`pending\` / \`pending\_waiting\_payment\` | \`action\_required\` / \`waiting\_payment\` | | Country in the response | Not available. | \`country\_code: "ARG"\` (new field) | > NOTE > > A Rapipago or Pago Fácil payment slip can only be canceled while its status is \`action\_required\`. After 30 days without payment, the order expires automatically. For more details about the complete integration with the Orders API, see \[Rapipago and Pago Fácil\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-integration/websites/rapipago-pagofacil) and the :TagComponent{tag="API" text="API Reference" href="/developers/en/reference/online-payments/checkout-api/overview" color="accent"}. :::: ::::: :::::: ::::::AccordionComponent{title="7\. Adapt the creation response fields" pill="Required"} The following table maps the main fields in the creation response between the two APIs. | Payments API | Orders API | Change | |---|---|---| | \`id\` | \`id\` | Format changes from numeric to alphanumeric with the \`ORD\` prefix. | | \`status\` | \`status\` / \`transactions.payments\[\].status\` | Now exists at two levels. | | \`status\_detail\` | \`status\_detail\` / \`transactions.payments\[\].status\_detail\` | Now exists at two levels. | | \`transaction\_amount\` | \`total\_amount\` / \`transactions.payments\[\].amount\` | Now exists at two levels and changes to a string. | | \`transaction\_amount\_refunded\` | \`transactions.refunds\[\].amount\` / \`status\_detail: partially\_refunded\` | Restructured as a refund array. | | \`date\_created\` | \`created\_date\` | Renamed. | | \`date\_last\_updated\` | \`last\_updated\_date\` | Renamed. | | \`payment\_method\_id\` | \`transactions.payments\[\].payment\_method.id\` | Becomes nested. | | \`payment\_type\_id\` | \`transactions.payments\[\].payment\_method.type\` | Renamed and nested. | | \`collector\_id\` | Does not exist | Removed from the creation response. | | \`point\_of\_interaction.transaction\_data.\*\` | \`transactions.payments\[\].payment\_method.{qr\_code, qr\_code\_base64, ticket\_url}\` | Restructured under \`payment\_method\`. | | \`transaction\_details.external\_resource\_url\` | \`transactions.payments\[\].payment\_method.ticket\_url\` | Renamed. | | Not available | \`total\_paid\_amount\` | New field. Total amount actually paid. | | Not available | \`capture\_mode\` | New field. Configured capture mode. | | Not available | \`processing\_mode\` | New field. Configured processing mode. | | Not available | \`country\_code\` | New field. Country code. | | \`card.{...}\` | Not returned at creation. The response includes only the \`token\` and payment identifier. | Reduced. Use the \[Save cards\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/saved-cards) endpoints for persisted card data. | | Not available | \`client\_token\` | New field. Client-side tracking token. | > NOTE > > To learn about all response fields in detail, see :TagComponent{tag="POST" text="/v1/orders" href="/developers/en/reference/online-payments/checkout-api/create-order/post" color="green"}. :::::: ::::::AccordionComponent{title="8\. Update creation error handling" pill="Required"} The Payments API returns one error at a time, the first one found. The Orders API returns a list with all request validation errors in a single response, making corrections faster. :::::TabsComponent ::::TabComponent{title="Renamed or consolidated errors"} The following table lists Payments API errors that were renamed or consolidated into more generic codes in the Orders API. | HTTP | Payments API | Orders API | Note | |---|---|---|---| | \`400\` | \`3000\` to \`3032\` | \`property\_value\` / \`property\_type\` / \`required\_properties\` | Consolidated into generic field validation codes. | | \`400\` | \`4000\` to \`4051\` | \`required\_properties\` / \`unsupported\_properties\` / \`minimum\_properties\` | Consolidated. | | \`400\` | \`23\` | \`property\_value\` | Invalid \`date\_of\_expiration\` format. | | \`400\` | \`2072\` | \`invalid\_total\_amount\` | Renamed. Now validates the sum of \`transactions.payments\[\].amount\` against \`total\_amount\`. | | \`400\` | \`2131\` | \`invalid\_order\_type\` / \`property\_value\` | Consolidated. | | \`400\` | \`4292\` | \`empty\_required\_header\` | Renamed. | | \`401\` | \`Unauthorized use of live credentials\` | \`invalid\_credentials\` | Renamed. | | \`409\` | \`2001\` | \`idempotency\_key\_already\_used\` | Consolidated into the idempotency mechanism. | | \`403\` | \`4\` (caller not authorized) | Not documented as a specific 403 error in the Orders API | Validate the behavior in the test environment. | :::: ::::TabComponent{title="Errors introduced by the Orders API"} The following table lists errors that did not exist in the Payments API and are introduced by the Orders API. | HTTP | Error | Note | |---|---|---| | \`400\` | \`invalid\_idempotency\_key\_length\` | The \`X-Idempotency-Key\` exceeded the permitted length of 1 to 128 characters. | | \`400\` | \`minimum\_items\` / \`maximum\_items\` | Number of array items outside the permitted range. | | \`400\` | \`invalid\_email\_for\_sandbox\` | Invalid email for the test environment. It must contain \`@testuser.com\`. | | \`400\` | \`order\_invalid\_sponsor\_id\` | Invalid sponsor identifier. | | \`400\` | \`invalid\_header\_value\` | Caller identifier (\`caller\_id\`) not found. | | \`400\` | \`order\_builder\_without\_transactions\` | The \`transactions\` node of an order in manual mode cannot be an empty array. Send \`null\`. | | \`402\` | No code | The order was created, but one or more transactions failed. Check the error field in the response. | | \`409\` | \`idempotency\_key\_already\_used\` | Idempotency key already used with a different body. | | \`423\` | \`resource\_locked\` | Idempotency key temporarily locked. Repeat the request after a few moments. | | \`429\` | \`usage\_quota\_exceeded\` | Request limit reached. Respect the \`Retry-After\` header and implement exponential backoff. | | \`500\` | \`idempotency\_validation\_failed\` | Idempotency key validation failed. Resend with a new key. | :::: ::::TabComponent{title="Errors that remain unchanged"} The following table lists errors that have the same behavior in both APIs. | HTTP | Error | Note | |---|---|---| | \`500\` | \`internal\_error\` | Generic error. Try again and, if it persists, contact support with the \`x-request-id\`. | :::: ::::: > NOTE > > For the complete list of Orders API errors, see \[Possible errors\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-management/integration-errors). :::::: ::::::AccordionComponent{title="9\. Implement order retrieval" pill="Required"} The retrieval endpoint changes from :TagComponent{tag="GET" text="/v1/payments/{id}" href="/developers/en/reference/online-payments/checkout-api-payments/get-payment/get" color="accent"} to :TagComponent{tag="GET" text="/v1/orders/{id}" href="/developers/en/reference/online-payments/checkout-api/get-order/get" color="accent"}. The response includes the complete order object, including all associated transactions, their refunds, and any chargebacks—information that required separate queries in the legacy API. | Information | Payments API | Orders API | |---|---|---| | Refunds | Separate query at :TagComponent{tag="GET" text="/v1/payments/{id}/refunds" href="/developers/en/reference/online-payments/checkout-api-payments/get-refunds/get" color="accent"}. | Included in \`transactions.refunds\[\]\` | | Chargebacks | Separate query at :TagComponent{tag="GET" text="/v1/chargebacks/{id}" href="/developers/en/reference/online-payments/checkout-api/chargebacks/get-chargeback/get" color="accent"}. | Referenced in \`transactions.chargebacks\[\]\`, with \`id\`, \`transaction\_id\`, \`case\_id\`, \`status\`, and \`references\`. | | 3DS data | \`payment\_method.data.threeds\` | \`transactions.payments\[\].payment\_method.transaction\_security\` | | Installments without Card and installment options | Not applicable to this endpoint. | \`config.payment\_method.{default\_type, installments\_cost, installments.interest\_free, installments.available}\` | ### Retrieval errors | HTTP | Error | Note | |---|---|---| | \`400\` | \`invalid\_path\_param\` | The submitted \`order\_id\` has an invalid format. | | \`401\` | \`invalid\_credentials\` | Invalid or expired Access Token. | | \`404\` | \`order\_not\_found\` | The \`order\_id\` does not match any created order. | | \`500\` | \`internal\_error\` | Generic error. Try again and, if it persists, contact support with the \`x-request-id\`. | :::::: ::::::AccordionComponent{title="10\. Update search" pill="Required"} The search endpoint changes from :TagComponent{tag="GET" text="/v1/payments/search" href="/developers/en/reference/online-payments/checkout-api-payments/search-payments/get" color="accent"} to :TagComponent{tag="GET" text="/v1/orders/search" href="/developers/en/reference/online-payments/checkout-api/search-order/get" color="accent"}, with restructured filters and pagination. Date ranges become required, and pagination uses \`page\` and \`page\_size\` instead of \`offset\` and \`limit\`. | Payments API | Orders API | Note | |---|---|---| | \`sort\` | \`sort\_by\` | Renamed. The default is \`created\_date\`. | | \`criteria\` | \`sort\_order\` | Renamed. The default is \`desc\`. | | \`begin\_date\` / \`end\_date\` | \`begin\_date\` / \`end\_date\` | Become required, in RFC3339 format. | | \`external\_reference\` | \`external\_reference\` | Unchanged. | | \`collector.id\` / \`payer.id\` | Not documented as filters. | Identity is obtained from the Access Token. | | \`offset\` / \`limit\` | \`page\` / \`page\_size\` | Page-based pagination. \`page\_size\` has a maximum of 100 and a default of 20\. | | Not available | \`status\` / \`status\_detail\` / \`payment\_method\_id\` / \`payment\_method\_type\` | New direct filters. | > NOTE > > For all filters available in the Orders API, see the :TagComponent{tag="GET" text="/v1/orders" href="/developers/en/reference/online-payments/checkout-api/search-order/get" color="accent"} endpoint. :::::: ::::::AccordionComponent{title="11\. Reserve, capture, and cancel amounts" pill="Based on your flow"} The amount reservation changes from a boolean field (\`capture\`) to a capture mode configured when creating the order (\`capture\_mode\`), combined with a dedicated capture endpoint. :::::TabsComponent ::::TabComponent{title="Reserve amounts"} The following table compares how to reserve an amount without immediate capture in both APIs. | Payments API | Orders API | |---|---| | :TagComponent{tag="POST" text="/v1/payments" href="/developers/en/reference/online-payments/checkout-api-payments/create-payment/post" color="green"} with \`"capture": "false"\`. | :TagComponent{tag="POST" text="/v1/orders" href="/developers/en/reference/online-payments/checkout-api/create-order/post" color="green"} with \`"capture\_mode": "manual"\`. | | Result: \`"status": "authorized"\`. | Result: \`"status": "action\_required"\` and \`"status\_detail": "waiting\_capture"\`. | :::: ::::TabComponent{title="Capture authorized payment"} The following table compares how to capture a previously authorized payment in both APIs. | Payments API | Orders API | |---|---| | :TagComponent{tag="PUT" text="/v1/payments/{id}" href="/developers/en/reference/online-payments/checkout-api-payments/update-payment/put" color="orange"} (with \`"capture": "true"\`) | :TagComponent{tag="POST" text="/v1/orders/{order\_id}/capture" href="/developers/en/reference/online-payments/checkout-api/capture-order/post" color="green"} | | Supports partial capture (by sending a smaller \`transaction\_amount\`). | Supports full capture. | | Result: \`status\` changes from \`authorized\` to \`approved\`. | Result: \`"status": "processed"\` and \`"status\_detail": "accredited"\`. | > WARNING > > The capture timeframe in the Orders API is up to 5 days from order creation. If it is not captured within this period, the order is canceled automatically. If your integration depends on partial capture, validate this flow before \[going to production\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/go-to-production). For more information, see \[Reserve and capture amounts\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-management/reserve-capture-cancel). :::: ::::TabComponent{title="Cancel reservation"} The following table compares how to cancel an amount reservation in both APIs. | Payments API | Orders API | |---|---| | :TagComponent{tag="PUT" text="/v1/payments/{id}" href="/developers/en/reference/online-payments/checkout-api-payments/create-cancellation/put" color="orange"} with \`"status": "cancelled"\` | :TagComponent{tag="POST" text="/v1/orders/{order\_id}/cancel" href="/developers/en/reference/online-payments/checkout-api/cancel-order/post" color="green"} | :::: ::::: > NOTE > > For more details, see \[Reserve and capture amounts\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-management/reserve-capture-cancel). :::::: ::::::AccordionComponent{title="12\. Update cancellations and refunds" pill="Required"} As in the Payments API, you can cancel an order before payment is completed or refund it, fully or partially, after approval. See below how each flow changes in the Orders API. :::::TabsComponent ::::TabComponent{title="Adapt cancellation"} An order can only be canceled when its status is \`action\_required\` or \`created\`, meaning the payment has not yet been completed. The endpoint changes from :TagComponent{tag="PUT" text="/v1/payments/{id}" href="/developers/en/reference/online-payments/checkout-api-payments/create-cancellation/put" color="orange"} to the dedicated :TagComponent{tag="POST" text="/v1/orders/{order\_id}/cancel" href="/developers/en/reference/online-payments/checkout-api/cancel-order/post" color="green"} endpoint. :::: ::::TabComponent{title="Adapt refunds"} A refund is made by sending a request to the :TagComponent{tag="POST" text="/v1/orders/{order\_id}/refund" href="/developers/en/reference/online-payments/checkout-api/refund-order/post" color="green"} endpoint. A full refund is made by sending the body without the \`transactions\` array. A partial refund requires the specific transaction identifier and the amount to be returned—unlike the legacy API, where specifying the amount was enough because there was only one transaction per payment. | Field | Payments API | Orders API | |---|---|---| | Endpoint | :TagComponent{tag="POST" text="/v1/payments/{id}/refunds" href="/developers/en/reference/online-payments/checkout-api-payments/create-refund/post" color="green"} | :TagComponent{tag="POST" text="/v1/orders/{order\_id}/refund" href="/developers/en/reference/online-payments/checkout-api/refund-order/post" color="green"} | | Full refund | Empty body. | Body without the \`transactions\` node. | | Partial refund | \`{ "amount": }\` | \`{ "transactions": \[{ "id": , "amount": }\] }\` | | Refund identifier | \`id\` (at the refund level) | \`transactions.refunds\[\].id\` | | Refund status | \`approved\` / \`in\_process\` / \`rejected\` / \`cancelled\` / \`authorized\` | \`processed\` / \`refunded\` - \`"status\_detail": "refunded"\` / \`"status\_detail": "partially\_refunded"\` | | Refund timeframe | Up to 180 days after approval. | Up to 180 days after approval. | | Get refund | :TagComponent{tag="GET" text="/v1/payments/{id}/refunds/{refund\_id}" href="/developers/en/reference/online-payments/checkout-api-payments/get-refund/get" color="accent"} | :TagComponent{tag="GET" text="/v1/orders/{id}" href="/developers/en/reference/online-payments/checkout-api/get-order/get" color="accent"} (under \`transactions.refunds\[\]\`) | :::: ::::: > NOTE > > For more details about these processes in the Orders API, see \[Refunds and cancellations\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-management/refunds-cancellations) and the :TagComponent{tag="API" text="API Reference" href="/developers/en/reference/online-payments/checkout-api/overview" color="accent"}. :::::: ::::::AccordionComponent{title="13\. Keep saved cards, customers, and addresses" pill="Based on your flow"} The Customers API endpoints are used by both the Payments API and the Orders API and do not change structure during migration. Only the way a saved card is used for a new charge changes, because the payment is now created as an order. | Resource | Endpoint unchanged between APIs | |---|---| | Create customer | :TagComponent{tag="POST" text="/v1/customers" href="/developers/en/reference/online-payments/checkout-api/customers/create-customer/post" color="green"} | | Search customers | :TagComponent{tag="GET" text="/v1/customers/search" href="/developers/en/reference/online-payments/checkout-api/customers/search-customer/get" color="accent"} | | Get customer | :TagComponent{tag="GET" text="/v1/customers/{id}" href="/developers/en/reference/online-payments/checkout-api/customers/get-customer/get" color="accent"} | | Update customer | :TagComponent{tag="PUT" text="/v1/customers/{id}" href="/developers/en/reference/online-payments/checkout-api/customers/update-customer/put" color="orange"} | | Save card | :TagComponent{tag="POST" text="/v1/customers/{customer\_id}/cards" href="/developers/en/reference/online-payments/checkout-api/cards/save-card/post" color="green"} | | List customer cards | :TagComponent{tag="GET" text="/v1/customers/{customer\_id}/cards" href="/developers/en/reference/online-payments/checkout-api/cards/get-customer-cards/get" color="accent"} | | Get card | :TagComponent{tag="GET" text="/v1/customers/{customer\_id}/cards/{id}" href="/developers/en/reference/online-payments/checkout-api/cards/get-card/get" color="accent"} | | Update card | :TagComponent{tag="PUT" text="/v1/customers/{customer\_id}/cards/{id}" href="/developers/en/reference/online-payments/checkout-api/cards/update-card/put" color="orange"} | | Delete card | :TagComponent{tag="DELETE" text="/v1/customers/{customer\_id}/cards/{id}" href="/developers/en/reference/online-payments/checkout-api/cards/delete-card/delete" color="red"} | | Customer addresses | :TagComponent{tag="POST" text="/v1/customers/{id}/addresses" href="/developers/en/reference/online-payments/checkout-api/addresses/create-address/post" color="green"}, :TagComponent{tag="GET" text="/v1/customers/{id}/addresses" href="/developers/en/reference/online-payments/checkout-api/addresses/list-addresses/get" color="accent"}, :TagComponent{tag="PUT" text="/v1/customers/{id}/addresses/{address\_id}" href="/developers/en/reference/online-payments/checkout-api/addresses/update-address/put" color="orange"}, and :TagComponent{tag="DELETE" text="/v1/customers/{id}/addresses/{address\_id}" href="/developers/en/reference/online-payments/checkout-api/addresses/delete-address/delete" color="red"} | What changes when paying with a saved card: | Payments API | Orders API | |---|---| | \`"payer.type": "customer"\`/ \`"payer.id": ""\` / \`token\` (generated using only the security code) | \`"payer.customer\_id": ""\` / \`transactions.payments\[\].payment\_method.token\` | | :TagComponent{tag="POST" text="/v1/payments" href="/developers/en/reference/online-payments/checkout-api-payments/create-payment/post" color="green"} | :TagComponent{tag="POST" text="/v1/orders" href="/developers/en/reference/online-payments/checkout-api/create-order/post" color="green"} | > NOTE > > Mercado Pago does not store the security code in either API. The flow to collect this data again remains identical. For more information, see \[Save cards\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/saved-cards). :::::: ::::::AccordionComponent{title="14\. Marketplace and Split Payments 1:1" pill="Based on your flow"} In the Payments API, marketplace integrations use \[OAuth\](https://www.mercadopago.com.ar/developers/en/docs/security/oauth) to obtain the connected seller's Access Token and send the \`application\_fee\` field, with the amount withheld by the integrator, in the payment creation body. > NOTE > > The Orders API does not yet have a documented explicit field equivalent to \`application\_fee\`. The \`integration\_data.sponsor.id\` node exists, but it does not replace the commission withholding mechanism. If your integration depends on Split Payments 1:1 or a Marketplace model, validate this point before migrating this specific flow and do not assume parity. :::::: ::::::AccordionComponent{title="15\. Integrate 3DS 2.0" pill="Based on your flow"} 3D Secure 2.0 authentication changes from a simple field to a dedicated configuration node at \`config.online.transaction\_security\`, with explicit control over chargeback liability. | Payments API | Orders API | Description | |---|---|---| | \`"three\_d\_secure\_mode": "optional"\` | \`"config.online.transaction\_security.validation": "on\_fraud\_risk"\` | Runs 3DS when the risk engine identifies that it is required. Recommended. | | \`"three\_d\_secure\_mode": "not\_supported"\` | \`config.online.transaction\_security.validation: "never"\` | Explicitly disables 3DS. This is the default value. | | Not available | \`config.online.transaction\_security.liability\_shift: "required"\` | Shifts chargeback liability to the issuer. Required when \`validation\` is anything other than \`never\`. | | Challenge response: \`"status": "pending"\`, with \`creq\` and \`external\_resource\_url\` fields. | Challenge response: \`"status = action\_required"\`, \`"status\_detail" = "pending\_challenge"\`, and URL at \`transactions.payments\[\].payment\_method.transaction\_security.url\`. | Renamed and restructured. | | Challenge timeout not documented | 40-minute challenge timeout. | Timeframe explicitly defined. | | Restriction: \`"capture": "true"\` and \`"binary\_mode": "false"\` required. | No equivalent restrictions documented. | Confirm the behavior with a \`capture\_mode\` other than \`automatic\` in the test environment. | Possible statuses after the 3DS flow in the Orders API: | \`status\` | \`status\_detail\` | Description | |---|---|---| | \`processed\` | \`accredited\` | Approved, with or without authentication. | | \`failed\` | \`failed\` | Rejected, without authentication or after authentication failure. | | \`action\_required\` | \`pending\_challenge\` | Authentication pending, for up to 40 minutes. | | \`canceled\` | \`expired\` | The challenge expired. A new order must be created. | > WARNING > > 3DS cannot be tested in production in either API. Always use test credentials. The test cards and \`cardholder\_name\` values used to simulate each scenario differ between the two APIs, so use the table specific to the Orders API. For more information about this flow, see \[Integrate 3DS\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-management/integrate-3ds). :::::: ::::::AccordionComponent{title="16\. Update notifications" pill="Required"} The \`HMAC-SHA256\` signature and validation mechanism is identical in both APIs. What changes is the notification topic and where it is configured. | Payments API | Orders API | Note | |---|---|---| | \`payment\` topic | \`orders\` topic | Main change. Reconfigure the Webhook for the new topic. | | Configurable through \`notification\_url\` in the body or in the panel. | Configurable only in the panel, under \[Your integrations\](https://www.mercadopago.com.ar/developers/panel/app) | The option to configure it per request has been removed. | | Resource to query: :TagComponent{tag="GET" text="/v1/payments/{id}" href="/developers/en/reference/online-payments/checkout-api-payments/get-payment/get" color="accent"}. | Resource to query: :TagComponent{tag="GET" text="/v1/orders/{id}" href="/developers/en/reference/online-payments/checkout-api/get-order/get" color="accent"}. | The endpoint changes. | | IPN available and without signature validation. | Not available. | Use only Webhooks in the new integration. | | 22-second response timeframe and retries every 15 minutes. | 22-second response timeframe and retries every 15 minutes. | Unchanged. | > NOTE > > For more details about the configuration and payload format, see \[Notifications\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/notifications). :::::: ::::::AccordionComponent{title="17\. Adapt chargebacks" pill="Based on your flow"} The chargeback retrieval endpoint :TagComponent{tag="GET" text="/v1/chargebacks/{id}" href="/developers/en/reference/online-payments/checkout-api/chargebacks/get-chargeback/get" color="accent"} is identical in both APIs. The difference is in the notification event and the new fields exposed directly in the order. | Payments API | Orders API | Note | |---|---|---| | Notification through the \`topic\_chargebacks\_wh\` topic | Notification through the \*\*Chargebacks\*\* event, in the \`chargebacks\` topic, with \`"action": "order.charged\_back"\`. | Configure this event in addition to \*\*Order (Mercado Pago)\*\*. | | Payment status: \`charged\_back\` | Order and transaction status: \`charged\_back\`, with \`"status\_detail": "in\_process"\`, \`"settled"\`, or \`"reimbursed"\`. | Additional \`status\_detail\` information. | | Retrieval via :TagComponent{tag="GET" text="/v1/chargebacks/{id}" href="/developers/en/reference/online-payments/checkout-api/chargebacks/get-chargeback/get" color="accent"}. | Retrieval via :TagComponent{tag="GET" text="/v1/chargebacks/{id}" href="/developers/en/reference/online-payments/checkout-api/chargebacks/get-chargeback/get" color="accent"}. | Unchanged. | > NOTE > > The following endpoints are also available: :TagComponent{tag="GET" text="/v1/chargebacks/search" href="/developers/en/reference/online-payments/checkout-api/chargebacks/search-chargebacks/get" color="accent"} to search chargebacks using a \`payment\_id\`, :TagComponent{tag="POST" text="/v1/chargebacks/{id}/documentation" href="/developers/en/reference/online-payments/checkout-api/chargebacks/upload-supporting-documentation/post" color="green"} to submit supporting documentation; and :TagComponent{tag="GET" text="/v1/chargebacks/documentation/{type}/{uuid}" href="/developers/en/reference/online-payments/checkout-api/chargebacks/get-supporting-documentation/get" color="accent"} to retrieve a previously submitted file. The resolution fields are identical in both APIs. | Field | Value | Description | |---|---|---| | \`coverage\_applied\` | \`true\` | Decision in favor of the seller. The amount is returned to the seller. | | \`coverage\_applied\` | \`false\` | Decision against the seller. The amount is deducted from the seller. | > NOTE > > For more information, see \[Manage chargebacks\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-management/chargebacks/management) and \[Chargeback notifications\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-management/chargebacks/notifications). :::::: ::::::AccordionComponent{title="18\. Improve payment approval" pill="Based on your flow"} Fraud prevention best practices remain conceptually the same. What changes is where additional data is sent in the request body. | Practice | Payments API | Orders API | |---|---|---| | Device ID | Security script and \`X-meli-session-id\` header in :TagComponent{tag="POST" text="/v1/payments" href="/developers/en/reference/online-payments/checkout-api-payments/create-payment/post" color="green"} | :TagComponent{tag="POST" text="/v1/orders" href="/developers/en/reference/online-payments/checkout-api/create-order/post" color="green"} (same mechanism) | | Additional buyer and product data | \`additional\_info.{items\[\], payer, shipments}\` | Distributed among \`items\[\]\` / \`payer\` / \`shipment\` (without the consolidated \`additional\_info\` node) | | Recognizable statement descriptor | \`statement\_descriptor\` (at the root level) | \`transactions.payments\[\].payment\_method.statement\_descriptor\` | | Industry data | \`additional\_info.travel.{passengers, routes}\` | Data is sent in the order structure. See \[Industry data\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-management/improve-payment-approval/industry-data); the examples, including \`category\_id\`, are not a closed list of values. | > NOTE > > For more details, see \[Improve payment approval\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/payment-management/improve-payment-approval/recommendations) in the Orders API. :::::: ::::::AccordionComponent{title="19\. Test the integration" pill="Required"} The use of test credentials, users, and cards follows the same approach. The main difference is the email required for the payer and the table of cardholder names used to simulate each scenario. | Item | Payments API | Orders API | |---|---|---| | Card test email | Test-user email pattern | \`test@testuser.com\` (the only accepted value) | | Simulating scenarios through the cardholder name | \`APRO\` / \`OTHE\` / \`CONT\` / \`CALL\` / \`FUND\` / \`SECU\` / \`EXPI\` / \`FORM\` | \`CARD\` / \`INST\` / \`DUPL\` / \`LOCK\` / \`CTNA\` / \`ATTE\` / \`BLAC\` / \`UNSU\` / \`TEST\` (expanded set) | | Result verification | :TagComponent{tag="GET" text="/v1/payments/{id}" href="/developers/en/reference/online-payments/checkout-api-payments/get-payment/get" color="accent"} | :TagComponent{tag="GET" text="/v1/orders/{id}" href="/developers/en/reference/online-payments/checkout-api/get-order/get" color="accent"} | > NOTE > > To consult the Orders API \`cardholder\_name\` values, see \[Test cards\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/resources/test-cards). For more details about the flow, see \[Test the integration\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/integration-test). :::::: ::::::AccordionComponent{title="20\. Measure the quality of the migrated integration" pill="Required"} The Orders API evaluation considers the following aspects to measure the quality of the migrated integration. | Evaluated aspect | Payments API | Orders API | |---|---|---| | Use of the official SDK for tokenization | Evaluated | Evaluated | | Device ID | Evaluated | Evaluated | | Handling of status and \`status\_detail\` | Evaluated | Evaluated (including the transaction level) | | Use of \`X-Idempotency-Key\` | Evaluated (only for creation and refunds) | Evaluated (for all write operations) | | Reconciliation with multiple transactions | Not applicable | Evaluated | | Use of 3DS when applicable | Not evaluated | Evaluated | Before \[going to production\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/go-to-production), confirm the following: - Activate production credentials in \[Your integrations\](https://www.mercadopago.com.ar/developers/panel/app). - Replace the test Public Key and Access Token with their production versions. - Implement an SSL/HTTPS certificate, which is required in production. - Reconfigure the Webhook for the \`orders\` topic. Disable the \`payment\` topic only after migrating new traffic and completing monitoring of outstanding Payments API transactions and notifications. - Ensure that all \`status\` and \`status\_detail\` values are handled at both the order and transaction levels. > NOTE > > For more details, see \[Integration quality\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/integration-quality) and \[Go to production\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/go-to-production). :::::: ::::::AccordionComponent{title="21\. Validate the migration" pill="Required"} After applying the changes, verify that the integration works correctly in all flows before going to production. Use the checkboxes below to confirm each point. ### Required validations :::CheckboxComponent{label="Server-side SDKs updated to the latest version, with Orders API support" defaultChecked="false"} ::: :::CheckboxComponent{label="Header 'X-Idempotency-Key' configured for all write operations" defaultChecked="false"} ::: :::CheckboxComponent{label="Field 'notification\_url' removed from the body and notifications reconfigured in Your integrations" defaultChecked="false"} ::: :::CheckboxComponent{label="Order creation validated for each migrated payment method" defaultChecked="false"} ::: :::CheckboxComponent{label="Field 'id' captured from the creation response, in ORD format, for use in subsequent operations" defaultChecked="false"} ::: :::CheckboxComponent{label="Order retrieval validated, including reading refunds and chargebacks from the response" defaultChecked="false"} ::: :::CheckboxComponent{label="Search migrated to 'GET /v1/orders' with the new pagination and required date filters" defaultChecked="false"} ::: :::CheckboxComponent{label="Webhook configured for the orders topic, with the new status values mapped" defaultChecked="false"} ::: :::CheckboxComponent{label="Orders and payment topics processed in parallel during the transition, with each payload routed to the correct flow" defaultChecked="false"} ::: :::CheckboxComponent{label="Production credentials activated and SSL/HTTPS certificate implemented" defaultChecked="false"} ::: \### Validations based on your flow :::CheckboxComponent{label="Reservation and capture flow validated with 'capture\_mode=manual'" defaultChecked="false"} ::: :::CheckboxComponent{label="Order cancellation validated" defaultChecked="false"} ::: :::CheckboxComponent{label="Full and partial refunds validated, including the new transaction-level format" defaultChecked="false"} ::: :::CheckboxComponent{label="Chargebacks event, in the chargebacks topic, configured and chargeback flow validated" defaultChecked="false"} ::: :::CheckboxComponent{label="3DS 2.0 flow tested in the test environment (if applicable)" defaultChecked="false"} ::: :::CheckboxComponent{label="Use of Marketplace or Split Payments 1:1 validated before migration (if applicable)" defaultChecked="false"} ::: \### Validations for flows that do not yet have an equivalent :::CheckboxComponent{label="Flows without a documented equivalent kept in the Payments API until support is announced" defaultChecked="false"} ::: > NOTE > > After completing this list, see \[Go to production\](https://www.mercadopago.com.ar/developers/en/docs/checkout-api-orders/go-to-production) for the next steps. ::::::