DEV Community

¿Cómo integrar Mercado Pago a tu web?

Nicolás Castro Garcia on June 14, 2020

La semana pasada, se me presentó un "examen" de certificación en el que tenía que integrar a una web el checkout de Mercado Pago (de acá en más MP,...
The discussion has been locked. New comments can't be added.
Preguntas en: @ncastrogarcia, una version actualizada en: https://www.youtube.com/watch?v=w1VBrIuSw2o
Collapse
 
rogemita profile image
Roger

Hola Nicolás, muy buena toda la información que compartiste y ademas de las respuestas que son muy completas!, te cuento que estuve renegando hasta recién con la primer experiencia de integración con MP y por suerte buscando sobre webhooks me encontré con este valioso post que hiciste, mil gracias por eso.
Si no es molestia quisiera dejarte aquí unas preguntas:

1 - Si podes darme alguna sugerencia para probar los webhooks en la etapa sandbox. Es decir, puedo crear el endpoint que me va a servir para atender los webhooks, pero como estoy en mi localhost, me gustaría saber si me das una sugerencia para probar, no se si usar alguna app que me permita hacer un tunel de mi local para la internet y usar ese endpoint cuando envio notification_url en mi "preferencia" de MP. Y sabrás alguna documentación concreta de los schemas de información que llegan al endpoint del webhook?

2 - Sabrás que diferencia habría entre webhooks y ipn y cual conviene usar?

3 - Hablando de la lógica de negocio, debería yo crear una orden pendiente cuando creo una "preference" y enviarle en el atributo "external_reference" el "id" de mi orden (db), para luego cuando llegue la notificación de webhook poder ir a buscarla a la MP API con ese mismo ID que guardé en "external_reference" y así ver el estado de pago? (eso suponiendo que me va a llegar el "external_reference" cuando me llegue una notificación de webhook si no mal entiendo, claro. De no ser así, que "referencia" me recomiendas guardar en la orden "pendiente" de mi sistema para luego utilizar para ir a buscar la información concreata del estado del pago?. De ser así y crear la orden al momento que genero el "preference" para el checkout, supongo que de alguna manera hay que luego limpiar las ordenes viejas que la gente no pagó y ya vencieron, o bien porque abrieron el checkout y se fueron o por cualquier otro motivo?

4 - Probaste el "modo binario" que ofrece MP alguna vez? De ser así, que experiencia tuviste con esto?

Millón de gracias, espero no molestar con las preguntas, gracias.

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Hola Roger!

Te contesto por partes:

  1. Para probar los webhooks en "sandbox" tenes que seguir los siguientes pasos:

    • Tenes que crear ambos usuarios de prueba, el comprador y el vendedor.
    • Usar las keys de tu usuario vendedor para generar toda la configuración del webhook y de la preferencia.
    • Comprar con la cuenta de tu usuario comprador (de prueba) pero no desde el link que devuelve init_point de sandbox, si no desde el init_point de producción directamente.
    • Con tu cuenta de usuario vendedor (de prueba), logueate a producción de mercadopago y ahí deberías ver la compra instantanea (proba el pago automático con unas de las tarjetas que están acá, teniendo en cuenta que el código de todas esas tarjetas son 123) Y ya con eso se debería ver tu notificación webhook
  2. Lejos de ser un experto en este tema, los webhooks se sienten más rápidos con una respuesta más limpia, en síntesis, más modernos. Estuve buscando un poco, y lo único que encontré es algo relacionado a paypal, en stackoverflow

  3. El external_reference es tal cual como lo estas diciendo. Igual te recomiendo que veas la respuesta que le hice a Luis Pastén en este mismo post, donde discutimos un poco de como viene la información de los webhooks y dejo un par de ejemplos. Igualmente te dejo un repositorio en github funcionando de toda esta ingregación (se supone que sigue viva esas keys, de última levantame un issue que lo reviso)

  4. Nunca lo probé el modo binario!

Gracias a vos por preguntar!

Si te quedaste con alguna otra duda, sentite libre de preguntar!

Saludos!

Collapse
 
rogemita profile image
Roger

Mil gracias Nico, gracias por tus respuestas. Genial, lo de webhook en realidad te preguntaba como emularlo para que lleguen las notificaciones a mi maquina local, y se me ocurría usar alguna app que haga de tunel para afuera y pasarle esa url a las notificaciones que le mando en la preferencia de pago. No se que hiciste vos para probar los handlers de los webhooks o si tenes alguna recomendación al respecto, gracias Nico!

 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Roger!

Perdón que respondi a medias jaja

Para hostear usé heroku, y eso me permitió ver las notificaciones y otros detalles, en un proyecto simil vivo.

Collapse
 
yordymora98 profile image
Yordy Mora

Hola Nicolás, primero que nada muy buen tutorial, muy bien explicado!
Quisiera preguntarte, yo estoy desarrollando en Angular, cabe la posibilidad de poder modificar el código que da mercadopago developers, o es necesario que este sea en Node.
Gracias nuevamente por la guía!

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Hola Yordy! gracias por leer!

La verdad es que nunca trabajé con Angular. No lo manejo. Desconozco si podes hacer back + front integrado, como con React + Nextjs o con Handlebars + node.

La realidad es que algo de backend vas a necesitar por las herramientas que brinda (manejo de requests y responses por ejemplo).

Saludos!

Collapse
 
yordymora98 profile image
Yordy Mora

Muchas Gracias Nicolás por tomarte el tiempo en poder responderme.
Y si, eso mismo estaba pensando, ya que sería re escribir código, pero tratando de implementarle la lógica y funcionalidades que tu planteas.
Agradezco la idea que planteas con React + Nextjs, espero que tengas buen día, y te agradezco nuevamente la guía.
¡Un saludo!

Collapse
 
sebalr profile image
Sebastian Larrieu

Hola Nicolás, te hago una consulta. Éstoy intentando hacer el checkout en modo modal en una web. Para eso hago una llamada ajax para obtener el id de preferencia pero por más que ponga el form con el script nunca aparece un boton ni nada que se le parezca (ni siquiera veo que se descargue el script .js que está dentro del form).
Tenés idea que pueda ser?
Gracias

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Asumo que estás usando algo similar a esto en tu front

<form action="/procesar-pago" method="POST">
  <script
   src="https://www.mercadopago.com.ar/integrations/v1/web-payment-checkout.js"
   data-preference-id="$$id$$">
  </script>
</form>
Enter fullscreen mode Exit fullscreen mode

Lo importante es el valor de data-preference-id, que dependiendo el lenguaje que estes usando en el back, le tenes que pasar el id de una manera distinta, fijate acá en el paso 2.

También, fijate de no estar tratando de comprar con la misma cuenta que generó la preferencia de pago (asumo que la preferencia fue creada satisfactoriamente).

Por último si ves todo bien, y tenes armado bien tu circuito, podes mandar un ticket al soporte en este link. Responden relativamente rápido.

Espero que te sirva!

Saludos!

Collapse
 
sebalr profile image
Sebastian Larrieu

Gracias por la respuesta. Exactamente ese código estoy usando, pero el id lo estaba obteniendo via api en un proyecto de backend separado del de frontend (la generación anda joya). Asumo que esto no se puede, voy a probar con el link en lugar del modal o el web tokenizer

Collapse
 
sebalr profile image
Sebastian Larrieu

Para futuras referencias. El problema es Angular que no acepta tags script en los templates

Collapse
 
luispastendev profile image
Luis Pastén

Hola Nicolás buen tutorial, tengo una duda estoy trabajando justo ahora con la pasarela de MP, ya casi estoy por terminar, mi pregunta va con respecto a los webhooks ya que estoy probando con el modo sandbox, cuando se realizan pagos por oxxo o transferencia bancaria MP notifica cuando se liquida la orden? estaba leyendo la documentación y quiero entender que se recibe un json en el webhook con el action "payment.updated", estube checando el modo sandbox pero las ordenes se quedan como pendientes no tengo forma de que mp emita un payment.updated para simular el pago de una orden.

ya tienes tu aplicación en producción¡? como debo procesar las notificaciones que me llegan para tener sincronizada la base de datos de mi plataforma con el status de las ordenes de mp?

Muchas gracias te mando un saludo desde mex.

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia • Edited

Hola Luis!

Te respondo por partes.
Primero que nada, es tal cual vos decis. Los pagos en efectivo (oxxo por ejemplo) se crean con un status pending. Es decir que al momento de generar el link, deberías plantear dentro de la preferencia del link, una back_urls.pending para que el usuario sepa que el pago todavía no fue realizado.

Segundo, vas a recibir 3 notificaciones de webhook. Una que se va a ver algo así:

{"action":"payment.created",
"api_version":"v1",
"data":{"id":"7125503101"},
"date_created":"2020-06-17T13:49:17Z",
"id":5990968261,
"live_mode":true,
"type":"payment",
"user_id":"469485398"}

luego te debería llegar esta notificación con topic: payment y resource:

    "id": 7125503101,
    "site_id": "MLA",
    "date_created": "2020-06-17T09:49:17.000-04:00",
    "date_approved": null,
    "money_release_date": null,
    "last_modified": "2020-06-17T09:49:17.000-04:00",
    "payer": {},
    "order_id": "1534217575",
    "external_reference": "referencia_externa",
    "merchant_order_id": "1534217575",
    "reason": "iPhone 8",
    "currency_id": "ARS",
    "transaction_amount": 600,
    "net_received_amount": 0,
    "total_paid_amount": 600,
    "shipping_cost": 0,
    "coupon_amount": 0,
    "coupon_fee": 0,
    "finance_fee": 0,
    "discount_fee": 0,
    "coupon_id": null,
    "status": "pending",
    "status_detail": "pending_waiting_payment",
    "issuer_id": null,
    "installment_amount": 0,
    "deferred_period": null,
    "payment_type": "ticket",
    "payment_method_id": "pagofacil", 
//aca te debería aparecer oxxo si lo seleccionaste
    "marketplace": "NONE",
    "operation_type": "regular_payment",
    "transaction_order_id": null,
    "statement_descriptor": null,
    "cardholder": null,
    "authorization_code": null,
    "marketplace_fee": 0,
    "deduction_schema": null,
    "refunds": [
    ],
    "amount_refunded": 0,
    "last_modified_by_admin": null,
    "api_version": "2",
    "concept_id": null,
    "concept_amount": 0,
    "collector": {}

y por último con topic: merchant_order:

{
  "id": 1534217575,
  "status": "closed",
  "external_reference": "referencia_externa",
  "preference_id": "469485398-1303f910-88c4-4fb1-ab09-6336e4b7e4c7",
  "payments": [
    {
      "id": 7125503101,
      "transaction_amount": 600,
      "total_paid_amount": 600,
      "shipping_cost": 0,
      "currency_id": "ARS",
      "status": "pending",
      "status_detail": "pending_waiting_payment",
      "operation_type": "regular_payment",
      "date_approved": "0001-01-01T00:00:00.000+00:00",
      "date_created": "2020-06-17T09:49:17.000-04:00",
      "last_modified": "2020-06-17T09:49:17.000-04:00",
      "amount_refunded": 0
    }
  ],
  "shipments": [
  ],
  "payouts": [
  ],
  "collector": {
    "id": 469485398,
    "email": "test_user_97555375@testuser.com",
    "nickname": "TETE2587273"
  },
  "marketplace": "NONE",
  "notification_url": "https://localhost:3000/webhook",
  "date_created": "2020-06-17T13:49:16.289+00:00",
  "last_updated": "2020-06-17T13:49:17.923+00:00",
  "sponsor_id": null,
  "shipping_cost": 0,
  "total_amount": 600,
  "site_id": "MLA",
  "paid_amount": 600,
  "refunded_amount": 0,
  "payer": {},
  "items": [
    {}
  ],
  "cancelled": false,
  "additional_info": "",
  "application_id": null,
  "order_status": "payment_in_process"
}

Y a partir de acá si sale todo bien, vas a volver a recibir 3 notificaciónes webhook:
Una con action: payment.updated:

{"action":"payment.updated", 
//nos dice que el pago con el id de data.id se actualizó
"api_version":"v1",
"data":{"id":"7125503101"},
"date_created":"2020-06-17T13:49:17Z",
"id":5990994133,
"live_mode":true,
"type":"payment",
"user_id":"469485398"
}

Una con topic: payment que va a recibir lo mismo que antes pero el status va a decir: approved

{
  "collection": {
    "id": 7125503101,
//este id fijate que es el mismo que el de la notificación anterior
    "site_id": "MLA",
    "date_created": "2020-06-17T09:49:17.000-04:00",
    "date_approved": null,
    "money_release_date": null,
    "last_modified": "2020-06-17T09:58:44.000-04:00",
    "payer": {},
    "order_id": "1534217575",
    "external_reference": "referencia_externa",
    "merchant_order_id": "1534217575",
    "reason": "iPhone 8",
    "currency_id": "ARS",
    "transaction_amount": 600,
    "net_received_amount": 0,
    "total_paid_amount": 600,
    "shipping_cost": 0,
    "coupon_amount": 0,
    "coupon_fee": 0,
    "finance_fee": 0,
    "discount_fee": 0,
    "coupon_id": null,
    "status": "approved",
//acá es donde vemos si el usuario pagó o no
    "status_detail": "by_payer",
    "issuer_id": null,
    "installment_amount": 0,
    "deferred_period": null,
    "payment_type": "ticket",
    "payment_method_id": "pagofacil",
// aca el método que usó para pagar en tu caso sería oxxo
    "marketplace": "NONE",
    "operation_type": "regular_payment",
    "transaction_order_id": null,
    "statement_descriptor": null,
    "cardholder": null,
    "authorization_code": null,
    "marketplace_fee": 0,
    "deduction_schema": null,
    "refunds": [
    ],
    "amount_refunded": 0,
    "last_modified_by_admin": null,
    "api_version": "2",
    "concept_id": null,
    "concept_amount": 0,
    "collector": {}
  }
}

Una con topic: merchant_order que va a recibir exactamento lo mismo que antes, pero payments[0].status se va a haber actualizado a approved y order_status a paid

{
  "id": 1534217575,
  "status": "closed",
  "external_reference": "referencia_externa",
  "preference_id": "469485398-1303f910-88c4-4fb1-ab09-6336e4b7e4c7",
  "payments": [
    {
      "id": 7125503101,
// este id es el del pago, de la notificación anterior
      "transaction_amount": 600,
      "total_paid_amount": 600,
      "shipping_cost": 0,
      "currency_id": "ARS",
      "status": "approved",
//acá confirma que pagó
      "status_detail": "by_payer",
      "operation_type": "regular_payment",
      "date_approved": "0001-01-01T00:00:00.000+00:00",
      "date_created": "2020-06-17T09:49:17.000-04:00",
      "last_modified": "2020-06-17T09:58:44.000-04:00",
      "amount_refunded": 0
    }
  ],
  "shipments": [
  ],
  "payouts": [
  ],
  "collector": {},
  "marketplace": "NONE",
  "notification_url": "https://mercadopago-checkout.herokuapp.com/webhook",
  "date_created": "2020-06-17T13:49:16.289+00:00",
  "last_updated": "2020-06-17T13:58:46.588+00:00",
  "sponsor_id": null,
  "shipping_cost": 0,
  "total_amount": 600,
  "site_id": "MLA",
  "paid_amount": 600,
  "refunded_amount": 0,
  "payer": {},
  "items": [],
  "cancelled": false,
  "additional_info": "",
  "application_id": null,
  "order_status": "paid"
//acá se actualizó porque pagó
}

En síntesis, la manera correcta de hacer el track a lo largo de toda la aplicación es con el merchant_order. El payment.id es una propiedad del objeto merchant_order.

Recordá que dentro de merchant_order, podes tener más de un método de pago, es decir, el usuario puede haber modificado el método de pago desde la aplicación y en ese caso, el objeto merchant_order cambiaría, teniendo dentro del array payments, algo similar a esto:

"payments": [
    {
      "id": 7125503101,
      "transaction_amount": 600,
      "total_paid_amount": 600,
      "shipping_cost": 0,
      "currency_id": "ARS",
      "status": "cancelled",
 //acá canceló el pago en efectivo
      "status_detail": "by_payer",
      "operation_type": "regular_payment",
      "date_approved": "0001-01-01T00:00:00.000+00:00",
      "date_created": "2020-06-17T09:49:17.000-04:00",
      "last_modified": "2020-06-17T09:58:44.000-04:00",
      "amount_refunded": 0
    },
    {
      "id": 7125727198,
      "transaction_amount": 600,
      "total_paid_amount": 600,
      "shipping_cost": 0,
      "currency_id": "ARS",
      "status": "approved",
// y acá pagó con otro método, que para saberlo, 
//tenemos que pegarle a     
// https://api.mercadopago.com/v1/payments/[ID]?access_token=[ACCESS_TOKEN]
// donde id es el id del payment (7125727198 en nuestro ejemplo)
// y ACCESS_TOKEN es el token de acceso de MP
      "status_detail": "accredited",
      "operation_type": "regular_payment",
      "date_approved": "2020-06-17T09:58:46.000-04:00",
      "date_created": "2020-06-17T09:58:45.000-04:00",
      "last_modified": "2020-06-17T09:58:46.000-04:00",
      "amount_refunded": 0
    }
  ],

Recordá que para hacer las pruebas en sandbox tenes que:
1- Utilizar el init_point para el link de pago y no el sandbox_init_point
2- Podes ingresar a la página de MP con tu usuario de test comprador, y ver el detalle de las transacciones directamente desde ahi
3- Podes cambiar el método de pago con tu usuario de test comprador, desde la página de MP

Te dejo por acá la documentación de los webhooks

Espero que te sea útil!

Collapse
 
luispastendev profile image
Luis Pastén • Edited

Gracias por contestar Nicolás, ahora me queda un poco mas claro, en este caso en producción llegan 3 notificaciones post al webhook?, actualmente estoy trabajando con php y estoy usando la sdk que proporcionan la cuestión es que en modo sandbox solo me esta llegando una notificación con la siguiente estructura:

{
    "action": "payment.created",
    "api_version": "v1",
    "data": {
        "id": "26774573"
    },
    "date_created": "2020-06-17T00:36:16Z",
    "id": 5988776238,
    "live_mode": false,
    "type": "payment",
    "user_id": "583365872"
}

En este caso lo que yo hago es utilizar el sdk que me imagino que internamente se conecta con la api de MP para extraer información extra de la orden como: (medio con el cual pago, monto etc.. etc..)

$body = @file_get_contents('php://input');
$data = json_decode($body);
$payment = \MercadoPago\Payment::find_by_id($data->data->id);
// TOMO LOS DATOS NECESARIOS PARA ACTUALIZAR MI ORDEN EN MI BASE DE DATOS... 

Te comparto mi estrategia haber que te parece

1-. cliente entra al checkout y realiza el submit
2-. genero la preferencia con los datos que me proporciono y los montos a cobrar
3-. genero una id única aleatoria para guardarla como folio de orden en mi base de datos la misma que pongo en la preferencia external_reference
4-. el cliente entra a mp y paga por el medio que quiera
5-. una ves concluido su pago puede haber 2 escenarios

5.1 PAGO CON TARJETA

  • capturo la el collection_id que me llega por get con la back_url de success y ejecuto de nuevo \MercadoPago\Payment::find_by_id() para buscar los datos de la orden
  • actualizo mi base de datos con algunos datos que me regresa y el status

5.2 PAGO CON TRANSFERENCIA O TICKET (OXXO 7VEN ETC)

  • genero una thankyou page con status pendiente he instrucciones postcompra
  • una ves pago el cliente me llega al webhook una notificación payment.updated en la cual también utilizo el id para buscar con \MercadoPago\Payment::find_by_id() y usar los datos para actualizar mi base de datos

A grandes rasgos esa es mi estrategia pero aún no subo mi plataforma a producción espero que todo se comporte de la misma manera aunque me deja un poco inquieto el saber que llegan 3 notificaciones cuando se recibe un pago por eso mismo te preguntaba si tu ya lo habías probado en live mode.

Nuevamente gracias por contestar y te envío un saludo!!

 
nicolascastrogarcia profile image
Nicolás Castro Garcia • Edited

Debes estar recibiendo una sola notificación porque nunca se paga el link de sandbox, fijate de pagarlo con una cuenta de test.

Siempre podes filtrar las notificaciones, de las 3 que llegan son:
1- Una que es type: payment.created (se creo el link)
2- Una que es topic: payment (se creo el pago)
3- Una que es topic merchant_order (se creo la transacción)

Luego, una vez que la persona paga:

1- type: payment.updated (pagó)
2- topic: payment (se updatea la información del pago)
3- topic: merchant_order(se updateo la información de la transacción)

Después, en cuanto tu estratégia, la veo muy sólida. El único caso te quedaría para probar, es si la persona decide cambiar el método de pago desde la aplicación de Mercado Pago. Esto lo digo porque si sucede, es probable que se te cambie el payment_id que viene en la notificación del payment updated.

 
luispastendev profile image
Luis Pastén • Edited

Muchas gracias Nico, dejo pendiente a ver como me va en las próximas semanas que subo el proyecto al servidor y te comento que tal me fue.

Gracias por el post, realmente de mucha ayuda para integrar ese medio de pago. Saludos!!

Collapse
 
fernando7390 profile image
Fernando7390

Hola Nicolas, recien me estoy incorporando a este mundo del diseño web. Te molesto por que vi que hiciste la certificación de MP. Yo trate de hacerla pero no pude, vi que estoy muy fuera de lo que piden, hago integraciones simples pero lo que piden no se como hacerlo, como ser:
Preferencia de pago *
Pega aquí el código de la preferencia de pago que creaste vía API, por ejemplo: 82632574-d1742963-3133-46af-aa25-5c3497f3d3b4

o

¿Recibiste la notificación de pago? indícanos el payment_id *
El payment_id es el ID del pago, por ejemplo: 645434222

y

JSON válido de la notificación Webhook *

Trabajo con PHP, quisiera saber si existe la posibilidad que me des un tutorial pago de como hacer lo que me piden. Como verás estoy bien mal, y encima lo que explican en MP no es muy amigable, no explican bien como hacerlo. Si me puedes dar una ayuda te lo agradecería, y como dije más arriba sería paga. Gracias y disculpa las molestias.

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Hola Fer!

No te sientas desanimado, no es una integración sencilla, en lo absoluto. Y la realidad es que la documentación deja mucho que desear.

Paso a explicar qué es puntualmente lo que te piden (que tampoco es muy claro si no hiciste la integración previamente):

1- Código de la preferencia de pago

Una de las primeras cosas que hay que hacer para realizar la integración con MP es la creación de una preferencia de pago. Esto vendría a ser en otras palabras, "pegarle" al endpoint de la api de mercado pago: api.mercadopago.com/checkout/prefe...

Esta preferencia de pago es lo que contiene toda la información de la venta en sí, por ejemplo:
Nombre, apellido, email, y dirección del comprador, items comprados, información del vendedor, metodos de pagos disponibles, entre otros.

Puntualmente en mi tutorial es lo que hacemos en el "PaymentService.js" en la función "createPaymentMercadoPago()"

Una ves que se hace un POST request a esa url con todos los datos necesarios, si todo salió bien, Mercado Pago nos va a devolver un JSON (javascript object notation), que va a contener un campo que es ID.

Ese campo id es lo que tenemos que entregar cuando nos piden el "código de la preferencia de pago"

2- payment_id

Una vez que tenemos la preferencia de pago creada, también vamos a tener el link de pago. Entonces lo que tenemos que hacer es, con una cuenta de prueba compradora (te la dan en el examen), pagar ese link que generamos con la cuenta vendedora de prueba (también te la dan en el examen).

Una vez que se pague la transacción (venta), mercadopago nos va a mandar una notificación webhook (en realidad nos va a mandar varias). En una de esas notificaciones, te va a llegar algo similar a esto:

{
"action":"payment.created",
"api_version":"v1",
"data":{"id":"7125503101"},
"date_created":"2020-06-17T13:49:17Z",
"id":5990968261,
"live_mode":true,
"type":"payment",
"user_id":"469485398"
}

Esto que estoy mostrando es un JSON, puntualmente el JSON válido de la notificación WEBHOOK que te piden. Pero lo importante es el id 7125503101, que es el ID de la notificación de pago que te piden.

Ahora bien, desconozco tus conocimientos previos, y experiencia. Pero independientemente de eso, algo que quiero que sepas y que es de suma importancia es que: NO ES UNA INTEGRACIÓN FÁCIL. No te tenes que sentir mal por no lograrlo, cuesta MUCHO hacer que funcione como uno quiere, si siquiera funciona.

En este momento no estoy dando clases. Pero te ofrezco que cualquier duda que tengas, o ayuda que necesites con mercado pago u otro tema relacionado a la programación me la digas por twitter en @ncastrogarcia que voy a estar más que dispuesto a ayudarte.

Abrazo!

Collapse
 
tonqac profile image
Gastón Giménez

Hola Nico, estuve leyendo atentamente tu post y sos un crack! Sabes que estoy intentando completar la certificación y lo único que me falta es mandar el JSON que devuelve la notificación webhook, pero no estoy pudiendo capturar esos datos. Sólo recibo algo parecido a esto:

{"data_id":"10463481227","source_news":"webhooks","type":"payment"}

¿Me podrás orientar? Graciass!!

 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Lo cierto es que no recuerdo muy bien qué era lo que pedian. Si mal no recuerdo con lo que me pasaste en este comentario deberia ser suficiente. Aunque siempre podes pegarle al endpoint de payments con el id que tenes en data_id para ver si está todo ok.

Saludos!

Collapse
 
fadelgado profile image
Facu Delgado • Edited

Hola Nicolas, se que dijiste q no programas en Angular, igualmente te hago una consulta porque no encuentro como resolverlo y capaz q vos tengas más idea. Resulta q usando el sdk De MP cuando quiero integrar el botón q genera el script de MP, no me aparece nada. Un usuario comento que es porque Angular bloquea los script de los templates o algo parecido a eso. Ahora, usando algo similar a lo q posteaste, un poco más sencillo poruqe hago la integración con checkout pro, logro generar el link de MP para redireccionar pero me aparece un problema de CORS. Hice de todo lo relacionado con CORS, instale la librería, puse los headers manualmente, le agregué req.method para las options, etc. Pero sigo con la misma falla, q es la que dejo en imagen. Dejo una leve descripción de la falla: Access to XMLHttpRequest at "link de MP generado correctamente con los datos para cobrar" redirected from http:localhost:3000/checkout from Origin mi página BLOCKED BY CORS POLICY. Redirect is not allowed for a preflight request.
Si sabes como resolver eso me sería de gran ayuda. Muchas gracias.

Collapse
 
uri99 profile image
urimihura

Nicoo gran tutorial, pero me quedaron 2 dudas:
1) dice que habría que hacerle un request POST al localhost:3000/payment/new , mi consulta es como haces para levantar todo el 'servicio' al localhost:3000?

2) y como se vería el post request? sería algo tipo así?:
axios.post("localhost:3000/payment/new" , {
name: "nombre",
price: 100,
unit: 1,
img: "imagen",
})
y despues el response sería la url del item publicado? cosa que podría hacer nose .then((response) => {console.log(response)}) para chusmearla nomás por ahora

