You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过tonapi.io Webhook正确获取交易状态?

如何通过tonapi.io Webhook正确获取交易状态?

我来帮你拆解下你遇到的问题,其实核心是对TON API的参数格式和鉴权规则理解有偏差,咱们一步步解决:


一、核心问题:account_id格式不匹配

你收到的「illegal base32 data」错误,本质是因为TON API的账户ID参数要求的是base64url格式(无填充),但webhook返回的是带0:前缀的十六进制格式。之前你尝试转base64url可能步骤有误,再加上鉴权的小问题,导致报错混淆了。


二、正确转换account_id的步骤

给你写个靠谱的转换工具函数(以JavaScript为例),一步到位把webhook里的account_id转成TON API需要的格式:

function convertTonAccountIdToBase64url(accountId) {
  // 先校验格式:必须带0:前缀
  if (!accountId.startsWith('0:')) {
    throw new Error('Invalid TON account format (missing "0:" prefix)');
  }
  // 去掉0:前缀,取纯十六进制部分
  const hexRaw = accountId.slice(2);
  // 十六进制转字节数组
  const byteArray = new Uint8Array(hexRaw.length / 2);
  for (let i = 0; i < hexRaw.length; i += 2) {
    byteArray[i / 2] = parseInt(hexRaw.slice(i, i + 2), 16);
  }
  // 字节数组转base64再转base64url(替换特殊字符+去掉填充)
  const base64 = btoa(String.fromCharCode(...byteArray));
  return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}

三、401未授权问题的排查方向

你已经加了Bearer头,但还是报401,大概率是这几个细节没注意:

  1. API Key格式问题:检查你的key有没有多余的空格、换行符(比如复制时带了末尾空格,或者从.env文件读取时带了换行),建议用trim()处理:
    const authHeader = `Bearer ${process.env.TON_API_KEY.trim()}`;
    
  2. 鉴权头格式错误:必须严格是Bearer (后面跟一个空格)+ API Key,不能少空格,也不能多写其他字符。
  3. API Key权限问题:去TON API的控制台看看你的key是否有效,有没有被禁用,或者是否有权限访问你调用的交易查询端点。

四、优化后的完整webhook处理代码

我把你的handler函数做了优化,加入了正确的格式转换、鉴权处理,还加了最佳实践的签名验证注释:

import { checkTransactionStatus } from "../utils/ton.js";

// 新增:account_id格式转换工具函数
function convertTonAccountIdToBase64url(accountId) {
  if (!accountId.startsWith('0:')) {
    throw new Error('Invalid TON account format (missing "0:" prefix)');
  }
  const hexRaw = accountId.slice(2);
  const byteArray = new Uint8Array(hexRaw.length / 2);
  for (let i = 0; i < hexRaw.length; i += 2) {
    byteArray[i / 2] = parseInt(hexRaw.slice(i, i + 2), 16);
  }
  const base64 = btoa(String.fromCharCode(...byteArray));
  return base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
}

export default async function handler(req, res) {
  if (req.method !== "POST") {
    return res.status(405).json({ error: "Method not allowed" });
  }

  try {
    const { tx_hash, account_id } = req.body;

    if (!tx_hash || !account_id) {
      return res.status(400).json({ error: "Invalid request body: missing tx_hash or account_id" });
    }

    // 【最佳实践】验证webhook签名,防止恶意请求
    // 你需要从TON API控制台获取webhook secret,然后验证X-TON-Signature头
    // const signature = req.headers['x-ton-signature'];
    // const isValid = verifyWebhookSignature(JSON.stringify(req.body), signature, process.env.TON_WEBHOOK_SECRET);
    // if (!isValid) return res.status(403).json({ error: "Invalid webhook signature" });

    // 1. 转换account_id为TON API要求的格式
    const formattedAccountId = convertTonAccountIdToBase64url(account_id);
    // 2. 确保鉴权头格式正确
    const authHeader = `Bearer ${process.env.TON_API_KEY.trim()}`;
    // 3. 调用TON API获取交易状态
    const status = await checkTransactionStatus(tx_hash, formattedAccountId, authHeader);

    return res.status(200).json({ status, transaction: tx_hash, account: formattedAccountId });
  } catch (error) {
    console.error("Webhook handler error:", error);
    return res.status(500).json({ error: "Internal server error", details: error.message });
  }
}

五、额外避坑提示

  1. tx_hash无需转换:webhook里的交易哈希是直接可用的十六进制格式,直接传给TON API即可。
  2. 错误信息的误导性:有时候TON API的错误信息会不准,比如base32错误可能其实是你调用的端点参数名写错了(比如用了account_id而端点要求account),一定要核对官方文档的参数名。
  3. 签名验证必做:不要忽略webhook签名验证,否则可能收到恶意伪造的交易通知。

备注:内容来源于stack exchange,提问作者Robert Grey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 09:49:35