PSE
Con Checkout API de Mercado Pago es posible ofrecer pagos con PSE (Pagos Seguros en Línea). Este sistema electrónico permite a los clientes realizar compras y pagos online utilizando directamente fondos de la cuenta de ahorros, cuenta corriente o billetera digital, actuando como un puente seguro entre bancos y tiendas, y eliminando así la necesidad de tarjetas de crédito.
Si ya configuraste tu ambiente de desarrollo y quieres ofrecer pagos vía PSE, sigue los pasos a continuación.
processing_mode. Para más información, accede a la sección Modelo de integración.Para recibir pagos, es necesario agregar en el frontend un formulario que permita capturar los datos del pagador de forma segura.
Si ya tienes un desarrollo que incluye un formulario de pago propio, asegúrate de incluir PSE entre las opciones de pago que deseas ofrecer, según se indica a continuación, y continúa con el paso Obtener tipos de documento.
Si aún no tienes un formulario de pago, agrega el modelo a continuación a tu proyecto e incluye el identificador de PSE como opción a ofrecer.
| Medio de pago | payment_method_id |
| PSE | pse |
html
<form id="form-checkout" action="/process_payment" method="post"> <div> <div> <label for="zipCode">Código postal</label> <input id="form-checkout__zipCode" name="zipCode" type="text"> </div> <div> <label for="streetName">Calle</label> <input id="form-checkout__streetName" name="streetName" type="text"> </div> <div> <label for="streetNumber">Número</label> <input id="form-checkout__streetNumber" name="streetNumber" type="text"> </div> <div> <label for="neighborhood">Barrio</label> <input id="form-checkout__neighborhood" name="neighborhood" type="text"> </div> <div> <label for="city">Ciudad</label> <input id="form-checkout__city" name="city" type="text"> </div> <div> <label for="federalUnit">Departamento</label> <input id="form-checkout__federalUnit" name="federalUnit" type="text"> </div> <div> <label for="phoneAreaCode">Código de área</label> <input id="form-checkout__phoneAreaCode" name="phoneAreaCode" type="text"> </div> <div> <label for="phoneNumber">Teléfono</label> <input id="form-checkout__phoneNumber" name="phoneNumber" type="text"> </div> <div> <label for="email">Correo electrónico</label> <input id="form-checkout__email" name="email" type="text"> </div> <div> <label for="personType">Tipo de persona</label> <select id="form-checkout__personType" name="personType" type="text"> <option value="natural">Natural</option> <option value="juridica">Jurídica</option> </select> </div> <div> <label for="identificationType">Tipo de documento</label> <select id="form-checkout__identificationType" name="identificationType" type="text"></select> </div> <div> <label for="identificationNumber">Número de documento</label> <input id="form-checkout__identificationNumber" name="identificationNumber" type="text"> </div> </div> <div> <div> <label for="banksList">Banco</label> <div id="banksList"></div> </div> </div> <div> <div> <input type="hidden" name="transactionAmount" id="transactionAmount" value="100"> <input type="hidden" name="description" id="description" value="Nombre del Producto"> <br> <button type="submit">Pagar</button> </div> </div> </form>
Para facilitar el llenado correcto del formulario de pago, es necesario obtener los tipos de documento que pueden ser aceptados.
La función a continuación permite completar automáticamente las opciones disponibles. Para eso, basta incluir en el formulario el elemento select con el id=form-checkout__identificationType, utilizado en el ejemplo del paso anterior.
Si ya tienes un desarrollo que contempla la obtención de tipos de documento, como se indica a continuación, avanza al paso Enviar pago.
Si aún no tienes esta función, agrega el código a continuación a tu proyecto.
javascript
document.getElementById('form-checkout__personType').addEventListener('change', e => { const personTypesElement = document.getElementById('form-checkout__personType'); updateSelectOptions(personTypesElement.value); }); function updateSelectOptions(selectedValue) { const naturalDocTypes = [ new Option('C.C', 'CC'), new Option('C.E.', 'CE'), new Option('Pasaporte', 'PAS'), new Option('Tarjeta de Extranjería', 'TE'), new Option('Tarjeta de Identidad ', 'TI'), new Option('Registro Civil', 'RC'), new Option('Documento de Identificación', 'DI') ]; const juridicaDocTypes = [ new Option('NIT', 'NIT') ]; const idDocTypes = document.getElementById('form-checkout__identificationType'); if (selectedValue === 'natural') { idDocTypes.options.length = 0; naturalDocTypes.forEach(item => idDocTypes.options.add(item, undefined)); } else { idDocTypes.options.length = 0; juridicaDocTypes.forEach(item => idDocTypes.options.add(item, undefined)); } }
Al crear un pago con PSE, es necesario enviar el código del banco que se utilizará para la transferencia. Para eso, es necesario listar los bancos disponibles y presentar estas opciones al pagador, permitiéndole elegir el banco de su preferencia.
Envía un GET con tu Access Token de pruebaClave privada de la aplicación creada en Mercado Pago, que es utilizada en el backend. Puedes acceder a ella a través de Tus integraciones > Detalles de aplicación > Pruebas > Credenciales de prueba. al endpoint /v1/payment_methodsAPI o, si lo prefieres, realiza la solicitud utilizando nuestros SDKs a continuación.
<?php
use MercadoPago\MercadoPagoConfig;
MercadoPagoConfig::setAccessToken("<YOUR_ACCESS_TOKEN>");
$client = new PaymentMethodClient();
$payment_method = $client->get();
?>
import { MercadoPagoConfig, PaymentMethods } from 'mercadopago';
const client = new MercadoPagoConfig({ accessToken: 'access_token' });
const paymentMethods = new PaymentMethods(client);
paymentMethods.get().then((result) => console.log(result))
.catch((error) => console.log(error));
MercadoPagoConfig.setAccessToken("<YOUR_ACCESS_TOKEN>");
PaymentMethodClient client = new PaymentMethodClient();
client.list();
require 'mercadopago'
sdk = Mercadopago::SDK.new('<YOUR_ACCESS_TOKEN>')
payment_methods_response = sdk.payment_methods.get()
payment_methods = payment_methods_response[:response]
using MercadoPago.Client.PaymentMethod;
using MercadoPago.Config;
using MercadoPago.Resource;
using MercadoPago.Resource.PaymentMethod;
MercadoPagoConfig.AccessToken = "<YOUR_ACCESS_TOKEN>";
var client = new PaymentMethodClient();
ResourcesList<PaymentMethod> paymentMethods = await client.ListAsync();
import mercadopago
sdk = mercadopago.SDK("ACCESS_TOKEN")
payment_methods_response = sdk.payment_methods().list_all()
payment_methods = payment_methods_response["response"]
curl -X GET \
-H 'accept: application/json' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \
'https://api.mercadopago.com/v1/payment_methods' \
La respuesta devolverá los medios de pago, donde podrás listar los bancos disponibles para pagos con PSE a través del campo financial_institutions dentro del objeto con id=pse, como en el ejemplo a continuación.
json
[ { "id": "pse", "name": "PSE", "payment_type_id": "bank_transfer", "status": "active", "secure_thumbnail": "https://www.mercadopago.com/org-img/MP3/API/logos/pse.gif", "thumbnail": "https://www.mercadopago.com/org-img/MP3/API/logos/pse.gif", "deferred_capture": "does_not_apply", "settings": [], "additional_info_needed": [ "entity_type" ], "min_allowed_amount": 1600, "max_allowed_amount": 340000000, "accreditation_time": 30, "financial_institutions": [ { "id": "1040", "description": "Banco Agrario" }, { "id": "1507", "description": "NEQUI" }, { "id": "1052", "description": "Banco AV Villas" }, { "id": "1032", "description": "Banco Caja Social" } ], "processing_modes": [ "aggregator" ] } ]
Luego, crea un elemento select en JavaScript y enriquécelo con los datos devueltos en esa solicitud, como muestra el ejemplo a continuación.
javascript
function setPse() { fetch('/payment_methods') .then(async function(response) { const paymentMethods = await response.json(); const pse = paymentMethods.filter((method) => method.id === 'pse')[0]; const banksList = pse.financial_institutions; const banksListElement = document.getElementById('banksList'); const selectElement = document.createElement('select'); selectElement.name = 'financialInstitution'; banksList.forEach(bank => { const option = document.createElement('option'); option.value = bank.id; option.textContent = bank.description; selectElement.appendChild(option); }); banksListElement.appendChild(selectElement); }).catch(function(reason) { console.error('Failed to get payment methods', reason); }); }
Para que los elementos dinámicos creados con este JavaScript se carguen cuando la página termine de renderizar, agrega el siguiente código:
javascript
(function initCheckout() { try { const docTypeElement = document.getElementById('form-checkout__identificationType'); setPse(); updateSelectOptions('natural') } catch(e) { return console.error('Error getting identificationTypes: ', e); } })();
El envío del pago debe realizarse mediante la creación de una order que contenga la transacción de pago asociada.
in_process y sin información. Recomendamos configurar las notificaciones del tópico Order para recibir actualizaciones sobre el cambio de estado, incluyendo los datos actualizados de la order. Alternativamente, puedes optar por enviar un GET al endpoint /v1/orders/{id} para obtener estos datos actualizados.Para eso, envía un POST con tu Access Token de pruebaClave privada de la aplicación creada en Mercado Pago, que es utilizada en el backend. Puedes acceder a ella a través de Tus integraciones > Detalles de aplicación > Pruebas > Credenciales de prueba. y los parámetros requeridos listados a continuación al endpoint /v1/ordersAPI y ejecuta la solicitud.
curl
curl --location --request POST 'https://api.mercadopago.com/v1/orders' \ -H 'Authorization: Bearer <YOUR_ACCESS_TOKEN>' \ -H 'X-Idempotency-Key: <SOME_UNIQUE_VALUE>' \ -H 'Content-Type: application/json' \ -d '{ "type": "online", "total_amount": "5000", "external_reference": "ext_ref_1234", "processing_mode": "automatic", "expiration_time": "PT20M", "payer": { "email": "test_user_co@testuser.com", "entity_type": "individual", "identification": { "type": "NIT", "number": "76262349" }, "first_name": "John", "last_name": "Doe", "phone": { "area_code": "57", "number": "3001234567" }, "address": { "street_name": "Calle 10", "street_number": "100", "city": "Bogota", "zip_code": "110111", "neighborhood": "Centro" } }, "transactions": { "payments": [ { "amount": "5000", "payment_method": { "id": "pse", "type": "bank_transfer", "financial_institution": "1051" } } ] }, "additional_info": { "payer.ip_address": "200.100.50.25" }, "config": { "online": { "callback_url": "https://merchant.com/pse/return" } } }'
Consulta en la tabla a continuación las descripciones de los parámetros que son obligatorios en la solicitud y de aquellos que, aunque opcionales, tienen alguna particularidad importante a destacar.
| Atributo | Tipo | Descripción | Obligatoriedad |
Authorization | Header | Hace referencia a tu clave privada, el Access Token de pruebaClave privada de la aplicación creada en Mercado Pago, que es utilizada en el backend. Puedes acceder a ella a través de Tus integraciones > Detalles de aplicación > Pruebas > Credenciales de prueba.. | Obligatorio |
X-Idempotency-Key | Header | Clave de idempotencia. Esta clave garantiza que cada solicitud sea procesada solo una vez, evitando duplicidades. Usa un valor exclusivo en el header de la solicitud, como un UUID V4 o un string aleatorio. | Obligatorio |
total_amount | Body. String | Valor total de la transacción. Debe ser mayor que 0. | Obligatorio |
external_reference | Body. String | Referencia externa de la order que puede ser, por ejemplo, un hashcode que funciona como identificador de origen de la transacción. | Obligatorio |
processing_mode | Body. String | Modo de procesamiento de la order. Los valores posibles son: - automatic: para crear y procesar la order en modo automático. - manual: para crear la order y procesarla posteriormente. Para más información, accede a la sección Modelo de integración. | Obligatorio |
expiration_time | Body. String | Permite definir el tiempo de expiración del pago utilizando el formato de duración ISO 8601. El plazo máximo para que el comprador complete el pago vía PSE es de 20 minutos ("PT20M"). Después de ese período, el pago expira automáticamente y el estado de la transacción pasa a ser expired. | Opcional |
transactions.payments.payment_method.id | Body. String | Identificador del medio de pago. El valor debe ser pse. | Obligatorio |
transactions.payments.payment_method.type | Body. String | Tipo del medio de pago. El valor debe ser bank_transfer. | Obligatorio |
transactions.payments.payment_method.financial_institution | Body. String | Código del banco utilizado para la transferencia. Los bancos disponibles deben obtenerse a través del paso Listar bancos. | Obligatorio |
payer.email | Body. String | Correo electrónico del comprador. | Obligatorio |
payer.entity_type | Body. String | Tipo de persona (natural o jurídica). Los valores posibles son: individual o association. | Obligatorio |
payer.identification.type | Body. String | Tipo de documento del comprador. Valores aceptados: RC (Registro Civil de Nacimiento), TI (Tarjeta de Identidad), CC (Cedula de Ciudadania), TE (Tarjeta de Extranjeria), CE (Cedula de Extranjeria), PAS (Pasaporte), NIT y DI (Documento de Identificación). | Obligatorio |
payer.identification.number | Body. String | Número de identificación del comprador. | Obligatorio |
payer.address.zip_code | Body. String | Código postal de la dirección del comprador. | Obligatorio |
payer.address.street_name | Body. String | Nombre de la calle de la dirección del comprador. | Obligatorio |
payer.address.street_number | Body. String | Número de la dirección del comprador. Si no tiene número, enviar "S/N". | Obligatorio |
payer.address.neighborhood | Body. String | Barrio donde se encuentra la dirección del comprador. | Obligatorio |
payer.address.city | Body. String | Ciudad donde se encuentra la dirección del pagador. | Obligatorio |
payer.phone.area_code | Body. String | Código de área del teléfono del comprador. Debe tener 3 posiciones. | Obligatorio |
payer.phone.number | Body. String | Número de teléfono del comprador. Debe tener entre 1 y 5 posiciones y solo acepta caracteres numéricos. | Obligatorio |
additional_info.payer.ip_address | Body. String | Dirección IP del comprador donde se genera el pago. | Obligatorio |
config.online.callback_url | Body. String | URL a la que el comprador será redirigido después de realizar el pago dentro de la página del banco. No debe ser nulo o vacío y debe tener, como máximo, 512 caracteres. | Obligatorio |
La respuesta retornará el parámetro redirect_url, que contiene la URL con las instrucciones para que el comprador realice el pago. Deberás redirigirlo a esa página, siguiendo las indicaciones del paso Disponibilizar el pago. Además, mostrará el estado action_required con status_detail=waiting_transfer hasta que el pago sea realizado.
json
{ "id": "ORDOMG01KNSWP75YHQJ9EKKB13QCFF25", "total_amount": "5000", "total_paid_amount": "0", "status": "action_required", "status_detail": "waiting_transfer", "config": { "online": { "callback_url": "https://merchant.com/pse/return" } }, "transactions": { "payments": [ { "payment_method": { "id": "pse", "type": "bank_transfer", "financial_institution": "1051", "redirect_url": "https://www.mercadopago.com.co/sandbox/payments/154019160992/bank_transfer?caller_id=2676136474&hash=fd05e480-3f06-4f41-90dc-b6910946e196" } } ] } }
Entre los parámetros devueltos, tenemos los indicados en la tabla a continuación.
| Atributo | Tipo | Descripción |
status | String | Devuelve el estado de la transacción. En este caso, devolverá action_required para indicar la necesidad de una acción para completar el procesamiento; es decir, que se realice el pago. |
status_detail | String | En los casos de transferencia bancaria, como es el caso de pagos con PSE, el status_detail obtenido es waiting_transfer, esperando que el usuario finalice el proceso de pago en el banco. |
transactions.payments.payment_method.redirect_url | String | URL a la que el comprador debe ser redirigido para completar el flujo de pago en la plataforma del banco elegido. Puedes ver más información en Disponibilizar el pago. |
Luego de la creación del pago, y para que el cliente pueda realizar la transferencia, es necesario redireccionarlo a la URL devuelta en la respuesta a la creación de la order bajo el parámetro redirect_url.
json
{ [...] "transactions": { "payments": [ { "payment_method": { "id": "pse", "type": "bank_transfer", "financial_institution": "1051", "redirect_url": "https://www.mercadopago.com.co/sandbox/payments/154019160992/bank_transfer?caller_id=2676136474&hash=fd05e480-3f06-4f41-90dc-b6910946e196" } } ] } }
Para ello, tienes dos opciones:
- Puedes hacer esa redirección automáticamente.
- Puedes disponibilizar esa URL al usuario por medio de un botón cliqueable, siguiendo el ejemplo a continuación.
html
<a href="https://www.mercadopago.com.co/payments/154019160992/bank_transfer?caller_id=2676136474&hash=fd05e480-3f06-4f41-90dc-b6910946e196" target="_blank">Pagar con PSE</a>
Si lo deseas, puedes cancelar un pago creado, siempre y cuando se encuentre pendiente o en proceso; es decir, con status=action_required.
Adicionalmente, recomendamos cancelar los pagos que no fueron realizados dentro de la fecha de vencimiento establecida, para evitar problemas de facturación y conciliación.
Para obtener más información, consulta la sección Reembolsos y cancelaciones.