We are evolving our integration process. Discover the new Orders API

AI resources

Paycash

PayCash is a cash payment platform that allows buyers to pay bills and services at authorized physical establishments, such as banks, agents, and collection networks. With this option, the buyer generates a payment code and can pay it in person at any enabled location.

With Mercado Pago's Checkout API, you can offer payments with Paycash, allowing your buyers to complete online purchases with cash payment.

In this documentation, you will find all the steps needed to integrate with Paycash.

Get available payment methods

To get a detailed list of all payment methods available for integration, send a GET with your Access TokenPrivate key of the application created in Mercado Pago and used in the backend. You can access it through Your integrations > Integration data > Credentials. to the endpoint /v1/payment_methodsAPI and execute the request or, if you prefer, make the request using the SDKs below.

MercadoPagoConfig.setAccessToken("ENV_ACCESS_TOKEN");

PaymentMethodClient client = new PaymentMethodClient();
client.list();
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' \
MercadoPagoConfig.setAccessToken("ENV_ACCESS_TOKEN");

PaymentMethodClient client = new PaymentMethodClient();
client.list();
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));
<?php
  use MercadoPago\MercadoPagoConfig;

  MercadoPagoConfig::setAccessToken("ENV_ACCESS_TOKEN");

  $client = new PaymentMethodClient();
  $payment_method = $client->get();

?>
import mercadopago
sdk = mercadopago.SDK("ACCESS_TOKEN")

payment_methods_response = sdk.payment_methods().list_all()
payment_methods = payment_methods_response["response"]
require 'mercadopago'
sdk = Mercadopago::SDK.new('ENV_ACCESS_TOKEN')

payment_methods_response = sdk.payment_methods.get()
payment_methods = payment_methods_response[:response]

Import MercadoPago.js

To integrate Checkout API, you need to capture the necessary data to process the payment.

This capture is done by including the MercadoPago.js library in your project, followed by the payment form. Use the code below to import the MercadoPago.js library before adding the payment form.

npm install @mercadopago/sdk-js
<body>
  <script src="https://sdk.mercadopago.com/js/v2"></script>
</body>

Configure credentials

Credentials are unique keys that we use to identify an integration in your account. They are used to capture payments in online stores and other applications securely.

This is the first step in a complete code structure that must be followed to correctly integrate payments. Pay attention to the blocks below to add them as indicated.

javascript

const mp = new MercadoPago("YOUR_PUBLIC_KEY");

Add payment form

With the MercadoPago.js library included, add the payment form below to your project to ensure the secure capture of buyer data. At this stage, it is important to use the list you consulted to get the available payment methods to create the payment options you want to offer.

html

<form id="form-checkout" action="/process_payment" method="post">
    <div>
      <div>
        <label for="payerFirstName">First name</label>
        <input id="form-checkout__payerFirstName" name="payerFirstName" type="text">
      </div>
      <div>
        <label for="payerLastName">Last name</label>
        <input id="form-checkout__payerLastName" name="payerLastName" type="text">
      </div>
      <div>
        <label for="email">E-mail</label>
        <input id="form-checkout__email" name="email" type="text">
      </div>
      <div>
        <label for="identificationType">Document type</label>
        <select id="form-checkout__identificationType" name="identificationType" type="text"></select>
      </div>
      <div>
        <label for="identificationNumber">Document number</label>
        <input id="form-checkout__identificationNumber" name="identificationNumber" type="text">
      </div>
    </div>

    <div>
      <div>
        <input type="hidden" name="transactionAmount" id="transactionAmount" value="100">
        <input type="hidden" name="description" id="description" value="Product Name">
        <br>
        <button type="submit">Pay</button>
      </div>
    </div>
  </form>

Get document types

After configuring the credential and adding the payment form, you need to get the document types that will be used to fill out the payment form.

By including the select element with the id: form-checkout__identificationType that is in the form, it will be possible to automatically fill in the available options when calling the following function:

javascript

function createSelectOptions(elem, options, labelsAndKeys = { label : "name", value : "id"}){
   const {label, value} = labelsAndKeys;

   elem.options.length = 0;

   const tempOptions = document.createDocumentFragment();

   options.forEach( option => {
       const optValue = option[value];
       const optLabel = option[label];

       const opt = document.createElement('option');
       opt.value = optValue;
       opt.textContent = optLabel;

       tempOptions.appendChild(opt);
   });

   elem.appendChild(tempOptions);
}

