Tino Developers
View .md

Telegram, Zalo and Lark notifications

Besides webhooks, TinoPay posts a notification for every transaction to Telegram, Zalo or Lark. Each notification app is tied to one bank account and filters by virtual account like a webhook. The routes are in the Notifications group of the API Reference; calling, authentication and error codes are in Getting started with TinoPay.

Updated: 2026-10-25. Sources: Tino's TinoPay module and the TinoPay API v1 documentation.

App types

typeBotendpoint (where it posts)
telegramthe shared bot @allpay_telebot by default; send bot_token to use your own botshared bot: a group ID starting with - (add @allpay_telebot to the group); own bot: a group ID (-…) or a private chat (positive number)
zaloyour own bot is required (bot_token from Zalo Bot Creator)the Zalo chat_id of a private chat or a group (groups start with zgr-)
larka Lark bot webhook URL, no bot_tokenhttps://open.larksuite.com/open-apis/bot/v2/hook/… (or open.feishu.cn)

bot_token is never returned: lists carry only bot_token_masked. In a UI, make the token field a password field and do not refill it when editing.

Adding an app (own bot)

  1. Check the bot token: {type, bot_token} → {valid, bot_name, error}. Show the bot name; when valid is false, show error.
  2. Find a chat: {type, bot_token} → {chats: [{id, title, type}], error}; the user picks one, and its id becomes the endpoint.
  3. Send a test message: {type, endpoint, bot_token} sends a real message → {connected, chat_title}. Allow saving only when connected is true; Telegram returns chat_title to prefill the name.
  4. Create the app: type, name (up to 250 characters), endpoint, bot_token, bank_account_id, virtual_accounts (empty means every virtual account), status (active by default, inactive) → 201. type cannot change after creation.

Step 2 by type:

  • Telegram returns right away the groups and people that messaged the bot in the last 24 hours. A non-null error (the bot is attached to another system's webhook): let the user enter the ID by hand.
  • Zalo keeps no old messages: the request waits up to about 20 seconds and only catches messages sent to the bot meanwhile (groups: mention the bot). Tell the user to message the bot now, and set the HTTP timeout to at least 30 seconds. When nothing arrives, chats is empty: let them retry or enter the ID by hand.

Shared Telegram bot: skip steps 1 and 2; enter the group ID, and step 3 sends no bot_token. Lark: only steps 3 and 4, with the webhook URL as endpoint.

Steps 2 and 3 are not retried on network errors (a retry would multiply the wait or send the test message twice): let the user try again.

Editing an app

  • When editing, steps 1–3 send app_id instead of bot_token to use the stored token; app_id must be an app of this merchant, otherwise 404 RESOURCE_NOT_FOUND.
  • Update the app: send only the fields to change, never type.
bot_token when editingResult
not sentkeep the stored token
a new stringreplace the token
nullTelegram goes back to the shared bot (endpoint must be a group ID -…); Zalo cannot drop its token

A bank_account_id that does not belong to the merchant: 404 BANK_ACCOUNT_NOT_FOUND.

Watching delivery errors

The app list carries last_error and last_error_at: the error of the latest delivery (token revoked, bot removed from the group…). Show a "connection error" warning with last_error; the next successful delivery resets it to null. A suspended merchant sends no notifications, as with webhooks.