y una tercera duda de yapa:
si quiero que el access token de la persona que va a recibir la plata sea una variable, mas que que esté hardcodeada, podría meterle una funcion que sea tipo setAccessToken(newAccessToken) que pueda ser llamada desde el front? (porque tengo entendido que en el tutorial está hardcodeado el access token en PaymentService.js)
Esto es porque en el programa que estoy haciendo, el dueño de la pagina no es el que recibe la plata, sino el usuario actual. Cosa que habria que pedirle al usuario acutal su access token (ahí setearía el access token), y que luego el link generado sea tal que para que él reciba la plata, no el dueño de la página.

desde ya muchisimas gracias!

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Hola!

1- Eso es porque estoy corriendo un servidor de nodejs en mi computadora local.
2- Lo del post es correcto, la response sería la url de pago del item.
3- Te tenes que meter con marketplace de mercadopago, es parecido a esto con un poquito más de dificultad porque tenes que configurar más cosas. El marketplace permite que haya muchos vendedores y muchos compradores, y vos como dueño del marketplace te puedas llevar una comision (fee) por cada transacción.

Saludos!

Collapse
 
uri99 profile image
urimihura

Genial, y otra consulta a ver si me podrías dar una mano:
Levanté el servidor pero cuando le hago una request me dice que falta el CORS header "Access-Control-Allow-Origin". Leí bastante del tema y entendí lo que significa, y entendí la solucion tambien, hay que agregarle unas cosas al header de la respuesta que le devuelve en la solicitud preliminar que le hace el navegador a la api. Mi pregunta es, sabes donde está esta solicitud preliminar? la busqué por todos lados pero no la pude encontrar.
Gracias!

 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Vas a tener que isntalar un paquete de npm que se llama cors:
