hm-tracking-sdk 0.1.9 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +449 -449
- package/dist/browser/index.es.js +28 -27
- package/dist/browser/index.umd.js +36 -36
- package/dist/sdk/telegram.js +29 -28
- package/dist/sdk/telegram.js.map +1 -1
- package/dist/sdk/types.d.ts +10 -10
- package/dist/sdk/types.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,449 +1,449 @@
|
|
|
1
|
-
# HM Tracking SDK 使用文档
|
|
2
|
-
|
|
3
|
-
本文档详细介绍如何使用 HM Tracking SDK,包括初始化、广告业务和支付业务的完整流程。
|
|
4
|
-
|
|
5
|
-
## 1. 安装
|
|
6
|
-
|
|
7
|
-
### 建议通过 npm/yarn 安装正式发布的包:
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
# 使用 yarn
|
|
11
|
-
yarn add hm-tracking-sdk axios crypto-js
|
|
12
|
-
|
|
13
|
-
# 或使用 npm
|
|
14
|
-
npm i hm-tracking-sdk axios crypto-js
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## 2. SDK 初始化
|
|
20
|
-
|
|
21
|
-
- 接口: init()
|
|
22
|
-
|
|
23
|
-
```ts
|
|
24
|
-
import { HmTrackingSDK, type SDKInitOptions } from "hm-tracking-sdk";
|
|
25
|
-
|
|
26
|
-
const options: SDKInitOptions = {
|
|
27
|
-
// 可选:不传则使用内置默认地址
|
|
28
|
-
baseURL: "https://your-api.example.com",
|
|
29
|
-
// 可选:回调校验用,SDK方会提供
|
|
30
|
-
appId: "app-xxxxxxx",
|
|
31
|
-
|
|
32
|
-
// 可选:本地存储 Key 前缀,避免项目间冲突
|
|
33
|
-
storageKeyPrefix: "your_app_prefix",
|
|
34
|
-
|
|
35
|
-
// 可选:浏览器环境下使用,可显式传入自定义用户
|
|
36
|
-
customUser: {
|
|
37
|
-
user: {
|
|
38
|
-
id: 123456789,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
username: "test_user",
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
hash: "your_hash_value",
|
|
47
|
-
},
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
const sdk = new HmTrackingSDK(options);
|
|
51
|
-
await sdk.init();
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
- 函数说明:初始化 SDK,先创建 HmTrackingSDK 对象,然后调用 init 方法完成初始化。
|
|
55
|
-
- 参数说明: `SDKInitOptions` 初始化SDK时的可选参数,数据结构及内部结构说明为:
|
|
56
|
-
|
|
57
|
-
```ts
|
|
58
|
-
export interface SDKInitOptions {
|
|
59
|
-
/** 自定义接口地址(可选)。不传则使用默认正式环境 */
|
|
60
|
-
baseURL?: string;
|
|
61
|
-
appId?: string; // 可选:回调校验用,SDK方提供
|
|
62
|
-
notifyUrl?: string; // 可选:SDK 初始化鉴权成功后的服务端回调地址
|
|
63
|
-
/** 本地存储 Key 前缀,避免冲突 */
|
|
64
|
-
storageKeyPrefix?: string;
|
|
65
|
-
/** 自定义用户信息(可选) */
|
|
66
|
-
customUser?: TelegramUserInfo;
|
|
67
|
-
/** 可选:TON Connect manifest 文件地址,规则请看5.1.0;未传则使用默认测试清单 */
|
|
68
|
-
tonConnectManifestUrl?: string;
|
|
69
|
-
}
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
- baseURL(可选)
|
|
73
|
-
- 说明:后端服务地址;不传则使用 SDK 内置默认地址。
|
|
74
|
-
- 类型:`string`
|
|
75
|
-
- appId (可选)
|
|
76
|
-
- 说明:服务器之间用来鉴权,SDK方提供
|
|
77
|
-
- 类型:`string`
|
|
78
|
-
- notifyUrl (可选)
|
|
79
|
-
- 说明:SDK方服务器回调参数
|
|
80
|
-
- 类型:`string`
|
|
81
|
-
- storageKeyPrefix(可选)
|
|
82
|
-
- 说明:本地缓存命名空间前缀;用于隔离不同项目的存储键。
|
|
83
|
-
- 类型:`string`
|
|
84
|
-
- customUser(可选)
|
|
85
|
-
- 说明:自定义用户数据,仅在非 Telegram 环境可用;若不传,SDK 会自动使用“匿名浏览器用户”(基于 Cookie 生成并持久化随机 userId),从而可以直接完成鉴权与后续请求。
|
|
86
|
-
- 类型:`TelegramUserInfo`
|
|
87
|
-
- tonConnectManifestUrl(可选)
|
|
88
|
-
- 说明:TON Connect manifest 文件地址。若不传,SDK 使用默认测试清单:`https://miniapp.spinfi.me/tonconnect-manifest.json`。当小程序部署后需要改为对应链接,具体见`5.1.0`说明
|
|
89
|
-
- 类型:`string`
|
|
90
|
-
- 返回值:`Promise<void>`。
|
|
91
|
-
|
|
92
|
-
### 2.1 初始化成功通知调用说明(服务端回调)
|
|
93
|
-
|
|
94
|
-
- 触发时机:当 SDK 调用 `init()` 完成鉴权后,服务端会读取鉴权请求体中的 `notifyUrl`,并向该地址发起一次通知,上报获取到的用户信息。
|
|
95
|
-
- 通知参数:可能是 JSON 对象或一个加密后的字符串。
|
|
96
|
-
- JSON 示例:
|
|
97
|
-
|
|
98
|
-
```json
|
|
99
|
-
{
|
|
100
|
-
"user": {
|
|
101
|
-
"id": 7506466780,
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"username": "nickname1992",
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
"
|
|
108
|
-
"
|
|
109
|
-
},
|
|
110
|
-
"
|
|
111
|
-
"hash": "a9d2d7c1b066bebb73c170006dc474061d7601183b388b037936aa7cb6620acf",
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
"
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
- 若为加密字符串:请与服务端约定解密方式及签名校验流程。
|
|
119
|
-
|
|
120
|
-
### 2.2 环境
|
|
121
|
-
|
|
122
|
-
- Telegram 环境
|
|
123
|
-
- SDK 自动读取当前Telegram用户的信息。
|
|
124
|
-
- 无需传入 `customUser`;若 Telegram 用户读取失败,SDK 会抛错提示。
|
|
125
|
-
- 浏览器环境(非 Telegram)
|
|
126
|
-
- 默认行为:若未传 `customUser`,SDK 会使用“匿名浏览器用户”:
|
|
127
|
-
- 首次访问生成随机 `userId`,存入 Cookie(如 `tg_tracking_uid`),后续复用。
|
|
128
|
-
- 便于无登录状态下完成鉴权,拿到 token 后再进行广告或调试。
|
|
129
|
-
- 自定义用户:也可传入 `customUser` 替代匿名用户。
|
|
130
|
-
|
|
131
|
-
### 2.3 环境判断
|
|
132
|
-
|
|
133
|
-
- 接口: isTelegramEnv()
|
|
134
|
-
|
|
135
|
-
```ts
|
|
136
|
-
import { isTelegramEnv } from "hm-tracking-sdk";
|
|
137
|
-
|
|
138
|
-
if (isTelegramEnv()) {
|
|
139
|
-
// Telegram WebApp 环境
|
|
140
|
-
} else {
|
|
141
|
-
// 浏览器/其他环境
|
|
142
|
-
}
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
- 函数说明:判断是否是Telegram环境。
|
|
146
|
-
- 返回值:`boolean`。
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## 3. 获取Telegram用户信息
|
|
151
|
-
|
|
152
|
-
- 接口: getTelegramUserUnsafe()
|
|
153
|
-
|
|
154
|
-
```ts
|
|
155
|
-
import { getTelegramUserUnsafe, type TelegramUserInfo } from "hm-tracking-sdk";
|
|
156
|
-
|
|
157
|
-
const user: TelegramUserInfo | null = getTelegramUserUnsafe();
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
- 函数说明:在 Telegram 环境下返回 `TelegramUserInfo`;获取失败返回 `null`。
|
|
161
|
-
- 返回值:`TelegramUserInfo | null`,数据结构为:
|
|
162
|
-
|
|
163
|
-
```ts
|
|
164
|
-
export interface TelegramUserInfo {
|
|
165
|
-
user: {
|
|
166
|
-
id: number;
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
username?: string;
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
hash?: string;
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
[key: string]: unknown;
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
- 环境要求:仅 Telegram WebApp 可用;在浏览器环境(非 Telegram)将返回 `null`。
|
|
185
|
-
|
|
186
|
-
---
|
|
187
|
-
|
|
188
|
-
## 4. 广告业务
|
|
189
|
-
|
|
190
|
-
### 4.1 展示广告
|
|
191
|
-
|
|
192
|
-
- 接口: showHmAdByPosition()
|
|
193
|
-
|
|
194
|
-
```ts
|
|
195
|
-
await sdk.showHmAdByPosition(adPositionName, {
|
|
196
|
-
onSuccess: (result) => {
|
|
197
|
-
console.log("广告观看完成", result);
|
|
198
|
-
},
|
|
199
|
-
onError: (error) => {
|
|
200
|
-
console.error("广告展示失败:", error);
|
|
201
|
-
},
|
|
202
|
-
});
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
- 函数说明:根据广告位名称展示广告。
|
|
206
|
-
- 参数说明
|
|
207
|
-
- adPositionName(必填)
|
|
208
|
-
- 说明:广告位名称,需要根据业务进行申请,具体请联系SDK开发者,使用示例值进行测试。
|
|
209
|
-
- 类型:`string`
|
|
210
|
-
- 示例值:
|
|
211
|
-
- `game_rewarded_ad_position`
|
|
212
|
-
- callbacks
|
|
213
|
-
- 说明:广告展示成功/失败的回调。
|
|
214
|
-
- 类型:
|
|
215
|
-
|
|
216
|
-
```ts
|
|
217
|
-
interface AdCallbacks {
|
|
218
|
-
onSuccess?: (result?: unknown) => void | Promise<void>;
|
|
219
|
-
onError?: (error: unknown) => void | Promise<void>;
|
|
220
|
-
}
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
- 返回值:`Promise<void>`。失败时抛出异常;如提供 `callbacks`,会触发 `onError`。
|
|
224
|
-
|
|
225
|
-
说明:SDK 会根据根据广告位名称获取相关广告配置并完成展示。
|
|
226
|
-
|
|
227
|
-
---
|
|
228
|
-
|
|
229
|
-
## 5. 支付业务
|
|
230
|
-
|
|
231
|
-
支付仅支持在 Telegram WebApp 内使用。
|
|
232
|
-
|
|
233
|
-
### 5.1 TON钱包相关API
|
|
234
|
-
|
|
235
|
-
#### 5.1.0 配置 tonconnect-manifest
|
|
236
|
-
|
|
237
|
-
- 作用
|
|
238
|
-
- TON Connect 要求每个 dApp(小程序) 提供 `tonconnect-manifest.json`。钱包在连接前会读取该文件以展示 dApp 名称、图标,并校验来源。
|
|
239
|
-
- 托管与访问要求
|
|
240
|
-
- 将该 JSON 文件托管在公网可访问的 HTTPS 地址(建议:`https://your-domain.com/tonconnect-manifest.json`,放在站点根路径)。
|
|
241
|
-
- 文件及其中引用的资源(如图标)须可在任意来源公开访问,避免 CORS 限制。
|
|
242
|
-
- 必须能通过 GET 直接获取,无需鉴权或特殊请求头。
|
|
243
|
-
- `url` 字段请避免末尾斜杠,例如使用 `https://mydapp.com` 而非 `https://mydapp.com/`。
|
|
244
|
-
- 最小示例
|
|
245
|
-
|
|
246
|
-
```json
|
|
247
|
-
{
|
|
248
|
-
"url": "https://your-domain.com",
|
|
249
|
-
"name": "Your DApp Name",
|
|
250
|
-
"iconUrl": "https://your-domain.com/icons/tonconnect-icon.png"
|
|
251
|
-
}
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
- 字段要求
|
|
255
|
-
- `url`(必填):应用基础 URL,点击钱包内图标时用于打开应用;避免末尾斜杠。
|
|
256
|
-
- `name`(必填):应用名称。
|
|
257
|
-
- `iconUrl`(必填):应用图标 URL,仅支持 PNG 或 ICO,不支持 SVG;建议 180x180 PNG。
|
|
258
|
-
- `termsOfUseUrl`(可选):条款页 URL。
|
|
259
|
-
- `privacyPolicyUrl`(可选):隐私政策 URL。
|
|
260
|
-
- SDK 行为与配置
|
|
261
|
-
- 默认使用测试清单:`https://miniapp.spinfi.me/tonconnect-manifest.json`。
|
|
262
|
-
- 生产环境建议通过初始化参数传入:
|
|
263
|
-
|
|
264
|
-
```ts
|
|
265
|
-
const sdk = new HmTrackingSDK({
|
|
266
|
-
tonConnectManifestUrl: "https://your-domain.com/tonconnect-manifest.json",
|
|
267
|
-
// 其他可选项...
|
|
268
|
-
});
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
- 自检
|
|
272
|
-
- 在浏览器访问你的 manifest URL,确认返回 200 且 JSON 内容正确。
|
|
273
|
-
- 打开连接钱包弹窗,应显示你在 manifest 中配置的名称与图标。
|
|
274
|
-
|
|
275
|
-
#### 5.1.1 钱包是否链接
|
|
276
|
-
|
|
277
|
-
- 接口: isWalletConnected()
|
|
278
|
-
|
|
279
|
-
```ts
|
|
280
|
-
sdk.isWalletConnected(): boolean
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
- 函数说明:同步检查是否已连接 TON 钱包;
|
|
284
|
-
- 返回值:`boolean`。
|
|
285
|
-
|
|
286
|
-
#### 5.1.2 链接钱包
|
|
287
|
-
|
|
288
|
-
- 接口: connectWallet()
|
|
289
|
-
|
|
290
|
-
```ts
|
|
291
|
-
sdk.connectWallet(): Promise<boolean>
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
- 函数说明:发起连接 TON 钱包;
|
|
295
|
-
- 返回值:`Promise<boolean>` 表示是否连接成功。
|
|
296
|
-
|
|
297
|
-
#### 5.1.3 断开钱包链接
|
|
298
|
-
|
|
299
|
-
- 接口: disconnectWallet()
|
|
300
|
-
|
|
301
|
-
```ts
|
|
302
|
-
sdk.disconnectWallet(): Promise<boolean>
|
|
303
|
-
```
|
|
304
|
-
|
|
305
|
-
- 函数说明:断开已连接的钱包;
|
|
306
|
-
- 返回值:`Promise<boolean>`,true 表示已断开或原本未连接;false 表示断开失败。
|
|
307
|
-
|
|
308
|
-
### 5.2 支付
|
|
309
|
-
|
|
310
|
-
#### 5.2.1 获取支持的支付方式
|
|
311
|
-
|
|
312
|
-
- 接口: getSupportedPayModes()
|
|
313
|
-
|
|
314
|
-
```ts
|
|
315
|
-
sdk.getSupportedPayModes(): Promise<MerchantPayModeListData>
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
- 函数说明:获取当前支持的币种及汇率配置;
|
|
319
|
-
- 返回值说明:`Promise<MerchantPayModeListData>`,见下方类型定义。
|
|
320
|
-
|
|
321
|
-
```ts
|
|
322
|
-
interface MerchantPayModeListData {
|
|
323
|
-
payModeList: MerchantPayModeItem[];
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
interface MerchantPayModeItem {
|
|
327
|
-
id: number;
|
|
328
|
-
title: string;
|
|
329
|
-
name: string; // 币种: 'USDT' | 'TON' | 'STARS'
|
|
330
|
-
rate: number; // 汇率
|
|
331
|
-
nameDesc: string;
|
|
332
|
-
}
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
#### 5.2.2 创建并支付订单
|
|
336
|
-
|
|
337
|
-
- 接口: payByMerchant()
|
|
338
|
-
|
|
339
|
-
```ts
|
|
340
|
-
|
|
341
|
-
// 创建并支付订单
|
|
342
|
-
const params: MerchantPayCreateRequest = {
|
|
343
|
-
currencyName: "TON", // "TON" | "USDT" | "STARS"
|
|
344
|
-
amount: 10.5, // 支付金额
|
|
345
|
-
outTradeNo: `order_${Date.now()}`, // 自定义订单号
|
|
346
|
-
notifyUrl: "https://your-server.com/payment-callback",
|
|
347
|
-
attach: JSON.stringify({ userId: "123", itemId: "456" })
|
|
348
|
-
};
|
|
349
|
-
const result: MerchantPayFinishResponseData = await sdk.payByMerchant(params);
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
- 函数说明:创建支付订单并根据币种发起支付流程(STARS、TON/USDT 链上交易);
|
|
353
|
-
|
|
354
|
-
- 参数说明:
|
|
355
|
-
|
|
356
|
-
```ts
|
|
357
|
-
interface MerchantPayCreateRequest {
|
|
358
|
-
currencyName: string; // "USDT" | "TON" | "STARS"
|
|
359
|
-
amount: number; // 支付金额
|
|
360
|
-
outTradeNo: string; // 商户订单号
|
|
361
|
-
notifyUrl: string; // 服务端支付回调地址
|
|
362
|
-
attach: string; // 附加信息,通常使用 JSON.stringify
|
|
363
|
-
}
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
- 返回值数据结构:
|
|
367
|
-
|
|
368
|
-
```ts
|
|
369
|
-
export interface MerchantPayOrderBase {
|
|
370
|
-
orderSn: string;
|
|
371
|
-
transactionSn: string;
|
|
372
|
-
outTradeNo: string;
|
|
373
|
-
price: number | string;
|
|
374
|
-
count: number;
|
|
375
|
-
totalPrice: number | string;
|
|
376
|
-
currencyId: number;
|
|
377
|
-
currencyName: string;
|
|
378
|
-
currencyRate: number;
|
|
379
|
-
currencyAmount: number | string;
|
|
380
|
-
payUrl: string | null;
|
|
381
|
-
payExpireDatetime: string;
|
|
382
|
-
payDatetime: string | null;
|
|
383
|
-
finishDatetime: string | null;
|
|
384
|
-
description: string;
|
|
385
|
-
status: number;
|
|
386
|
-
statusDesc: string;
|
|
387
|
-
closeCode: string | null;
|
|
388
|
-
closeCodeDesc: string | null;
|
|
389
|
-
createDatetime: string;
|
|
390
|
-
updateDatetime: string;
|
|
391
|
-
transferHash: string | null;
|
|
392
|
-
transactionHash: string | null;
|
|
393
|
-
transactionLt: string | null;
|
|
394
|
-
}
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
```ts
|
|
398
|
-
// 支付完成回调返回的订单结果
|
|
399
|
-
type MerchantPayFinishResponseData = MerchantPayOrderBase;
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
#### 5.2.3 查询支付结果
|
|
403
|
-
|
|
404
|
-
- 接口: merchantPayQueryResult()
|
|
405
|
-
|
|
406
|
-
```ts
|
|
407
|
-
sdk.merchantPayQueryResult(data: MerchantPayQueryResultRequest): Promise<MerchantPayQueryResultResponseData>
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
- 函数说明:通过系统订单号 `orderSn` 或商户订单号 `outTradeNo` 查询订单最新结果;
|
|
411
|
-
- 参数说明:`MerchantPayQueryResultRequest`,见下方类型:
|
|
412
|
-
|
|
413
|
-
```ts
|
|
414
|
-
interface MerchantPayQueryResultRequest {
|
|
415
|
-
orderSn?: string;
|
|
416
|
-
outTradeNo?: string;
|
|
417
|
-
}
|
|
418
|
-
```
|
|
419
|
-
|
|
420
|
-
- 返回值说明:`Promise<MerchantPayQueryResultResponseData>`,同 `MerchantPayOrderBase`。
|
|
421
|
-
|
|
422
|
-
```ts
|
|
423
|
-
type MerchantPayQueryResultResponseData = MerchantPayOrderBase;
|
|
424
|
-
```
|
|
425
|
-
|
|
426
|
-
#### 5.2.4 支付结果通知(服务端回调)
|
|
427
|
-
|
|
428
|
-
- 说明:当你的服务接收 `notifyUrl` 的支付结果通知时,应返回统一响应结构,以便平台确认处理状态。
|
|
429
|
-
- 返回值示例:
|
|
430
|
-
|
|
431
|
-
```json
|
|
432
|
-
{
|
|
433
|
-
"code": 1,
|
|
434
|
-
"msg": "通知支付结果成功",
|
|
435
|
-
"timestamp": 1756442387,
|
|
436
|
-
"datetime": "2025-08-29T04:39:47.518Z",
|
|
437
|
-
"data": {}
|
|
438
|
-
}
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
- 约定说明:
|
|
442
|
-
- **code**: 1 表示成功;非 1 表示失败
|
|
443
|
-
- **msg**: 描述信息
|
|
444
|
-
- **timestamp/datetime**: 服务端时间
|
|
445
|
-
- **data**: 业务扩展字段(本例为空对象)
|
|
446
|
-
|
|
447
|
-
---
|
|
448
|
-
|
|
449
|
-
|
|
1
|
+
# HM Tracking SDK 使用文档
|
|
2
|
+
|
|
3
|
+
本文档详细介绍如何使用 HM Tracking SDK,包括初始化、广告业务和支付业务的完整流程。
|
|
4
|
+
|
|
5
|
+
## 1. 安装
|
|
6
|
+
|
|
7
|
+
### 建议通过 npm/yarn 安装正式发布的包:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# 使用 yarn
|
|
11
|
+
yarn add hm-tracking-sdk axios crypto-js
|
|
12
|
+
|
|
13
|
+
# 或使用 npm
|
|
14
|
+
npm i hm-tracking-sdk axios crypto-js
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 2. SDK 初始化
|
|
20
|
+
|
|
21
|
+
- 接口: init()
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { HmTrackingSDK, type SDKInitOptions } from "hm-tracking-sdk";
|
|
25
|
+
|
|
26
|
+
const options: SDKInitOptions = {
|
|
27
|
+
// 可选:不传则使用内置默认地址
|
|
28
|
+
baseURL: "https://your-api.example.com",
|
|
29
|
+
// 可选:回调校验用,SDK方会提供
|
|
30
|
+
appId: "app-xxxxxxx",
|
|
31
|
+
|
|
32
|
+
// 可选:本地存储 Key 前缀,避免项目间冲突
|
|
33
|
+
storageKeyPrefix: "your_app_prefix",
|
|
34
|
+
|
|
35
|
+
// 可选:浏览器环境下使用,可显式传入自定义用户
|
|
36
|
+
customUser: {
|
|
37
|
+
user: {
|
|
38
|
+
id: 123456789,
|
|
39
|
+
firstName: "Test",
|
|
40
|
+
lastName: "User",
|
|
41
|
+
username: "test_user",
|
|
42
|
+
languageCode: "zh-hans",
|
|
43
|
+
photoUrl: "https://t.me/i/userpic/320/example.svg",
|
|
44
|
+
},
|
|
45
|
+
authDate: Math.floor(Date.now() / 1000),
|
|
46
|
+
hash: "your_hash_value",
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const sdk = new HmTrackingSDK(options);
|
|
51
|
+
await sdk.init();
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- 函数说明:初始化 SDK,先创建 HmTrackingSDK 对象,然后调用 init 方法完成初始化。
|
|
55
|
+
- 参数说明: `SDKInitOptions` 初始化SDK时的可选参数,数据结构及内部结构说明为:
|
|
56
|
+
|
|
57
|
+
```ts
|
|
58
|
+
export interface SDKInitOptions {
|
|
59
|
+
/** 自定义接口地址(可选)。不传则使用默认正式环境 */
|
|
60
|
+
baseURL?: string;
|
|
61
|
+
appId?: string; // 可选:回调校验用,SDK方提供
|
|
62
|
+
notifyUrl?: string; // 可选:SDK 初始化鉴权成功后的服务端回调地址
|
|
63
|
+
/** 本地存储 Key 前缀,避免冲突 */
|
|
64
|
+
storageKeyPrefix?: string;
|
|
65
|
+
/** 自定义用户信息(可选) */
|
|
66
|
+
customUser?: TelegramUserInfo;
|
|
67
|
+
/** 可选:TON Connect manifest 文件地址,规则请看5.1.0;未传则使用默认测试清单 */
|
|
68
|
+
tonConnectManifestUrl?: string;
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
- baseURL(可选)
|
|
73
|
+
- 说明:后端服务地址;不传则使用 SDK 内置默认地址。
|
|
74
|
+
- 类型:`string`
|
|
75
|
+
- appId (可选)
|
|
76
|
+
- 说明:服务器之间用来鉴权,SDK方提供
|
|
77
|
+
- 类型:`string`
|
|
78
|
+
- notifyUrl (可选)
|
|
79
|
+
- 说明:SDK方服务器回调参数
|
|
80
|
+
- 类型:`string`
|
|
81
|
+
- storageKeyPrefix(可选)
|
|
82
|
+
- 说明:本地缓存命名空间前缀;用于隔离不同项目的存储键。
|
|
83
|
+
- 类型:`string`
|
|
84
|
+
- customUser(可选)
|
|
85
|
+
- 说明:自定义用户数据,仅在非 Telegram 环境可用;若不传,SDK 会自动使用“匿名浏览器用户”(基于 Cookie 生成并持久化随机 userId),从而可以直接完成鉴权与后续请求。
|
|
86
|
+
- 类型:`TelegramUserInfo`
|
|
87
|
+
- tonConnectManifestUrl(可选)
|
|
88
|
+
- 说明:TON Connect manifest 文件地址。若不传,SDK 使用默认测试清单:`https://miniapp.spinfi.me/tonconnect-manifest.json`。当小程序部署后需要改为对应链接,具体见`5.1.0`说明
|
|
89
|
+
- 类型:`string`
|
|
90
|
+
- 返回值:`Promise<void>`。
|
|
91
|
+
|
|
92
|
+
### 2.1 初始化成功通知调用说明(服务端回调)
|
|
93
|
+
|
|
94
|
+
- 触发时机:当 SDK 调用 `init()` 完成鉴权后,服务端会读取鉴权请求体中的 `notifyUrl`,并向该地址发起一次通知,上报获取到的用户信息。
|
|
95
|
+
- 通知参数:可能是 JSON 对象或一个加密后的字符串。
|
|
96
|
+
- JSON 示例:
|
|
97
|
+
|
|
98
|
+
```json
|
|
99
|
+
{
|
|
100
|
+
"user": {
|
|
101
|
+
"id": 7506466780,
|
|
102
|
+
"firstName": "first",
|
|
103
|
+
"lastName": "name",
|
|
104
|
+
"username": "nickname1992",
|
|
105
|
+
"languageCode": "zh",
|
|
106
|
+
"allowsWriteToPm": true,
|
|
107
|
+
"isPremium": false,
|
|
108
|
+
"photoUrl": "https://t.me/i/userpic/320/uLzA4KyVzKwd0vi6Uvupe6U2mdnVEQOIbUZbFTQff6B3UhjRpQObL9I8Nq81G0ln.svg"
|
|
109
|
+
},
|
|
110
|
+
"authDate": 1735792133,
|
|
111
|
+
"hash": "a9d2d7c1b066bebb73c170006dc474061d7601183b388b037936aa7cb6620acf",
|
|
112
|
+
"chatInstance": "-2254244616056098321",
|
|
113
|
+
"chatType": "sender",
|
|
114
|
+
"startParam": "..."
|
|
115
|
+
}
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- 若为加密字符串:请与服务端约定解密方式及签名校验流程。
|
|
119
|
+
|
|
120
|
+
### 2.2 环境
|
|
121
|
+
|
|
122
|
+
- Telegram 环境
|
|
123
|
+
- SDK 自动读取当前Telegram用户的信息。
|
|
124
|
+
- 无需传入 `customUser`;若 Telegram 用户读取失败,SDK 会抛错提示。
|
|
125
|
+
- 浏览器环境(非 Telegram)
|
|
126
|
+
- 默认行为:若未传 `customUser`,SDK 会使用“匿名浏览器用户”:
|
|
127
|
+
- 首次访问生成随机 `userId`,存入 Cookie(如 `tg_tracking_uid`),后续复用。
|
|
128
|
+
- 便于无登录状态下完成鉴权,拿到 token 后再进行广告或调试。
|
|
129
|
+
- 自定义用户:也可传入 `customUser` 替代匿名用户。
|
|
130
|
+
|
|
131
|
+
### 2.3 环境判断
|
|
132
|
+
|
|
133
|
+
- 接口: isTelegramEnv()
|
|
134
|
+
|
|
135
|
+
```ts
|
|
136
|
+
import { isTelegramEnv } from "hm-tracking-sdk";
|
|
137
|
+
|
|
138
|
+
if (isTelegramEnv()) {
|
|
139
|
+
// Telegram WebApp 环境
|
|
140
|
+
} else {
|
|
141
|
+
// 浏览器/其他环境
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
- 函数说明:判断是否是Telegram环境。
|
|
146
|
+
- 返回值:`boolean`。
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## 3. 获取Telegram用户信息
|
|
151
|
+
|
|
152
|
+
- 接口: getTelegramUserUnsafe()
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
import { getTelegramUserUnsafe, type TelegramUserInfo } from "hm-tracking-sdk";
|
|
156
|
+
|
|
157
|
+
const user: TelegramUserInfo | null = getTelegramUserUnsafe();
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
- 函数说明:在 Telegram 环境下返回 `TelegramUserInfo`;获取失败返回 `null`。
|
|
161
|
+
- 返回值:`TelegramUserInfo | null`,数据结构为:
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
export interface TelegramUserInfo {
|
|
165
|
+
user: {
|
|
166
|
+
id: number;
|
|
167
|
+
firstName?: string;
|
|
168
|
+
lastName?: string;
|
|
169
|
+
username?: string;
|
|
170
|
+
photoUrl?: string;
|
|
171
|
+
languageCode?: string;
|
|
172
|
+
allowsWriteToPm?: boolean;
|
|
173
|
+
isPremium?: boolean;
|
|
174
|
+
};
|
|
175
|
+
authDate?: number;
|
|
176
|
+
hash?: string;
|
|
177
|
+
startParam?: string;
|
|
178
|
+
chatType?: string;
|
|
179
|
+
chatInstance?: string;
|
|
180
|
+
[key: string]: unknown;
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
- 环境要求:仅 Telegram WebApp 可用;在浏览器环境(非 Telegram)将返回 `null`。
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 4. 广告业务
|
|
189
|
+
|
|
190
|
+
### 4.1 展示广告
|
|
191
|
+
|
|
192
|
+
- 接口: showHmAdByPosition()
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
await sdk.showHmAdByPosition(adPositionName, {
|
|
196
|
+
onSuccess: (result) => {
|
|
197
|
+
console.log("广告观看完成", result);
|
|
198
|
+
},
|
|
199
|
+
onError: (error) => {
|
|
200
|
+
console.error("广告展示失败:", error);
|
|
201
|
+
},
|
|
202
|
+
});
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
- 函数说明:根据广告位名称展示广告。
|
|
206
|
+
- 参数说明
|
|
207
|
+
- adPositionName(必填)
|
|
208
|
+
- 说明:广告位名称,需要根据业务进行申请,具体请联系SDK开发者,使用示例值进行测试。
|
|
209
|
+
- 类型:`string`
|
|
210
|
+
- 示例值:
|
|
211
|
+
- `game_rewarded_ad_position`
|
|
212
|
+
- callbacks
|
|
213
|
+
- 说明:广告展示成功/失败的回调。
|
|
214
|
+
- 类型:
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
interface AdCallbacks {
|
|
218
|
+
onSuccess?: (result?: unknown) => void | Promise<void>;
|
|
219
|
+
onError?: (error: unknown) => void | Promise<void>;
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
- 返回值:`Promise<void>`。失败时抛出异常;如提供 `callbacks`,会触发 `onError`。
|
|
224
|
+
|
|
225
|
+
说明:SDK 会根据根据广告位名称获取相关广告配置并完成展示。
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## 5. 支付业务
|
|
230
|
+
|
|
231
|
+
支付仅支持在 Telegram WebApp 内使用。
|
|
232
|
+
|
|
233
|
+
### 5.1 TON钱包相关API
|
|
234
|
+
|
|
235
|
+
#### 5.1.0 配置 tonconnect-manifest
|
|
236
|
+
|
|
237
|
+
- 作用
|
|
238
|
+
- TON Connect 要求每个 dApp(小程序) 提供 `tonconnect-manifest.json`。钱包在连接前会读取该文件以展示 dApp 名称、图标,并校验来源。
|
|
239
|
+
- 托管与访问要求
|
|
240
|
+
- 将该 JSON 文件托管在公网可访问的 HTTPS 地址(建议:`https://your-domain.com/tonconnect-manifest.json`,放在站点根路径)。
|
|
241
|
+
- 文件及其中引用的资源(如图标)须可在任意来源公开访问,避免 CORS 限制。
|
|
242
|
+
- 必须能通过 GET 直接获取,无需鉴权或特殊请求头。
|
|
243
|
+
- `url` 字段请避免末尾斜杠,例如使用 `https://mydapp.com` 而非 `https://mydapp.com/`。
|
|
244
|
+
- 最小示例
|
|
245
|
+
|
|
246
|
+
```json
|
|
247
|
+
{
|
|
248
|
+
"url": "https://your-domain.com",
|
|
249
|
+
"name": "Your DApp Name",
|
|
250
|
+
"iconUrl": "https://your-domain.com/icons/tonconnect-icon.png"
|
|
251
|
+
}
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
- 字段要求
|
|
255
|
+
- `url`(必填):应用基础 URL,点击钱包内图标时用于打开应用;避免末尾斜杠。
|
|
256
|
+
- `name`(必填):应用名称。
|
|
257
|
+
- `iconUrl`(必填):应用图标 URL,仅支持 PNG 或 ICO,不支持 SVG;建议 180x180 PNG。
|
|
258
|
+
- `termsOfUseUrl`(可选):条款页 URL。
|
|
259
|
+
- `privacyPolicyUrl`(可选):隐私政策 URL。
|
|
260
|
+
- SDK 行为与配置
|
|
261
|
+
- 默认使用测试清单:`https://miniapp.spinfi.me/tonconnect-manifest.json`。
|
|
262
|
+
- 生产环境建议通过初始化参数传入:
|
|
263
|
+
|
|
264
|
+
```ts
|
|
265
|
+
const sdk = new HmTrackingSDK({
|
|
266
|
+
tonConnectManifestUrl: "https://your-domain.com/tonconnect-manifest.json",
|
|
267
|
+
// 其他可选项...
|
|
268
|
+
});
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
- 自检
|
|
272
|
+
- 在浏览器访问你的 manifest URL,确认返回 200 且 JSON 内容正确。
|
|
273
|
+
- 打开连接钱包弹窗,应显示你在 manifest 中配置的名称与图标。
|
|
274
|
+
|
|
275
|
+
#### 5.1.1 钱包是否链接
|
|
276
|
+
|
|
277
|
+
- 接口: isWalletConnected()
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
sdk.isWalletConnected(): boolean
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
- 函数说明:同步检查是否已连接 TON 钱包;
|
|
284
|
+
- 返回值:`boolean`。
|
|
285
|
+
|
|
286
|
+
#### 5.1.2 链接钱包
|
|
287
|
+
|
|
288
|
+
- 接口: connectWallet()
|
|
289
|
+
|
|
290
|
+
```ts
|
|
291
|
+
sdk.connectWallet(): Promise<boolean>
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
- 函数说明:发起连接 TON 钱包;
|
|
295
|
+
- 返回值:`Promise<boolean>` 表示是否连接成功。
|
|
296
|
+
|
|
297
|
+
#### 5.1.3 断开钱包链接
|
|
298
|
+
|
|
299
|
+
- 接口: disconnectWallet()
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
sdk.disconnectWallet(): Promise<boolean>
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
- 函数说明:断开已连接的钱包;
|
|
306
|
+
- 返回值:`Promise<boolean>`,true 表示已断开或原本未连接;false 表示断开失败。
|
|
307
|
+
|
|
308
|
+
### 5.2 支付
|
|
309
|
+
|
|
310
|
+
#### 5.2.1 获取支持的支付方式
|
|
311
|
+
|
|
312
|
+
- 接口: getSupportedPayModes()
|
|
313
|
+
|
|
314
|
+
```ts
|
|
315
|
+
sdk.getSupportedPayModes(): Promise<MerchantPayModeListData>
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
- 函数说明:获取当前支持的币种及汇率配置;
|
|
319
|
+
- 返回值说明:`Promise<MerchantPayModeListData>`,见下方类型定义。
|
|
320
|
+
|
|
321
|
+
```ts
|
|
322
|
+
interface MerchantPayModeListData {
|
|
323
|
+
payModeList: MerchantPayModeItem[];
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
interface MerchantPayModeItem {
|
|
327
|
+
id: number;
|
|
328
|
+
title: string;
|
|
329
|
+
name: string; // 币种: 'USDT' | 'TON' | 'STARS'
|
|
330
|
+
rate: number; // 汇率
|
|
331
|
+
nameDesc: string;
|
|
332
|
+
}
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
#### 5.2.2 创建并支付订单
|
|
336
|
+
|
|
337
|
+
- 接口: payByMerchant()
|
|
338
|
+
|
|
339
|
+
```ts
|
|
340
|
+
|
|
341
|
+
// 创建并支付订单
|
|
342
|
+
const params: MerchantPayCreateRequest = {
|
|
343
|
+
currencyName: "TON", // "TON" | "USDT" | "STARS"
|
|
344
|
+
amount: 10.5, // 支付金额
|
|
345
|
+
outTradeNo: `order_${Date.now()}`, // 自定义订单号
|
|
346
|
+
notifyUrl: "https://your-server.com/payment-callback",
|
|
347
|
+
attach: JSON.stringify({ userId: "123", itemId: "456" })
|
|
348
|
+
};
|
|
349
|
+
const result: MerchantPayFinishResponseData = await sdk.payByMerchant(params);
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
- 函数说明:创建支付订单并根据币种发起支付流程(STARS、TON/USDT 链上交易);
|
|
353
|
+
|
|
354
|
+
- 参数说明:
|
|
355
|
+
|
|
356
|
+
```ts
|
|
357
|
+
interface MerchantPayCreateRequest {
|
|
358
|
+
currencyName: string; // "USDT" | "TON" | "STARS"
|
|
359
|
+
amount: number; // 支付金额
|
|
360
|
+
outTradeNo: string; // 商户订单号
|
|
361
|
+
notifyUrl: string; // 服务端支付回调地址
|
|
362
|
+
attach: string; // 附加信息,通常使用 JSON.stringify
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
- 返回值数据结构:
|
|
367
|
+
|
|
368
|
+
```ts
|
|
369
|
+
export interface MerchantPayOrderBase {
|
|
370
|
+
orderSn: string;
|
|
371
|
+
transactionSn: string;
|
|
372
|
+
outTradeNo: string;
|
|
373
|
+
price: number | string;
|
|
374
|
+
count: number;
|
|
375
|
+
totalPrice: number | string;
|
|
376
|
+
currencyId: number;
|
|
377
|
+
currencyName: string;
|
|
378
|
+
currencyRate: number;
|
|
379
|
+
currencyAmount: number | string;
|
|
380
|
+
payUrl: string | null;
|
|
381
|
+
payExpireDatetime: string;
|
|
382
|
+
payDatetime: string | null;
|
|
383
|
+
finishDatetime: string | null;
|
|
384
|
+
description: string;
|
|
385
|
+
status: number;
|
|
386
|
+
statusDesc: string;
|
|
387
|
+
closeCode: string | null;
|
|
388
|
+
closeCodeDesc: string | null;
|
|
389
|
+
createDatetime: string;
|
|
390
|
+
updateDatetime: string;
|
|
391
|
+
transferHash: string | null;
|
|
392
|
+
transactionHash: string | null;
|
|
393
|
+
transactionLt: string | null;
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
```ts
|
|
398
|
+
// 支付完成回调返回的订单结果
|
|
399
|
+
type MerchantPayFinishResponseData = MerchantPayOrderBase;
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
#### 5.2.3 查询支付结果
|
|
403
|
+
|
|
404
|
+
- 接口: merchantPayQueryResult()
|
|
405
|
+
|
|
406
|
+
```ts
|
|
407
|
+
sdk.merchantPayQueryResult(data: MerchantPayQueryResultRequest): Promise<MerchantPayQueryResultResponseData>
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
- 函数说明:通过系统订单号 `orderSn` 或商户订单号 `outTradeNo` 查询订单最新结果;
|
|
411
|
+
- 参数说明:`MerchantPayQueryResultRequest`,见下方类型:
|
|
412
|
+
|
|
413
|
+
```ts
|
|
414
|
+
interface MerchantPayQueryResultRequest {
|
|
415
|
+
orderSn?: string;
|
|
416
|
+
outTradeNo?: string;
|
|
417
|
+
}
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
- 返回值说明:`Promise<MerchantPayQueryResultResponseData>`,同 `MerchantPayOrderBase`。
|
|
421
|
+
|
|
422
|
+
```ts
|
|
423
|
+
type MerchantPayQueryResultResponseData = MerchantPayOrderBase;
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
#### 5.2.4 支付结果通知(服务端回调)
|
|
427
|
+
|
|
428
|
+
- 说明:当你的服务接收 `notifyUrl` 的支付结果通知时,应返回统一响应结构,以便平台确认处理状态。
|
|
429
|
+
- 返回值示例:
|
|
430
|
+
|
|
431
|
+
```json
|
|
432
|
+
{
|
|
433
|
+
"code": 1,
|
|
434
|
+
"msg": "通知支付结果成功",
|
|
435
|
+
"timestamp": 1756442387,
|
|
436
|
+
"datetime": "2025-08-29T04:39:47.518Z",
|
|
437
|
+
"data": {}
|
|
438
|
+
}
|
|
439
|
+
```
|
|
440
|
+
|
|
441
|
+
- 约定说明:
|
|
442
|
+
- **code**: 1 表示成功;非 1 表示失败
|
|
443
|
+
- **msg**: 描述信息
|
|
444
|
+
- **timestamp/datetime**: 服务端时间
|
|
445
|
+
- **data**: 业务扩展字段(本例为空对象)
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
|