PAYATHON 2026

如何使用 TeleBot 的 send_invoice method 发送发票?

支付阿杰

结论

TeleBot.send_invoice() 的 prices 参数需要传入由 telebot.types.LabeledPrice 对象组成的列表,不能直接使用字典列表。字典里即使包含 label 和 amount,部分版本的 pyTelegramBotAPI 也可能无法将其正确序列化为 Telegram Bot API 所需的价格数组。Telegram 最终收到的价格列表为空时,会返回以下错误:

Bad Request: there must be at least one price

正确写法

from telebot import types

prices = [
    types.LabeledPrice(label="flowers", amount=1000)
]

bot.send_invoice(
    chat_id=chat_id,
    title="Flowers Delivery",
    description=description_of_package,
    invoice_payload="some-invoice-payload-for-internal-use",
    provider_token=keys.TEST_TRANZZO_PAYMENT,
    currency="UAH",
    prices=prices,
    start_parameter="test-start-parameter"
)

也可以在调用方法时直接创建价格对象:

from telebot import types

bot.send_invoice(
    chat_id=chat_id,
    title="Flowers Delivery",
    description=description_of_package,
    invoice_payload="some-invoice-payload-for-internal-use",
    provider_token=keys.TEST_TRANZZO_PAYMENT,
    currency="UAH",
    prices=[
        types.LabeledPrice(label="flowers", amount=1000)
    ],
    start_parameter="test-start-parameter"
)

原因

Telegram Bot API 要求 prices 是一个非空的 LabeledPrice 数组,其中每个价格项都必须包含:

  • label:价格项目名称。
  • amount:以货币最小单位表示的整数金额。

发送请求前,pyTelegramBotAPI 会把 Python 对象转换成 Telegram API 所需的 JSON。使用 types.LabeledPrice,可以让价格项按照库预期的格式完成序列化。

如果直接传入字典:

prices=[{"label": "flowers", "amount": 1000}]

部分版本可能无法正确处理。这样一来,代码中虽然写了价格,Telegram 实际收到的 prices 却可能仍是空列表。

金额单位

amount 必须是以货币最小单位表示的整数,不能使用浮点数。对于保留两位小数的货币:

types.LabeledPrice(label="flowers", amount=1000)

通常表示 10.00 UAH,不是 1000 UAH。如果要收取 1000.00 UAH,通常应写为:

types.LabeledPrice(label="flowers", amount=100000)

实际换算方式应以 Telegram 对该货币采用的小数位数为准。

还需要处理预结账请求

发票成功发送后,机器人还要在用户付款前处理 pre_checkout_query,并及时确认:

@bot.pre_checkout_query_handler(func=lambda query: True)
def process_pre_checkout_query(query):
    bot.answer_pre_checkout_query(
        pre_checkout_query_id=query.id,
        ok=True
    )

在实际业务中,应先检查 query.invoice_payload、商品状态和金额等信息,确认无误后再返回 ok=True。如果校验失败,则应返回 ok=False 并提供错误说明。

机器人还需要处理包含 successful_payment 的消息,以便在支付成功后执行发货、更新订单等操作。支付服务商 token、币种和金额也必须符合对应支付服务商的配置要求。

备注:内容仅供参考。