es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

La URL de cancelación de Stripe no cancela el pago, por lo tanto, Stripe no envía un payintent cancelado.

Estoy usando Stripe con Node.js para realizar pagos y estoy creando una sesión y utilizando la interfaz de pago de Stripe Checkout. Estoy utilizando un webhook para escuchar los eventos, cuando se crea o se realiza con éxito el pago, Stripe envía el evento “payment_intent.succeeded” para que pueda hacer algo con él. Pero el problema es cuando hago clic en la URL de cancelación para cancelar el pago, Stripe no cancela el pago ni envía el evento “payment_intent.canceled”, lo cual es un problema porque entonces no sé si se canceló el pago y no puedo hacer lo que había planeado. Aquí está mi código:

// Esto compartirá la clave pública de Stripe con el frontend
const webhook = async (req, res) => {
// Verificación de firma
const payload = req.body;
const sig = req.headers[“stripe-signature”];
const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;

let event;

try {
// Verificar si la respuesta es realmente de Stripe
event = stripe.webhooks.constructEvent(payload, sig, endpointSecret);
} catch (error) {
console.log(error.message);
res.status(400).json({ success: false });
return;
}

// Obtener el ID del anuncio
const adID = event.data.object.metadata.id;
const userEmail = event.data.object.metadata.email;

// Verificar si el pago falló
if (
event.type === “payment_intent.canceled” ||
event.type === “charge.failed” ||
event.type === “charge.expired”
) {
const paymentIntent = event.data.object;
console.log(PaymentIntent ${paymentIntent.status});

// Enviar la solicitud de eliminación
await axios.delete(`${process.env.SERVER_URL}/api/v1/single-ad`, {
  data: { id: adID, email: userEmail },
});

return res.status(200).json({ message: "El anuncio se eliminó correctamente" });

}

// El bloque if nunca se ejecuta porque Stripe no envía nada si el pago se cancela.
}
“`

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Solución para manejar pagos cancelados con Stripe y Node.js

    Si estás utilizando Stripe con Node.js para manejar pagos y te encuentras con un problema en el que Stripe no envía ninguna notificación cuando el pago es cancelado, puedes solucionarlo configurando un temporizador y comprobando si el pago fue exitoso o no.

    Aquí tienes un ejemplo de solución:

    1. Al crear una sesión, guarda el ID de la sesión en una base de datos junto con una marca de tiempo de cuándo fue creada.
    2. Configura un temporizador para comprobar si el pago fue exitoso dentro de un período de tiempo específico, por ejemplo, 5 minutos.
    3. Si el pago es exitoso, Stripe enviará un evento payment_intent.succeeded, y puedes manejarlo normalmente.
    4. Si el pago falla, Stripe enviará un evento payment_intent.payment_failed, y puedes manejarlo en consecuencia.
    5. Si el temporizador expira y no has recibido ningún evento, asume que el pago fue cancelado y manejarlo en consecuencia.

    Aquí tienes una versión actualizada de tu código con la implementación del temporizador:

    const webhook = async (req, res) => {
      const payload = req.body;
      const sig = req.headers["stripe-signature"];
      const endpointSecret = process.env.STRIPE_WEBHOOK_SECRET;
    
      let event;
    
      try {
        event = stripe.webhooks.constructEvent(payload, sig, endpointSecret);
      } catch (error) {
        console.log(error.message);
        res.status(400).json({ success: false });
        return;
      }
    
      const adID = event.data.object.metadata.id;
      const userEmail = event.data.object.metadata.email;
    
      if (event.type === "payment_intent.succeeded") {
        const paymentIntent = event.data.object;
        console.log(`PaymentIntent ${paymentIntent.status}`);
    
        // Manejar pago exitoso
        await axios.post(`${process.env.SERVER_URL}/api/v1/single-ad`, {
          id: adID,
          email: userEmail
        });
    
        return res.status(200).json({ message: "Pago exitoso." });
      } else if (event.type === "payment_intent.payment_failed") {
        const paymentIntent = event.data.object;
        console.log(`PaymentIntent ${paymentIntent.status}`);
    
        // Manejar pago fallido
        await axios.delete(`${process.env.SERVER_URL}/api/v1/single-ad`, {
          data: { id: adID, email: userEmail }
        });
    
        return res.status(200).json({ message: "Pago fallido." });
      } else {
        // Configurar un temporizador para comprobar si el pago ha sido cancelado
        const expirationTime = Date.now() + 300000; // 5 minutos a partir de ahora
    
        const timer = setInterval(async () => {
          const session = await stripe.checkout.sessions.retrieve(adID);
    
          if (session.payment_intent) {
            const paymentIntent = await stripe.paymentIntents.retrieve(session.payment_intent);
    
            if (paymentIntent.status === "succeeded") {
              clearInterval(timer);
              await axios.post(`${process.env.SERVER_URL}/api/v1/single-ad`, {
                id: adID,
                email: userEmail
              });
    
              return res.status(200).json({ message: "Pago exitoso." });
            } else if (paymentIntent.status === "requires_payment_method" || paymentIntent.status === "requires_confirmation") {
              clearInterval(timer);
              await axios.delete(`${process.env.SERVER_URL}/api/v1/single-ad`, {
                data: { id: adID, email: userEmail }
              });
    
              return res.status(200).json({ message: "Pago cancelado." });
            }
          }
    
          if (Date.now() > expirationTime) {
            clearInterval(timer);
            await axios.delete(`${process.env.SERVER_URL}/api/v1/single-ad`, {
              data: { id: adID, email: userEmail }
            });
    
            return res.status(200).json({ message: "Pago cancelado." });
          }
        }, 1000);
      }
    }
    

    En este código actualizado, hemos agregado un temporizador que verifica el estado del pago cada segundo hasta que tenga éxito, falle o se agote el tiempo. Si el pago es exitoso, lo manejamos normalmente como antes. Si el pago falla o agota el tiempo, asumimos que fue cancelado y lo manejamos en consecuencia.

    Nota: Esta solución es solo un ejemplo, y puedes ajustar la duración del temporizador y el manejo de pagos cancelados según tus necesidades.

Comments are closed.