y extendiendo desde tu servidor:
app.use(
require("cors")({
origin: function (origin, callback) {
callback(null, origin);
},
credentials: true
})
);

 
uri99 profile image
urimihura

Nico ahí lo instalé y metí eso en alguna parte del servidor, pero me sigue tirando el error de antes. Que significa "extendiendo desde tu servidor"? Donde tendría que poner eso que me estas pasando??
y como siempre muchas gracias por tu ayuda

 
uri99 profile image
urimihura

lo metí en app.js y funcionó, pero ahora me tira: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at mercadopago.com.ar/checkout/v1/red.... (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

osea parece ser que está habiendo una falla de comunicación entre la api y mercadopago, ya no mas entre mi pagina y la api.

y ese link que devuelve (que está adentro del error) parece ser la respuesta que quiero, pero siempre que lo trato de abrir me dice "error: no puedes pagarte a vos mismo". Traté desde incognito, otro navegador, el celular y la computadora de 3 amigos, y siempre tira lo mismo. Lo raro es que a uno de esos 3 amigos si le abre bien el coso para pagar, con el nombre y precio apropiado

Sabes que podría ser? Desde ya sabelo que cuando termine te voy a estar comprando unos cafecitos por tu trabajo jajaja

Collapse
 
andresgiacosa profile image
Andres

Hola Nicolás, excelente tu publicación!!

Mientras leía me surgió una duda, todos los pagos que se darían en tu página de ejemplo son a la misma cuenta de MP? Es decir, todo lo que se pague se acreditaría en la cuenta de MP registrada con ese access_token?

Te pregunto esto porque me interesa saber si hay una forma de redirigir el pago directamente a una cuenta vendedor específica para que en mi aplicación yo no sea intermediario de la transacción. Por ejemplo, si tengo una pagina donde personas ofrecen servicios (vendedores) y clientes contratan (compradores) un servicio elegido, que el checkout se haga a la cuenta de MP de ese vendedor seleccionado. En este caso tendría que tener el access_token de cada vendedor?

Desde ya muchas gracias y nuevamente excelente todo!

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Hola, tenes que implementar un marketplace mercadopago.com.ar/developers/es/g...

Podes cobrar hasta un fee por cada transacción. Saludos!

Collapse
 
sara1297 profile image
sara1297

Hola Nicolás, estoy integrando mercado pago con next, sin embargo no me aparece el botón para realizar el pago, aunque si lo incluyo en el head aparece al final de mi página, pero no donde yo lo quisiera colocar, me podrías colaborar por favor? Quedo atenta muchísimas gracias

Collapse
 
dannter profile image
Daniel Es

Excelente material Nicolás! muchas gracias!. Tengo una pregunta, espero me puedas ayudar ya que no encuentro referencia en ninguna parte. Sabes cómo activar el estilo para mobiles que aparece en la documentación mercadopago.com.mx/developers/en/g...

Quiero integrar el web checkout dentro de un chatbot en messenger pero no encuentro como hacer para que se adapte el estilo a mobile, como se muestra en la documentación del link, en la sección de Header.
Saludos!

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Hola Daniel,

si estas usando webtokenize, si es así, no deberías tener problemas en personalizar ciertas cosas

Si no estás usando eso, pasame más información de lo que estas tratando de hacer que vemos como solucionarlo.

Saludos!

Collapse
 
dannter profile image
Daniel Es

Hola Nicolás, si efectivamente es ese el que estoy usando y lo implemento dentro de un webview de messenger developers.facebook.com/docs/messe.... Estoy pensando que tal vez se implementa internamente dentro de un iFrame y por eso no detecta que es mobile, o aún así debería verse la versión mobile? tu que opinas, saludos!

Collapse
 
jorgeguevarab profile image
Jorge Guevara

Amigo, esto es oro puro. Gracias por compartir tu conocimiento

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Gracias a vos por tomarte el tiempo de leerlo!

Collapse
 
susegroj profile image
El Rojo ● • Edited

¿Hay alguien que haya implementado el checkout pro de node js en alguna app de react?
Intento hacerlo con gatsby (parecido a nextjs) pero no se cómo controlar la acción del botón que genera el script que se agrega

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Hola! Si te referis a implementarlo en el front (con este tipo de checkout), la unica manera es con Nexjs, que nos va a permitir tener el back y front juntos. Si no, tenes que hacer un backend y desde tu front en React, hacer el request

Collapse
 
fras28 profile image
Franco Selvarolo

Hola Nico!
estoy intentando integrar el CheckOut pro de mercado pago unicamente desde el Front con una aplicacion React.js, es posible realizar eso ? de ser asi sabes como ?
(busque en un monton de foros y probe 200 cosas y no le encuentro la vuelta)
desde ya gracias !!

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia • Edited

Hola! necesitas un servidor para poder guardar claves de acceso de mercadopago. No hay una forma segura de hacerlo sólo desde el frontend. Sé que mercadopago ofrece algunas cosas para poder integrar botones de pago rápido y demás, pero no las usé

Collapse
 
fras28 profile image
Franco Selvarolo

Jooyaa!! Gracias Nico

Collapse
 
barreiraugusto profile image
barreiraugusto

Hola Nicolás.... Gracias por compartir esta info, para los que estamos arrancando esto vale oro.... Necesito consultarte algo. Que puede estar pasando que, en mi Marketplace con credenciales de producción, para pagos con tarjeta de débito y con crédito de mercado pago no tengo problemas para hacer compras, pero cuando lo quiero hacer en efectivo me dice... "Algo salió mal... No pudimos procesar tu pago" y en las notificaciones solo tengo esto {"resource":"api.mercadolibre.com/merchant_orde...}
Tengo todas las back_urls configuradas y funcionando.

Gracias...

Collapse
 
matiascorteze profile image
matiascorteze

Hola Nicolás, cómo te va? Soy un muy novato aprendiz en todo esto. Arranqué un proyecto de tienda online con carrito usando HTML/CSS/vanilla Javascript, quise integrar un simple checkout de Mercadopago que me lea el total del carrito y derive a Mercadopago con ese valor, pero no pude.

Investigando, me dijeron que eso se hace usando Node.JS así que estuve viendo un par de tutos para integrar, lo cual parecía que iba a funcionar, pero no jajaja.

Ahora me encuentro con este post increíble de tu parte que enseña todo paso a paso, pero se ve que en algo estoy fallando porque sigo sin poder integrar.

Quizá te puedo escribir por privado para pagarte una tutoría y que me enseñes integración básica para una web de ventas simple? O si hay alguna versión más APB y sencilla que pueda seguir para que al tocar el botón de COMPRAR me derive a una pantalla de MercadoPago con el valor del carrito?

Cualquier info se agradece muchísimo,
un abrazo!

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Hola Matías!, si queres mandame un mensaje privado por acá, o contactame por twitter en @ncastrogarcia y vemos como te puedo ayudar.

Igualmente, si queres algo sencillo, podes crear links de pagos únicos desde la misma app de mercado pago.

Saludos!

mercadopago.com.ar/tools/create

Collapse
 
storchia profile image
storchia • Edited

Hola Nicolas!
Brillante laburo y muchisimas gracias por compartirlo, en breve te invito unos cafecitos como corresponde

Realice al pie de la letra tu implementacion y funciona barbaro.

Ahora en una situacion de Carro de Compras en donde hay que pasar varios "items". Como lo resolverias? entiendo que me esta faltando una parte del codigo porque logro pasar en el body:

{
name: [ 'Otro mas', 'First Book' ],
unit: [ '2', '1' ],
img: [ 'images\1602475489688-Page1.png', 'images\1602463339226-3.jpg' ],
price: [ '1456', '125' ],
}

pero luego no puedo enviarlo a MP, envia solo el primer articulo o sea el [0] del obejto.

Alguna idea?

Muchisimas gracias nuevamente!

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Hola!

Los items los tenes que mandar en la preferencia. La clave items dentro del objeto de preferencia tiene que ser un array [item1, item2, item3], donde cáda item tiene que ser un objeto que contenga los requisitos que explican en la documentación de mercadopago acá.

En síntesis, usando tu ejemplo, debería quedarte algo así:

   const items = [   
         {
            "id": "",
            "picture_url": "",
            "title": "Libro 1",
            "description": "Libro 1",
            "category_id": "",
            "currency_id": "ARS",
            "quantity": 1,
            "unit_price": 10
        },       {
            "id": "",
            "picture_url": "",
            "title": "Libro 2",
            "description": "libro 2",
            "category_id": "",
            "currency_id": "ARS",
            "quantity": 1,
            "unit_price": 10
        }
    ];  

Enter fullscreen mode Exit fullscreen mode

Entonces después cuando creas la preferencia, le pasas ese array de objetos a la clave items de la preferencia:

const preferences = { 
      items: items, // ACÁ TIENE QUE IR EL ARRAY DE ITEMS QUE CREAMOS ARRIBA
      external_reference: "referencia del negocio", 
      payer: { 
        name: "Lalo",
        surname: "Landa",
        email: "test_user_63274575@testuser.com", 
        phone: {
          area_code: "11",
          number: "22223333"
        },
        address: {
          zip_code: "1111",
          street_name: "False",
          street_number: "123"
        }
      }, 
      payment_methods: {
        excluded_payment_methods: [
          {
            id: "amex"
          }
        ],
        excluded_payment_types: [{ id: "atm" }],
        installments: 6,
        default_installments: 6 
      }, 
      back_urls: {
        success: "https://localhost:3000/success", 
        pending: "https://localhost:3000.com/pending",
        failure: "https://localhost:3000.com/error"
      }, 
      notification_url: "https://localhost:3000/webhook", 
      auto_return: "approved" 
    };
Enter fullscreen mode Exit fullscreen mode

Si no anduvo podes preguntarme devuelta, o hablarme a mi twitter

Espero que se arregle!

Saludos!

Collapse
 
drahdavid profile image
drahdavid • Edited

Hola como estás Nicolás , antes que nada mil gracias por tu tiempo y por la novedad en el tema que publicás, no hay casi material al respecto. Quería hacerte algunas consultas básicas, ya que no hace mucho que estoy en esto, y hasta lo más básico me resulta un poco confuso. Quería saber como levanto el servidor para realizar las peticiones desde postman. Vos utilizás el live server de Visual Studio, o algo como Xammp ?

Y en caso de levantar el server hacia que URL realizo el Post : Actualmente estoy intentando con localhost:3000/payment/new

Intengo iniciar el servidor :

[nodemon] 2.0.4
[nodemon] to restart at any time, enter rs
[nodemon] watching path(s): .
[nodemon] watching extensions: js,mjs,json
[nodemon] starting node ./bin/www

Agradecería si me orientas . Mil gracias de nuevo.

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Hola! para ejecutar el servidor lo hago con npm, veo que usas nodemon, por lo que estas encaminado. Y por defecto node ejecuta el proceso en el puerto 3000. No sé si respondi tu duda. Saludos!

Collapse
 
sebapinery profile image
sebapinery

Hola Nico, antes que nada, MUCHAS GRACIAS por compartir este laburo, la documentacion de MP deja bastante que desear y la integracion es bastante engorrosa. Con esta info siento luz al final del tunel jajaja.

Te consulto:
Cuando estoy haciendo al peticion POST a "/payment/new" estoy enviandole en el body los campos "name, unit,img, y price" y me esta devolviendo por consola un error, me dice:

data: {
message: 'items.0.unit_price must be a number',
error: 'invalid_items',
status: 400,
cause: null
}

Estoy enviando unit y price como numeros en el body.

Si cambio los valores en el PaymentService.js a valores fijos si me genera el link.

Donde puede estar el error?

Muchas gracias por tu tiempo y ayuda!

Collapse
 
lucasadlerstein profile image
Lucas

Hola Nico,
Excelente lo detallado de lo que escribiste!
Te hago una consulta, esto te abre el checkout pro de mercadopago?
Me refiero a si te abre todo con su interfaz para que la gente elija con que pagar y pueda pagar con dinero en cuenta.
Gracias!

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Mil disculpas por tardar tanto en contestar! pero sí, te redirecciona a mercado pago y el comprador puede elegir entre las opciones que vos le indicaste en las preferencias de pago.

Collapse
 
kiquetal profile image
Enrque\m/Talavera

Se podría saber cuál fue el exámen de certificación?Saludos!

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Buenas! Es el Developer Partner Program Mercado Pago.

Me contactaron por mail, para una "jornada de certificación". La jornada consistió básicamente de una charla en la que explicaban el aspecto comercial y técnico de Mercado Pago. Y después la resolución de un "examen" que es lo que ves en este post.

El mail que me llego fue este alt

Fijate de revisar por acá partners.mercadopago.com/ si te interesa

Espero que te sirva!

Saludos

Collapse
 
orestes7054 profile image
orestes7054

Excelente tutorial. Es verdad que la documentación es super escasa, y con lo poco que hay es imposible customizar cada venta. Estoy armando un carrito de compras sencillo, la verdad que intenté obviar node js., pero solo por cuestión de servidores (todavía no elegí el hosting). Te hago dos preguntas:
1) Existe alguna forma de poder probar el código en un localhost (sé que decía que no una de las notas, pero no encuentro otra forma de probar el pago).
2) Cuando suba los archivos al servidor, la ejecución de nodejs en que parte se haría. Gracias de nuevo! Zarpado tu laburo!

