Gramix API v1
Hãy dùng hướng dẫn này làm hợp đồng giao tiếp khi phát triển tích hợp phía máy chủ.
Thông tin chung
API công khai cho phép xem số dư, nạp tiền vào ví và mua Telegram Stars, Telegram Premium cũng như GRAM.
Base URL
https://api.gramix.io/api/v1Định dạng dữ liệu
- Nội dung yêu cầu và phản hồi API đều sử dụng application/json.
- Giá trị tiền tệ được truyền dưới dạng chuỗi với bốn chữ số thập phân. Để tính toán chính xác, hãy dùng kiểu decimal hoặc lưu giá trị dưới dạng chuỗi.
- Thời gian trong webhook được truyền theo định dạng ISO 8601. Không nên phụ thuộc vào các trường JSON không được mô tả.
Danh sách phương thức
| Phương thức | Endpoint | Mục đích | Mã HTTP |
|---|---|---|---|
GET | /api/v1/wallets/balance | Trả về số dư hiện tại. | 200 |
POST | /api/v1/wallets/balance | Tạo hoặc trả về address và memo để nạp tiền trên mạng TON. | 201 |
POST | /api/v1/purchase/stars | Mua từ 50 đến 1.000.000 Telegram Stars cho Telegram username đã chỉ định. | 201 |
POST | /api/v1/purchase/premium/{duration} | Mua Telegram Premium trong 3, 6 hoặc 12 tháng. | 201 |
POST | /api/v1/purchase/gram | Mua và gửi từ 1 đến 10.000 GRAM cho người nhận Telegram đã chỉ định. | 201 |
Xác thực
Mọi phương thức đều yêu cầu khóa API đang hoạt động, được truyền qua HTTP header x-api-key.
x-api-key: YOUR_API_KEYVí dụ yêu cầu
curl --request GET 'https://api.gramix.io/api/v1/wallets/balance' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Accept: application/json'Nếu thiếu header, hoặc khóa không hợp lệ, đã bị thu hồi hay không hoạt động, API sẽ trả về 401 Unauthorized.
Định dạng phản hồi chung
Phản hồi thành công
Phản hồi thành công chứa statusCode và data. Với yêu cầu POST, API trả về mã HTTP 201.
{
"statusCode": 200,
"data": {}
}Phản hồi lỗi
Phản hồi lỗi chứa statusCode và message dễ đọc. Logic phía máy khách nên dựa trước hết vào mã trạng thái HTTP.
{
"statusCode": 400,
"message": "Idempotency-Key header is required"
}Lỗi thường gặp
| Mã HTTP | message |
|---|---|
400 | Bad Request |
401 | Unauthorized |
403 | Insufficient balance |
404 | Not Found |
405 | Method Not Allowed |
500 | Internal server error |
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"statusCode": 401,
"message": "Unauthorized"
}HTTP/1.1 403 Forbidden
Content-Type: application/json
{
"statusCode": 403,
"message": "Insufficient balance"
}Schema dùng chung
PaymentCurrency
paymentCurrency xác định số dư dùng để thanh toán giao dịch. Chỉ chấp nhận gram và usdt viết thường.
type PaymentCurrency = "gram" | "usdt";RecipientName
recipientName là Telegram username của người nhận, không bao gồm @. Độ dài từ 5 đến 32 ký tự; chỉ cho phép chữ Latin viết thường, chữ số và _.
durov
user_123
telegram_user@durov
User123
1username
user-name
abcPurchaseRequestBase
{
"recipientName": "telegram_user",
"paymentCurrency": "usdt"
}PurchaseResponse
Mọi phương thức mua đều trả về orderId, status và idempotencyKey. Đơn hàng mới thường có trạng thái processing.
{
"statusCode": 201,
"data": {
"orderId": "7ba77616-7706-4215-9e6f-b6c67e4df292",
"status": "processing",
"idempotencyKey": "order_20260713_0001"
}
}type OrderStatus = "created" | "processing" | "completed" | "failed" | "canceled";Tính lũy đẳng của giao dịch mua
Mọi phương thức /purchase/* đều yêu cầu header idempotency-key dài từ 8 đến 64 ký tự.
idempotency-key: UNIQUE_REQUEST_KEY- Cho phép chữ Latin, chữ số, _ và -. Khóa phải là duy nhất trong phạm vi một khóa API.
- Khi xảy ra lỗi mạng, hãy gửi lại chính yêu cầu đó với cùng một khóa. Hãy dùng khóa mới cho mỗi giao dịch mua mới.
order_20260713_0001
01J2Y5VN7CV8ZQ7DPZ9J0P6E4M
client-req-12345678Lỗi có thể xảy ra
{
"statusCode": 400,
"message": "Idempotency-Key header is required"
}{
"statusCode": 400,
"message": "Idempotency-Key must be between 8 and 64 characters"
}{
"statusCode": 400,
"message": "Idempotency-Key contains invalid characters"
}Ví
GET /api/v1/wallets/balance
Trả về số dư hiện tại.
| Header | Bắt buộc | Mô tả |
|---|---|---|
x-api-key | có | Xác thực |
Accept | không | application/json |
Ví dụ yêu cầu
curl --request GET 'https://api.gramix.io/api/v1/wallets/balance' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Accept: application/json'{
"statusCode": 200,
"data": {
"gram": "14.2500",
"usdt": "125.5000"
}
}POST /api/v1/wallets/balance
Tạo hoặc trả về address và memo để nạp tiền trên mạng TON.
| Header | Bắt buộc | Mô tả |
|---|---|---|
x-api-key | có | Xác thực |
Accept | không | application/json |
curl --request POST 'https://api.gramix.io/api/v1/wallets/balance' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Accept: application/json'{
"statusCode": 201,
"data": {
"address": "UQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
"memo": "a1b2c3d4e5f6g7h8"
}
}Việc ghi có được thực hiện bất đồng bộ. GRAM được ghi vào gram, còn USDT trên mạng TON được ghi vào usdt.
Quy trình nạp tiền được khuyến nghị
POST /wallets/balance- Bắt buộc truyền memo trong phần bình luận giao dịch hoặc forward payload. Nếu thiếu memo, giao dịch chuyển tiền sẽ không được ghi có tự động.
GET /wallets/balance
Giao dịch mua
Giao dịch mua được xử lý bất đồng bộ. API kiểm tra yêu cầu và số dư, tạo đơn hàng, trừ tiền rồi trả về orderId với trạng thái processing.
Khi đơn hàng chuyển sang trạng thái failed, số tiền đã trừ sẽ được hoàn lại vào đúng số dư ban đầu.
POST /api/v1/purchase/stars
Mua từ 50 đến 1.000.000 Telegram Stars cho Telegram username đã chỉ định.
| Header | Bắt buộc | Mô tả |
|---|---|---|
x-api-key | có | Xác thực |
idempotency-key | có | 8–64 |
Accept | không | application/json |
Content-Type | có | application/json |
{
"recipientName": "telegram_user",
"paymentCurrency": "usdt",
"stars": 500
}curl --request POST 'https://api.gramix.io/api/v1/purchase/stars' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'idempotency-key: stars_20260713_0001' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"recipientName": "telegram_user",
"paymentCurrency": "usdt",
"stars": 500
}'{
"statusCode": 201,
"data": {
"orderId": "7ba77616-7706-4215-9e6f-b6c67e4df292",
"status": "processing",
"idempotencyKey": "stars_20260713_0001"
}
}POST /api/v1/purchase/premium/{duration}
Mua Telegram Premium trong 3, 6 hoặc 12 tháng.
| Header | Bắt buộc | Mô tả |
|---|---|---|
x-api-key | có | Xác thực |
idempotency-key | có | 8–64 |
Accept | không | application/json |
Content-Type | có | application/json |
{
"recipientName": "telegram_user",
"paymentCurrency": "gram"
}curl --request POST 'https://api.gramix.io/api/v1/purchase/premium/6' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'idempotency-key: premium_6_20260713_0001' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"recipientName": "telegram_user",
"paymentCurrency": "gram"
}'{
"statusCode": 201,
"data": {
"orderId": "18ca3cce-8441-4de6-874a-fd34792ae1b5",
"status": "processing",
"idempotencyKey": "premium_6_20260713_0001"
}
}{
"statusCode": 400,
"message": "Invalid premium duration. Allowed values: 3, 6, 12"
}POST /api/v1/purchase/gram
Mua và gửi từ 1 đến 10.000 GRAM cho người nhận Telegram đã chỉ định.
| Header | Bắt buộc | Mô tả |
|---|---|---|
x-api-key | có | Xác thực |
idempotency-key | có | 8–64 |
Accept | không | application/json |
Content-Type | có | application/json |
{
"recipientName": "telegram_user",
"paymentCurrency": "usdt",
"gram": 2.5
}curl --request POST 'https://api.gramix.io/api/v1/purchase/gram' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'idempotency-key: gram_20260713_0001' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"recipientName": "telegram_user",
"paymentCurrency": "usdt",
"gram": 2.5
}'{
"statusCode": 201,
"data": {
"orderId": "882dd8ca-5d68-4b85-bb26-c25ee38d9a98",
"status": "processing",
"idempotencyKey": "gram_20260713_0001"
}
}Webhook trạng thái đơn hàng
Nếu webhookUrl được cấu hình cho khóa API, API sẽ gửi yêu cầu POST sau khi đơn hàng xử lý xong.
POST {webhookUrl}
Content-Type: application/jsonĐơn hàng thành công gửi sự kiện order.completed; đơn hàng thất bại gửi order.failed.
{
"event": "order.completed",
"orderId": "7ba77616-7706-4215-9e6f-b6c67e4df292",
"status": "completed",
"processingStatus": "completed_fragment_purchase",
"type": "stars",
"amount": "7.6500",
"currency": "usd",
"recipientName": "telegram_user",
"createdAt": "2026-07-13T10:20:30.000Z"
}{
"event": "order.failed",
"orderId": "7ba77616-7706-4215-9e6f-b6c67e4df292",
"status": "failed",
"processingStatus": "failure_fragment_purchase",
"type": "stars",
"amount": "7.6500",
"currency": "usd",
"recipientName": "telegram_user",
"createdAt": "2026-07-13T10:20:30.000Z"
}Schema webhook
| Trường | Kiểu | Giới hạn |
|---|---|---|
event | string | order.completed | order.failed |
orderId | UUID | — |
status | string | completed | failed |
type | string | stars | gram | premium_* |
amount | decimal(4) | — |
currency | string | gram | usd |
recipientName | string | — |
createdAt | ISO 8601 | — |
Yêu cầu đối với trình xử lý webhook
Hãy phản hồi HTTP 2xx càng sớm càng tốt, xử lý sự kiện theo cách lũy đẳng và không phụ thuộc vào thứ tự phân phối.
Ví dụ đầy đủ về quy trình phía máy khách
- Kiểm tra số dư.
- Nếu cần, hãy lấy thông tin nạp tiền, nạp vào ví và chờ số dư thay đổi.
- Tạo giao dịch mua với idempotency-key duy nhất.
- Lưu orderId, status và idempotencyKey. Phản hồi 201 có nghĩa là đơn hàng đã được tiếp nhận để xử lý.
- Chờ order.completed hoặc order.failed và đối chiếu sự kiện theo orderId.
GET /api/v1/wallets/balance
x-api-key: YOUR_API_KEYPOST /api/v1/wallets/balance
x-api-key: YOUR_API_KEYPOST /api/v1/purchase/stars
x-api-key: YOUR_API_KEY
idempotency-key: order_20260713_0001
Content-Type: application/json
{
"recipientName": "telegram_user",
"paymentCurrency": "usdt",
"stars": 500
}Ví dụ máy khách TypeScript
type SuccessResponse<T> = {
statusCode: number;
data: T;
};
type ApiError = {
statusCode: number;
message: string;
};
type PurchaseResponse = {
orderId: string;
status: "created" | "processing" | "completed" | "failed" | "canceled";
idempotencyKey: string;
};
type WalletBalance = {
gram: string;
usdt: string;
};
const BASE_URL = "https://api.gramix.io";
async function apiRequest<T>(path: string, apiKey: string, init: RequestInit = {}): Promise<T> {
const response = await fetch(
`${BASE_URL}${path}`,
{
...init,
headers: {
Accept: "application/json",
"x-api-key": apiKey,
...(init.body ? { "Content-Type": "application/json" } : {}),
...init.headers,
},
},
);
const payload = (await response.json()) as SuccessResponse<T> | ApiError;
if (!response.ok) {
const error = payload as ApiError;
throw new Error(`[${error.statusCode}] ${error.message}`);
}
return (payload as SuccessResponse<T>).data;
}
export function getBalance(apiKey: string): Promise<WalletBalance> {
return apiRequest<WalletBalance>("/api/v1/wallets/balance", apiKey);
}
export function purchaseStars(
apiKey: string,
idempotencyKey: string,
input: {
recipientName: string;
paymentCurrency: "gram" | "usdt";
stars: number;
},
): Promise<PurchaseResponse> {
return apiRequest<PurchaseResponse>("/api/v1/purchase/stars", apiKey, {
method: "POST",
headers: { "idempotency-key": idempotencyKey },
body: JSON.stringify(input),
});
}Sẵn sàng bắt đầu tích hợp?
Tạo khóa API và cấu hình URL webhook.