接入指南
本页介绍接入兔思开放平台需要了解的全部基础信息:环境、请求规范、签名算法与接入流程。读完大约需要 10 分钟。
兔思开放平台通过 HTTPS + JSON 接口提供数字权益商品的查询、下单与对账能力。开始之前,您需要:
- 一个通过资质审核的企业账号;
- 一对
AppId/AppSecret(在控制台「应用管理」中创建,沙箱与正式环境各一对); - 一个可公网访问的回调地址(HTTPS),用于接收订单结果。
| 环境 | 域名 | 用途 |
|---|---|---|
| 沙箱 | https://sandbox-api.tobunny.com | 联调测试,不产生真实费用,订单在 10 秒内自动流转为终态 |
| 正式 | https://api.tobunny.com | 生产环境,按实际结算价扣款 |
两个环境的接口路径、参数与响应完全一致,切换环境只需更换域名与密钥。
- 协议:仅支持 HTTPS;
- 编码:
Content-Type: application/json; charset=utf-8; - 参数位置:GET 请求放在 query,POST 请求放在 JSON body;
- 时间:时间戳为秒级 Unix 时间戳;时间字段为 ISO 8601 北京时间,如
2026-09-29T10:00:00+08:00; - 金额:单位为元,保留两位小数的字符串,如
"9.90"。
每个请求必须携带以下四个请求头:
| 请求头 | 说明 |
|---|---|
X-App-Id | 您的 AppId |
X-Timestamp | 秒级 Unix 时间戳,与服务器时间相差不超过 300 秒 |
X-Nonce | 16–32 位随机字符串,5 分钟内不得重复 |
X-Sign | 按下文算法计算的签名,小写十六进制 |
- 构造
payload:GET 请求把 query 参数按 key 升序拼成k1=v1&k2=v2(无参数则为空字符串,值不做 URL 编码);POST 请求直接取原始 body 字符串。 - 拼接待签名串:
stringToSign = appId + "\n" + timestamp + "\n" + nonce + "\n" + payload。 - 计算签名:
sign = lowercase(hex(HMAC_SHA256(appSecret, stringToSign)))。
注意:POST 请求实际发送的 body 必须与参与签名的字符串逐字节一致,不要在签名之后再格式化 JSON。
Node.js 示例
Section titled “Node.js 示例”import crypto from 'node:crypto';
const appId = 'your_app_id';const appSecret = 'your_app_secret';const timestamp = Math.floor(Date.now() / 1000);const nonce = crypto.randomBytes(8).toString('hex');const body = JSON.stringify({ outOrderNo: 'ORD20260929001', goodsId: 'G100001', quantity: 1, account: '13800000000' });
const stringToSign = [appId, timestamp, nonce, body].join('\n');const sign = crypto.createHmac('sha256', appSecret).update(stringToSign).digest('hex');
const res = await fetch('https://sandbox-api.tobunny.com/v1/orders', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-App-Id': appId, 'X-Timestamp': String(timestamp), 'X-Nonce': nonce, 'X-Sign': sign, }, body,});console.log(await res.json());Python 示例
Section titled “Python 示例”import hmac, hashlib, json, time, secretsimport requests
app_id, app_secret = "your_app_id", "your_app_secret"timestamp = str(int(time.time()))nonce = secrets.token_hex(8)body = json.dumps( {"outOrderNo": "ORD20260929001", "goodsId": "G100001", "quantity": 1, "account": "13800000000"}, separators=(",", ":"), ensure_ascii=False,)
string_to_sign = "\n".join([app_id, timestamp, nonce, body])sign = hmac.new(app_secret.encode(), string_to_sign.encode(), hashlib.sha256).hexdigest()
r = requests.post( "https://sandbox-api.tobunny.com/v1/orders", data=body.encode("utf-8"), headers={ "Content-Type": "application/json", "X-App-Id": app_id, "X-Timestamp": timestamp, "X-Nonce": nonce, "X-Sign": sign, },)print(r.json())PHP 示例
Section titled “PHP 示例”<?php$appId = 'your_app_id';$appSecret = 'your_app_secret';$timestamp = (string) time();$nonce = bin2hex(random_bytes(8));$body = json_encode( ['outOrderNo' => 'ORD20260929001', 'goodsId' => 'G100001', 'quantity' => 1, 'account' => '13800000000'], JSON_UNESCAPED_UNICODE);
$stringToSign = implode("\n", [$appId, $timestamp, $nonce, $body]);$sign = hash_hmac('sha256', $stringToSign, $appSecret);
$ch = curl_init('https://sandbox-api.tobunny.com/v1/orders');curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', "X-App-Id: $appId", "X-Timestamp: $timestamp", "X-Nonce: $nonce", "X-Sign: $sign", ],]);echo curl_exec($ch);- 注册账号:在控制台注册企业账号,填写基本信息。
- 资质审核:提交营业执照与业务说明,1 个工作日内完成审核。
- 沙箱联调:获取沙箱 AppId 和 AppSecret,在沙箱环境完成接口联调。
- 充值上线:签署协议并预充值,切换正式环境。
- 运营支持:专属对接群,商品上新与活动策划持续支持。