Collapse
 
developer_noob profile image
Ivan C • Edited

Buenas amigo, muy buen post me esta ayudando mucho, junto con los comentarios a los que has respondido, pero tengo una duda, en desarrollo ya cree mi orden o mi ticket para pagar en oxxo, mi duda es hay forma de cambiar o actualizar esa compra de pendiente a pagada de forma manual para poder checar como actuan mi webhook de payment.update ?

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Hola ivan, tenes que usar los usuarios de prueba, tanto el vendedor como el comprador tienen que ser de prueba. Podes leer un poco más sobre eso acá mercadopago.com.ar/developers/es/g...

Collapse
 
jhonzsoto profile image
jhonzsoto

hola Nicolas te puedo hacer un pregunta medio o totalmente boluda, lo que hiciste lo puedo hacer con React.js ? recien comienzo y estoy tratando de integrar mercado pago a una ecommerce que estoy haciendo pero me resulta muy complicado ver la manera de intergrar MP. saludos !

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Hola! no porque react no te permite hacer parte de back, tendrias que usar Nextjs como adicional a React para poder hacerlo. Saludos

Collapse
 
minichampi profile image
Mak5 • Edited

Hola buenas tardes, he intentado hacer el examen de integración checkout pro, pero al hacer el pago me marco un error. De que algún dato es de prueba e implemente todo lo que solicita el examen con todos los datos que proporciona alguien sabe por qué marca el error.
examen

