跳到主要内容

推荐与返佣 (Referral & Rebates)

ZTDX 提供多层级的推荐激励计划,用户可以通过邀请新用户交易来获得返佣收益。推荐系统同时支持链下数据库链上智能合约两种模式,确保数据透明可查。

概述

推荐系统特性

  • 5级返佣制度:Bronze (10%) → Diamond (30%)
  • 自动等级升级:根据推荐人数自动提升返佣比例
  • 链上透明:所有数据可在区块链上查询验证
  • EIP-712 签名:创建和绑定推荐码需要钱包签名
  • 实时结算:每笔交易后立即计算返佣

等级体系

等级名称推荐人数返佣比例下一级要求
0Bronze0-910%10 人
1Silver10-4915%50 人
2Gold50-9920%100 人
3Platinum100-49925%500 人
4Diamond500+30%已达最高

创建推荐码

每个用户可以创建一个唯一的推荐码用于邀请其他用户。推荐码基于用户地址自动生成。

接口信息

  • Method: POST
  • Path: /api/v1/referral/codes
  • Authentication: 需要 JWT Token
  • Content-Type: application/json

请求参数

参数类型必须描述
signaturestringEIP-712 签名(0x 开头)
timestampnumberUnix 时间戳(秒)

EIP-712 签名

创建推荐码的 typed data 结构:

{
"types": {
"CreateReferralCode": [
{ "name": "wallet", "type": "address" },
{ "name": "timestamp", "type": "uint256" }
]
},
"message": {
"wallet": "0x742d35cc6634c0532925a3b844bc9e7595f0beb",
"timestamp": "1704067200"
}
}

前端签名示例

