# MD for: https://www.mercadopago.com.mx/developers/en/docs/qr-code-ca/payment-processing.md \# Integrate transaction processing Transaction processing with QR code is performed through the creation of orders that include withdrawals without an associated purchase. When creating an order, the customer will be able to perform transactions in person by scanning the code. There are three QR Code models available for integration, defined at the time of order creation: \* \*\*Static model\*\*: In this model, a single QR code associated with the previously created POS receives the information from each generated order. \* \*\*Dynamic model\*\*: An exclusive and single-use QR code is generated for each transaction, containing the specific data of the created order. \* \*\*Hybrid model\*\*: Allows the cashout to be made both through the static QR and the dynamic one. The order is linked to the static QR code of the POS, while a dynamic QR is also generated simultaneously. Once the cashout transaction is made with either code, the other will be automatically disabled for use. This integration allows you to create, process and cancel orders, in addition to making refunds and querying information and status updates for cash-out transactions. > WARNING > > The cash withdrawal feature is only available for Managed Wallet clients. Therefore, if you are a seller and need this functionality, you must request activation from your account manager. :::::AccordionComponent{title="Create an order with cash-out"} To configure cash withdrawal transaction processing with QR Code, it is necessary to identify the store and POS to which the order will be associated. Remember that both the store and the POS must have been \[previously created\](https://www.mercadopago.com.mx/developers/en/docs/qr-code-ca/create-store-and-pos). Next, you can create the order for cash-out. To do this, send a \*\*POST\*\* request to the endpoint :TagComponent{tag="API" text="/v1/orders" href="/developers/en/reference/in-person-payments/qr-code-ca/orders/create-order/post"}, including your :toolTipComponent\[Test Access Token\]{link="/developers/en/docs/qr-code-ca/create-application" linkText="Access test credentials" content="Private key of the application created in Mercado Pago, which is used in the backend. You can access it through \*Your integrations > Integration data > Test > Test credentials\*. During integration, use the Test Access Token and, when finished, replace it with the Production Access Token if it is your own integration, or with the Access Token obtained through OAuth in the case of third-party integrations. For more information, go to the documentation."}. Also, make sure to include the \`external\_pos\_id\` of the POS to which you want to assign the order, obtained in the previous step. \`\`\`curl curl --location --request POST 'https://api.mercadopago.com/v1/orders' \\ --header 'X-Idempotency-Key: 02ff8cd0-c4e9-4fe8-a977-6c3c2bc6336c' \\ --header 'Content-Type: application/json' \\ --header 'Authorization: Bearer {{ACCESS\_TOKEN}}' \\ --data '{ "type": "qr", "total\_amount": "50.00", "expiration\_time": "PT15M", "config": { "qr": { "external\_pos\_id": "EXTERNALPOS019285", "mode": "static" } }, "transactions": { "cash\_outs": \[ { "amount": "50.00", "additional\_info":{ "external\_cashier\_id": 123445 } } \] } }' \`\`\` | Parameter | Type | Description | Required | | ---- | ---- | ---- | ---- | | \`X-Idempotency-Key\` | \*header\* | Idempotency key. This key ensures that each request is processed only once, avoiding duplicates. Use a unique value in the request \`header\`, such as a UUID (Universally Unique Identifier) V4 or a random \*string\*. | Required | | \`type\` | \*string\* | Type of order, associated with the Mercado Pago solution for which it was created. For Mercado Pago QR Code transactions, the only possible value is \*qr\*, which is the value associated with creating orders for Mercado Pago QR Code transactions. | Required | | \`external\_reference\` | \*string\* | It is the external reference of the order, assigned at the time of creation. The maximum allowed limit is 64 characters and the allowed ones are: uppercase and lowercase letters, numbers and the hyphen (-) and underscore (\_) symbols. The field cannot be used to send PII data. | Required | | \`expiration\_time\` | \*string\* | Specifies the order's validity period in ISO 8601 duration format (e.g., P3Y6M4DT12H30M5S). Minimum of 30 seconds and maximum of 3600 hours. In all modes (Dynamic QR, Static QR, and Hybrid QR), the default value is 15 minutes and the value sent is always respected. | Optional | | \`config.qr.external\_pos\_id\` | \*string\* | External identifier of the POS, defined by the integrator during its creation. By including it, the order information is associated with the POS and store previously created within the Mercado Pago system. Important: The \`external\_pos\_id\` field must have the same value defined as \`external\_id\` when creating your POS. | Required | | \`config.qr.mode\` | \*string\* | QR code mode associated with the order. The possible values are listed below and, if none is sent, the default value will be \`static\`. \`static\`: Static mode, where the static QR code associated with the POS defined in the \`external\_pos\_id\` field receives the order information. \`dynamic\`: Dynamic mode, where a unique QR code is generated for each transaction, including the specific data of the created order. This code must be built from the information returned in the \`qr\_data\` field of the response, whose value is unique for each order. \`hybrid\`: Allows the transaction to be performed using either mode, static or dynamic, since the order will be linked to the static QR code associated with the POS (\`external\_pos\_id\`), and a QR will be generated dynamically in parallel. However, only one of the generated QRs can be used by the customer. | Optional | | \`transactions.cash\_outs\` | \*array\* | Array with information about the cash withdrawal transactions associated with the order. | Required | | \`transactions.cash\_outs.amount\` | \*string\* | Withdrawal amount. Can contain two decimals or none. Example: 100.00\. | Required | | \`transactions.cash\_outs.additional\_info.external\_cashier\_id\` | \*Number\* | Identifier of the cashier performing the transaction. Can assume any value. | Required | > NOTE > > For more details about the parameters that must be sent in this request, check our \[API Reference\](https://www.mercadopago.com.mx/developers/en/reference/in-person-payments/qr-code-ca/orders/create-order/post). The response varies according to the QR model chosen for integration. Select below the option that corresponds to your case. ::::TabsComponent :::TabComponent{title="Static model"} When creating an order by specifying the \`config.qr.mode\` field as \`static\`, the QR that should be scanned by the customer is \*\*the one obtained in the response to the POS creation request\*\*, since it is the one that receives the information from the created order. If the request is successful, the response will return an order with \`created\` status. Check below an example response for a request to create an order for \*\*cash withdrawal (cash-out)\*\* in the static model. > NOTE > > During integration development, it is possible to scan the generated QR codes using the Mercado Pago application, accessing it with a buyer test account. For more information, check the documentation \[Test the integration\](https://www.mercadopago.com.mx/developers/en/docs/qr-code-ca/test-integration). \`\`\`json { "id": "ORD01JYHP5MGKC5PMPZBHSTMLNDQX", "type": "qr", "processing\_mode": "automatic", "external\_reference": "ExtRef\_123456", "total\_amount": "100.00", "expiration\_time": "PT15M", "country\_code": "MX", "user\_id": "1898180000", "status": "created", "status\_detail": "created", "currency": "MXN", "created\_date": "2025-06-24T19:20:52.429Z", "last\_updated\_date": "2025-06-24T19:20:52.429Z", "integration\_data": { "application\_id": "8950412930770000" }, "transactions": { "cash\_outs": \[ { "id": "CAS01JYHP5MGKC5PMPZBHSW42LLPA", "amount": "100.00", "status": "created", "status\_detail": "ready\_to\_process", "additional\_info":{ "external\_cashier\_id": 123445 } } \] }, "config": { "qr": { "external\_pos\_id": "POSDOC", "mode": "static" } } } \`\`\` The created order will be automatically linked to the POS specified in the request, allowing the customer to perform the transaction at the physical point of sale. Additionally, the linking also facilitates reconciliation. After the transaction, it will be processed in an integrated way. ::: :::TabComponent{title="Dynamic model"} When creating an order by specifying the \`dynamic\` mode in the \`config.qr.mode\` field, the request response will include the additional field \`type\_response.qr\_data\`. This field contains a \*string\* in \[EMVCo\](https://www.emvco.com/emv-technologies/qr-codes/) format, which can be converted into a QR code to be printed or displayed on a screen or device. If the request is successful, the response will return an order with \`created\` status. > NOTE > > During integration development, it is possible to scan the generated QR codes using the Mercado Pago application, accessing it with a buyer test account. For more information, check the documentation \[Test the integration\](https://www.mercadopago.com.mx/developers/en/docs/qr-code-ca/test-integration). Check below an example response for a request to create an order for \*\*cash withdrawal (cash-out)\*\* in the dynamic model. \`\`\`json { "id": "ORD01JYHP5MGKC5PMPZBHSTMLNDQX", "type": "qr", "processing\_mode": "automatic", "external\_reference": "ExtRef\_123456", "total\_amount": "100.00", "expiration\_time": "PT15M", "country\_code": "MX", "user\_id": "1898180000", "status": "created", "status\_detail": "created", "currency": "MXN", "created\_date": "2025-06-24T19:20:52.429Z", "last\_updated\_date": "2025-06-24T19:20:52.429Z", "integration\_data": { "application\_id": "8950412930770000" }, "transactions": { "cash\_outs": \[ { "id": "CAS01JYHP5MGKC5PMPZBHSW42LLPA", "amount": "100.00", "status": "created", "status\_detail": "ready\_to\_process", "additional\_info":{ "external\_cashier\_id": 123445 } } \] }, "config": { "qr": { "external\_pos\_id": "POSDOC", "mode": "dynamic" } }, "type\_response": { "qr\_data": "00020101021226580014br.gov.bcb.qr01368ee55a9c-7db3-41e0-a8cd-fbff4d4765b5204000053039865802BR5925PABLO JOSE DE OLIVEIRA CA6009SAO PAULO61088051040062070503\*\*\*630442E4" } } \`\`\` In this model, an exclusive QR code is generated for each created order, incorporating the specific transaction data. After the transaction, it is processed in an integrated way. ::: :::TabComponent{title="Hybrid model"} When creating an order by specifying the \`hybrid\` mode in the \`config.qr.mode\` field, the request response includes the additional field \`type\_response.qr\_data\`. Just like in the dynamic model, the value of this field contains a \*string\* in \[EMVCo\](https://www.emvco.com/emv-technologies/qr-codes/) format, which can be converted into a QR code for customer use. Additionally, the customer will also be able to scan the QR code obtained in the response to the POS creation request to perform the transaction, as occurs in the static model, since it is the one that receives the information from the created order. In this way, the transaction can be performed both through the \*\*static POS QR\*\* and through a \*\*dynamic QR\*\* generated at the same time. The order is always linked to the static QR, but the customer can choose to use either one. As soon as the transaction is completed on one of them, the other is automatically disabled, avoiding transaction duplication. > NOTE > > During integration development, it is possible to scan the generated QR codes using the Mercado Pago application, accessing it with a buyer test account. For more information, check the documentation \[Test the integration\](https://www.mercadopago.com.mx/developers/en/docs/qr-code-ca/test-integration). If the request is successful, the response will return an order with \`status created\`. See below an example response for a request to create an order for \*\*cash withdrawal (cash-out)\*\* in the hybrid model. \`\`\`json { "id": "ORD01JYHP5MGKC5PMPZBHSTMLNDQX", "type": "qr", "processing\_mode": "automatic", "external\_reference": "ExtRef\_123456", "total\_amount": "100.00", "expiration\_time": "PT15M", "country\_code": "MX", "user\_id": "1898180000", "status": "created", "status\_detail": "created", "currency": "MXN", "created\_date": "2025-06-24T19:20:52.429Z", "last\_updated\_date": "2025-06-24T19:20:52.429Z", "integration\_data": { "application\_id": "8950412930770000" }, "transactions": { "cash\_outs": \[ { "id": "CAS01JYHP5MGKC5PMPZBHSW42LLPA", "amount": "100.00", "status": "created", "status\_detail": "ready\_to\_process", "additional\_info":{ "external\_cashier\_id": 123445 } } \] }, "config": { "qr": { "external\_pos\_id": "POSDOC", "mode": "hybrid" } }, "type\_response": { "qr\_data": "00020101021226580014br.gov.bcb.qr01368ee55a9c-7db3-41e0-a8cd-fbff4d4765b5204000053039865802BR5925PABLO JOSE DE OLIVEIRA CA6009SAO PAULO61088051040062070503\*\*\*630442E4" } } \`\`\` ::: :::: > WARNING > > Store the order \`id\` returned in the creation. It is necessary for future operations and to validate notifications. Check \*\*Resources\*\* for more \[details about the order and transaction status\](https://www.mercadopago.com.mx/developers/en/docs/qr-code-ca/resources/status-order-transaction). ::::: :::AccordionComponent{title="Cancel an order"} Order cancellation can only be performed when its \`status\` is \`created\`. If the cancellation request is made with another status, the API will return an error informing the conflict. To cancel an order, send a \*\*POST\*\* to the endpoint :TagComponent{tag="API" text="/v1/orders/{order\_id}/cancel" href="/developers/en/reference/in-person-payments/qr-code-ca/orders/cancel-order/post"}, including your :toolTipComponent\[Test Access Token\]{link="/developers/en/docs/qr-code-ca/create-application" linkText="Access test credentials" content="Private key of the application created in Mercado Pago, which is used in the backend. You can access it through \*Your integrations > Integration data > Test > Test credentials\*. During integration, use the Test Access Token and, when finished, replace it with the Production Access Token if it is your own integration, or with the Access Token obtained through OAuth in the case of third-party integrations. For more information, go to the documentation."}. It is also necessary to send the \*\`id\`\* of the order you want to cancel, obtained in the response to its creation. \`\`\`curl curl -X POST \\ 'https://api.mercadopago.com/v1/orders/ORDER\_ID/cancel'\\ -H 'Content-Type: application/json' \\ -H 'X-Idempotency-Key: 0d5020ed-1af6-469c-ae06-c3bec19954bb' \\ -H 'Authorization: Bearer TEST-751\*\*\*\*\*\*\*\*69209-05\*\*\*\*\*\*\*\*101e5ea9\*\*\*\*\*\*\*\*17b9d2fb\*\*\*\*\*\*\*\*0424235' \\ \`\`\` If the request is successful, the response will include the \`status\` field with the value \`canceled\`. \`\`\`json { "id": "ORD01K371WBFDS4MD9JG0K8ZMECBE", "type": "qr", "processing\_mode": "automatic", "external\_reference": "ext\_ref\_1234", "description": "Smartphone", "total\_amount": "50.00", "expiration\_time": "PT16M", "country\_code": "MX", "user\_id": "240424235", "status": "canceled", "status\_detail": "canceled", "currency": "MXN", "created\_date": "2025-08-21T19:32:21.621Z", "last\_updated\_date": "2025-08-21T19:33:52.012Z", "integration\_data": { "application\_id": "147632494144930", "integrator\_id": "dev\_1234", "platform\_id": "dev\_1234567890" }, "transactions": { "cash\_outs": \[ { "id": "CAS01JYHP5MGKC5PMPZBHSW42LLPA", "amount": "100.00", "status": "canceled", "status\_detail": "canceled\_by\_api" } \] }, "config": { "qr": { "external\_pos\_id": "STORE001POS001", "mode": "static" } } } \`\`\` ::: :::AccordionComponent{title="Refund an order"} It is possible to refund an order created through our API. In this case, the refund will always be a total return of the order amount. To make a refund of an order via API, it must have the \`status processed\`. If the status is different, the API will return an error message indicating the conflict. > WARNING > > An order can be refunded via API up to 72 hours after the cashout has been made. After this period, it will not be possible to make the return. To make a full refund of an order, send a \*\*POST\*\* to the endpoint :TagComponent{tag="API" text="/v1/orders/{order\_id}/refund" href="/developers/en/reference/in-person-payments/qr-code-ca/orders/refund-order/post"}, including your :toolTipComponent\[Test Access Token\]{link="/developers/en/docs/qr-code-ca/create-application" linkText="Access test credentials" content="Private key of the application created in Mercado Pago, which is used in the backend. You can access it through \*Your integrations > Integration data > Test > Test credentials\*. During integration, use the Test Access Token and, when finished, replace it with the Production Access Token if it is your own integration, or with the Access Token obtained through OAuth in the case of third-party integrations. For more information, go to the documentation."}. It is also necessary to inform the \`id\` of the order you want to refund, obtained in the response to its creation. \`\`\`curl curl --location --request POST 'https://api.mercadopago.com/v1/orders/ORDER\_ID/refund' \\ --header 'X-Idempotency-Key: 91b59be9-27b8-449f-a6bd-32dca8b424cd' \\ --header 'Authorization: Bearer {{ACCESS\_TOKEN}}' \`\`\` If the request is successful, the response will bring the \`status accredited\` and a new node \`transactions.refunds\`, which will contain the refund details, in addition to the original cashout \`id\` and the refund transaction \`id\`. \`\`\`json { "id": "ORD01JYHREYXTR31HRB5S9Q9G8QS7", "status": "processed", "status\_detail": "accredited", "transactions": { "refunds": \[ { "id": "REF01JYHRNEK69845P0E6VBXKXAKK", "transaction\_id": "CAS01JYHREYXTR31HRB5S9QE68G0N", "reference\_id": "116228240060", "amount": "100.00", "status": "processing" } \] } } \`\`\` In the refund request response, a new transaction of type \`refund\` with \`status processing\` is created. To follow the final status of the refund, wait for the update notification or check the order data to verify its status. When the refund is confirmed, the status will be changed to \`refunded\`. After the refund is confirmed, the status of the order can be checked through a GET request, as shown in the example below: \`\`\`json { "id": "ORD01JYHREYXTR31HRB5S9Q9G8QS7", "type": "qr", "processing\_mode": "automatic", "external\_reference": "ExtRef\_123456", "total\_amount": "100.00", "expiration\_time": "PT15M", "country\_code": "URY", "user\_id": "1898180608", "status": "refunded", "status\_detail": "refunded", "created\_date": "2025-06-24T20:00:55.137Z", "last\_updated\_date": "2025-06-24T20:04:27.622Z", "integration\_data": { "application\_id": "8950412930771472" }, "transactions": { "cash\_outs": \[ { "id": "CAS01JYHREYXTR31HRB5S9QE68G0N", "reference\_id": "116228240060", "amount": "100.00", "status": "refunded", "status\_detail": "refunded", "additional\_info":{ "external\_cashier\_id": 123445 } } \], "refunds": \[ { "id": "REF01JYHRNEK69845P0E6VBXKXAKK", "transaction\_id": "CAS01JYHREYXTR31HRB5S9QE68G0N", "reference\_id": "116228240060", "amount": "100.00", "status": "processed" } \] }, "config": { "qr": { "external\_pos\_id": "SUC001POS001", "mode": "static" } } } \`\`\` The \`transaction\_id\` field in the refund identifies which transaction (\`cash\_outs\`) is being refunded, hence it starts with the \`CAS\` prefix. ::: :::AccordionComponent{title="Query order data"} It is possible to query the data of an order and its associated transactions, including their status or values. To make the query, send a \*\*GET\*\* to the endpoint :TagComponent{tag="API" text="/v1/orders/{order\_id}" href="/developers/en/reference/in-person-payments/qr-code-ca/orders/get-order/get"} including your :toolTipComponent\[Test Access Token\]{link="/developers/en/docs/qr-code-ca/create-application" linkText="Access test credentials" content="Private key of the application created in Mercado Pago, which is used in the backend. You can access it through \*Your integrations > Integration data > Test > Test credentials\*. During integration, use the Test Access Token and, when finished, replace it with the Production Access Token if it is your own integration, or with the Access Token obtained through OAuth in the case of third-party integrations. For more information, go to the documentation."}. Also, make sure to include the order \`id\` obtained in the response to its creation. \`\`\`curl curl --location --request GET 'https://api.mercadopago.com/v1/orders/ORDER\_ID' \\ --header 'Authorization: Bearer {{ACCESS\_TOKEN}}' \`\`\` > WARNING > > This request is only available for orders created less than 3 months ago. To access information for older orders, it is necessary to contact our customer service. If the request is successful, the response will return all the order information, including its status, cashout status and/or refund status in real time. \`\`\`json { "id": "ORD01JYHP5MGKC5PMPZBHSTMLNDQX", "type": "qr", "processing\_mode": "automatic", "external\_reference": "ExtRef\_123456", "total\_amount": "100.00", "expiration\_time": "PT15M", "country\_code": "MX", "user\_id": "1898180608", "status": "created", "status\_detail": "created", "currency": "MXN", "created\_date": "2025-06-24T19:46:02.381Z", "last\_updated\_date": "2025-06-24T19:46:02.381Z", "integration\_data": { "application\_id": "8950412930771472" }, "transactions": { "cash\_outs": \[ { "id": "CAS01JYHQKQ2D39PCBEK3K36G0SQD", "amount": "100.00", "status": "created", "status\_detail": "ready\_to\_process", "additional\_info":{ "external\_cashier\_id": 123445 } } \] }, "config": { "qr": { "external\_pos\_id": "SUC001POS001", "mode": "static" } } } \`\`\` ::: After integrating transaction processing, you will be able to \[configure notifications\](https://www.mercadopago.com.mx/developers/en/docs/qr-code-ca/notifications).