// Get Identification Types
(async function getIdentificationTypes () {
   try {
       const identificationTypes = await mp.getIdentificationTypes();
       const docTypeElement = document.getElementById('form-checkout__identificationType');

       createSelectOptions(docTypeElement, identificationTypes)
   }catch(e) {
       return console.error('Error getting identificationTypes: ', e);
   }
})()

Send payment

After completing the payment form inclusion and obtaining the document types, you need to send the buyer's email, document type and number, the payment method used, and the payment amount details using our Payments API or one of our SDKs.

To configure payments with Paycash, send a POST with the required parameters to the endpoint /v1/paymentsAPI and execute the request or, if you prefer, use one of our SDKs indicated below.

For this step, when making the request via API or SDKs, you need to send your Access TokenPrivate key of the application created in Mercado Pago and used in the backend. You can access it through Your integrations > Integration data > Credentials.. Additionally, you will be required to send the X-Idempotency-Key header with your idempotency key to ensure the execution and re-execution of requests, avoiding unwanted situations such as duplicate payments, for example.
using MercadoPago.Config;
using MercadoPago.Client.Payment;
using MercadoPago.Resource.Payment;

MercadoPagoConfig.AccessToken = "ENV_ACCESS_TOKEN";

var request = new PaymentCreateRequest
{
    DateOfExpiration = DateTime.Parse("2026-02-03T20:00:00.000-05:00"),
    TransactionAmount = 5000,
    Description = "Product title",
    PaymentMethodId = "paycash",
    Payer = new PaymentPayerRequest
    {
        Email = "test_user_mx@testuser.com",
    },
};

var client = new PaymentClient();
Payment payment = await client.CreateAsync(request);
curl --location 'https://api.mercadopago.com/v1/payments' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer ENV_ACCESS_TOKEN' \
--header 'X-Idempotency-Key: <SOME_UNIQUE_VALUE>' \
--data-raw '{
  "transaction_amount": 100,
  "description": "Product title",
  "date_of_expiration": "2026-02-03T20:00:00.000-05:00",
  "payment_method_id": "paycash",
  "payer": { "email": "test_user_mx@testuser.com" }
}'
package main

import (
	"context"
	"fmt"
	"time"
	"github.com/mercadopago/sdk-go/pkg/config"
	"github.com/mercadopago/sdk-go/pkg/payment"
)

func main() {
	accessToken := "{{ACCESS_TOKEN}}"
	idempotencyKey := "{{SOME_UNIQUE_VALUE}}"

	cfg, err := config.New(accessToken)
	if err != nil {
		fmt.Println(err)
		return
	}

// Step 4: Initialize the API client
	client := payment.NewClient(cfg)

// Step 5: Create the request array
	expirationDate, _ := time.Parse(time.RFC3339, "2026-02-03T20:00:00.000-05:00")

	request := payment.Request{
		TransactionAmount: 5000,
               Description: "Product title",
		PaymentMethodID:   "paycash",
		Payer: &payment.PayerRequest{
			Email: "<PAYER_EMAIL>",
		},
		DateOfExpiration: &expirationDate,
	}

// Step 5: Make the request
	resource, err := client.Create(context.Background(), request, idempotencyKey)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println(resource)
}
PaymentCreateRequest paymentCreateRequest = PaymentCreateRequest.builder()
          .transactionAmount(new BigDecimal("<TRANSACTION_AMOUNT>"))
          .paymentMethodId("<PAYMENT_METHOD_ID>")
	   .dateOfExpiration(OffsetDateTime.parse("2026-02-03T20:00:00.000-05:00"))
          .payer(
              PaymentPayerRequest.builder()
                  .email("<EMAIL>").build()
          ).build();

Map<String, String> customHeaders = new HashMap<>();
customHeaders.put("x-idempotency-key", "<SOME_UNIQUE_VALUE>");

MPRequestOptions requestOptions = MPRequestOptions.builder()
    .customHeaders(customHeaders).build();