async function createReferralCode() {
const wallet = await getConnectedWallet();
const timestamp = Math.floor(Date.now() / 1000);

const domain = {
name: "ZTDX",
version: "1",
chainId: 421614,
verifyingContract: vaultAddress
};

const types = {
CreateReferralCode: [
{ name: "wallet", type: "address" },
{ name: "timestamp", type: "uint256" }
]
};

const message = {
wallet: wallet.address.toLowerCase(),
timestamp: timestamp.toString()
};

const provider = new BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const signature = await signer.signTypedData(domain, types, message);

const response = await fetch('/api/v1/referral/codes', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${jwtToken}`
},
body: JSON.stringify({ signature, timestamp })
});

return response.json();
}

请求示例

{
"signature": "0xabcdef123456...",
"timestamp": 1704067200
}

响应示例

{
"code": "A1B2C3D4",
"rebate_rate": "0.10",
"tier": 0,
"valid_until": 1735689600,
"created_at": 1704067200000
}

响应字段说明

字段类型描述
codestring推荐码(8位大写字母数字,基于地址生成)
rebate_ratestring当前返佣比例(Decimal 字符串)
tiernumber当前等级(0-4)
valid_untilnumber有效期(秒级时间戳)
created_atnumber创建时间(毫秒级时间戳)

推荐码生成算法

推荐码基于用户地址的 SHA256 哈希生成,确保唯一性和可重现性

// 后端算法(Rust)
fn generate_referral_code(address: &str) -> String {
let hash = sha256(address.as_bytes());
let code = hex::encode(hash).chars().take(8).collect();
code.to_uppercase()
}

这意味着:

  • ✅ 相同地址总是生成相同的推荐码
  • ✅ 推荐码不会重复
  • ✅ 可通过地址反推验证推荐码

错误响应

HTTP 状态码错误码描述
400CODE_ALREADY_EXISTS用户已有推荐码
400TIMESTAMP_EXPIRED时间戳已过期
400INVALID_SIGNATURE_FORMAT签名格式无效
401SIGNATURE_INVALIDEIP-712 签名验证失败

绑定推荐码

新用户可以绑定一个推荐码,成为他人的推荐用户。每个地址只能绑定一次,绑定后不可更改

接口信息

  • Method: POST
  • Path: /api/v1/referral/bind
  • Authentication: 需要 JWT Token
  • Content-Type: application/json

请求参数

参数类型必须描述
codestring推荐码(8位大写)
signaturestringEIP-712 签名
timestampnumberUnix 时间戳(秒)

EIP-712 签名

绑定推荐码的 typed data 结构:

{
"types": {
"BindReferralCode": [
{ "name": "wallet", "type": "address" },
{ "name": "code", "type": "string" },
{ "name": "timestamp", "type": "uint256" }
]
},
"message": {
"wallet": "0x123...",
"code": "A1B2C3D4",
"timestamp": "1704067200"
}
}

请求示例

{
"code": "A1B2C3D4",
"signature": "0xabcdef123456...",
"timestamp": 1704067200
}

响应示例

{
"bound": true,
"referrer_address": "0x742d35cc6634c0532925a3b844bc9e7595f0beb",
"referrer_code": "A1B2C3D4",
"bonus": "10.00"
}

错误响应

HTTP 状态码错误码描述
404CODE_NOT_FOUND推荐码不存在
400ALREADY_BOUND已绑定过推荐码
400SELF_REFERRAL不能绑定自己的推荐码
400TIMESTAMP_EXPIRED时间戳已过期
401SIGNATURE_INVALIDEIP-712 签名验证失败
重要提醒
  • 每个地址只能绑定一次推荐码
  • 绑定后不可更改或解绑
  • 不能使用自己的推荐码

推荐面板

获取用户的完整推荐数据dashboard,包括收益、等级、活动记录等。

接口信息

  • Method: GET
  • Path: /api/v1/referral/dashboard
  • Authentication: 需要 JWT Token

响应示例

{
"referral_code": "A1B2C3D4",
"referral_count": 52,
"tier": {
"level": 2,
"name": "Gold",
"rebate_rate": "0.20",
"next_level_requirement": 100
},
"total_earned": "5250.50",
"pending_earnings": "450.25",
"claimed_earnings": "4800.25",
"recent_referrals": [
{
"user_address": "0x123...",
"created_at": 1704067200000,
"total_trading_volume": "15000.00"
}
],
"activities": [
{
"type": "commission",
"amount": "15.50",
"timestamp": 1704067200000,
"details": "Trading fee rebate from 0x123..."
},
{
"type": "referral",
"amount": "0",
"timestamp": 1704063600000,
"details": "New referral: 0x456..."
}
]
}

响应字段说明

字段类型描述
referral_codestring用户的推荐码
referral_countnumber成功邀请的总用户数
tierobject当前等级信息
tier.levelnumber等级编号(0-4)
tier.namestring等级名称
tier.rebate_ratestring返佣比例(Decimal 字符串)
tier.next_level_requirementnumber | null下一级所需推荐人数
total_earnedstring累计总收益(Decimal 字符串)
pending_earningsstring待领取收益
claimed_earningsstring已领取收益
recent_referralsarray最近的推荐用户列表
activitiesarray活动记录(佣金、推荐、领取等)

领取返佣

将已结算的返佣提取至账户余额(链下)或通过智能合约提取(链上)。

链下领取

接口信息

  • Method: POST
  • Path: /api/v1/referral/claim
  • Authentication: 需要 JWT Token

响应示例

{
"success": true,
"amount": "450.25",
"new_balance": "1450.25"
}

链上领取签名

获取用于链上领取的后端签名。用户需要使用这个签名调用智能合约的 claimRebate 函数。

接口信息

  • Method: POST
  • Path: /api/v1/referral/on-chain/claim-signature
  • Authentication: 需要 JWT Token
  • Content-Type: application/json

请求参数

参数类型必须描述
amountstring领取金额(Wei,18位小数)

请求示例

{
"amount": "450250000000000000000"
}

响应示例

{
"signature": "0xdeadbeef123456...",
"nonce": 5,
"expiry": 1704070800,
"vault_address": "0xVaultContractAddress"
}

响应字段说明

字段类型描述
signaturestring后端签名(用于合约验证)
noncenumber当前 nonce 值
expirynumber签名过期时间(秒级时间戳,通常 1 小时后)
vault_addressstringVault 合约地址

前端调用合约示例

async function claimOnChain(amount) {
// 1. 获取后端签名
const { signature, nonce, expiry, vault_address } = await fetch(
'/api/v1/referral/on-chain/claim-signature',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${jwtToken}`
},
body: JSON.stringify({ amount })
}
).then(r => r.json());

// 2. 调用智能合约
const contract = new ethers.Contract(
vault_address,
referralABI,
signer
);

const tx = await contract.claimRebate(
amount,
nonce,
expiry,
signature
);

// 3. 等待交易确认
await tx.wait();

return tx.hash;
}

错误响应

HTTP 状态码错误码描述
400NO_PENDING_EARNINGS没有待领取的佣金
400BELOW_MINIMUM低于最低领取金额(10 USDT)
400INVALID_AMOUNT金额无效

链上查询接口(公开)

以下接口用于查询链上智能合约的数据,无需认证,任何人都可以查询。

查询用户返佣信息

查询用户在 ReferralRebate 合约中的返佣数据。

