Suggest edit
Help us improve the documentation
Did you see wrong information and would you like us to explain something else or improve our manuals? Please leave your suggestions on GitHub.

Integrate Checkout API payment for cards

Integrating Mercado Pago's Checkout API for cards allows you to offer a complete payment option within the site. The entire experience takes place in your store, so customers avoid exiting your site while making a purchase.

Use our sample projects for a complete integration. You can adapt them according to your needs.

How does it work?

API-integration-flowchart


With our Mercado Pago Checkout API, you should take into account two aspects: data capture and payment confirmation submission.

  1. First, you need a frontend to collect card data and generate a security token with the information required to create a payment.
  2. Then, you need a backend that takes the generated token and payment data, such as amount and item, to confirm and make a payment.

Both for frontend and backend, we recommend our libraries to collect user sensitive data securely.

For more information, check API References.


Card data capture

Client-Side

To create a payment, you should capture card data through the buyer's browser. For security reasons, never store data in your servers.

      1. Include MercadoPago.js library

Use our official library to access Mercado Pago API from your application and collect data securely.

Html

<script src="https://secure.mlstatic.com/sdk/javascript/v1/mercadopago.js"></script>

Card information will be turned into a token so that you can send data to your servers securely.

      2. Add payment form

To capture sensitive data from your customer's cards, please use our form with the corresponding attributes, which ensures information security and correct token generation. For example, you should observe data-checkout attributes and avoid putting the name attribute in fields containing sensitive data. This way your servers will never store data.

You can easily include anything you need, change the suggested label attribute, and add your own style.

The following example assumes that transactionAmount and description data were obtained in a previous step in which customers selected the product or service to be paid.

Html

<form action="/process_payment" method="post" id="paymentForm">
   <h3>Buyer Details</h3>
     <div>
       <div>
         <label for="email">E-mail</label>
         <input id="email" name="email" type="text" value="test@test.com"></select>
       </div>
       <div>
         <label for="docType">Document Type</label>
         <select id="docType" name="docType" data-checkout="docType" type="text"></select>
       </div>
       <div>
         <label for="docNumber">Document Number</label>
         <input id="docNumber" name="docNumber" data-checkout="docNumber" type="text"/>
       </div>
     </div>
   <h3>Card Details</h3>
     <div>
       <div>
         <label for="cardholderName">Card Holder</label>
         <input id="cardholderName" data-checkout="cardholderName" type="text">
       </div>
       <div>
         <label for="">Expiration Date</label>
         <div>
           <input type="text" placeholder="MM" id="cardExpirationMonth" data-checkout="cardExpirationMonth"
             onselectstart="return false" onpaste="return false"
             oncopy="return false" oncut="return false"
             ondrag="return false" ondrop="return false" autocomplete=off>
           <span class="date-separator">/</span>
           <input type="text" placeholder="YY" id="cardExpirationYear" data-checkout="cardExpirationYear"
             onselectstart="return false" onpaste="return false"
             oncopy="return false" oncut="return false"
             ondrag="return false" ondrop="return false" autocomplete=off>
         </div>
       </div>
       <div>
         <label for="cardNumber">Card Number</label>
         <input type="text" id="cardNumber" data-checkout="cardNumber"
           onselectstart="return false" onpaste="return false"
           oncopy="return false" oncut="return false"
           ondrag="return false" ondrop="return false" autocomplete=off>
       </div>
       <div>
         <label for="securityCode">CVV</label>
         <input id="securityCode" data-checkout="securityCode" type="text"
           onselectstart="return false" onpaste="return false"
           oncopy="return false" oncut="return false"
           ondrag="return false" ondrop="return false" autocomplete=off>
       </div>
       <div id="issuerInput">
         <label for="issuer">Issuer</label>
         <select id="issuer" name="issuer" data-checkout="issuer"></select>
       </div>
       <div>
         <label for="installments">Installments</label>
         <select type="text" id="installments" name="installments"></select>
       </div>
       <div>
         <input type="hidden" name="transactionAmount" id="transactionAmount" value="100" />
         <input type="hidden" name="paymentMethodId" id="paymentMethodId" />
         <input type="hidden" name="description" id="description" />
         <br>
         <button type="submit">Pay</button>
         <br>
       </div>
   </div>
 </form>

      3. Configure your public key

Add your public key like this:

Javascript

window.Mercadopago.setPublishableKey("YOUR_PUBLIC_KEY");

If you still don't have an account to check your credentials, sign in.

      4. Get data for your form

        Get document types

If your country has more than one type of document, this field will be mandatory. Use the document list to fill out your data.

When you call the next function, MercadoPago.js will automatically fill out the available options, including the select type element with id = docType in the form:

Javascript

window.Mercadopago.getIdentificationTypes();

Find more information in the document type section.

        Get card payment method

Avoid mistakes and offer the correct available installments by validating your customers' data as they fill it out. Use the code in the following example to identify payment method with the first 6 digits of the card and check if it is necessary to identify the issuing bank.

Javascript