Image description

Integrator ID:
★ dev_24c65fb163bf11ea96500......
Test User (Vendedor) | Producción
★ Access Token:
APP_USR-292655009721353......
★ Public Key:
APP_USR-a68157fb-55......
Test User (Comprador o pagador)
★ Email:
test_user_94....

Collapse
 
juan_solanaortiz_58e5125 profile image
Juan Solana Ortiz

Hola Nicolas antes que nada felicitarte por tu excelente post, estoy haciendo el examen de Checkout Pro y el resultado es:

  • No encontramos el script security.js en la URL que nos compartiste.

Estoy utilizando NextJS y el modulo next/script para cargar el script externo, si reviso las peticiones y el código de mi app si está el security.js.
¿Tienes alguna idea de qué puede estar pasando?
¡Muchas gracias!

Collapse
 
tomasmarmay1 profile image
Tomi

Nico una pregunta, tenes idea como integrarlo con python mas especifico con Flask ?

Collapse
 
nicolascastrogarcia profile image
Nicolás Castro Garcia

Hola Tomi, no manejo python!

Collapse
 
florencia_skiba_c4d762269 profile image
Florencia Skiba

Hola Nicolas, queria saber si habías tratado de realizar la integración con Ruby? Si lo hiciste que desafíos encontraste? Muy bueno el articulo!!!!

Collapse
 
mateor profile image
mateor.eth • Edited

Nico como estas? Gracias por el tutorial, super claro.

Sabes si es posible integrar MP con aplicación desarrollada con Supabase + Next.js?