接口信息

  • Method: GET
  • Path: /api/v1/referral/on-chain/user-rebate/:address
  • Authentication: 不需要

路径参数

参数类型必须描述
addressstring以太坊地址

响应示例

{
"total_rebate": "5250500000000000000000",
"claimed_rebate": "4800250000000000000000",
"pending_rebate": "450250000000000000000",
"last_claim_time": 1704063600
}

响应字段说明

字段类型描述
total_rebatestring总返佣金额(Wei,18 位小数)
claimed_rebatestring已领取金额(Wei)
pending_rebatestring待领取金额(Wei)
last_claim_timenumber上次领取时间(秒级时间戳)

查询推荐人信息

查询用户在 ReferralRebate 合约中的推荐人信息。

接口信息

  • Method: GET
  • Path: /api/v1/referral/on-chain/referral-info/:address
  • Authentication: 不需要

响应示例

{
"referrer": "0x742d35cc6634c0532925a3b844bc9e7595f0beb",
"referral_tier": 2,
"total_referrals": 52,
"is_active": true
}

响应字段说明

字段类型描述
referrerstring推荐人地址(如果有)
referral_tiernumber推荐人当前等级(0-4)
total_referralsnumber推荐人的总推荐数
is_activeboolean推荐人是否活跃

查询已领取金额

查询用户已从合约领取的总金额。

接口信息

  • Method: GET
  • Path: /api/v1/referral/on-chain/claimed/:address
  • Authentication: 不需要

响应示例

{
"address": "0x742d35cc6634c0532925a3b844bc9e7595f0beb",
"total_claimed": "4800250000000000000000",
"total_claimed_usd": "4800.25",
"claim_count": 12
}

查询 Operator 状态

查询后端 Operator 在合约中的状态。

接口信息

  • Method: GET
  • Path: /api/v1/referral/on-chain/operator-status
  • Authentication: 不需要

响应示例

{
"operator_address": "0xOperatorAddress",
"is_operator": true,
"referral_rebate_contract": "0xReferralRebateAddress",
"referral_storage_contract": "0xReferralStorageAddress"
}

返佣计算规则

交易手续费分成

用户交易 → 支付手续费

手续费 × 推荐人返佣比例

推荐人收益

示例

  • 被推荐人交易量:10,000 USDT
  • 手续费率:0.1%(10 USDT)
  • 推荐人等级:Gold (20%)
  • 推荐人收益:10 × 20% = 2 USDT

实时结算

  • ✅ 每笔交易完成后立即计算返佣
  • ✅ 返佣自动累加到 pending_earnings
  • ✅ 用户可以随时领取 pending_earnings
  • ✅ 链上数据与链下数据定期同步

最佳实践

1. 创建推荐码后分享

const { code } = await createReferralCode();

// 生成推荐链接
const referralLink = `https://ztdx.io?ref=${code}`;

// 分享到社交媒体
shareToTwitter(referralLink);

2. 新用户绑定推荐码

// 从 URL 获取推荐码
const urlParams = new URLSearchParams(window.location.search);
const refCode = urlParams.get('ref');

if (refCode && !userHasReferrer) {
await bindReferralCode(refCode);
}

3. 定期查看收益

// 每日检查可领取收益
const { pending_earnings } = await getDashboard();

if (parseFloat(pending_earnings) >= 100) {
// 超过100 USDT时领取
await claimEarnings();
}

4. 升级等级

const { tier } = await getDashboard();

if (tier.next_level_requirement) {
const progress = (tier.level / tier.next_level_requirement) * 100;
console.log(`升级进度: ${progress.toFixed(2)}%`);
}

常见问题

Q: 推荐码可以修改吗?

A: 不可以。推荐码基于用户地址生成,是唯一且固定的。

Q: 一个用户可以有多个推荐人吗?

A: 不可以。每个用户只能绑定一次推荐码,绑定后不可更改。

Q: 返佣何时到账?

A: 链下返佣是实时的,每笔交易后立即计入 pending_earnings。链上返佣需要后端定期同步到合约。

Q: 最低领取金额是多少?

A: 10 USDT。这是为了节省 gas 费用。

Q: 如何验证推荐数据?

A: 所有推荐数据都记录在区块链上,您可以通过链上查询接口验证任何数据,确保透明公正。


智能合约地址

Arbitrum Sepolia(测试网)

  • ReferralRebate: 0xReferralRebateAddress
  • ReferralStorage: 0xReferralStorageAddress

Arbitrum One(主网)

  • 待部署

相关文档