Payment SDK React Integration - MercadoPago

1k views Asked by At

I´m trying to integrate the payment SDK of MercadoPago.

The documentation indicates to add this two scripts on the html, but I can´t make it work on React. How can I pass this scripts to a React component?

// SDK MercadoPago.js V2
<script src="https://sdk.mercadopago.com/js/v2"></script>

<script>
  // Agrega credenciales de SDK
  const mp = new MercadoPago("PUBLIC_KEY", {
    locale: "es-AR",
  });

  // Inicializa el checkout
  mp.checkout({
    preference: {
      id: "YOUR_PREFERENCE_ID",
    },
    render: {
      container: ".cho-container", // Indica el nombre de la clase donde se mostrará el botón de pago
      label: "Pagar", // Cambia el texto del botón de pago (opcional)
    },
  });
</script>

I´ve tried this, but does not work, (idk why it makes a POST to localhost:3001 (client):

export default function Suscripcion(props) {
  //const { id } = useParams(); // id de producto
  const id = 1122;
  const [preferenceId, setPreferenceId] = useState(null);

  const PUBLIC_KEY_VENDEDOR_PRUEBA =
    "TEST-001debb2-d8d5-40a4-953f-8ca65aaa0fa0";7

  function addCheckOut() {
    const mp = new window.MercadoPago(PUBLIC_KEY_VENDEDOR_PRUEBA, {
      locale: "es-AR",
    });

    // Inicializa el checkout
    mp.checkout({
      preference: {
        id: preferenceId,
      },
      render: {
        container: `#${FORM_ID}`, // Indica el nombre de la clase donde se mostrará el botón de pago
        label: "Pagar", // Cambia el texto del botón de pago (opcional)
      },
    });
  }

  useEffect(async () => {
    // luego de montarse el componente, le pedimos al backend el preferenceId
    try {
      const post = await fetch("http://localhost:3000/api/orders", {
        method: "POST",
        made: "cors",
        headers: {
          "Content-Type": "application/json",
          "Access-Control-Allow-Origin": "*",
        },
        body: JSON.stringify({
          productId: id,
          name: "agustin",
          lastname: "miotti",
          email: "[email protected]",
        }),
      });

      const data = await post.json();

      console.log(data.id);
      setPreferenceId(await data.id);
    } catch (error) {
      console.log(error);
    }
  }, []);

  
  useEffect(() => {
    if (preferenceId) {
      // con el preferenceId en mano, inyectamos el script de mercadoPago

      const script = document.createElement("script");
      script.type = "text/javascript";
      script.src = "https://sdk.mercadopago.com/js/v2";
      script.addEventListener("load", addCheckOut);

      //script.setAttribute("preference", preferenceId);
      //   const form = document.getElementById(FORM_ID);
      //   form.appendChild(script);
      document.body.appendChild(script);
    }
  }, [preferenceId]);

  return <form id={FORM_ID} method="GET" />;
}

Can anyone help me with this? Maybe it looks prety simple, but i still don´t get it.

1

There are 1 answers

8
logancodemaker On

Try this

hooks/useScript.js

import { useEffect, useState } from "react"

export default function useScript(url) {
  const [loaded, setLoaded] = useState(false)
  useEffect(() => {
    const existingScript = document.querySelector(`[src="${url}"]`)

    if (existingScript) {
      setLoaded(true)
    } else {
      const script = document.createElement("script")
      script.src = url
      script.async = true
      script.onload = () => {
        setLoaded(true)
      }

      document.body.appendChild(script)
    }
  }, [url])

  return {
    loaded
  }
}

Suscripcion.jsx

import { useEffect, useRef, useState } from "react"
import useScript from './hooks/useScript'

const PUBLIC_KEY_VENDEDOR_PRUEBA = "TEST-001debb2-d8d5-40a4-953f-8ca65aaa0fa0";

export default function Suscripcion(props) {
  //const { id } = useParams(); // id de producto
  const id = 1122;

  const [preferenceId, setPreferenceId] = useState(null)
  const formRef = useRef(null)
  const initialized = useRef(false)

  const { loaded } = useScript("https://sdk.mercadopago.com/js/v2")

  useEffect(() => {
    if (initialized.current) {
      return
    }

    if (!loaded) {
      return
    }

    if (preferenceId === null) {
      return
    }

    initialized.current = true

    const mp = new window.MercadoPago(PUBLIC_KEY_VENDEDOR_PRUEBA, {
      locale: "es-AR",
    });

    mp.checkout({
      preference: {
        id: preferenceId,
      },
      render: {
        container: formRef.current.id, // Indica el nombre de la clase donde se mostrará el botón de pago
        label: "Pagar", // Cambia el texto del botón de pago (opcional)
      },
    });

  }, [loaded, preferenceId])


  useEffect(() => {
    // luego de montarse el componente, le pedimos al backend el preferenceId
    const fetchId = async () => {
      try {
        const post = await fetch("http://localhost:3000/api/orders", {
          method: "POST",
          made: "cors",
          headers: {
            "Content-Type": "application/json",
            "Access-Control-Allow-Origin": "*",
          },
          body: JSON.stringify({
            productId: id,
            name: "agustin",
            lastname: "miotti",
            email: "[email protected]",
          }),
        });

        const data = await post.json();

        console.log(data.id);
        setPreferenceId(await data.id);
      } catch (error) {
        console.log(error);
      }
    }

    fetchId()

  }, []);

  return <form ref={formRef} id="checkout-page" method="GET" />;
}