Saltar al contenido
Integración

La cuota de Google Wallet: 3 mensajes por pase cada 24 horas, bien gastados

Google acepta 3 notificaciones visibles por objeto cada 24 horas; el exceso lanza QuotaExceededException. Cómo presupuestar el canal sin perder cambios.

Por Magdi Khalifah7 min de lecturaActualizado

Google Wallet acepta un máximo de 3 avisos visibles por objeto cada 24 horas — sea por mensaje (AddMessageRequest con TEXT_AND_NOTIFY) o por una actualización que pide aviso (notifyPreference: notifyOnUpdate); el intento que excede el límite recibe QuotaExceededException. El PATCH sin aviso — el default — no consume cuota.

Así lo documenta Google a agosto de 2026, y así se comporta en producción. Lo que la documentación no trae es la parte operativa: cómo presupuestar tres avisos diarios cuando por un mismo pase compiten campañas, recordatorios y eventos transaccionales. Eso es lo que sigue.

Qué consume cuota y qué no

La distinción que ordena todo el diseño:

  • Consume cuota: todo lo que enciende la pantalla del titular. El mensaje con notificación visible (AddMessageRequest con TEXT_AND_NOTIFY) — y también el UPDATE/PATCH que pide aviso con notifyPreference: notifyOnUpdate, disponible para campos específicos de entradas de evento (nombre, lugar, fecha, asiento) y solo cuando el evento empieza en 3 horas o menos — fuera de esa ventana el aviso no se dispara: Google documenta para esas actualizaciones el mismo techo de 3 por pase cada 24 horas.
  • No consume cuota: el PATCH del objeto o de la clase sin notifyPreference — el default, y el modo en que operamos la sincronización de contenido (el cambio llega en silencio a todos los pases del grupo — el detalle está en Class y Object). Tampoco consume cuota mover la vigencia del objeto (validTimeInterval): expirar un pase explica por qué ese PATCH es obligatorio al cambiar la fecha.

Consecuencia de diseño: sincronizar contenido y avisar son dos operaciones distintas, y conviene tratarlas así en tu código aunque la API permita fusionarlas. Nuestro flujo separa ambas a propósito — el PATCH siempre silencioso, el aviso siempre como mensaje presupuestado — porque acoplar el aviso al UPDATE deja el contenido rehén de la cuota: si usas notifyOnUpdate, esos avisos entran a la misma ventana de 3, solo se disparan con el evento a menos de 3 horas, y tu contabilidad tiene que sumarlos igual.

Qué pasa cuando te pasas

Dos cosas, una documentada y una que conviene respetar:

  1. El intento excedente falla con QuotaExceededException. El mensaje no se entrega.
  2. Google se reserva además reducir la entrega de notificaciones a emisores que percibe como spam — está en su documentación, no es una leyenda.

De ahí la primera regla operativa: un fallo de cuota no se reintenta ciego. El reintento va a fallar las próximas horas (la ventana es de 24 horas) y solo acumula señales de mal emisor. La respuesta correcta es degradar: aplicar el cambio de contenido en silencio y registrar que el aviso se suprimió.

Presupuesta antes de enviar, no después del error

Nuestro patrón en producción: llevar un contador propio de avisos enviados por objeto en la ventana de 24 horas y consultarlo antes de cada envío. Presupuesto agotado → el cambio se aplica en silencio y la supresión queda registrada con su motivo, visible para el operador — un canal degradado en silencio y sin registro es un canal en el que no puedes confiar.

Dos matices que hacen que esto funcione de verdad:

  • Tu contador es consultivo; la autoridad es Google. El cap server-side existe aunque tu contador falle o pierda una fila. Diseña asumiendo que tu cuenta puede sub-contar — es el sentido de fallo correcto, como se ve abajo.
  • Cuenta los enviados, no los intentados. Las supresiones registradas no incrementan la ventana; solo los avisos que efectivamente salieron. Si las supresiones inflaran el contador, un día ruidoso bloquearía avisos que Google sí habría aceptado.

Reserva el último mensaje para lo transaccional

Tres avisos diarios se agotan rápido cuando el mismo pase recibe campañas del emisor y eventos del titular. El patrón que adoptamos: las campañas paran en 2 de 3 — el tercer mensaje del día queda reservado para el evento transaccional que no puede esperar a mañana: el «Pago confirmado», el recordatorio del vencimiento de hoy.

