随着 Telegram 迈向区块链&小程序时代,Telegram 内部已经与 TON 钱包做了集成,并为了应对 Apple 和 Google 关于数字产品销售的监管需要上线了 Telegram Stars 作为支付方式。依托 Telegram 生态的数亿用户,将会产生不少的开发需求和问题,本文基于grammY框架,踩了一些坑,分享支付机器人开发过程中的心得,希望对你有帮助。
支付机器人
初始化
在使用测试环境进行机器人开发时,创建 Bot 实例,需要将environment
指定为test
,否则将会产生401 Unauthorized
错误。
另外如果当前的网络环境需要使用科学上网才能访问 Telegram,还需要配置baseFetchConfig.agent
为你的代理地址。
new Bot(process.env.BOT_TOKEN!, {
client: {
baseFetchConfig: {
// highlight-next-line
agent: isDevEnv ? new HttpsProxyAgent('http://127.0.0.1:7890') : null
},
// highlight-next-line
environment: isDevEnv ? 'test' : 'prod'
}
})
Stars 支付流程
// highlight-next-line
// 1. 调用 `sendInvoice` 发送发票,currency 参数指定为`XTR`
ctx.api.sendInvoice(ctx.chat!.id, 'Title', 'Description', `payload`, 'XTR', [{ label: 'Label', amount: 1 }])
// highlight-next-line
// 2. 检查发票,等待字段 `pre_checkout_query` 的更新
bot.on('pre_checkout_query', (ctx) => {
// highlight-next-line
// 3. 通过 `answerPreCheckoutQuery` 批准或取消订单
ctx.answerPreCheckoutQuery(true)
// ctx.answerPreCheckoutQuery(false, {
// error_message: 'An unexpected error occurred. Please try again later.'
// })
})
// highlight-next-line
// 4. 等待字段 `successful_payment` 的更新
bot.on(':successful_payment', ctx => {
// highlight-next-line
// 5. 支付成功回调,存储成功支付的 `telegram_payment_charge_id`(未来可能需要用它来发起退款)
console.log(ctx.message?.successful_payment.telegram_payment_charge_id)
// highlight-next-line
// 6. 向用户交付其所购买的商品和服务,业务逻辑...
ctx.reply('payment-success').catch(console.error)
})
TON 支付流程
- 生成指定钱包的支付链接
function generatePaymentLink(
toWallet: string,
amount: number | string | bigint,
comment: string,
app: "tonhub" | "tonkeeper"
) {
if (app === "tonhub") {
return `https://tonhub.com/transfer/${toWallet}?amount=${toNano(
amount
)}&text=${comment}`;
}
return `https://app.tonkeeper.com/transfer/${toWallet}?amount=${toNano(
amount
)}&text=${comment}`;
}
- 将生成的链接以菜单形式返回给用户,并提供
check_transaction
事件用于检查交易
const tonhubPaymentLink = generatePaymentLink(process.env.OWNER_WALLET!, amount, comment, 'tonhub')
const tonkeeperPaymentLink = generatePaymentLink(process.env.OWNER_WALLET!, amount, comment, 'tonkeeper')
const menu = new InlineKeyboard()
.url("Click to pay in TonHub", tonhubPaymentLink)
.row()
.url("Click to pay in TonKeeper", tonkeeperPaymentLink)
.row()
.text(`I sent ${amount} TON`, "check_transaction");
await ctx.reply(
`Tips`,
{ reply_markup: menu, parse_mode: "HTML" }
);
- 监听
check_transaction
事件,校验支付状态,处理支付成功的逻辑
bot.callbackQuery("check_transaction", checkTransaction);
async function checkTransaction(ctx) {
await verifyTransactionExistance(
process.env.OWNER_WALLET,
ctx.session.amount,
ctx.session.comment
);
}
async function verifyTransactionExistance(
toWallet: Address,
value: number,
comment: string
) {
const endpoint =
process.env.NETWORK === "mainnet"
? "https://toncenter.com/api/v2/jsonRPC"
: "https://testnet.toncenter.com/api/v2/jsonRPC";
const httpClient = new HttpApi(endpoint, {
apiKey: process.env.TONCENTER_TOKEN,
});
const transactions = await httpClient.getTransactions(toWallet, {
limit: 100,
});
let incomingTransactions = transactions.filter(
(tx) => Object.keys(tx.out_msgs).length === 0
);
for (let i = 0; i < incomingTransactions.length; i++) {
let tx = incomingTransactions[i];
// Skip the transaction if there is no comment in it
if (!tx.in_msg?.msg_data) {
continue;
}
// Convert transaction value from nano
let txValue = fromNano(tx.in_msg.value);
// Get transaction comment
let txComment = tx.in_msg.message;
if (txComment === comment && txValue === value.toString()) {
return true;
}
}
return false;
}
注意事项
测试环境账号注册
在 Telegram 的账号体系中,测试环境与主环境完全隔离,因此在进行测试环境登录时,无法直接使用现有账号进行登录,在扫码时会提示
AUTH_TOKEN_INVALID2
错误,以及无法收到验证码的情况。
所以你需要先注册一个测试账号,截止 2024 年 8 月,测试账号只能通过 iPhone 端 Telegram 进行。具体操作流程如下:1、登录 Telegram iPhone
2、多次点击右下角Setting
Tab 进入 Debug 页面
3、点击操作列表中的Accounts
项
4、点击Login to another account
选择Test
环境,完成账号注册账号注册完成后,就可以按官方流程进入测试环境。在使用测试环境时,您可以采用未加密的 HTTP 链接来测试您的 Web 应用或 Web 登录功能。
另外测试环境的 Telegram Star 也需要进行购买,不过可以参考下文使用 stripe 提供的测试信用卡无限制进行购买。
信用卡测试支付
在您的机器人支付功能仍在开发和测试阶段时,请使用 “Stripe 测试模式” 提供商。在此模式下,您可以进行支付操作而不会实际计费任何账户。测试模式中无法使用真实信用卡,但您可以使用测试卡,如
4242 4242 4242 4242
(完整测试卡列表)。您可以随意在测试模式与实时模式间切换,但在正式上线前,请务必查阅上线检查清单。
引用参考
grammY 是一个用于创建 Telegram Bot 的框架。它可以从 TypeScript 和 JavaScript 中使用,在 Node.js、 Deno 和浏览器中运行。
Bot Payments API for Digital Goods and Services
用于数字商品和服务的机器人支付 API
How to integrate Telegram Stars Payment to your bot
如何将 Telegram Stars 支付集成到您的机器人中
- 测试环境账号注册
- TON Faucet 水龙头
- 官方 Demo 出售饺子的机器人
- 本文项目 Demo 地址
- 原文地址
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。