PSE
Com o Checkout Transparente do Mercado Pago é possível oferecer pagamentos com PSE - Pagos Seguros en Línea -, serviço que permite fazer compras e pagamentos pela Internet utilizando recursos online diretamente da poupança, conta corrente ou carteira digital.
Para oferecer pagamentos com PSE, siga as etapas abaixo.
Obter meios de pagamento
Server-Side
Para obter uma lista detalhada com todos os meios de pagamento disponíveis para integração, envie um GET com seu Access Token ao endpoint /v1/payment_methods ou, se preferir, faça a requisição utilizando nossos SDKs abaixo.
<?php
use MercadoPago\Client\PaymentMethod\PaymentMethodClient;
use MercadoPago\MercadoPagoConfig;
MercadoPagoConfig::setAccessToken("YOUR_ACCESS_TOKEN");
$client = new PaymentMethodClient();
$payment_methods = $client->list();
?>
import MercadoPago, { PaymentMethod } from 'mercadopago';
const client = new MercadoPago({ accessToken: '<ACCESS_TOKEN>' });
const paymentMethod = new PaymentMethod(client);
paymentMethod.get()
.then(paymentMethods => res.status(200).json(paymentMethods))
.catch(console.log);
MercadoPagoConfig.setAccessToken("ENV_ACCESS_TOKEN");
PaymentMethodClient client = new PaymentMethodClient();
client.list();
require 'mercadopago'
sdk = Mercadopago::SDK.new('ENV_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 = "ENV_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 ENV_ACCESS_TOKEN' \
'https://api.mercadopago.com/v1/payment_methods' \
Uma vez obtidos os meios de pagamento, você pode listar os bancos disponíveis para pagamentos com PSE através do campo financial_institutions
dentro do objeto com id=pse
, conforme exemplo de resposta abaixo. Esta lista de bancos será necessária para continuar a integração durante a fase de Listar Bancos.
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" ] } ]
Para que a lista de métodos de pagamento seja consumida pelo frontend nas etapas a seguir, você precisará criar um novo endpoint GET /payment_methods
no seu aplicativo.
Adicionar formulário de pagamento
Client-Side
No frontend do seu projeto, você deve adicionar o seguinte formulário de pagamento.
html
<form id="form-checkout" action="/process_payment" method="post"> <div> <div> <label for="zipCode">Zip Code</label> <input id="form-checkout__zipCode" name="zipCode" type="text"> </div> <div> <label for="streetName">Street Name</label> <input id="form-checkout__streetName" name="streetName" type="text"> </div> <div> <label for="streetNumber">Street Number</label> <input id="form-checkout__streetNumber" name="streetNumber" type="text"> </div> <div> <label for="neighborhood">Neighborhood</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">Unidad Federal</label> <input id="form-checkout__federalUnit" name="federalUnit" type="text"> </div> <div> <label for="phoneAreaCode">PhoneAreaCode</label> <input id="form-checkout__phoneAreaCode" name="phoneAreaCode" type="text"> </div> <div> <label for="phoneNumber">PhoneNumber</label> <input id="form-checkout__phoneNumber" name="phoneNumber" type="text"> </div> <div> <label for="email">E-mail</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 del 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="Nome do Produto"> <br> <button type="submit">Pagar</button> </div> </div> </form>
Obter tipos de documento
Client-Side
Para criar um pagamento com PSE, é necessário obter o tipo e número do documento do usuário. A especificidade destes documentos está diretamente relacionada ao perfil do usuário — seja ele pessoa física ou jurídica —, selecionado no momento de preenchimento do formulário de pagamento. Essas informações podem ser coletadas de maneira automática por meio da função a seguir:
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)); } }
Listar bancos
Client-Side
Ao criar um pagamento com PSE, é necessário enviar o código do banco que será utilizado para a transferência. Para isso, é preciso listar os bancos disponíveis e apresentar essas opções ao pagador, permitindo que ele escolha o banco de sua preferência.
Caso ainda não o tenha feito, obtenha os meios de pagamento, conforme indicado na etapa Obter meios de pagamento, e filtre a lista de bancos disponíveis para PSE. A seguir, crie um elemento select
em javascript e enriqueça-o com os dados retornados nessa chamada, como mostra o exemplo abaixo:
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 os elementos dinâmicos criados com esses javascript sejam carregados quando a página terminar de renderizar, adicione o seguinte 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); } })();
Enviar pagamento
Server-Side
Ao finalizar a inclusão do formulário de pagamento, obter os tipos de documento e configurar lista de bancos, utilize nossa API de Pagamentos ou um de nossos SDKs para encaminhar o e-mail do comprador, o telefone, o endereço, o tipo e o número do documento, o meio de pagamento utilizado e o detalhe do valor a ser pago.
Para configurar pagamentos com PSE, envie um POST com os devidos parâmetros ao endpoint /v1/payments e execute a requisição ou, se preferir, utilize um de nossos SDKs abaixo.
<?php
use MercadoPago\Client\Common\RequestOptions;
use MercadoPago\Client\Payment\PaymentClient;
use MercadoPago\MercadoPagoConfig;
MercadoPagoConfig::setAccessToken("YOUR_ACCESS_TOKEN");
$client = new PaymentClient();
$request_options = new RequestOptions();
$request_options->setCustomHeaders(["X-Idempotency-Key: <SOME_UNIQUE_VALUE>"]);
$client = new PaymentClient();
$createRequest = [
"transaction_amount" => 5000,
"description" => "Product description",
"payment_method_id" => "pse",
"callback_url" => "http://www.your-site.com",
"notification_url" => "http://www.your-site.com",
"additional_info" => [
"ip_address" => "127.0.0.1"
],
"transaction_details" => [
"financial_institution" => $_POST['financialInstitution']
],
"payer" => [
"email" => $_POST['email'],
"entity_type" => "individual",
"first_name" => $_POST['firstName'],
"last_name" => $_POST['lastName'],
"identification" => [
"type" => $_POST['identificationType'],
"number" => $_POST['identificationNumber']
],
"address" => [
"zip_code" => $_POST['zipCode'],
"street_name" => $_POST['streetName'],
"street_number" => $_POST['streetNumber'],
"neighborhood" => $_POST['neighborhood'],
"city" => $_POST['city'],
"federal_unit" => $_POST['federalUnit']
],
"phone" => [
"area_code" => $_POST['phoneAreaCode'],
"number" => $_POST['phoneNumber']
],
],
];
$payment = $client->create($createRequest, $request_options);
print_r($payment);
?>
import { Payment, MercadoPagoConfig } from 'mercadopago';
const client = new MercadoPagoConfig({ accessToken: '<ACCESS_TOKEN>' });
const payment = new Payment(client);
const requestOptions = {
idempotencyKey: '<IDEMPOTENCY_KEY>',
};
const body = {
transaction_amount: 5000,
description: 'Product description',
payment_method_id: 'pse',
callback_url: 'http://www.your-site.com',
notification_url: 'http://www.your-site.com',
payer: {
entity_type: 'individual',
email: req.body.email,
first_name: req.body.firstName,
last_name: req.body.lastName,
identification: {
type: req.body.identificationType,
number: req.body.identificationNumber
},
address: {
zip_code: req.body.zipCode,
street_name: req.body.streetName,
street_number: req.body.streetNumber,
neighborhood: req.body.neighborhood,
city: req.body.city,
federal_unit: req.body.federalUnit
},
phone: {
area_code: req.body.phoneAreaCode,
number: req.body.phoneNumber
}
},
additional_info: {
ip_address: '127.0.0.1'
},
transaction_details: {
financial_institution: req.body.financialInstitution
}
};
payment.create({body, requestOptions})
.then(function (response) {
console.info(response)
})
.catch(function (error) {
console.error(error);
});
MercadoPagoConfig.setAccessToken("YOUR_ACCESS_TOKEN");
Map<String, String> customHeaders = Map.of("X-Idempotency-Key", "...");
MPRequestOptions requestOptions = MPRequestOptions.builder().customHeaders(customHeaders).build();
PaymentClient client = new PaymentClient();
IdentificationRequest identification = IdentificationRequest.builder()
.type(request.getIdentificationType())
.number(request.getIdentificationNumber())
.build();
PaymentPayerAddressRequest address = PaymentPayerAddressRequest.builder()
.zipCode(request.getZipCode())
.streetName(request.getStreetName())
.streetNumber(request.getStretNumber())
.neighborhood(request.getNeighborhood())
.city(request.getCity())
.federalUnit(request.getFederalUnit())
.build();
PaymentPayerPhoneRequest phone = PaymentPayerPhoneRequest.builder()
.areaCode(request.getPhoneAreaCode())
.number(request.getPhoneNumber())
.build();
PaymentPayerRequest payer = PaymentPayerRequest.builder()
.email(request.getEmail())
.entityType("individual")
.firstName("firstName")
.lastName("lastName")
.identification(identification)
.address(address)
.phone(phone)
.build();
PaymentAdditionalInfoRequest additionalInfo = PaymentAdditionalInfoRequest.builder()
.ipAddress("127.0.0.1")
.build();
PaymentTransactionDetailsRequest transactionDetails = PaymentTransactionDetailsRequest.builder()
.financialInstitution(request.getFinancialInstitution())
.build();
PaymentCreateRequest paymentCreateRequest = PaymentCreateRequest.builder()
.transactionAmount(new BigDecimal(5000))
.description("Product description")
.paymentMethodId("pse")
.additionalInfo(additionalInfo)
.transactionDetails(transactionDetails)
.callbackUrl("https://your-site.com")
.notificationUrl("https://your-site.com")
.payer(payer)
.build();
client.create(paymentCreateRequest);
require 'mercadopago'
sdk = Mercadopago::SDK.new('ACCESS_TOKEN')
custom_headers = {
'x-idempotency-key': '<SOME_UNIQUE_VALUE>'
}
request_options = Mercadopago::RequestOptions.new(custom_headers: custom_headers)
body = {
transaction_amount: 5000,
description: "Product description",
payment_method_id: "pse",
callback_url: "https://your-site.com",
notification_url: "https://your-site.com",
additional_info: {
ip_address: "127.0.0.1"
},
transaction_details: {
financial_institution: params[:financialInstitution]
},
payer: {
email: params[:email],
entity_type: "individual",
first_name: params[:firstName],
last_name: params[:lastName],
identification: {
type: params[:identificationType],
number: params[:identificationNumber]
}
address: {
zip_code: params[:zipCode],
street_name: params[:streetName],
street_number: params[:streetNumber],
neighborhood: params[:neighborhood],
city: params[:city],
federal_unit: params[:federalUnit]
}
phone: {
area_code: params[: phoneAreaCode],
number: params[: phoneNumber]
}
}
}
payment_response = sdk.payment.create(body, request_options)
payment = payment_response[: response]
MercadoPagoConfig.AccessToken = "ACCESS_TOKEN";
var requestOptions = new RequestOptions();
requestOptions.CustomHeaders.Add(Headers.IDEMPOTENCY_KEY, "YOUR_IDEMPOTENCY_KEY");
var identification = new IdentificationRequest() {
Type = request.IdentificationType,
Number = request.IdentificationNumber
};
var address = new PaymentPayerAddressRequest() {
ZipCode = request.ZipCode,
StreetName = request.StreetName,
StreetNumber = request.StreetNumber,
Neighborhood = request.Neighborhood,
City = request.City,
FederalUnit = request.FederalUnit
};
var phone = new PaymentPayerPhoneRequest() {
AreaCode = request.PhoneAreaCode,
Number = request.PhoneNumber
};
var payer = new PaymentPayerRequest() {
Email = request.Email,
EntityType = "individual",
FirstName = firstName,
LastName = lastName,
Identification = identification,
Address = address,
Phone = phone
};
var additionalInfo = new PaymentAdditionalInfoRequest() {
IpAddress = "127.0.0.1"
};
var transactionDetails = new PaymentTransactionDetailsRequest() {
FinancialInstitution = request.FinancialInstitution
};
var paymentCreateRequest = new PaymentCreateRequest() {
TransactionAmount = 5000,
Description = "Product description",
PaymentMethodId = "pse",
AdditionalInfo = additionalInfo,
TransactionDetails = transactionDetails,
CallbackUrl = "https://your-site.com",
NotificationUrl = "https://your-site.com",
Payer = payer
};
var client = new PaymentClient();
var payment = await client.CreateAsync(paymentCreateRequest, requestOptions);
import mercadopago
sdk = mercadopago.SDK("ACCESS_TOKEN")
request_options = mercadopago.config.RequestOptions()
request_options.custom_headers = {
'X-Idempotency-Key': '<SOME_UNIQUE_VALUE>'
}
body = {
"transaction_amount": 5000,
"description": "Product description",
"payment_method_id": "pse",
"callback_url": "https://your-site.com",
"notification_url": "https://your-site.com",
"additional_info": {
"ip_address": "127.0.0.1"
},
"transaction_details": {
"financial_institution": request.POST.get("financialInstitution")
},
"payer": {
"email": request.POST.get("email"),
"entity_type": "individual",
"first_name": request.POST.get("firstName"),
"last_name": request.POST.get("lastName"),
"identification": {
"type": request.POST.get("identificationType"),
"number": request.POST.get("identificationNumber")
},
"address": {
"zip_code": request.POST.get("zipCode"),
"street_name": request.POST.get("streetName"),
"street_number": request.POST.get("streetNumber"),
"neighborhood": request.POST.get("neighborhood"),
"city": request.POST.get("city"),
"federal_unit": request.POST.get("federalUnit")
},
"phone": {
"area_code": request.POST.get("phoneAreaCode"),
"number": request.POST.get("phoneNumber")
}
}
}
payment_response = sdk.payment().create(body, request_options)
payment = payment_response["response"]
curl --location --request POST 'https://api.mercadopago.com/v1/payments' \
-H 'Authorization: Bearer ENV_ACCESS_TOKEN' \
-H 'X-Idempotency-Key: SOME_UNIQUE_VALUE' \
-H 'Content-Type: application/json' \
--d '{
"transaction_amount": 5000,
"description": "Product description",
"payment_method_id": "pse",
"callback_url": "http://www.your-site.com",
"notification_url": "http://www.your-site.com",
"payer": {
"email": "test_user_19549678@testuser.com",
"entity_type": "individual",
"first_name": "first name",
"last_name": "last_name",
"identification": {
"type": "type",
"number": "number"
},
"address": {
"zip_code": "111",
"street_name": "street name",
"street_number": "street number",
"neighborhood": "neighborhood",
"city": "city",
"federal_unit": "federal unit"
},
"phone": {
"area_code": "area code",
"number": "number"
}
},
"additional_info": {
"ip_address": "127.0.0.1"
},
"transaction_details": {
"financial_institution": "1009"
}
}'
É necessário preencher os campos obrigatórios listados abaixo, seguindo as especificações mostradas na tabela a seguir:
Campo | Descrição | Possíveis valores/validações | Chamado para obter os valores |
transaction_amount | Valor do pagamento. | Deve ser maior que 0. | - |
transaction_details.financial_institution | Banco informado no POST para efetuar a transferência eletrônica. A lista de bancos deve ser mostrada ao usuário e permitida a seleção. A lista é atualizada, por isso é recomendável consumir as informações a cada hora. | No debe ser nulo ni vacío y debe corresponder a un banco existente. | https://api.mercadopago.com/v1/payment_methods/search?site_id=MCO&id=pse&public_key=YOUR_PUBLIC_KEY |
payer.entity_type | Tipo de pessoa, física ou jurídica. | individual ou association | - |
payer.identification.type | Tipo de documento do comprador. | Valores aceitos: - RC (Registro Civil de Nacimiento) - TI (Tarjeta de Identidad) - CC (Cedula de Ciudadania) - TE (Tarjeta de Extranjeria) - CE (Cedula de Extranjeria) - PAS (Pasaporte) - NIT - DI (Documento de Identificación) | curl -X GET \ 'https://api.mercadopago.com/v1/identification_types' \ -H 'Authorization: Bearer YOUR_PUBLIC_KEY' |
payer.identification.number | Número do documento do comprador. | String Deve ter de 1 até 15 posições numéricas. Se é do tipo 'passaporte', aceitará valores alfanuméricos. | - |
payer.first_name | Nome do comprador. | Deve ter de 1 até 32 posições. | - |
payer.last_name | Sobrenome do comprador. | Deve ter de 1 até 32 posições. | - |
payer.address.zip_code | Código postal do comprador. | Deve ter exatamente 5 posições. | - |
payer.address.street_name | Nome da rua onde o comprador reside. | Deve ter de 1 até 18 posições. | - |
payer.address.street_number | Núúmero da residência do comprador. | Deve ter de 1 até 5 posições. | - |
payer.address.neighborhood | Nome do bairro onde o comprador reside. | Deve ter de 1 até 18 posições. | - |
payer.address.city | Cidade do comprador. | Deve ter de 1 até 18 posições. | - |
payer.phone.area_code | Código de área do telefone do comprador. | Deve ter 3 posições. | - |
payer.phone.number | Número de telefone do comprador. | String Deve ter de 1 até 5 posições e só aceita caracteres numéricos. | - |
additional_info.ip_address | Endereço do IP do comprador, onde o pagamento é gerado. | - | - |
callback_url | Página onde o comprador é redirecionado por padrão após efetuar o pagamento dentro da página do banco, quando o comprador indica que deseja retornar à loja. Você pode ver sugestões de mensagens para mostrar ao comprador no subtítulo Exemplos de mensagens para callback URL. | Não deve ser nulo ou vazio e deve ter, no máximo, 512 caracteres. | - |
notification_url | URL usada para notificar a aplicação de que a transferência foi concluída. | Não deve ser nulo ou vazio e deve ter, no máximo, 512 caracteres. | - |
A resposta mostrará o status pendente
até que o comprador realize o pagamento. Além disso, o parâmetro external_resource_url
retornará uma URL para a qual você deverá redirecionar o comprador para que ele conclua o fluxo de pagamento.
Você pode ver um exemplo dessa resposta abaixo. Tenha em conta que as informações foram omitidas para mostrar os campos mais relevantes.
json
{ "id": 1312147735, … "operation_type": "regular_payment", "payment_method_id": "pse", "payment_type_id": "bank_transfer", "payment_method": { "id": "pse", "type": "bank_transfer" }, "status": "pending", "status_detail": "pending_waiting_transfer", … "description": "Título del producto", … "callback_url": "http://www.your-site.com", "transaction_details": { … "total_paid_amount": 5000, … "external_resource_url": "https://www.mercadopago.com.co/sandbox/payments/1312147735/bank_transfer?caller_id=1148920820&hash=f41dd14f-b3a6-4ac4-9b78-5cfeb5a35e77", … "financial_institution": "1009", … "bank_transfer_id": 129229, "transaction_id": "10022214" }, }
Exemplos de mensagens para callback URL
Após o comprador realizar o pagamento na plataforma do banco escolhido, ele será redirecionado para uma URL de callback. Nesta página, ele receberá informações sobre o status da transação.
Abaixo, apresentamos exemplos de mensagens que você pode exibir, alinhadas aos três possíveis status em que o pagamento pode se encontrar.
Status aprovado
Status pendente
Status rejeitado
Expiração
O pagamento criado com PSE expira automaticamente em 15 minutos após ter sido criado e seu status passa a ser rejeitado
. Caso o comprador não acesse a web e efetue o pagamento dentro desse prazo, um novo pagamento deverá ser criado.