document.getElementById('cardNumber').addEventListener('change', guessPaymentMethod);

function guessPaymentMethod(event) {
   let cardnumber = document.getElementById("cardNumber").value;
   if (cardnumber.length >= 6) {
       let bin = cardnumber.substring(0,6);
       window.Mercadopago.getPaymentMethod({
           "bin": bin
       }, setPaymentMethod);
   }
};

function setPaymentMethod(status, response) {
   if (status == 200) {
       let paymentMethod = response[0];
       document.getElementById('paymentMethodId').value = paymentMethod.id;

       if(paymentMethod.additional_info_needed.includes("issuer_id")){
           getIssuers(paymentMethod.id);
       } else {
           getInstallments(
               paymentMethod.id,
               document.getElementById('transactionAmount').value
           );
       }
   } else {
       alert(`payment method info error: ${response}`);
   }
}

        Obtain issuer

It is important to identify the card's issuing bank when completing the form to avoid conflicts between different issuers and to be able to provide the relevant information to the payment methods that require it.

Add the following code to obtain the issuer_id:

Javascript

function getIssuers(paymentMethodId) {
   window.Mercadopago.getIssuers(
       paymentMethodId,
       setIssuers
   );
}

function setIssuers(status, response) {
   if (status == 200) {
       let issuerSelect = document.getElementById('issuer');
       response.forEach( issuer => {
           let opt = document.createElement('option');
           opt.text = issuer.name;
           opt.value = issuer.id;
           issuerSelect.appendChild(opt);
       });

       getInstallments(
           document.getElementById('paymentMethodId').value,
           document.getElementById('transactionAmount').value,
           issuerSelect.value
       );
   } else {
       alert(`issuers method info error: ${response}`);
   }
}

        Get number of installments

If you don't want to offer installments, skip this step.

The number of installments is also a mandatory field for credit card payments. You can use the function in the following example to fill out the select type suggested field called installments and get the available installments.

Javascript

function getInstallments(paymentMethodId, transactionAmount, issuerId){
   window.Mercadopago.getInstallments({
       "payment_method_id": paymentMethodId,
       "amount": parseFloat(transactionAmount),
       "issuer_id": issuerId ? parseInt(issuerId) : undefined
   }, setInstallments);
}

function setInstallments(status, response){
   if (status == 200) {
       document.getElementById('installments').options.length = 0;
       response[0].payer_costs.forEach( payerCost => {
           let opt = document.createElement('option');
           opt.text = payerCost.recommended_message;
           opt.value = payerCost.installments;
           document.getElementById('installments').appendChild(opt);
       });
   } else {
       alert(`installments method info error: ${response}`);
   }
}

      5. Create card token

Before payment submission, you must create a token containing all card information securely. You should generate it as follows:

Javascript

doSubmit = false;
document.getElementById('paymentForm').addEventListener('submit', getCardToken);
function getCardToken(event){
   event.preventDefault();
   if(!doSubmit){
       let $form = document.getElementById('paymentForm');
       window.Mercadopago.createToken($form, setCardTokenAndPay);
       return false;
   }
};

function setCardTokenAndPay(status, response) {
   if (status == 200 || status == 201) {
       let form = document.getElementById('paymentForm');
       let card = document.createElement('input');
       card.setAttribute('name', 'token');
       card.setAttribute('type', 'hidden');
       card.setAttribute('value', response.id);
       form.appendChild(card);
       doSubmit=true;
       form.submit();
   } else {
       alert("Verify filled data!\n"+JSON.stringify(response, null, 4));
   }
};

The createToken method will return a card_token with the secure card display. The second field of the createToken method is the callback function, which will process the response (in this case, we use the setCardTokenAndPay function). We will take and save the response ID in a hidden attribute called token and then send the form to your servers.

Important

Remember that the token is valid for 7 days and can be used only once.


Payment submission to Mercado Pago

Server-Side

To continue with the Mercado Pago payment process, your backend should know how to receive form information with the generated token and the filled out data.

In the above example, after the submit action, your backend should display a /process_payment endpoint, which is defined in the form action attribute, to receive all data.

Once the request –with all the collected information– is in your backend, it should be submitted to Mercado Pago through our APIs. The minimum mandatory fields to submit are: token, transaction_amount, installments, payment_method_id and payer.email.

For this to work, you should configure your private key. Also, to interact with our APIs, you should use Mercado Pago official SDK.

You can find payment status in status value.

<?php
    require_once 'vendor/autoload.php';

    MercadoPago\SDK::setAccessToken("YOUR_ACCESS_TOKEN");

    $payment = new MercadoPago\Payment();
    $payment->transaction_amount = (float)$_POST['transactionAmount'];
    $payment->token = $_POST['token'];
    $payment->description = $_POST['description'];
    $payment->installments = (int)$_POST['installments'];
    $payment->payment_method_id = $_POST['paymentMethodId'];
    $payment->issuer_id = (int)$_POST['issuer'];

    $payer = new MercadoPago\Payer();
    $payer->email = $_POST['email'];
    $payer->identification = array( 
        "type" => $_POST['docType'],
        "number" => $_POST['docNumber']
    );
    $payment->payer = $payer;

    $payment->save();

    $response = array(
        'status' => $payment->status,
        'status_detail' => $payment->status_detail,
        'id' => $payment->id
    );
    echo json_encode($response);

