← Blog

Cómo integrar pagos con MercadoPago en Node.js: suscripciones y pagos únicos

D
Damián Oliva
·25 de septiembre de 2024

Por qué MercadoPago en Argentina

Para proyectos en Argentina y Latinoamérica, MercadoPago es la pasarela de pagos con mayor penetración. Su Checkout Pro acepta tarjetas de crédito, débito, transferencias y efectivo sin que el usuario necesite cuenta de MP. Para suscripciones, el sistema de Preapproval (débito automático) es confiable y bien documentado.

Setup inicial

npm install mercadopago
# .env
MP_ACCESS_TOKEN=TEST-xxxx  # o PROD-xxxx en producción
MP_WEBHOOK_SECRET=tu_secret
import { MercadoPagoConfig, Preference, Payment } from 'mercadopago';

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

Checkout Pro: crear preferencia de pago

const preference = new Preference(client);

const createPaymentLink = async (order) => {
  const response = await preference.create({
    body: {
      items: [{
        title: order.description,
        quantity: 1,
        currency_id: 'ARS',
        unit_price: order.amount,
      }],
      back_urls: {
        success: `${process.env.FRONTEND_URL}/pago/exitoso`,
        failure: `${process.env.FRONTEND_URL}/pago/fallido`,
        pending: `${process.env.FRONTEND_URL}/pago/pendiente`,
      },
      notification_url: `${process.env.API_URL}/webhooks/mercadopago`,
      external_reference: order._id.toString(),
      auto_return: 'approved',
    },
  });

  return response.init_point; // URL del checkout
};

Suscripciones con Preapproval

import { PreApprovalPlan, PreApproval } from 'mercadopago';

// Crear plan de suscripción
const plan = await new PreApprovalPlan(client).create({
  body: {
    reason: 'Plan mensual Mi App',
    auto_recurring: {
      frequency: 1,
      frequency_type: 'months',
      transaction_amount: 5000, // ARS
      currency_id: 'ARS',
    },
    back_url: `${process.env.FRONTEND_URL}/suscripcion/confirmada`,
    status: 'active',
  },
});

// Crear suscripción para un usuario
const subscription = await new PreApproval(client).create({
  body: {
    preapproval_plan_id: plan.id,
    payer_email: user.email,
    back_url: `${process.env.FRONTEND_URL}/suscripcion/confirmada`,
  },
});

// Redirigir al usuario a subscription.init_point

Webhook para confirmar pagos

app.post('/webhooks/mercadopago', async (req, res) => {
  const { type, data } = req.body;

  if (type === 'payment') {
    const payment = new Payment(client);
    const paymentData = await payment.get({ id: data.id });

    if (paymentData.status === 'approved') {
      const orderId = paymentData.external_reference;
      await Order.findByIdAndUpdate(orderId, { status: 'paid', mpPaymentId: data.id });
    }
  }

  if (type === 'subscription_preapproval') {
    await updateSubscriptionStatus(data.id);
  }

  res.status(200).send('OK');
});
Newsletter

Ideas directamente
a tu bandeja de entrada

Comparto lo que estoy construyendo, lo que aprendo y lo que me parece interesante del mundo tech y startups. Sin spam. Cuando tenga algo que valga la pena.

Sin spam. Unsubscribe en cualquier momento.