Telegram Bot不仅能为用户提供便捷服务,还能通过内置的支付API实现商业化,其中会员订阅是最常见的模式之一。本文将带领你从零开始,利用Telegram官方Bot API开发一个支持会员订阅支付的完整解决方案,涵盖从支付基础概念到实战代码的每一步。
准备工作:创建Bot与配置支付提供商
开始开发前,你需要完成以下步骤:
- 通过@BotFather创建自己的Bot,并获取API Token。
- 在BotFather中启用支付功能:发送
/setpayments给BotFather,选择你的Bot,然后选择一个支付提供商(如Stripe)并绑定账户。完成后BotFather会提供一个支付提供商令牌(Provider Token)。 - 准备一个支持HTTPS的服务器或使用开发环境,用于接收Telegram的Webhook请求(也可使用GetUpdates轮询,但Webhook是生产推荐方式)。
理解Telegram Payment API核心概念
Telegram支付API基于Invoice(发票)和Pre-checkout(预结算)机制,关键点包括:
- Invoice:由
sendInvoice方法创建,包含商品标题、描述、货币与价格等。 - Provider Token:支付服务商提供的标识,用于识别收款商户。
- Pre-checkout Query:用户确认支付前,Telegram会发送一个预支付回调,开发者需要调用
answerPreCheckoutQuery确认或拒绝。 - Successful Payment:支付成功后,Bot会收到包含支付信息的更新消息。
设计会员订阅的数据结构
为了管理用户订阅状态,你需要使用数据库。以下以SQLite为例设计简单的数据表:
CREATE TABLE subscriptions (
user_id INTEGER PRIMARY KEY,
status TEXT NOT NULL DEFAULT 'active',
expires_at INTEGER NOT NULL
);user_id:Telegram用户ID。status:订阅状态,如 active、expired。expires_at:订阅到期时间(Unix时间戳)。
创建并发送Invoice
当用户触发订阅命令时,Bot需要调用 sendInvoice 方法。下面是一个使用Python(python-telegram-bot v20+)的示例:
from telegram import Update
from telegram.ext import Application, CommandHandler, CallbackQueryHandler, ContextTypes
async def subscribe(update: Update, context: ContextTypes.DEFAULT_TYPE):
chat_id = update.effective_chat.id
payload = f"member_" # 自定义payload用于后续识别
await update.effective_chat.send_invoice(
title="会员订阅(月度)",
description="解锁所有高级功能,有效期30天",
payload=payload,
provider_token="YOUR_PROVIDER_TOKEN",
currency="USD",
prices=[{"label":"月度会员", "amount": 499}] # 金额单位是分
)注意:金额单位通常为最小货币单位(美分)。你可以设置 start_parameter 参数来支持会话ID,但订阅场景中保持简单即可。
处理支付回调
用户完成支付后,Telegram会发送预付款查询和成功支付更新。你必须处理这两个事件:
处理预付款查询(pre_checkout_query)
async def pre_checkout(update: Update, context: ContextTypes.DEFAULT_TYPE):
query = update.pre_checkout_query
# 验证payload,确保支付来自你的Bot
if query.invoice_payload.startswith("member_"):
await query.answer(ok=True)
else:
await query.answer(ok=False, error_message="支付数据异常,请重试")处理支付成功(successful_payment)
async def successful_payment(update: Update, context: ContextTypes.DEFAULT_TYPE):
payment = update.effective_message.successful_payment
user_id = update.effective_user.id
payload = payment.invoice_payload
# 解析用户ID(从payload中)或直接使用user_id
expires_at = int(time.time()) + 30 * 24 * 3600 # 30天
# 写入数据库
conn = sqlite3.connect('db.sqlite')
conn.execute("INSERT OR REPLACE INTO subscriptions (user_id, status, expires_at) VALUES (?, ?, ?)",
(user_id, 'active', expires_at))
conn.commit()
await update.effective_message.reply_text("订阅成功!欢迎加入会员。")实现订阅自动续费(进阶)
Telegram原生API并不支持自动扣款,所谓“自动续费”需要用户每次主动支付。不过你可以通过以下方式优化体验:
- 在用户订阅到期前,通过Bot发送提醒消息,附上重新支付的按钮。
- 使用Telegram的
sendInvoice参数start_parameter存储用户ID,以便快速再次调用。
async def remind_renewal(chat_id: int):
# 查找用户状态,若即将过期则发送账单
pass管理会员功能
有了订阅状态,你可以在Bot命令中加入权限检查。例如创建一个装饰器:
def require_subscription(func):
async def wrapper(update: Update, context: ContextTypes.DEFAULT_TYPE):
user_id = update.effective_user.id
sub = fetch_subscription(user_id)
if sub and sub['expires_at'] > time.time():
return await func(update, context)
else:
await update.effective_message.reply_text("该命令需要会员订阅,请使用 /subscribe 订阅。")
return wrapper然后装饰你的会员专属命令:
@require_subscription
async def member_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
await update.effective_message.reply_text("欢迎进入会员专区!")安全与错误处理
支付功能涉及真实资金,务必注意:
- 验证Webhook请求是否来自Telegram(通过IP或Secret Token)。
- 妥善保护Provider Token,切勿硬编码在客户端。
- 处理支付回调可能出现的重复通知,确保数据库操作的幂等性。
- 使用异常捕获机制,防止因数据库或网络故障导致支付丢失。
总结
通过以上步骤,你已经掌握了为Telegram Bot添加会员订阅支付的核心技术。从创建Invoice、处理预付款,到更新用户状态并限制权限,一套完整的付费系统可以快速落地。如果你需要更多高级功能(如多级会员、优惠券),可以在此基础上扩展。请始终参考官方支付API文档,确保合规与安全。