# Integración con Stripe

URL: https://traqio.app/es/docs/integrations/stripe
Last updated: 2026-11-13

Conecta tu Stripe: pagos, renovaciones y reembolsos de tu SaaS llegan a la campaña de cada usuario, con una sola llamada de servidor en el registro.

**Stripe** cobra a los clientes de tu SaaS e informa de cada pago con un webhook. Conectada a Traqio, tu cuenta de Stripe vincula cada factura pagada, cada renovación y cada reembolso al usuario que se registró: así una campaña recibe el dinero que pagaron sus registros, del primer al duodécimo mes, con **una sola llamada de servidor en el registro y ninguna por pago**. Es el equivalente web de la [integración con RevenueCat](https://traqio.app/es/docs/integrations/revenuecat), con las mismas reglas para reembolsos, pagos de prueba y duplicados.

> **Tu Stripe, no la facturación de Traqio** Esto conecta tu cuenta de Stripe, en solo lectura, para medir tus ingresos. No tiene nada que ver con cómo te factura Traqio.

## Configuración

### Informa del registro una vez

Donde tu backend crea la cuenta, infórmala con el id de usuario y el trackID con el que llegó el visitante; consulta [el SDK de Node](https://traqio.app/es/docs/sdks/node) (PHP y Python funcionan igual). El email es opcional: el SDK calcula su hash en tu servidor y solo envía el hash, la clave de respaldo descrita más abajo.

```ts
await traqio.signup({
  userId: user.id,
  trackId: trackIdFromRequest(req),
  email: user.email, // opcional: hash local, nunca se envía
});
```

### Pon el id de usuario en los metadata de Stripe

Define `metadata.traqio_user_id` con el **mismo** id al crear la suscripción: Stripe copia los metadata de una suscripción en cada factura que genera, renovaciones incluidas. En el cliente también funciona.

```ts
await stripe.subscriptions.create({
  customer: customerId,
  items: [{ price: priceId }],
  metadata: { traqio_user_id: user.id },
});

// Stripe Checkout:
await stripe.checkout.sessions.create({
  mode: "subscription",
  subscription_data: { metadata: { traqio_user_id: user.id } },
  // …
});
```

### Crea una clave restringida

Panel de Stripe → Desarrolladores → Claves de API → **Crear clave restringida**. Configura **Clientes: Lectura**, **Facturas: Lectura** y **Endpoints de webhook: Escritura**; deja todo lo demás en Ninguno. Una clave de producción (`rk_live_…`) mide los pagos reales; una clave de prueba (`rk_test_…`) permite probar la conexión solo con pagos de prueba.

### Pégala en Traqio

En la consola: tu producto → Integraciones → Ingresos → **Stripe**. Traqio lee un cliente y una factura para comprobar la clave, y luego crea su endpoint de webhook en tu cuenta de Stripe (URL `https://api.traqio.app/webhooks/stripe/<id del producto>`) y guarda su secreto de firma. Una clave que Stripe rechaza no se guarda, y el mensaje nombra el permiso que falta.

> **¿Sin permiso de Endpoints de webhook?** Añade el endpoint tú mismo en Stripe → Desarrolladores → Webhooks, con la URL que muestra la consola y los eventos indicados más abajo, marca « Añadí el endpoint de webhook yo mismo » y pega su secreto de firma (whsec_…) junto con la clave.

### Haz un pago en modo de prueba

Con una clave de prueba, un pago en modo de prueba aparece en los **Eventos recientes de Stripe** de la consola como *Modo de prueba: conexión verificada*, con el importe que leyó Traqio. Nunca se cuenta. Los pagos de producción son los que cuentan; cada línea dice a qué usuario se acreditó, o por qué no está vinculado.

## Cómo encuentra un pago a su usuario

Traqio prueba en este orden, y se detiene en la primera respuesta:

| Dónde | Qué lee Traqio |
| --- | --- |
| La suscripción de la factura | metadata.traqio_user_id: la copia que Stripe pone en cada factura |
| La factura | metadata.traqio_user_id |
| El cliente de Stripe | metadata.traqio_user_id, leído con la clave restringida |
| El email del cliente | SHA-256 del email sin espacios y en minúsculas, comparado con el emailHash enviado en el registro, solo si un único usuario lo tiene |

Un pago que ninguno vincula a un usuario queda **no vinculado**: registrado, contado en los ingresos del producto, sin acreditar a ninguna campaña. Un id que Traqio aún no conoce (el pago llegó antes que la llamada de registro) se conserva, y el pago se une al usuario cuando llega el registro.

## Qué hace cada evento de Stripe

| Evento de Stripe | En Traqio |
| --- | --- |
| invoice.paid | una compra: amount_paid, en la moneda de la factura; una factura de 0 € (prueba gratuita, saldo a favor) no mueve dinero |
| charge.refunded | un reembolso: ingreso negativo, una entrada aparte frente a la factura reembolsada; cada reembolso parcial una vez |
| customer.subscription.created / updated / deleted | visible con el cambio de estado (trialing → active…): no se mueve dinero |
| Todo lo que esté en modo de prueba | visible como modo de prueba, nunca contado |

- **Moneda**: cada pago se guarda en la moneda en que se pagó y se convierte a la moneda de informes del producto al tipo de ese día en los informes.
- **Duplicados**: un evento de Stripe se procesa una vez, y un pago se indexa por su id de factura: una reentrega, o la misma factura informada también por tu servidor con `transactionId`, es una sola fila. Consulta [Contar una compra una sola vez](https://traqio.app/es/docs/concepts/events-and-revenue#transaction-id).
- **Reembolsos**: solo se restan de pagos que Traqio registró; una factura pagada antes de conectar Stripe nunca se sumó, así que su reembolso no resta nada.
- **Importes brutos**: lo que pagó el cliente, impuestos incluidos; la parte de impuestos se guarda, no se aplica. Las comisiones de Stripe no se restan.

## Límites

- Traqio cuenta **facturas**. Un pago único de Checkout cuenta cuando su sesión crea una factura (`invoice_creation.enabled`); un PaymentIntent sin factura no cuenta.
- Una cuenta de Stripe por producto de Traqio. Una cuenta de Stripe que vende varios productos envía todos sus pagos a cada producto conectado, donde los clientes de los demás aparecen como no vinculados.
- Los pagos del sitio se atribuyen y se muestran en Traqio, pero aún no se envían a Meta ni a TikTok.

## Preguntas frecuentes

**¿Por qué una clave restringida y no un inicio de sesión con Stripe Connect?**
Una clave restringida funciona en cualquier cuenta de Stripe desde que se crea, y es más acotada: lee clientes y facturas, y puede crear un endpoint de webhook. No puede cobrar, reembolsar ni cambiar nada. Traqio rechaza una clave secreta completa (sk_…) y guarda la clave restringida cifrada.

**¿Traqio escribe algo en mi cuenta de Stripe?**
Una sola cosa: el endpoint de webhook que crea para sí mismo, descrito como el de Traqio. Desconectar Stripe en la consola lo elimina. No se escribe nada más y nunca se toca ningún objeto de dinero.

**¿Y si un pago no nombra a ningún usuario?**
Sigue siendo ingreso: se registra y cuenta en el total del producto, como no vinculado; no llega a ninguna campaña. Traqio nunca asigna un pago al azar, y la lista de eventos de Stripe dice por qué cada pago no está vinculado.

**¿Sigo llamando a track() en cada pago?**
No. Con Stripe conectado, signup() es la única llamada de servidor. Si mantienes un track() para un pago de Stripe, pasa el id de la factura (in_…) como transactionId con store: "stripe": ambos informes acaban en una sola fila.
