diff --git a/StarTransactionsBot/README.md b/StarTransactionsBot/README.md
new file mode 100644
index 0000000..13b72ef
--- /dev/null
+++ b/StarTransactionsBot/README.md
@@ -0,0 +1,9 @@
+# CustomBot
+
+This bot basically have no any useful behaviour, but you may customize it as a playground
+
+## Launch
+
+```bash
+../gradlew run --args="BOT_TOKEN"
+```
diff --git a/StarTransactionsBot/build.gradle b/StarTransactionsBot/build.gradle
new file mode 100644
index 0000000..5f15acb
--- /dev/null
+++ b/StarTransactionsBot/build.gradle
@@ -0,0 +1,21 @@
+buildscript {
+    repositories {
+        mavenCentral()
+    }
+
+    dependencies {
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
+    }
+}
+
+apply plugin: 'kotlin'
+apply plugin: 'application'
+
+mainClassName="StarTransactionsBotKt"
+
+
+dependencies {
+    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+
+    implementation "dev.inmo:tgbotapi:$telegram_bot_api_version"
+}
diff --git a/StarTransactionsBot/src/main/kotlin/StarTransactionsBot.kt b/StarTransactionsBot/src/main/kotlin/StarTransactionsBot.kt
new file mode 100644
index 0000000..92707ca
--- /dev/null
+++ b/StarTransactionsBot/src/main/kotlin/StarTransactionsBot.kt
@@ -0,0 +1,131 @@
+import dev.inmo.kslog.common.KSLog
+import dev.inmo.kslog.common.LogLevel
+import dev.inmo.kslog.common.defaultMessageFormatter
+import dev.inmo.kslog.common.setDefaultKSLog
+import dev.inmo.micro_utils.coroutines.subscribeSafelyWithoutExceptions
+import dev.inmo.tgbotapi.extensions.api.answers.answer
+import dev.inmo.tgbotapi.extensions.api.answers.payments.answerPreCheckoutQueryOk
+import dev.inmo.tgbotapi.extensions.api.bot.getMe
+import dev.inmo.tgbotapi.extensions.api.edit.edit
+import dev.inmo.tgbotapi.extensions.api.get.getStarTransactions
+import dev.inmo.tgbotapi.extensions.api.send.reply
+import dev.inmo.tgbotapi.extensions.behaviour_builder.telegramBotWithBehaviourAndLongPolling
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.command
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onCommand
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onMessageDataCallbackQuery
+import dev.inmo.tgbotapi.extensions.behaviour_builder.triggers_handling.onPreCheckoutQuery
+import dev.inmo.tgbotapi.extensions.utils.extensions.sameChat
+import dev.inmo.tgbotapi.extensions.utils.types.buttons.dataButton
+import dev.inmo.tgbotapi.extensions.utils.types.buttons.flatInlineKeyboard
+import dev.inmo.tgbotapi.extensions.utils.types.buttons.inlineKeyboard
+import dev.inmo.tgbotapi.extensions.utils.types.buttons.payButton
+import dev.inmo.tgbotapi.extensions.utils.withContentOrNull
+import dev.inmo.tgbotapi.types.RawChatId
+import dev.inmo.tgbotapi.types.UserId
+import dev.inmo.tgbotapi.types.buttons.InlineKeyboardMarkup
+import dev.inmo.tgbotapi.types.message.content.TextContent
+import dev.inmo.tgbotapi.types.message.textsources.TextSource
+import dev.inmo.tgbotapi.types.message.textsources.TextSourcesList
+import dev.inmo.tgbotapi.types.payments.LabeledPrice
+import dev.inmo.tgbotapi.types.payments.stars.StarTransaction
+import dev.inmo.tgbotapi.utils.*
+import kotlinx.coroutines.*
+
+/**
+ * The main purpose of this bot is just to answer "Oh, hi, " and add user mention here
+ */
+@OptIn(PreviewFeature::class)
+suspend fun main(vararg args: String) {
+    val botToken = args.first()
+    val adminUserId = args.getOrNull(1) ?.toLongOrNull() ?.let(::RawChatId) ?.let(::UserId) ?: error("Pass user-admin for full access to the bot")
+
+    val isDebug = args.any { it == "debug" }
+    val isTestServer = args.any { it == "testServer" }
+
+    if (isDebug) {
+        setDefaultKSLog(
+            KSLog { level: LogLevel, tag: String?, message: Any, throwable: Throwable? ->
+                println(defaultMessageFormatter(level, tag, message, throwable))
+            }
+        )
+    }
+
+    telegramBotWithBehaviourAndLongPolling(botToken, CoroutineScope(Dispatchers.IO), testServer = isTestServer) {
+        val me = getMe()
+
+        val payload = "sample payload"
+        command("start") {
+            reply(
+                it,
+                price = LabeledPrice("1", 1L),
+                title = "Sample",
+                description = "Sample description",
+                payload = payload,
+                replyMarkup = flatInlineKeyboard {
+                    payButton("Pay")
+                },
+            )
+        }
+
+        onPreCheckoutQuery(initialFilter = { it.invoicePayload == payload }) {
+            answerPreCheckoutQueryOk(it)
+        }
+
+        val transactionsDataPrefix = "getStarTransactions"
+        fun buildTransactionsData(offset: Int, limit: Int = 10) = "$transactionsDataPrefix $offset $limit"
+        fun parseTransactionsData(data: String): Pair<Int, Int> = data.split(" ").drop(1).let {
+            it.first().toInt() to it.last().toInt()
+        }
+        suspend fun buildStarTransactionsPage(offset: Int, limit: Int = 10): Pair<TextSourcesList, InlineKeyboardMarkup> {
+            val transactions = getStarTransactions(offset, limit)
+            return buildEntities {
+                transactions.transactions.forEach {
+                    regular("Transaction Id: ") + bold(it.id.string) + "\n"
+                    regular("Date: ") + bold(it.date.asDate.toStringDefault()) + "\n"
+                    regular("Amount: ") + bold(it.amount.toString()) + "\n"
+                    when (it) {
+                        is StarTransaction.Incoming -> {
+                            regular("Type: ") + bold("incoming") + "\n"
+                            regular("Partner: ") + bold(it.partner.type) + "\n"
+                        }
+                        is StarTransaction.Outgoing -> {
+                            regular("Type: ") + bold("outgoing") + "\n"
+                            regular("Partner: ") + bold(it.partner.type) + "\n"
+                        }
+                        is StarTransaction.Unknown -> {
+                            regular("Type: ") + bold("unknown") + "\n"
+                            regular("Partner: ") + bold(it.partner.type) + "\n"
+                        }
+                    }
+                }
+            } to inlineKeyboard {
+                row {
+                    val prevOffset = (offset - limit).coerceAtLeast(0)
+                    if (prevOffset < offset) {
+                        dataButton("<", buildTransactionsData(prevOffset, limit))
+                    }
+                    val nextOffset = (offset + limit)
+                    dataButton(">", buildTransactionsData(nextOffset, limit))
+                }
+            }
+        }
+
+        onCommand("transactions", initialFilter = { it.sameChat(adminUserId) }) {
+            val (text, keyboard) = buildStarTransactionsPage(0)
+
+            reply(it, text, replyMarkup = keyboard)
+        }
+
+        onMessageDataCallbackQuery(Regex("$transactionsDataPrefix \\d+ \\d+")) {
+            val (offset, limit) = parseTransactionsData(it.data)
+            val (text, keyboard) = buildStarTransactionsPage(offset, limit)
+            edit(
+                it.message.withContentOrNull<TextContent>() ?: return@onMessageDataCallbackQuery,
+                text,
+                replyMarkup = keyboard,
+            )
+        }
+
+        allUpdatesFlow.subscribeSafelyWithoutExceptions(this) { println(it) }
+    }.second.join()
+}
diff --git a/gradle.properties b/gradle.properties
index 378fc01..2356463 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -5,7 +5,7 @@ org.gradle.jvmargs=-Xmx2344m
 
 
 kotlin_version=1.9.23
-telegram_bot_api_version=14.1.0
+telegram_bot_api_version=15.0.0
 micro_utils_version=0.21.0
 serialization_version=1.6.3
 ktor_version=2.3.11
diff --git a/settings.gradle b/settings.gradle
index ba16eb9..637922f 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -50,4 +50,6 @@ include ":BoostsInfoBot"
 
 include ":BusinessConnectionsBot"
 
+include ":StarTransactionsBot"
+
 include ":CustomBot"