?>

You can find payment status in status value.

var mercadopago = require('mercadopago');
mercadopago.configurations.setAccessToken("YOUR_ACCESS_TOKEN");

var payment_data = {
  transaction_amount: Number(req.body.transactionAmount),
  token: req.body.token,
  description: req.body.description,
  installments: Number(req.body.installments),
  payment_method_id: req.body.paymentMethodId,
  issuer_id: req.body.issuer,
  payer: {
    email: req.body.email,
    identification: {
      type: req.body.docType,
      number: req.body.docNumber
    }
  }
};

mercadopago.payment.save(payment_data)
  .then(function(response) {
    res.status(response.status).json({
      status: response.body.status,
      status_detail: response.body.status_detail,
      id: response.body.id
    });
  })
  .catch(function(error) {
    res.status(response.status).send(error);
  });

You can find payment status in status value.

MercadoPago.SDK.setAccessToken("YOUR_ACCESS_TOKEN");

Payment payment = new Payment();
payment.setTransactionAmount(Float.valueOf(request.getParameter("transactionAmount")))
       .setToken(request.getParameter("token"))
       .setDescription(request.getParameter("description"))
       .setInstallments(Integer.valueOf(request.getParameter("installments")))
       .setPaymentMethodId(request.getParameter("paymentMethodId"));

Identification identification = new Identification();
identification.setType(request.getParameter("docType"))
              .setNumber(request.getParameter("docNumber"));

Payer payer = new Payer();
payer.setEmail(request.getParameter("email"))
     .setIdentification(identification);

payment.setPayer(payer);

payment.save();

System.out.println(payment.getStatus());

You can find payment status in status value.

require 'mercadopago'
$mp = MercadoPago.new('YOUR_ACCESS_TOKEN')

payment_data = {
  "transaction_amount": request.body.transactionAmount.to_f,
  "token": request.body.token,
  "description": request.body.description,
  "installments": request.body.installments.to_i,
  "payment_method_id": request.body.paymentMethodId,
  "payer": {
    "email": request.body.email,
    "identification": {
      "type": request.body.docType,
      "number": request.body.docNumber
    }
  }
}

payment = $mp.post('/v1/payments', payment_data)

puts payment

You can find payment status in status value.

using MercadoPago;
using MercadoPago.DataStructures.Payment;
using MercadoPago.Resources;

MercadoPago.SDK.SetAccessToken("YOUR_ACCESS_TOKEN");

Payment payment = new Payment()
{
    TransactionAmount = float.Parse(Request["transactionAmount"]),
    Token = Request["token"],
    Description = Request["description"],
    Installments = int.Parse(Request["installments"]),
    PaymentMethodId = Request["paymentMethodId"],
    Payer = new Payer(){
        Email = Request["email"],
        Identification = new Identification(){
          Type = Request["docType"],
          Number = Request["docNumber]
        }
    }
};

payment.Save();

console.log(payment.Status);

You can find payment status in status value.

curl -X POST \
    -H 'accept: application/json' \
    -H 'content-type: application/json' \
    -H 'Authorization: Bearer YOUR_ACCESS_TOKEN' \
    'https://api.mercadopago.com/v1/payments' \
    -d '{
          "transaction_amount": 168,
          "token": "ff8080814c11e237014c1ff593b57b4d",
          "description": "Durable Iron Shirt",
          "installments": 1,
          "payment_method_id": "visa",
          "issuer_id": 310,
          "payer": {
            "email": "test@test.com"
          }
    }'

        Response

Json

{
    "status": "approved",
    "status_detail": "accredited",
    "id": 3055677,
    "date_approved": "2019-02-23T00:01:10.000-04:00",
    "payer": {
        ...
    },
    "payment_method_id": "visa",
    "payment_type_id": "credit_card",
    "refunds": [],
    ...
}

Check API References to learn about all the available fields for full payments.

Error Response Handling

Possible payment statuses are:

payment-status

For improved payment approval, you need to correctly inform results to your customers when making or creating a payment.

This will prevent rejections and chargebacks in the case of already approved transactions. For example, this allows you to correct data upload mistakes or change payment methods.

We recommend using error response handling and the suggested communication in each case.

Note

Avoid rejected payments with our recommendations to improve the approval process.

Receive payment notifications

Finally, you always need to be notified of new payments and status updates. For example, if they were approved, rejected, or are pending.

Configure webhook notifications or IPN notifications.

Sample projects

Checkout API

Use our complete integration examples on GitHub in PHP or NodeJS to download instantly.

Payment form

If you want to deploy other technology in your server, you can download a complete payment form sample from GitHub.


Next steps

Your search returns no results.

Verifique a ortografia de termos de pesquisa ou teste com outras palavras-chave.