Mercado Pago

Mercado Pago
Mercado Pago is an online payment platform developed by Mercado Libre that allows users and merchants to make and receive payments securely and efficiently.
Supported operations
| Operation | Description |
|---|---|
| ✅ Direct payment | Combines authorization and capture in one step. |
| ✅ Refund | Returns the full amount of a transaction. |
| ✅ Partial refund | Returns part of the captured amount. |
Integration
1. Configure Mercado Pago as a payment method
To integrate Mercado Pago, you must first perform a series of configurations from the OrkestaPay portal. Visit our Providers configuration guide and find the Mercado Pago payment method.
2. Implement payment button
To tokenize the payment data, follow these steps:
- Include OrkestaPay scripts: Use the OrkestaPay scripts in your web application.
- Initialize parameters: Define the OrkestaPay credentials here, as well as data related to the payment to be processed.
- Render the payment button: Place the Mercado Pago button in your frontend.
Required resources:
CSS
<link
rel="stylesheet"
href="https://checkout.orkestapay.com/web/components/payment-methods/styles.css"
integrity="sha384-5/NLomvLQk75JVAmEdaNkdkgLavuAlRS256szA++bmuw6Zph/wFYlWFHz9Fss7JF"
crossorigin="anonymous"
/>JS
<script
src="https://checkout.orkestapay.com/script/orkestapay.js"
integrity="sha384-lQoLMYDY2Cz/Y+8BLiNbhfLVHWawqsA/gE/8WRTpF6ZS3EABNKXhrq/0bBu4M1aI"
crossorigin="anonymous"
></script>
<script
src="https://checkout.orkestapay.com/web/components/payment-methods/main.js"
integrity="sha384-hvoIO7IyazX+Cc2LqBdHXx7Z3tq766248YzywLTN+D6f41Lub/VHUh2Pe5Q7WKfA"
crossorigin="anonymous"
></script>Code example
In the following code snippet there are certain parameters that need to be replaced with your merchant data:
public_key: Public key; these credentials can be obtained from the OrkestaPay portal.merchant_id:Merchant ID; these credentials can be obtained from the OrkestaPay portal.is_sandbox:Defines whether the credentials you are about to use are for testing or production.
In this example, sensitive credentials are captured in a form. These credentials must be handled from the backend.
client_id: This key, together with the secret key, will allow authentication to communicate with the OrkestaPay API. It is used on the server.client_secret:This key, together with the access key, will allow authentication to communicate with the OrkestaPay API. It is used on the server.completed_redirect_url: This URL is used to redirect the user once the payment has been successfully completed.canceled_redirect_url: This URL is used to redirect the user if they decide not to complete the payment.
INFORMATIONTo consult OrkestaPay credentials, you can visit our guide Get API keys.
<!DOCTYPE html>
<html lang="en">
<head>
<base href="/" />
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="apple-touch-icon" type="image/x-icon" href="favicon.ico" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<title>MercadoPago web component</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous"
/>
<link rel="stylesheet" href="https://checkout.orkestapay.com/web/components/payment-methods/styles.css" />
<style>
.code {
color: inherit;
overflow-wrap: break-word;
white-space: pre-wrap;
}
</style>
</head>
<body>
<main class="container">
<section class="row mt-5">
<h1 id="card-title" class="col-12 text-center">OrkestaPay payment method MercadoPago web component</h1>
</section>
<section class="row">
<article class="col-12 col-md-6 offset-md-3">
<div class="row">
<section class="pt-3 col-12 col-md-6">
<label for="client-id" class="form-label"> OrkestaPay client ID <span class="text-danger">*</span> </label>
<input type="text" id="client-id" class="form-control" />
<small id="client-id-error" class="text-danger"></small>
</section>
<section class="pt-3 col-12 col-md-6">
<label for="client-secret" class="form-label"> OrkestaPay client secret <span class="text-danger">*</span> </label>
<input type="password" id="client-secret" class="form-control" />
<small id="client-secret-error" class="text-danger"></small>
</section>
<section class="pt-3 col-12">
<label for="completed-redirect-url" class="form-label"> Completed redirect URL <span class="text-danger">*</span> </label>
<input type="text" id="completed-redirect-url" class="form-control" />
<small id="completed-redirect-url-error" class="text-danger"></small>
</section>
<section class="pt-3 col-12">
<label for="canceled-redirect-url" class="form-label"> Canceled redirect URL <span class="text-danger">*</span> </label>
<input type="text" id="canceled-redirect-url" class="form-control" />
<small id="canceled-redirect-url-error" class="text-danger"></small>
</section>
<section class="pt-3 col-12">
<article class="form-check">
<input type="checkbox" id="redirect" class="form-check-input" />
<label for="redirect" class="form-check-label"> Redirect </label>
</article>
</section>
</div>
</article>
<article id="button-container" class="pt-3 col-12 col-md-6 offset-md-3"></article>
<article class="pt-3 col-12">
<div id="payment-details" class="w-100 alert" role="alert"></div>
</article>
</section>
</main>
<noscript> Please enable JavaScript to continue using this application. </noscript>
<script type="text/javascript" src="https://checkout.orkestapay.com/script/orkestapay.js"></script>
<script type="text/javascript" src="https://checkout.orkestapay.com/web/components/payment-methods/main.js"></script>
<script type="text/javascript">
//#region FRONTEND
let orkestaPay;
let paymentId = null;
const clientId = document.getElementById("client-id");
const clientSecret = document.getElementById("client-secret");
const completedRedirectUrl = document.getElementById("completed-redirect-url");
const canceledRedirectUrl = document.getElementById("canceled-redirect-url");
const redirect = document.getElementById("redirect");
const { public_key, merchant_id, is_sandbox, country_code, currency, amount, customer_id } = initValues();
(async function main() {
initFormValue();
orkestaPay = initOrkestaPay({ is_sandbox, merchant_id, public_key });
const mercadoPagoButton = document.createElement("orkestapay-mercadopago-button");
await customElements.whenDefined("orkestapay-mercadopago-button");
mercadoPagoButton.params = {
payment_details: { createPayment, confirmPayment },
theme: { button_color: "default" },
};
const container = document.getElementById("button-container");
container.appendChild(mercadoPagoButton);
})();
function handlePaymentCreated(payment) {
const code = document.createElement("code");
code.innerHTML = JSON.stringify(payment, null, 2);
code.classList.add("code");
const paymentDetails = document.getElementById("payment-details");
paymentDetails.classList.add("alert-success");
paymentDetails.replaceChildren(code);
paymentId = payment.payment_id;
return paymentId ?? null;
}
function initValues() {
const url = new URL(window.location.href);
return {
public_key: "<REPLACE_WITH_YOUR_PUBLIC_KEY>",
merchant_id: "<REPLACE_WITH_YOUR_MERCHANT_ID>",
is_sandbox: true,
country_code: "MX",
currency: "MXN",
amount: "100.00",
};
}
//#endregion FRONTEND
//#region BACKEND
async function createPayment(paymentMethod) {
if (!paymentMethod) return null;
const { payment_method_id } = paymentMethod;
const order = await createOrder();
if (!order) return null;
const { order_id } = order;
const deviceInfo = await orkestaPay.getDeviceInfo();
if (!deviceInfo) return;
const { device_session_id } = deviceInfo;
let settings = null;
if (redirect.checked) {
const completed_redirect_url = completedRedirectUrl.value.trim();
const canceled_redirect_url = canceledRedirectUrl.value.trim();
if (completed_redirect_url && canceled_redirect_url) {
settings = {
redirection_url: {
completed_redirect_url,
canceled_redirect_url,
},
};
}
}
const url = `${orkestaPay.getApiUrl()}/v1/payments`;
const Authorization = await authenticate();
const body = JSON.stringify({
payment_source: {
payment_method_id,
type: "MERCADO_PAGO",
...(settings && { settings }),
},
device_session_id,
order_id,
});
return fetch(url, {
method: "POST",
headers: {
Authorization,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body,
})
.then(handleFetchResponse)
.then(handlePaymentCreated)
.catch(handleFetchError);
}
async function confirmPayment() {
if (!paymentId) return;
const url = `${orkestaPay.getApiUrl()}/v1/payments/${paymentId}/confirm`;
const Authorization = await authenticate();
const body = JSON.stringify({});
return fetch(url, {
method: "POST",
headers: {
Authorization,
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body,
})
.then(handleFetchResponse)
.then(handlePaymentCreated)
.catch(handleFetchError);
}
async function createOrder() {
const url = `${orkestaPay.getApiUrl()}/v1/orders`;
const Authorization = await authenticate();
const body = JSON.stringify({
merchant_order_id: crypto.randomUUID(),
subtotal_amount: amount,
total_amount: amount,
country_code,
customer: {
email: "<REPLACE_WITH_AN_EMAIL>",
},
currency,
products: [
{
product_id: crypto.randomUUID(),
quantity: 1,
unit_price: amount,
name: "A random product",
},
],
});
return fetch(url, {
method: "POST",
headers: { Authorization, "Content-Type": "application/json" },
body,
})
.then(handleFetchResponse)
.catch(handleFetchError);
}
async function authenticate() {
const url = `${orkestaPay.getApiUrl()}/v1/oauth/tokens`;
const body = JSON.stringify({
client_id: clientId.value.trim(),
client_secret: clientSecret.value.trim(),
grant_type: "client_credentials",
});
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body,
})
.then(handleFetchResponse)
.catch(handleFetchError);
if (!response) return null;
const { token_type, access_token } = response;
return `${token_type} ${access_token}`;
}
function handleFetchResponse(response) {
return response.ok ? response.json() : Promise.reject(body);
}
function handleFetchError(error) {
console.error(error);
return null;
}
//#endregion BACKEND
</script>
</body>
</html>
NOTEThis code is for demonstration purposes only, integrating frontend code and code that should be executed from a backend. Therefore, it is your responsibility to implement with best practices.
Code explanation
Initial variables and functions
orkestaPay: Object to interact with the OrkestaPay API.paymentId: Stores the current payment ID.initValues: Initial configuration, such as keys and transaction details (amount, currency, etc.).
main function
main function- It is a self-executing asynchronous function that:
- Initializes the form with default values (
initFormValue()). - Configures the OrkestaPay SDK (
initOrkestaPay). - Creates a MercadoPago button (
orkestapay-mercadopago-button) as a Web Component. - Configures the button parameters:
payment_details: Defines functions to create and confirm payments.theme: Styles the button.
- Inserts the button into the container (
button-container).
- Initializes the form with default values (
Backend operations
Authentication (authenticate)
authenticate)- Obtains an access token by sending the credentials (
client_id,client_secret) to the API. - Returns the token to authorize other requests.
Order registration (createOrder)
createOrder)- Creates a new order in the API.
- Includes basic information such as total amount, currency, and products (fictional in this case).
Payment creation (createPayment)
createPayment)- Steps:
- Obtains the
payment_method_id. - Registers an order (
createOrder). - Obtains device information (
getDeviceInfo). - If the
redirectcheckbox is checked, includes redirect URLs. - Makes a
POSTrequest to the API to create the payment. - Processes the response and displays the payment details (
handlePaymentCreated).
- Obtains the
Payment confirmation (confirmPayment)
confirmPayment)- Confirms the previously created payment via its
paymentId.
Response and error handling
handleFetchResponse: Returns the response body if successful; otherwise, rejects the promise.handleFetchError: Displays errors in the console.
