El escenario es conocido. Tienes un Payment Link de Stripe. Lo pegas en posts, en tu bio, en tu newsletter. Llega dinero. Y cuando abres el dashboard de Stripe, todos los pagos se ven idénticos: un nombre, un correo, un monto, una marca de tiempo. Nada te dice cuál de las cuarenta cosas que publicaste ese mes produjo realmente la venta.
La mayoría asume que cerrar ese hueco requiere un backend en forma: una base de datos de sesiones, un checkout a medida, manejadores de webhook, un ingeniero. No lo requiere. Stripe trae un campo que hace todo el trabajo, y si puedes crear un Payment Link puedes usarlo.
El único campo que hace el trabajo: client_reference_id
Todo Payment Link de Stripe acepta un parámetro de query llamado client_reference_id. Agrégalo al enlace y el valor que pongas ahí viaja con el cliente a través del checkout y sale del otro lado adjunto a la sesión completada. Un enlace terminado en ?client_reference_id=post_8842 produce un pago sellado con post_8842.
Puedes ver el valor sin escribir una línea de código. Aparece en la Checkout Session dentro del dashboard de Stripe, está disponible en la API, y viene incluido en el payload del webhook checkout.session.completed. Stripe lo restringe a caracteres alfanuméricos, guiones y guiones bajos, y le pone un límite de longitud, así que mantén el valor corto y con forma de máquina. No pongas ahí un correo ni un nombre.
Esa restricción es todo el diseño. El campo está pensado para contener una referencia a un registro de tu propio sistema, no los datos en sí. Tú generas un id, recuerdas qué significa, y Stripe te lo devuelve cuando aterriza el dinero.
La cadena que va del post al pago
La atribución no es un truco ingenioso. Son cuatro pasos aburridos hechos con constancia, y que falle cualquiera de ellos rompe la cadena.
- Dale a cada post su propio enlace. No un enlace usado en todas partes: uno por post, idealmente uno por post por plataforma.
- Registra el clic. Cuando alguien siga el enlace, anota a qué post pertenecía y deja una cookie propia para poder reconocerlo cuando vuelva más adelante.
- Lleva el id hasta el checkout. Agrégalo a la URL del Payment Link como client_reference_id antes de que el cliente pase a Stripe.
- Empareja el pago. Cuando se dispare checkout.session.completed, lee el id de vuelta y une la venta con el post que la inició.
El paso dos es donde la versión sin backend se pone interesante. Si tu visitante pasa directo del post al Payment Link, puedes hacer todo con una redirección: el enlace rastreado sabe a qué post pertenece, así que puede agregar client_reference_id a la URL de Stripe y mandar al visitante para allá. Sin almacenamiento, sin sesión, sin servidor. El id viaja en la URL de principio a fin.
Cuando el visitante no compra de inmediato
La mayoría no compra en la primera visita. Hacen clic en tu post, miran tu sitio, cierran la pestaña, y vuelven cuatro días después desde un marcador o desde una búsqueda en Google. Si el id solo vive en la URL, esa segunda visita llega sin nada adjunto y la venta se vuelve inatribuible.
La solución es una cookie propia puesta en la primera visita. Cuando el enlace rastreado manda al visitante a tu sitio, deja una cookie con el id de seguimiento. Cuando después pase a tu Payment Link, lee la cookie y agrega su valor como client_reference_id. Las cookies propias puestas por tu propio dominio no se bloquean como sí ocurre con las cookies de rastreo de terceros, así que esto sobrevive a las opciones de privacidad habituales de los navegadores.
Aun así necesitas una regla para cuando no hay cookie ni id. La respuesta correcta es no atribuir nada. Una venta que no puedes rastrear es una venta que no deberías acreditarle a nada, porque acreditada al post equivocado es peor que no acreditada. Un hueco honesto te dice que tu medición tiene agujeros; una coincidencia inventada te dice que redobles la apuesta en un post que no hizo nada.
Payment Links frente a una Checkout Session a medida
Si ya construyes Checkout Sessions en código, tienes más opciones: puedes fijar client_reference_id del lado del servidor, adjuntar metadata arbitraria a la sesión, y pasar valores a la suscripción o a la factura resultante. La metadata es más flexible que client_reference_id porque guarda pares clave-valor y no está limitada a un solo token.
Los Payment Links son el camino sin código, y para efectos de atribución son casi igual de buenos. Pierdes la posibilidad de adjuntar metadata estructurada al momento de crear, pero conservas el único campo que importa. Si tu producto entero es un Payment Link en una bio y una página de Notion para el onboarding, ese campo es la diferencia entre saber y adivinar.
Una nota práctica para suscripciones: client_reference_id vive en la Checkout Session, no en la suscripción que la sesión crea. Si quieres que la atribución persista en las facturas de renovación futuras, copia el valor a la suscripción o al cliente como metadata cuando se complete la primera sesión. Si no, atribuirás el primer pago y perderás todas las renovaciones posteriores.
Poner en el campo un valor que signifique algo
No metas texto suelto ahí. Usa un id corto y opaco que apunte a un registro que tú controlas, y guarda ese mapeo en algún lugar que puedas consultar. Un valor como a1b2c3d4 que se resuelve a “LinkedIn, 14 de agosto, el post sobre errores de precios” es mucho más útil que intentar meter esos tres datos en un campo alfanumérico de longitud limitada.
Si de verdad no tienes ningún sistema donde guardar el mapeo, funciona una forma corta codificada: inicial de la plataforma, fecha, y un código de dos caracteres para el post, por ejemplo li0814pm. Es feo, no escala más allá de unos pocos cientos de posts, y lo vas a lamentar en algún momento. Pero le gana a no tener atribución, y se puede migrar después.
Dónde deja de escalar la versión manual
La mecánica de arriba es genuinamente simple. Lo que no es simple es hacerlo para cada post, en cada plataforma, todos los días, para siempre. Publicar la misma idea en X, LinkedIn, Threads, Bluesky y una newsletter significa cinco enlaces rastreados distintos, cinco ids, cinco filas en el mapeo, y cinco oportunidades de pegar el equivocado. A las dos semanas, la mayoría vuelve en silencio a un solo enlace para todo.
Esa es la parte que automatiza seenpaid. Publica tu post en las redes que hayas conectado, acuña automáticamente un enlace rastreado distinto por post y plataforma, lleva el id de seguimiento hasta tu checkout de Stripe, y lee tu cuenta de Stripe para emparejar de vuelta los pagos resultantes. Nunca tocas un client_reference_id a mano. La lógica de atribución es la misma que se describe arriba, corriendo de forma constante en vez de cuando te acuerdas.
Cómo se ve cuando funciona
El resultado de todo esto es una frase que antes no podías decir: este post en concreto, en esta plataforma en concreto, produjo esta cantidad de dólares. No clics. No impresiones. Dólares, emparejados con pagos que de verdad se cobraron.
Esa frase cambia el comportamiento más rápido que cualquier gráfico de interacción. El post del que estabas orgulloso no produjo nada. La respuesta improvisada que casi no publicas trajo tres clientes. La plataforma en la que más tiempo inviertes resulta ser la que menos paga. Nada de eso es visible hasta que el clic y el cobro comparten un identificador, y Stripe te dio el campo para hacerlo. Úsalo.