PaymentClient client = new PaymentClient();
client.create(paymentCreateRequest, requestOptions);
import { MercadoPagoConfig, Payments } from 'mercadopago';

const client = new MercadoPagoConfig({ accessToken: '<YOUR_ACCESS_TOKEN>' });
const payments = new Payments(client);

payments.create({
body: {
		transaction_amount: '<TRANSACTION_AMOUNT>',
		payment_method_id: '<PAYMENT_METHOD_ID>',
		date_of_expiration: "2026-02-03T20:00:00.000-05:00",
		payer: {
			email: '<EMAIL>'
			}
},
	requestOptions: { idempotencyKey: '<SOME_UNIQUE_VALUE>' }
})
	.then((result) => console.log(result))
	.catch((error) => console.log(error));
<?php
  use MercadoPago\Client\Payment\PaymentClient;

  $client = new PaymentClient();
  $request_options = new RequestOptions();
  $request_options->setCustomHeaders(["X-Idempotency-Key: <SOME_UNIQUE_VALUE>"]);

  $payment = $client->create([
    "transaction_amount" => (float) $_POST['<TRANSACTION_AMOUNT>'],
    "payment_method_id" => $_POST['<PAYMENT_METHOD_ID>'],
    "date_of_expiration" => "2026-02-03T20:00:00.000-05:00",
    "payer" => [
      "email" => $_POST['<EMAIL>']
    ]
  ], $request_options);
  echo implode($payment);
?>
import mercadopago
sdk = mercadopago.SDK("ENV_ACCESS_TOKEN")

payment_data = {
    "transaction_amount": 100,
    "description": "Product title",
    "payment_method_id": "paycash",
    "date_of_expiration": "2026-02-03T20:00:00.000-05:00",
    "payer": {
        "email": "test_user_mx@testuser.com"
    }
}

payment_response = sdk.payment().create(payment_data)
payment = payment_response["response"]
require 'mercadopago'
sdk = Mercadopago::SDK.new('ENV_ACCESS_TOKEN')

payment_request = {
  transaction_amount: 100,
  description: 'Product title',
  payment_method_id: 'paycash',
  date_of_expiration: '2026-02-03T20:00:00.000-05:00',
  payer: {
    email: 'test_user_mx@testuser.com'
  }
}

payment_response = sdk.payment.create(payment_request)
payment = payment_response[:response]

The details of each parameter sent in the request body, along with their possible values, are described in the table below.

FieldTypeDescriptionRequiredExample
transaction_amountnumberTransaction amount to be processed.Required100
descriptionstringBrief description of the product or service.Optional"Product title"
payment_method_idstringCrucial field to initiate the payment flow; must be filled with the value "paycash".Required"paycash"
date_of_expirationstringExpiration date of the payment ticket. If this field is not sent, a default expiration date of 2 days after ticket creation will be set. Only full days are considered for both the provided and default expiration date. Weekends are not counted. Therefore, if the integrator sends a date with minutes, the expiration date will be adjusted to the end of the day sent. Example: if the integrator sends "2026-02-03T20:00:00.000-05:00" (February 3, 2026 at 20:00, UTC-5), the expiration date will be February 3, 2026, set to 23:59 of that day.Optional"2026-02-03T20:00:00.000-05:00"
payerobjectContains detailed information about the payer, such as the email address.Required{ "email": "test_user_mx@testuser.com" }

The response will show the pending status until the buyer completes the payment. Additionally, in the response to the request, the external_resource_url parameter will return a URL containing the instructions for the buyer to make the payment. You can redirect them to this same link to complete the payment flow.

json

