<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Lucas</title>
    <description>The latest articles on DEV Community by Lucas (@lmanmai).</description>
    <link>https://dev.to/lmanmai</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F538072%2Fea2978ae-18b0-4fb3-a234-0408a2e7c51b.jpeg</url>
      <title>DEV Community: Lucas</title>
      <link>https://dev.to/lmanmai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lmanmai"/>
    <language>en</language>
    <item>
      <title>Integrar Mercado Pago en nuestra API</title>
      <dc:creator>Lucas</dc:creator>
      <pubDate>Thu, 18 Apr 2024 00:43:20 +0000</pubDate>
      <link>https://dev.to/lmanmai/integrar-mercado-pago-a-nuestra-api-12f8</link>
      <guid>https://dev.to/lmanmai/integrar-mercado-pago-a-nuestra-api-12f8</guid>
      <description>&lt;p&gt;En mi caso estas serian las rutas que tengo destinadas para el checkout&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyruvovthgq4pia9v1y7f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyruvovthgq4pia9v1y7f.png" alt="Image description" width="767" height="91"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;/checkout/:userId: Esta ruta permite obtener todas las órdenes de compra asociadas a un usuario específico.&lt;/li&gt;
&lt;li&gt;/checkout/dashboard/getAllOrders: Esta ruta permite obtener todas las órdenes de compra, en mi caso tengo un dashboard aparte para revisar las ordenes.&lt;/li&gt;
&lt;li&gt;/checkout/create_preference: Esta ruta se utiliza para crear una preferencia de pago en Mercado Pago.&lt;/li&gt;
&lt;li&gt;/checkout/getpayment_info: Esta ruta recibe la información de pago de Mercado Pago una vez completada la transacción.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ahora dentro de los controladores lo primero que tenemos que hacer es importar del paquete de mercado pago MercadoPagoConfig y Preference e inicializar el accesToken ,este nos lo brinda Mercado Pago cuando nos registramos como desarrolladores desde &lt;a href="https://www.mercadopago.com.ar/developers/es/docs/checkout-pro/landing"&gt;CheckOut Pro&lt;/a&gt;,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Product from "../models";
import PurchaseModel from "../models/purchaseItemModel";
import { Request, Response } from "express";
import { MercadoPagoConfig, Preference } from "mercadopago";
require("dotenv").config();

const client = new MercadoPagoConfig({
  accessToken: process.env.ACCESS_TOKEN_MP as string,
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Crear una Preferencia de Pago&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;La preferencia de pago nos va a permitir realizar el pago, Mercado Pago nos brinda ciertas opciones para ajustar dependiendo lo que necesitemos, en mi caso estoy mapeando el objeto que recibe (el carrito de compras).&lt;br&gt;
Dentro del body, items vendria a ser nuestros productos, las back_urls son las urls a las que mercado pago nos va a redirigir despues de alguna acción cuando finalizemos la compra, notification_url es la url donde se va a enviar la notificacion cuando se complete la compra.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports.createPreference = async (req: Request, res: Response) =&amp;gt; {
  try {
    const productsData = req.body.map((item: any) =&amp;gt; {
      return {
        id: item.productID,
        title: item.title,
        quantity: Number(item.quantity),
        unit_price: Number(item.price),
        currency_id: "ARS",
        description: item.userID,
        picture_url: item.productItemPosterPath,
      };
    });
    const body = {
      items: productsData,
      back_urls: {
        success: `${process.env.BACK_URL}postcheckout/-`,
        failure: `${process.env.BACK_URL}checkout`,
        pending: `${process.env.BACK_URL}checkout`,
      },
      auto_return: "approved",
      notification_url: `${process.env.NOTIFICACION_URL}getpayment_info`,
    };
    const preference = new Preference(client);
    const result = await preference.create({ body });
    res.json({
      id: result.id,
    });
  } catch (error: any) {
    console.log(error);
    res
      .status(500)
      .json({ msg: `Error al crear la preferencia: (${error.message})` });
  }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Obtener Información de Pago&lt;/strong&gt;&lt;br&gt;
El controlador getPaymentInfo se encarga de recibir la información de pago de Mercado Pago y procesarla, este controlador recibe la información de pago de Mercado Pago, verifica el estado de la orden y actualiza el stock de productos en la base de datos en caso de que la orden se haya pagado correctamente.&lt;br&gt;
Es importante que responda un 200 para que mercado pago deje de enviar solicitudes a nuestro servidor.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports.getPaymentInfo = async (req: Request, res: Response) =&amp;gt; {
  try {
    const notificationData = req.body;
    if (notificationData.topic === "merchant_order") {
      const response = await fetch(notificationData.resource, {
        method: "GET",
        headers: {
          Authorization: `Bearer ${process.env.ACCESS_TOKEN_MP}`,
        },
      });

      if (response.ok) {
        const res = await response.json();
        console.log(res, "respuesta JSONN");
        if (res.status === "closed" &amp;amp;&amp;amp; res.order_status === "paid") {
          const newPurchaseOrder = new PurchaseModel({
            userId: res.items[0].description,
            items: res.items,
            orderId: res.id,
          });
          const basketItems = res.items;
          for (const item of basketItems) {
            const product = await Product.findById(item.id);
            if (product) {
              product.sizes.forEach((size: any) =&amp;gt; {
                size.qty -= item.quantity;
              });
              await product.save();
            }
          }
          await newPurchaseOrder.save();
        }
      }
    }

    res.sendStatus(200);
  } catch (error) {
    console.error("Error al procesar la notificación de Mercado Pago:", error);
    res.status(500).json({ error: "Internal server error" });
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Obtener Órdenes de Usuario&lt;/strong&gt;&lt;br&gt;
El controlador getUserOrders se encarga de obtener todas las órdenes de compra asociadas a un usuario específico, en mi caso lo uso para mostrarle al usuario sus compras exitosas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;exports.getUserOrders = async (req: Request, res: Response) =&amp;gt; {
  try {
    const { userId } = req.params;
    const orders = await PurchaseModel.find({ userId: userId });

    res.json({
      msg: `Ordenes realizadas por el usuario ${userId}`,
      status: 200,
      orders,
    });
  } catch (error: any) {
    console.log(error);
    res.status(500).json({
      msg: `Error al traer las ordenes del usurio: (${error.message})`,
    });
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>mercadopago</category>
      <category>node</category>
      <category>api</category>
    </item>
  </channel>
</rss>
