Stripe
Stripe usa Checkout Sessions: el usuario paga en la página hospedada de Stripe y la fuente de verdad es el webhook, nunca el redirect de vuelta.
Configuración
import { StripeGateway } from '@kaizen/payments-gateway'
StripeGateway.register({
secret_key: process.env.STRIPE_SECRET_KEY!, // sk_test_… / sk_live_…
webhook_secret: process.env.STRIPE_WEBHOOK_SECRET!, // whsec_…
})| Campo | Tipo | Descripción |
|---|---|---|
secret_key | string | Clave secreta de la API de Stripe |
webhook_secret | string | Secreto del endpoint de webhook, para verificar la firma |
Variables de entorno
Los valores los aportas tú desde tu propio entorno y se los pasas a StripeGateway.register():
STRIPE_SECRET_KEY=sk_test_xxxxxxxxxxxxxxxxxxxxxxxx
STRIPE_WEBHOOK_SECRET=whsec_xxxxxxxxxxxxxxxxxxxxxxxx| Variable | Campo | Descripción |
|---|---|---|
STRIPE_SECRET_KEY | secret_key | Clave secreta de la API (sk_test_… / sk_live_…) |
STRIPE_WEBHOOK_SECRET | webhook_secret | Secreto del endpoint de webhook (whsec_…) para verificar la firma |
Crear un cobro
curl -X POST http://localhost:3000/payments/charge \
-H 'content-type: application/json' \
-d '{
"gateway": "stripe",
"amount": 4900,
"currency": "eur",
"reference": "pedido-001",
"redirect": {
"success_url": "http://localhost:3000/ok",
"cancel_url": "http://localhost:3000/ko"
}
}'amountva en la unidad mínima de la moneda (4900 = 49,00 €).redirect.success_url/cancel_urlviajan por pago (en el body), no en la config.- La respuesta trae un
redirect_url(el Checkout de Stripe): manda ahí al usuario.
La respuesta tiene el mismo formato que el resto de pasarelas:
{
"payment_id": "b9c1…",
"gateway": "stripe",
"status": "pending",
"redirect_url": "https://checkout.stripe.com/c/pay/…"
}Flujo end-to-end en local (Stripe CLI)
Levanta tu consumidor (
pnpm start).Abre el túnel del Stripe CLI y copia el
whsec_…que imprime aSTRIPE_WEBHOOK_SECRET; reinicia para que lo tome:bashstripe listen --events checkout.session.completed \ --forward-to localhost:3000/webhooks/stripeTIP
--eventsfiltra a lo único que manejamos. Sin él, el CLI reenvía todos los eventos y el gateway responde400a los que no soporta.Crea un pago (el
curlde arriba) y abre elredirect_url.Paga con la tarjeta de prueba
4242 4242 4242 4242, fecha futura y CVC cualquiera.Stripe dispara
checkout.session.completed→ el CLI lo reenvía → el gateway verifica la firma sobre elrawBody, el core casa elPaymentporgateway_ref(=session.id), lo pasa acapturedy emitepayment.captured.Reenviar el mismo evento no re-procesa: la idempotencia por
(gateway, event_id)responde200.
Notas de la integración
client_reference_idlleva tureferencedentro de Stripe;gateway_refes elsession.id, que es lo que casa el webhook con elPayment.createPaymentmanda unaIdempotency-Key(tureference), así los reintentos no crean sesiones de Checkout duplicadas.- La firma se verifica siempre con
stripe.webhooks.constructEventsobre el body crudo. Firma inválida →400.