По какой ссылке? На бота что ли?
В таком случае к ссылке добавляется GET параметр start с каким-то уникальным содержимым. Пусть это будет ID чата реферера
https://t.me/botusername?start=242915
При нажатии на кнопку "START" к сообщению добавится нагрузка из параметра, в примере выше в бота прилетит сообщение вида
/start 242915
. Дальше уже можно либо в обработчике команды start, либо в кастомном обработчике это всё сделать
@dp.message_handler(regexp='^/start\s\d+')
async def referral_handler(message: types.Message):
referrer_chat_id = re.search(r'\d+', message.text).group(0)
referral_chat_id = message.chat.id
А дальше уже заносим в базу или куда там нужно.
Естественно, логично было бы сделать защиту от банальной отправки
/start 242915
, можно генерить рандомный код, который связывать с пользователем, делать одноразовые коды и тд, тут уже на усмотрение
https://core.telegram.org/bots#deep-linking