{
    "id": 146232108035,
    "date_created": "2026-02-19T15:25:07.765-05:00",
    "date_approved": null,
    "date_last_updated": "2026-02-19T15:25:07.765-05:00",
    "date_of_expiration": "2026-02-21T00:59:59.000-05:00",
    "money_release_date": null,
    "money_release_status": "released",
    "operation_type": "regular_payment",
    "issuer_id": "12845",
    "payment_method_id": "paycash",
    "payment_type_id": "ticket",
    "payment_method": {
        "id": "paycash",
        "type": "ticket",
        "issuer_id": "12845",
        "data": {},
        "forward_data": {}
    },
    "status": "pending",
    "status_detail": "pending_waiting_payment",
    "currency_id": "PEN",
    "description": null,
    "live_mode": true,
    "sponsor_id": null,
    "authorization_code": null,
    "money_release_schema": null,
    "taxes_amount": 0,
    "counter_currency": null,
    "brand_id": null,
    "shipping_amount": 0,
    "build_version": "3.143.0-rc-4",
    "pos_id": null,
    "store_id": null,
    "integrator_id": null,
    "platform_id": null,
    "corporation_id": null,
    "charges_execution_info": {
        "internal_execution": {
            "date": "2026-02-19T15:25:07.752-05:00",
            "execution_id": "01KHVNSY80AK1CR7EFNTN1DFHM"
        }
    },
    "payer": {
        "type": null,
        "id": "211339136",
        "operator_id": null,
        "email": null,
        "identification": {
            "number": null,
            "type": null
        },
        "phone": {
            "number": null,
            "extension": null,
            "area_code": null
        },
        "first_name": null,
        "last_name": null,
        "entity_type": null
    },
    "collector_id": 164720860,
    "marketplace_owner": null,
    "metadata": {},
    "additional_info": {
        "tracking_id": "platform:v1-whitelabel,so:ALL,type:N/A,security:none"
    },
    "order": {},
    "external_reference": null,
    "transaction_amount": 100,
    "transaction_amount_refunded": 0,
    "coupon_amount": 0,
    "differential_pricing_id": null,
    "financing_group": null,
    "deduction_schema": null,
    "barcode": {
        "content": "7041771529112930",
        "width": 1,
        "height": 30,
        "type": "Code128C"
    },
    "installments": 1,
    "transaction_details": {
        "payment_method_reference_id": "7041771529112930",
        "acquirer_reference": null,
        "barcode": {
            "content": "7041771529112930",
            "width": 1,
            "height": 30,
            "type": "Code128C"
        },
        "digitable_line": null,
        "verification_code": "10550843579",
        "net_received_amount": 0,
        "total_paid_amount": 100,
        "overpaid_amount": 0,
        "external_resource_url": "https://www.mercadopago.com.pe/payments/146232108035/ticket?caller_id=211339136&hash=c67143dd-b538-4a74-ba8b-829ae0a3caeb",
        "installment_amount": 0,
        "financial_institution": null,
        "payable_deferral_period": null
    },
    "fee_details": [],
    "charges_details": [
        {
            "id": "146232108035-001",
            "name": "mercadopago_fee",
            "type": "fee",
            "accounts": {
                "from": "collector",
                "to": "mp"
            },
            "client_id": 0,
            "date_created": "2026-02-19T15:25:07.767-05:00",
            "last_updated": "2026-02-19T15:25:07.767-05:00",
            "amounts": {
                "original": 5.06,
                "refunded": 0
            },
            "metadata": {
                "source": "proc-svc-charges",
                "source_detail": "processing_fee_charge",
                "reason": ""
            },
            "reserve_id": null,
            "refund_charges": [],
            "external_charge_id": "01KHVNSY8XPAMY1NVZFG1MF4S4",
            "update_charges": []
        }
    ],
    "captured": true,
    "binary_mode": false,
    "call_for_authorize_id": null,
    "statement_descriptor": null,
    "card": {},
    "notification_url": null,
    "refunds": [],
    "processing_mode": "aggregator",
    "merchant_account_id": null,
    "merchant_number": null,
    "point_of_interaction": {
        "type": "UNSPECIFIED",
        "business_info": {
            "unit": "online_payments",
            "sub_unit": "default",
            "branch": "Merchant Services"
        },
        "transaction_data": {}
    },
    "accounts_info": null,
    "release_info": null,
    "tags": null
}

Cancel payment

Only payments with pending or in process status can be canceled. When the cancellation is performed by the seller, the status_detail changes to by_collector.

Cancellation also occurs automatically when the current date exceeds the value set in the date_of_expiration field provided during payment creation. In that case, the status_detail will be expired.

For more information, see the Refunds and cancellations.

Payment establishments

When completing the integration, it is important to share with buyers the information about the different places where they can make the payment. To check the available establishments for PayCash payments, visit the official website.