Integrate payment processing
Payment processing with Mercado Pago Point is based on creating orders associated with a payment transaction. These orders allow your system to initiate and track each payment processed on the terminal, link it to the corresponding operation through external_reference, and keep its reconciliation up to date based on status changes.
In PDV mode, the seller creates an order, which is automatically sent to the indicated Point terminal so the buyer can complete the payment.
In SELF_SERVICE mode, the order is processed in real time between the kiosk used by the buyer and Mercado Pago, without manual intervention. In this mode, the terminal is dedicated to payment processing, with restricted access to settings and advanced features.
Integrated payment processing with Mercado Pago Point will allow you to create orders, process them, cancel them, or make refunds and query their information or status updates.
To start processing payments with Point from points of sale, you first need to identify which terminal you want to assign the order to.
Remember that the terminal must be set to PDV or SELF_SERVICE mode.
For this, send a request to the endpoint Get terminalsGET, using your test Access TokenPrivate key linked to an application, used in the backend to authenticate operations in the test environment. You can find it in the application's Credentials section, within the test environment. It cannot process real payments, must never be exposed in the frontend, and starts with the `APP_USR` prefix.Access test credentials.
If necessary, you can filter the search using the optional query params store_id and pos_id, which correspond to the store and box identifiers returned in the response to the creation of each one.
curlcurl -X GET \ 'https://api.mercadopago.com/terminals/v1/list?limit=50&offset=0&store_id=12354567&pos_id=23545678' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}'
The response to this request will show the terminals associated with your account, allowing you to select the one you want to use to create your order.
The terminal can be identified by the last characters of the id field, which correspond to the serial number printed on the back label of the physical terminal.
json{ "data": { "terminals": [ { "id": "NEWLAND_N950__N950NCB801293324", "pos_id": "23545678", "store_id": "12354567", "external_pos_id": "SUC0101POS", "operating_mode": "PDV | SELF_SERVICE" } ] }, "paging": { "total": 1, "offset": 0, "limit": 50 } }
Then, you'll need to create the order. For this, send a request to the endpoint /v1/ordersPOST, making sure to include your test Access TokenPrivate key linked to an application, used in the backend to authenticate operations in the test environment. You can find it in the application's Credentials section, within the test environment. It cannot process real payments, must never be exposed in the frontend, and starts with the `APP_USR` prefix.Access test credentials, and the ID of the terminal to which you want to assign the order, obtained in the previous step.
The same creation request is used for PDV and SELF_SERVICE modes. In SELF_SERVICE mode, you can define how long each screen remains available using the optional config.point.screen_time parameter. In PDV mode, config.point.screen_time does not apply.
If you wish, by setting credit card as the default payment method (default_type=credit_card), you can use the installment preset to define the financing type (with or without interest), the number of installments, and who will bear the financial cost. To activate the preset, include the fields default_installments and installments_cost inside the config.payment_method object when creating the order.
curlcurl -X POST \ 'https://api.mercadopago.com/v1/orders' \ -H 'Content-Type: application/json' \ -H 'X-Idempotency-Key: {{SOME_UNIQUE_VALUE}}' \ -H 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}' \ -d '{ "type": "point", "external_reference": "ext_ref_1234", "expiration_time": "PT16M", "transactions": { "payments": [ { "amount": "24.00" } ] }, "config": { "point": { "terminal_id": "NEWLAND_N950__N950NCB801293324", "print_on_terminal": "no_ticket", "ticket_number": "S0392JED" }, "payment_method": { "default_type": "credit_card", "default_installments": 3, "installments_cost": "seller" } }, "description": "Point Smart 2", "integration_data": { "platform_id": "dev_1234567890", "integrator_id": "dev_1234567890", "sponsor": { "id": "446566691" } } }'
Check the table below for descriptions of parameters that have some important particularity that should be highlighted.
| Attribute | Type | Description | Required |
Authorization | Header | Refers to the test Access TokenPrivate key linked to an application, used in the backend to authenticate operations in the test environment. You can find it in the application's Credentials section, within the test environment. It cannot process real payments, must never be exposed in the frontend, and starts with the `APP_USR` prefix.Access test credentials. | Required |
X-Idempotency-Key | Header | Idempotency key. It is used to ensure that each request is processed only once, avoiding duplications. Use a unique value in the header of your request, such as a UUID V4 or random strings. | Required |
type | Body.String | Type of order, associated with the Mercado Pago solution for which it is being created. For payments with Mercado Pago Point, the only possible value is point. | Required |
external_reference | Body.String | It is an external reference of the order, assigned at the time of its creation. It must be a unique value for each order and cannot contain PII data. The maximum allowed limit is 64 characters and the allowed ones are: uppercase and lowercase letters, numbers and hyphen (-) and underscore (_) symbols. | Required |
expiration_time | Body. String | Indicates the validity period of the payment order from its creation. During this time, the order will be available for processing by the customer; if it is not processed within the specified period, it will automatically expire and cannot be used, requiring the generation of a new payment order to continue. The minimum allowed value is 30 seconds (PT30S) and the maximum is 3 hours (PT3H). Usage examples: for a 30-second expiration: "PT30S", for 10 minutes: "PT10M", and for 1 hour and 15 minutes: "PT1H15M". | Optional |
transactions.payments.amount | Body.String | Total amount of the payment order. It accepts up to 2 decimal places, and the decimal separator is optional. Valid examples: 10, 10.5, and 10.00. | Required |
config.point.screen_time | Body.String | Available only in SELF_SERVICE mode. Defines, in ISO 8601 format, how long the terminal screens remain available to process the order. It accepts values from 5 seconds (PT5S) to 5 minutes (PT5M); if omitted, it uses 15 seconds (PT15S). The timer resets when the screen changes or the user interacts with the terminal. If the order is not processed within this period, it is canceled. The card-reading screen is displayed for a maximum of 60 seconds, even if a higher value is configured. | Optional |
config.point.terminal_id | Body.String | Identifier of the Point terminal that will receive the order. You must send it exactly as it was returned by the Get terminalsGET request, as in the following example: NEWLAND_N950__N950NCB801293324. | Required |
config.point.print_on_terminal | Body.String | Defines whether the terminal prints the transaction receipt. In PDV mode, it accepts seller_ticket —the default value— or no_ticket. In SELF_SERVICE mode, it accepts seller_ticket, no_ticket, or buyer_ticket —the default value—. | Optional |
config.payment_method.default_type | Body.String | Indicates the payment method that the terminal will accept. If it is not sent, the terminal will accept all payment methods and the customer can choose the one they want. To use the installment pre-configuration feature, it must be sent as credit_card. Possible values: debit_card (accepts only debit card payments), credit_card (accepts only credit card payments), and qr (accepts only QR code payments). In SELF_SERVICE mode, the supported values are credit_card and debit_card; qr is available only in PDV mode. | Optional |
config.payment_method.default_installments | Body.Integer | When the default payment method is a credit card (default_type = credit_card), send this parameter to inform the terminal that the number of installments has been preselected, skipping the selection screen. If the card used for the payment does not support the specified number of installments, the terminal will display the selection screen. | Conditional |
config.payment_method.installments_cost | Body.String | When the default payment method is a credit card (default_type=credit_card) and default_installments is greater than 1, send this parameter to define who will bear the financing cost of the installments. Possible values: seller (the seller assumes the financial cost, resulting in interest-free installments; the seller must have installments enabled in their Mercado Pago account, with at least one active plan that includes the requested number of installments, and the transaction amount must meet the plan's minimum amount) and buyer (the buyer assumes the financial cost, resulting in installments with interest). If default_installments=1, send seller or omit this field, since a single installment has no financing cost. If default_installments is greater than 1 and this field is not sent, the API returns the 400 - missing_installments_cost error. | Conditional |
If the request was successful, the response will return an order with status created.
json{ "id": "ORD00001111222233334444555566", "type": "point", "user_id": "5238400195", "external_reference": "ext_ref_1234", "description": "Point Smart 2", "expiration_time": "PT16M", "processing_mode": "automatic", "country_code": "AR", "integration_data": { "application_id": "1234567890", "platform_id": "dev_1234567890", "integrator_id": "dev_1234567890", "sponsor": { "id": "446566691" } }, "status": "created", "status_detail": "created", "created_date": "2024-09-10T14:26:42.109320977Z", "last_updated_date": "2024-09-10T14:26:42.109320977Z", "config": { "point": { "terminal_id": "NEWLAND_N950__N950NCB801293324", "print_on_terminal": "no_ticket", "ticket_number": "S0392JED" }, "payment_method": { "default_type": "credit_card", "installments_cost": "seller", "default_installments": 3 } }, "transactions": { "payments": [ { "id": "PAY01J67CQQH5904WDBVZEM4JMEP3", "amount": "24.00", "status": "created" } ] } }
order_id) and the payment ID (transactions.payments.id) obtained when creating it, and associate them with external_reference. This data will allow you to perform other operations, query your notifications, and keep your system reconciled. You can also consult our documentation in the Resources section to learn about the possible statuses of an order and a transaction.Once created, the order will be sent to the assigned terminal.
In PDV mode, if the order does not load automatically, press the Update button or, if the terminal has one, the green button to receive it. If you do not complete the expiration_time parameter, the order will expire 15 minutes after it is created.
In SELF_SERVICE mode, the order is processed without manual intervention. If you do not complete the expiration_time parameter, the order will expire 15 seconds after it is created. If the payment receipt is printed by the kiosk, send no_ticket in config.point.print_on_terminal to prevent it from being printed by the Point terminal.
An order can be canceled via API or, when it has at_terminal status, directly from the terminal.
at_terminal, whether requested via API or performed from the terminal, configure your Webhook notifications beforehand. The notification confirms that the cancellation took effect and allows you to maintain your reconciliation.-
If the order's
statusiscreated, it must be canceled via API and is processed synchronously. -
If its
statusisat_terminal, it has already been retrieved by the terminal. In this case, cancellation can be requested asynchronously via API or performed directly from the terminal.
Choose the option that best suits your needs to learn how to cancel your order.
To cancel an order with created or at_terminal status via API, send a request to the /v1/orders/{order_id}/cancelPOST endpoint, including your test Access TokenPrivate key linked to an application, used in the backend to authenticate operations in the test environment. You can find it in the application's Credentials section, within the test environment. It cannot process real payments, must never be exposed in the frontend, and starts with the `APP_USR` prefix.Access test credentials and the order ID obtained in the response to its creation.
x-allow-cancelable-status header is omitted or has a value other than at_terminal, the API cancellation request for an order with status=at_terminal returns the 409 cannot_cancel_order error.
In addition, the feature is available on Point Smart 1 and Point Smart 2 terminals that have their software updated to the latest available version. Otherwise, the request is handled as if the header had not been sent and returns the same error.
curlcurl -X POST \ 'https://api.mercadopago.com/v1/orders/{{ORDER_ID}}/cancel' \ -H 'Content-Type: application/json' \ -H 'X-Idempotency-Key: {{SOME_UNIQUE_VALUE}}' \ -H 'x-allow-cancelable-status: at_terminal' \ -H 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}'
The result depends on the order status at the time of the request:
- For
created, cancellation is synchronous and the API returnsHTTP 200, with the order instatus=canceledand the payment instatus_detail=canceled_by_api. Thex-allow-cancelable-statusheader is optional and, when sent, is ignored. - For
at_terminal, the API accepts the request asynchronously and returnsHTTP 202. The order remains instatus=at_terminal, while the payment changes tostatus_detail=cancellation_requested, until a Webhook notification confirms the cancellation. If the payment is already being processed, the terminal may prioritize it and not complete the cancellation; therefore, theHTTP 202response must not be interpreted as final confirmation.
Response for an order in created
json{ "id": "ORD00009999222233334444555566", "user_id": "5238400195", "type": "point", "external_reference": "ext_ref_1234", "description": "Point Smart 2", "expiration_time": "PT16M", "country_code": "AR", "processing_mode": "automatic", "integration_data": { "application_id": "1234567890", "platform_id": "dev_1234567890", "integrator_id": "dev_1234567890", "sponsor": { "id": "446566691" } }, "status": "canceled", "status_detail": "canceled", "created_date": "2024-09-10T14:26:42.109320977Z", "last_updated_date": "2024-09-10T14:26:42.109320977Z", "config": { "point": { "terminal_id": "NEWLAND_N950__N950NCB801293324", "print_on_terminal": "no_ticket", "ticket_number": "S0392JED" }, "payment_method": { "default_type": "credit_card", "default_installments": 3, "installments_cost": "seller" } }, "transactions": { "payments": [ { "id": "PAY01J67CQQH5904WDBVZEM4JMEP4", "amount": "24.00", "status": "canceled", "status_detail": "canceled_by_api" } ] } }
Response for an order in at_terminal
json{ "id": "ORD00009999222233334444555566", "status": "at_terminal", "status_detail": "at_terminal", "transactions": { "payments": [ { "id": "PAY01J67CQQH5904WDBVZEM4JMEP4", "status": "at_terminal", "status_detail": "cancellation_requested" } ] } }
The HTTP 202 response only confirms that the request was accepted. Consider the order canceled only after receiving confirmation through Webhook notifications.
If needed, it is possible to refund an order created through our API. This endpoint allows you to make a total or partial refund of a payment transaction associated with the order. To request a total refund, you do not need to send a body in the request. For a partial refund, you must inform in the body the amount to be refunded and the transaction identifier.
Choose the option that best suits your needs and follow the corresponding instructions.
To make a total refund of an order, send a request to the endpoint /v1/orders/{order_id}/refundPOST without sending a body in the request. Make sure to include your test Access TokenPrivate key linked to an application, used in the backend to authenticate operations in the test environment. You can find it in the application's Credentials section, within the test environment. It cannot process real payments, must never be exposed in the frontend, and starts with the `APP_USR` prefix.Access test credentials. You must also include the ID of the order (order_id) you want to refund, obtained in the response to its creation.
curlcurl -X POST \ 'https://api.mercadopago.com/v1/orders/{{ORDER_ID}}/refund' \ -H 'Content-Type: application/json' \ -H 'X-Idempotency-Key: {{SOME_UNIQUE_VALUE}}' \ -H 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}'
If the request is successful, the response will return status=refunded and a new node transactions.refunds, which will contain the details of the refund, along with the original payment ID (transactions.payments.id) and the refund transaction ID (transaction_id).
json{ "id": "ORD00001111222233334444555566", "status": "refunded", "status_detail": "refunded", "transactions": { "refunds": [ { "id": "REF01J67CQQH5904WDBVZEM1234D", "transaction_id": "PAY01J67CQQH5904WDBVZEM4JMEP3", "reference_id": "12345678", "amount": "24.00", "status": "processed" } ] } }
If needed, you can query the data of an order and its associated transactions, whether payments or refunds, including their statuses or values.
Although the recurring use of this API query is not recommended, it can be useful if you need additional information about the order.
To query order data, send a request to the endpoint /v1/orders/{order_id}GET, making sure to include your test Access TokenPrivate key linked to an application, used in the backend to authenticate operations in the test environment. You can find it in the application's Credentials section, within the test environment. It cannot process real payments, must never be exposed in the frontend, and starts with the `APP_USR` prefix.Access test credentials, and the ID of the order (order_id) whose information you want to query, obtained in the response to its creation.
curlcurl -X GET \ 'https://api.mercadopago.com/v1/orders/{{ORDER_ID}}' \ -H 'Content-Type: application/json' \ -H 'Authorization: Bearer {{YOUR_ACCESS_TOKEN}}'
If the request was successful, the response will return all the order information, including its status and the status of the payment and/or refund in real time:
json{ "id": "ORD00001111222233334444555566", "user_id": "5238400195", "type": "point", "external_reference": "ext_ref_1234", "processing_mode": "automatic", "description": "Point Smart 2", "expiration_time": "PT16M", "country_code": "AR", "integration_data": { "application_id": "1234567890", "platform_id": "dev_1234567890", "integrator_id": "dev_1234567890", "sponsor": { "id": "446566691" } }, "status": "refunded", "status_detail": "refunded", "created_date": "2024-09-10T14:26:42.109320977Z", "last_updated_date": "2024-09-10T14:26:42.109320977Z", "config": { "point": { "terminal_id": "NEWLAND_N950__N950NCB801293324", "print_on_terminal": "no_ticket", "ticket_number": "S0392JED" }, "payment_method": { "default_type": "credit_card", "default_installments": 3, "installments_cost": "seller" } }, "transactions": { "payments": [ { "id": "PAY01J67CQQH5904WDBVZEM4JMEP3", "amount": "24.00", "refunded_amount": "24.00", "paid_amount": "24.00", "status": "refunded", "status_detail": "refunded", "reference_id": "12345678", "payment_method": { "type": "credit_card", "installments": 6, "id": "master" } } ], "refunds": [ { "id": "REF01J67CQQH5904WDBVZEM1234D", "transaction_id": "PAY01J67CQQH5904WDBVZEM4JMEP3", "reference_id": "12345678", "amount": "24.00", "status": "processed" } ] } }