跳到主要内容

Telegram 支付机器人开发小记

· 阅读需 7 分钟
小学后生
Full Stack Developer

随着 Telegram 迈向区块链&小程序时代,Telegram 内部已经与 TON 钱包做了集成,并为了应对 Apple 和 Google 关于数字产品销售的政策监管需要上线了 Telegram Stars 作为支付方式。依托 Telegram 生态的数亿用户,存在着大量机遇,并为区块链走向 Mass Adoption 铺设了一条新的高速公路。本文基于 grammY 框架,分享支付机器人开发过程中的心得,助你成功。

支付机器人

点击此处访问完整 Demo 地址

初始化

在使用测试环境进行机器人开发时,创建 Bot 实例,需要将environment指定为test,否则将会产生401 Unauthorized错误。

另外如果当前的网络环境需要使用科学上网才能访问 Telegram,还需要配置baseFetchConfig.agent为你的代理地址。

Bot Init
new Bot(process.env.BOT_TOKEN!, {
client: {
baseFetchConfig: {
agent: isDevEnv ? new HttpsProxyAgent('http://127.0.0.1:7890') : null
},
environment: isDevEnv ? 'test' : 'prod'
}
})

Stars 支付流程

Pay With Stars
// 1. 调用 `sendInvoice` 发送发票,currency 参数指定为`XTR`
ctx.api.sendInvoice(ctx.chat!.id, 'Title', 'Description', `payload`, 'XTR', [{ label: 'Label', amount: 1 }])

// 2. 检查发票,等待字段 `pre_checkout_query` 的更新
bot.on('pre_checkout_query', (ctx) => {

// 3. 通过 `answerPreCheckoutQuery` 批准或取消订单
ctx.answerPreCheckoutQuery(true)
// ctx.answerPreCheckoutQuery(false, {
// error_message: 'An unexpected error occurred. Please try again later.'
// })
})

// 4. 等待字段 `successful_payment` 的更新
bot.on(':successful_payment', ctx => {

// 5. 支付成功回调,存储成功支付的 `telegram_payment_charge_id`(未来可能需要用它来发起退款)
console.log(ctx.message?.successful_payment.telegram_payment_charge_id)

// 6. 向用户交付其所购买的商品和服务,业务逻辑...
ctx.reply('payment-success').catch(console.error)
})

TON 支付流程

  1. 生成指定钱包的支付链接
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}`;
}
  1. 将生成的链接以菜单形式返回给用户,并提供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" }
);
  1. 监听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、多次点击右下角SettingTab 进入 Debug 页面 3、点击操作列表中的Accounts项 4、点击Login to another account选择Test环境,完成账号注册

    账号注册完成后,就可以按官方流程进入测试环境。在使用测试环境时,您可以采用未加密的 HTTP 链接来测试您的 Web 应用或 Web 登录功能。

    另外测试环境的 Telegram Star 也需要进行购买,不过可以参考下文使用 stripe 提供的测试信用卡无限制进行购买。

  • 信用卡测试支付

    在您的机器人支付功能仍在开发和测试阶段时,请使用 “Stripe 测试模式” 提供商。在此模式下,您可以进行支付操作而不会实际计费任何账户。测试模式中无法使用真实信用卡,但您可以使用测试卡,如 4242 4242 4242 4242 (完整测试卡列表)。您可以随意在测试模式与实时模式间切换,但在正式上线前,请务必查阅上线检查清单

引用参考