Sugeriría que no ha almacenado suficientes datos en su tabla.
Tal como está ahora, siempre deberá mirar cada pago anterior para determinar si el actual está activo o en espera de activación, un gran impacto en el rendimiento y una consulta más compleja.
Un expires_at
calculado columna para payments
, que se resuelve al agregar un nuevo pago como MAX(payments.expires_at) + INTERVAL service_plans.days DAYS
le permitirá calcular la cantidad de días restantes mirando solo una fila... y si un usuario está o no en un plan.