Ir al artículo
Aniq-UI

Food StudioPagos

Pagos

Cómo cobra el pago, cómo conectar Stripe o PayPal y qué le pasa a un pedido en cada paso.

Para el paquete Full Stack

Cómo cobra el pago

El cliente paga en la propia página del proveedor, Stripe Checkout o PayPal, así que ni el sitio web ni la API ven nunca un número de tarjeta. La API calcula ella misma el precio del pedido, a partir de su propio menú, sus tarifas y sus descuentos, nunca a partir de los precios que envía el navegador.

MétodoSe ofrece cuandoQué pasa
Pago con tarjeta (Stripe)STRIPE_SECRET_KEY está configuradaEl pedido se guarda sin pagar y el navegador va a la página de Stripe. El pedido pasa a pagado cuando la API ha preguntado a Stripe qué pasó y el importe coincide.
PayPalPAYPAL_CLIENT_ID y PAYPAL_CLIENT_SECRET están configuradosLo mismo, en la página de PayPal: la API captura el pago aprobado antes de que el pedido cuente como pagado.
Pago de demostraciónNo hay ningún proveedor configuradoMarca el pedido como pagado sin mover dinero, para poder probar todo el proceso en local. Nunca se ofrece junto a un proveedor configurado.

Los invitados pueden pagar con su nombre y su correo; los clientes con sesión iniciada ven el pedido en su cuenta. Un pedido pagado pasa a la cola de la cocina; el personal no puede confirmar uno sin pagar.

Los precios están en dólares estadounidenses. En los ajustes de demostración, la entrega cuesta $2.99 y la recogida es gratuita, con un mínimo de entrega de $10.00. No hay una línea de impuestos aparte: el cliente paga los precios del menú más la tarifa, menos cualquier descuento. El personal cambia las tarifas en el panel, en Settings, Restaurant, que también muestra los métodos de pago que ofrece esta versión y si cada uno funciona en modo de prueba o real.

Conecta Stripe

  1. Añade tu clave secreta

    Desde la página de claves de API del panel de Stripe, pon la clave secreta en el .env de la API. Usa una clave de prueba (sk_test_…) hasta que estés listo para cobrar dinero real: no mueve nada.

    El .env de la API
    STRIPE_SECRET_KEY=sk_test_…
  2. Suscribe el webhook

    En Stripe, añade un endpoint de webhook en la dirección de tu API seguida de /api/payments/webhooks/stripe, suscrito a checkout.session.completed, checkout.session.expired, charge.refunded y charge.dispute.created. Copia su secreto de firma en el .env de la API.

    El .env de la API
    STRIPE_WEBHOOK_SECRET=whsec_…
  3. Comprueba las direcciones de retorno

    Stripe devuelve el navegador a API_PUBLIC_URL, y la API lo reenvía al sitio web en STOREFRONT_URL. En local, los dos valores por defecto funcionan. En tus propios dominios, configura ambos con las direcciones reales.

  4. Reinicia la API

    Resultado esperado: El pago ofrece "Pay by card", y Settings, Restaurant, Payments lo muestra como ofrecido, en modo de prueba.

La clave publicable no es necesaria: el pago se hace en la propia página de Stripe. Para probar el webhook en tu propio equipo, la CLI de Stripe puede reenviar eventos a http://localhost:8000/api/payments/webhooks/stripe y muestra el secreto de firma que debes usar mientras está en marcha.

Conecta PayPal

  1. Añade las credenciales de tu aplicación

    Desde el panel de desarrollador de PayPal, copia el client id y el secreto de tu aplicación en el .env de la API. PAYPAL_ENV es sandbox por defecto, que no mueve dinero; live acepta pagos reales.

    El .env de la API
    PAYPAL_CLIENT_ID=your-paypal-sandbox-client-id
    PAYPAL_CLIENT_SECRET=your-paypal-sandbox-client-secret
    PAYPAL_ENV=sandbox
  2. Suscribe el webhook

    Añade un webhook en la dirección de tu API seguida de /api/payments/webhooks/paypal, con los eventos de captura de pago: completado, denegado, reembolsado y revertido. Copia el id del webhook en el .env de la API: la API verifica cada llamada con él.

    El .env de la API
    PAYPAL_WEBHOOK_ID=your-paypal-webhook-id
  3. Reinicia la API

    Resultado esperado: El pago ofrece PayPal.

Qué le pasa a un pedido

EventoEl pedido
El cliente lo haceSe guarda como pendiente y sin pagar. Reserva su stock y los puntos de recompensa que el cliente canjeó.
El proveedor confirma el pagoPagado, por la vuelta del cliente o por el webhook, lo que llegue primero. La vuelta del navegador por sí sola nunca marca un pedido como pagado: la API pregunta antes al proveedor.
El cliente abandona la página de pagoSe comprueba con el proveedor a los 35 minutos con Stripe y a las 3 horas con PayPal, y luego se cancela como pago fallido, devolviendo su stock y sus puntos.
El proveedor informa de un reembolso completoReembolsado, y se retiran los puntos que ganó. Un reembolso parcial de Stripe se registra y deja el pedido como está.

Un pago que llega para un pedido ya cancelado se registra como pendiente de reembolso y nunca recupera el pedido. El personal no puede marcar un pedido como reembolsado a mano: los reembolsos se hacen en Stripe o PayPal, y el webhook actualiza el pedido.

El pago de demostración

  • Sin ningún proveedor configurado, el pago muestra "Demo payment" y "Place demo order". El pedido queda pagado al momento, sin mover dinero, para poder probar de principio a fin la cola de la cocina y la página de seguimiento.
  • En cuanto se configura Stripe o PayPal, el pago de demostración desaparece, y se rechaza un pedido que lo pida.
  • El webhook propio del pago de demostración, POST /api/payments/webhooks/demo, rechaza todas las llamadas salvo que PAYMENT_WEBHOOK_SECRET esté configurado y se envíe como cabecera x-webhook-secret.

Cobrar pagos reales

  • Cambia a las claves reales (sk_live_…, o la aplicación real de PayPal con PAYPAL_ENV=live) y a un webhook creado en modo real, que tiene su propio secreto de firma o id.
  • Configura API_PUBLIC_URL y STOREFRONT_URL con tus direcciones reales, y añade el sitio web a CORS_ORIGIN: una dirección de retorno fuera de esa lista se rechaza.
  • Settings, Restaurant, Payments muestra cada método como "Live, real money" en cuanto funciona con credenciales reales.
  • Los importes están siempre en dólares estadounidenses: la API cobra en CURRENCY de back-end/src/common/constants/ordering.constants.ts, y los dos frontends muestran los precios en dólares. Otra moneda supone un cambio de código en la API y en los frontends, con NEXT_PUBLIC_ANALYTICS_CURRENCY configurado a juego.

¿Te atascaste en un paso?

Busca una solución antes de empezar de nuevo.

Solución de problemas

Preferencias de Cookies

Utilizamos cookies para mejorar tu experiencia de navegación, analizar el tráfico del sitio y personalizar el contenido. Al hacer clic en "Aceptar Todo", consientes nuestro uso de cookies para análisis y publicidad personalizada.