Referencia de seguimiento para desarrolladores: window.RTR_HOOKS
Última actualización:
Esta página está pensada para desarrolladores y agencias que conectan los widgets de reserva de Rentware con sus propias etiquetas. Describe la parte del navegador. El seguimiento en el servidor a través de Rentware (GA4, Google Ads y Meta desde nuestro servidor) no necesita código: consulta Seguimiento de conversiones: qué configurar y dónde.
Resumen
- El widget no envía nada a las etiquetas del navegador a menos que la página defina
window.RTR_HOOKS. El nombre antiguowindow.RENTWARE_HOOKStambién funciona; si existen los dos, prevaleceRTR_HOOKS. RTR_HOOKSse lee cada vez que se dispara un evento. Puede definirse tarde, por ejemplo desde una etiqueta de GTM, siempre que exista antes del evento.- El widget nunca carga una etiqueta por sí mismo.
gtag,fbq,umamiyoaiqtienen que estar ya en la página; si falta una función, ese canal se omite sin avisar. Solo eldataLayerse crea si no existe. - El widget no comprueba el consentimiento para tus etiquetas. Cárgalas solo después del consentimiento (es tarea de tu banner de cookies).
- Todos los importes son netos: descuentos aplicados, fianzas excluidas, IVA en
tax. Los importes son números en unidades principales (49.5), salvo donde se indique.
Fragmento
<script>
window.RTR_HOOKS = Object.assign(window.RTR_HOOKS || {}, {
// eventos de comercio electrónico al estilo GA4 en window.dataLayer (Google Tag Manager; funciona sin GTM)
enableDataLayer: true,
// gtag('event', …) directamente
// enableGtagTracking: true,
// gtag('event', 'conversion', …) adicional en la compra
// gtagAdsSendTo: 'AW-123456789/AbCdEfGhIj',
// gtag('set', 'user_data', …) para conversiones mejoradas
// enableGtagUserDataTracking: true,
// fbq('track', …) en tu píxel de Meta
// enableMetaTracking: true,
// además fbq('init', id, {…}) con datos del cliente (coincidencia avanzada)
// metaPixelId: '123456789012345',
// umami.track(…)
// enableUmamiTracking: true,
// oaiq('measure', 'order_created', …)
// enableOpenAiTracking: true,
// onAddToCart: (data) => {},
// onInitiateCheckout: (data) => {},
// onCheckoutSuccess: (data) => {},
})
</script>
Object.assign conserva las claves que otro script ya haya definido.
Todas las opciones
| Clave | Tipo | Efecto |
|---|---|---|
enableDataLayer |
boolean | Envía add_to_cart, begin_checkout, add_shipping_info y purchase a window.dataLayer |
enableGtagTracking |
boolean | Llama a gtag('event', …) con los mismos cuatro eventos |
gtagAdsSendTo |
string | En la compra, llama además a gtag('event', 'conversion', {…, send_to}), p. ej. 'AW-123456789/AbCdEfGhIj' |
enableGtagUserDataTracking |
boolean | Cuando se guardan los datos del cliente, llama a gtag('set', 'user_data', {…}) |
enableMetaTracking |
boolean | Llama a fbq('track', …): AddToCart, InitiateCheckout, Purchase |
metaPixelId |
string | Con enableMetaTracking: cuando se guardan los datos del cliente, llama a fbq('init', metaPixelId, {…}) con los datos del cliente |
enableUmamiTracking |
boolean | Llama a umami.track(…): add_to_cart, begin_checkout, purchase |
enableOpenAiTracking |
boolean | En la compra, llama a oaiq('measure', 'order_created', …) |
onAddToCart |
function | Se llama después de añadir un artículo |
onInitiateCheckout |
function | Se llama cuando se abre el checkout |
onCheckoutSuccess |
function | Se llama cuando se completa la reserva |
Eventos por paso
| Paso | dataLayer / gtag | Píxel de Meta | Umami | OpenAI | Se dispara cuando |
|---|---|---|---|---|---|
| Añadir al carrito | add_to_cart |
AddToCart |
add_to_cart |
– | se ha añadido un artículo correctamente |
| Checkout abierto | begin_checkout |
InitiateCheckout |
begin_checkout |
– | se abre el checkout |
| Datos del cliente guardados | add_shipping_info |
– | – | – | se guarda el formulario de contacto y facturación |
| Reserva completada | purchase |
Purchase |
purchase |
order_created |
consulta «Cuándo se dispara purchase» |
No hay ningún evento del navegador para elegir ubicación y fechas, para ver un artículo ni para iniciar el pago (add_payment_info solo existe en el servidor). No hay CustomEvent del DOM.
Cuándo se dispara purchase
purchase se dispara cuando la reserva se completa, que no siempre coincide con el momento del pago:
- Reserva, pago por adelantado o transferencia bancaria, vale: justo después de enviarla (aún sin pagar).
- Pago con tarjeta dentro del checkout: cuando el pago se realiza correctamente.
- Pagos con redirección (PayPal, métodos de pago que salen de la página): solo cuando el visitante vuelve a una página con el widget. Si no vuelve nunca, no hay
purchaseen el navegador. La compra en el servidor se envía de todos modos.
dataLayer
Antes de cada evento, el widget envía { ecommerce: null } para borrar el objeto de comercio electrónico anterior, como recomienda Google.
// add_to_cart: cada artículo cuya cantidad ha aumentado, incluidos los añadidos automáticamente
{ event: 'add_to_cart', ecommerce: {
currency: 'EUR',
value: 59.5, // Σ precio × cantidad
items: [{ item_id: 'a1b2c3', item_name: 'SUP Board', price: 29.75, quantity: 2, index: 0 }]
} }
// begin_checkout y add_shipping_info: valor neto del carrito
{ event: 'begin_checkout', ecommerce: { currency: 'EUR', value: 59.5 } }
{ event: 'add_shipping_info', ecommerce: { currency: 'EUR', value: 59.5 } }
// purchase
{ event: 'purchase', ecommerce: {
transaction_id: 'SNLDX1', // referencia del pedido
currency: 'EUR',
value: 59.5, // neto, descuentos aplicados, fianzas excluidas
tax: 11.31, // IVA
items: [{ item_id: 'a1b2c3', item_name: 'SUP Board', price: 29.75, quantity: 2 }]
} }
pricees el precio unitario neto con descuento. Las líneas de fianza nunca están enitems.transaction_ides la referencia del pedido (p. ej.SNLDX1). El servidor envía el mismo valor comotransaction_idde GA4,order_idde Google Ads yorder_idde Meta.- El dataLayer no contiene correo electrónico, teléfono ni ID de evento.
gtag
Con enableGtagTracking, el widget llama a gtag('event', name, params) con los mismos objetos ecommerce que el dataLayer (los items de purchase también llevan index).
Con gtagAdsSendTo, la compra desencadena además:
gtag('event', 'conversion', {
transaction_id: 'SNLDX1', currency: 'EUR', value: 59.5, tax: 11.31,
items: [/* como arriba */],
send_to: 'AW-123456789/AbCdEfGhIj'
})
Con enableGtagUserDataTracking, cuando se guardan los datos del cliente:
gtag('set', 'user_data', {
email: 'jane@example.com',
phone_number: '+4915112345678', // solo si es un E.164 válido; si no, se omite
address: { first_name: 'Jane', last_name: 'Doe', city: 'Berlin', postal_code: '10115', country: 'DE' }
})
Se usa la dirección de envío si el cliente la ha introducido; si no, la de facturación.
Píxel de Meta
fbq('track', 'AddToCart', { content_ids: ['a1b2c3'], content_type: 'product', currency: 'EUR', value: '29.75' })
fbq('track', 'InitiateCheckout', { value: '59.50', currency: 'EUR' })
fbq('track', 'Purchase', {
order_id: 'SNLDX1',
currency: 'EUR',
value: '59.50',
content_ids: ['a1b2c3'],
content_type: 'product',
contents: [{ id: 'a1b2c3', quantity: 2, price: '29.75', item_name: 'SUP Board' }],
num_items: 1 // número de líneas del carrito
}, { eventID: 'purchase_SNLDX1' })
- Los importes de Meta son cadenas con dos decimales.
eventIDespurchase_+ referencia del pedido, el mismoevent_idque el Purchase de la API de conversiones en el servidor, así que Meta deduplica ambos.- Con
metaPixelId, cuando se guardan los datos del cliente:fbq('init', metaPixelId, { em, fn, ln, ct, zp, country })(valores sin cifrar; el píxel les aplica el hash).
Umami
Con enableUmamiTracking y el script de Umami en la página:
umami.track('add_to_cart', { item_id: 'a1b2c3', item_name: 'SUP Board', quantity: 1, currency: 'EUR', value: 29.75 })
umami.track('begin_checkout', { value: 59.5, currency: 'EUR' })
umami.track('purchase', { revenue: 59.5, currency: 'EUR', transaction_id: 'SNLDX1', num_items: 1 })
Solo purchase lleva revenue. Los campos vacíos se omiten. Umami no instala cookies; tú decides si pides consentimiento.
Píxel de OpenAI Ads
Con enableOpenAiTracking y el píxel de OpenAI (oaiq) en la página:
oaiq('measure', 'order_created', {
type: 'contents',
amount: 5950, // unidades menores (céntimos), neto
currency: 'EUR',
contents: [{ id: 'a1b2c3', name: 'SUP Board', content_type: 'product', quantity: 2 }]
}, { event_id: 'purchase_SNLDX1' })
También puedes dejar la opción desactivada y llamar tú mismo a oaiq en onCheckoutSuccess.
Callbacks
Los errores que se lanzan dentro de un callback se capturan y se registran en la consola, para que no rompan la reserva.
onAddToCart({ productId, quantity, currency, name })
productId es el ID del artículo y quantity, la cantidad añadida.
onInitiateCheckout({ transactionTotal, transactionId })
transactionTotal es el importe a pagar (bruto, fianzas incluidas), no el valor neto del carrito que usan los demás eventos. transactionId es la referencia del pedido.
onCheckoutSuccess({ ecommerceData, fbqData, eventID, price })
ecommerceData.purchase: el objetopurchasedel dataLayer (transaction_id,currency,value,tax,items).fbqData: los parámetros del Purchase de Meta (sinorder_id).eventID:purchase_+ referencia del pedido.price: objeto heredado{ gross, net, vat }en céntimos, fianzas incluidas. UsaecommerceDataen su lugar.
Ejemplo, un píxel propio:
window.RTR_HOOKS = Object.assign(window.RTR_HOOKS || {}, {
onCheckoutSuccess: ({ ecommerceData, eventID }) => {
const p = ecommerceData.purchase
myPixel('purchase', { order: p.transaction_id, value: p.value, currency: p.currency, dedup: eventID })
},
})
Google Tag Manager
- Añade el fragmento con
enableDataLayer: true, ya sea en la página o como etiqueta HTML personalizado (Custom HTML) de GTM con el activador Inicialización - Todas las páginas (Initialization – All Pages). - Crea activadores de tipo Evento personalizado (Custom Event) para
add_to_cart,begin_checkout,add_shipping_infoypurchase. - Crea variables de tipo Variable de capa de datos (Data Layer Variable, versión 2), por ejemplo
ecommerce.value,ecommerce.currency,ecommerce.transaction_id,ecommerce.items. - Etiquetas de evento de GA4: nombre del evento
{{Event}}o el nombre fijo, y «Enviar datos de comercio electrónico» con la fuente de datos «Capa de datos». - Purchase de Meta a través de GTM: define el ID de evento como
purchase_{{DLV - ecommerce.transaction_id}}. Así coincide con el Purchase del servidor y Meta los deduplica.
Si también usas el seguimiento en el servidor a través de Rentware para la misma propiedad de GA4, no envíes allí también los eventos del dataLayer: GA4 solo deduplica purchase (por transaction_id), así que add to cart y los demás eventos del embudo se contarían dos veces.
Consentimiento
El widget lee el consentimiento para lo que envía al servidor de Rentware (que decide qué va a GA4, Google Ads y Meta). No controla tus propias etiquetas.
- Lee Google Consent Mode v2 de
window.dataLayer: entradasgtag('consent', 'default' | 'update', {…})y objetos al estilo de GTM como{ event: 'consent_update', ad_storage: 'granted', … }. Los aplica en orden: unupdateposterior sobrescribe los valores anteriores. - Señales:
ad_storage,analytics_storage,ad_user_data,ad_personalization. Cada una esdeniedpor defecto. - Si la página no tiene ninguna entrada de Consent Mode, la solicitud se marca como «sin señal de consentimiento», y el registro de seguimiento muestra
skipped: no consent signal. - Las entradas
defaultespecíficas de una región (conregion) no se pueden asociar a la ubicación del visitante en el navegador: solo se aplican sus valoresdenied. - El consentimiento tardío funciona: el consentimiento se vuelve a leer en cada solicitud. Un visitante que acepta después de que se cargue el widget queda cubierto a partir de la siguiente solicitud, siempre que tu banner envíe un
updatede Consent Mode awindow.dataLayer. - El widget solo lee el dataLayer llamado
dataLayeren la misma ventana. Un dataLayer con otro nombre, o un widget dentro de un iframe, significa que no hay señal de consentimiento.
Para comprobar una página: acepta el banner, abre la consola y escribe dataLayer. Tiene que haber una entrada consent (o un evento consent_update) antes de que el visitante reserve.
ID de clic
- El widget captura
gclid,gbraidywbraidde la URL (gclidtambién del parámetro del vinculador_glde Google o de la cookie_gcl_aw) yfbclidde la URL o de la cookie_fbcde Meta. La URL prevalece sobre la cookie. - La captura se hace solo con consentimiento
ad_storage. Antes de eso no se lee ninguna cookie ni se guarda nada. Si el consentimiento llega más tarde mientras el ID de clic sigue en la URL, se captura en ese momento. - Los ID de clic se guardan en
sessionStoragepara la pestaña (misma pestaña, mismo dominio; desaparecen al cerrarla). Gana el primer clic. - El widget los envía con sus solicitudes al servidor de Rentware, que los usa para Google Ads y Meta. No se añaden a tus eventos del navegador.
- ¿La página de destino y la de reserva son distintas? Ejecuta también el script del widget en la página de destino, o deja que tu etiqueta de Google (con
url_passthrough) o tu píxel de Meta escriba la cookie_gcl_aw/_fbc.gbraidywbraidno tienen cookie de respaldo.
Lista de comprobación
- Añade
RTR_HOOKS, abre la página y acepta el banner. - Añade un artículo al carrito y escribe
dataLayeren la consola: las últimas entradas son{ ecommerce: null }y{ event: 'add_to_cart', … }. - Completa una reserva con «reservar» o pago por adelantado y revisa la entrada
purchase; sutransaction_ides la referencia del pedido. - Después, cancela la reserva de prueba en Rentware.