La reserva es deliberadamente asimétrica y conservadora: se implementa como umbral por origen del mensaje, no como contabilidad separada. Un evento transaccional madrugador puede consumir un cupo «de campaña»; una campaña jamás consume el cupo reservado. El peor caso de esa asimetría es una campaña de más que se suprime — nunca un pago confirmado que el titular no se entera.

El retry que duplica el push

La trampa más cara de este canal: cada mensaje enviado es un mensaje nuevo — cada envío crea una entrada con su propio identificador. Si un job de entrega se reintenta después de haber enviado (porque falló algo posterior al envío), el reintento envía otro mensaje: el titular ve dos avisos idénticos y tú quemaste 2 de tus 3 cupos en un solo evento.

La defensa es idempotencia alrededor de la unidad completa — consultar cuota, enviar y registrar como una sola operación con clave estable por evento lógico — con un detalle contraintuitivo: si el registro contable falla después de que el mensaje ya salió, ese fallo se traga, no se propaga. Propagarlo marcaría la unidad como fallida y el siguiente reintento re-enviaría el mensaje. El trade-off es explícito: preferimos sub-contar un aviso (benigno — el cap de Google sigue de autoridad) antes que notificar dos veces al titular.

Haz visible la degradación — o el canal miente

Una consecuencia de degradar a silencio que aprendimos tarde: si la supresión no se ve, el operador cree que avisó y el titular nunca se enteró. La degradación silenciosa es correcta hacia Google y hacia el titular; hacia el operador tiene que ser ruidosa.

Tres piezas que en nuestra experiencia valen su costo:

  • El conteo de suprimidos junto al de enviados. Donde el panel dice «enviados: 500», también dice cuántos quedaron sin aviso y por qué. Un operador que lanza una campaña sobre pases ya saturados merece ver el alcance real, no el intentado.
  • El motivo registrado por supresión. «Cuota de 24 horas» no es lo mismo que «el titular nunca guardó el pase»: se remedian distinto, y una fila sin motivo no le sirve a nadie seis semanas después.
  • Una alerta sobre el volumen de supresiones. Supresiones sostenidas día tras día no son mala suerte: son la señal de que estás intentando comunicar más de lo que el canal acepta, y la respuesta es editorial — consolidar avisos, repensar la cadencia — no técnica.

Qué merece uno de los tres

Con el presupuesto resuelto queda la pregunta editorial. Nuestra prueba, la misma para todos los tipos de operación: ¿el titular haría algo distinto hoy por enterarse?

Pasan la prueba: el vencimiento que se acerca, el pago que quedó confirmado, el evento que está por empezar, la subida de nivel en un programa de lealtad. No la pasan: correcciones menores, ajustes cosméticos, todo lo que puede simplemente amanecer actualizado.

La cuota, vista así, no es una limitación que sufrir sino una decisión editorial que Google toma por ti: si necesitas más de tres interrupciones diarias por pase, el problema rara vez es la cuota.

Preguntas frecuentes

¿La cuota es por titular o por pase?

Por objeto — es decir, por pase emitido. Un titular con dos pases de tu operación tiene dos presupuestos independientes de 3 mensajes cada 24 horas; un pase compartido en dos dispositivos sigue siendo un solo objeto y un solo presupuesto.

¿Actualizar el contenido del pase avisa algo al titular?

Por defecto, no: el PATCH sin notifyPreference es silencioso, no consume cuota y el pase amanece con el contenido nuevo. Google también permite pedir el aviso en el propio UPDATE (notifyPreference: notifyOnUpdate) para campos específicos de entradas y solo con el evento a 3 horas o menos de empezar — y ese aviso comparte el mismo techo de 3 por pase cada 24 horas.

¿Qué pasa con el cuarto cambio importante del día?

El contenido nunca se pierde: el pase se actualiza igual, en silencio. Lo que se pierde es el aviso — por eso conviene degradar a silencio de forma deliberada y registrada cuando el presupuesto se agotó, en lugar de provocar la excepción de Google.

¿Apple Wallet tiene una cuota equivalente?

No publicada. El push de Apple es silencioso y el texto visible sale del changeMessage del campo que cambió, así que no existe un contador equivalente que administrar — el detalle está en APNs para pases digitales. La disciplina editorial — qué amerita aviso — aplica igual en ambas plataformas.

Sigue leyendo

Todas las guías