Bitget APIBitget API
统一账户经典账户
旧文档
  • 概览
  • API 文档
  • WebSocket
  • Agent Hub
  • SDK
  • 更新日志
Copied to clipboard
快速开始
统一账户快速开始最佳实践指南rToken 交易指南CFD 交易指南带单 API 介绍历史数据下载指南FastApi 接入指南
模拟盘
限频规则
API 参考
API 文档枚举
错误码
概览

FastApi 接入指南

背景

欢迎与 Bitget 交易所合作,您作为 Broker 在接入我们的 FastApi 时,需要按照我们给出的标准进行接入。在本文档中,我们将为您介绍如何接入到 Bitget 的 FastApi。

接入准备

该功能需要联系您的 Bitget BD(Business Development)进行申请。请联系 BD 并提交以下资料:

信息说明
name平台名称
contact联系方式 — 邮箱或手机号
ip服务器 IP — Broker 平台调用 Bitget API 接口的常用 IP 地址
logo(AI)平台 Logo — 文件格式为 Adobe Illustrator
logo(PNG)平台 Logo — 文件格式为 PNG,像素要求为 64 × 64
callbackUrl回调地址 — 用于 Broker 用户信息回传
rsaPublicKey(2048 bit)公钥 — 基于 RSA 算法;格式规则为 RSA PKCS8 2048 位

申请成功后,BD 会提供以下信息:

参数名称参数类型说明
clientIdStringBroker 平台 ID — 由 Bitget 分配的唯一标识

技术实现

下面涉及到的一些属性信息,主要用于对接功能实现。

参数名称参数类型提供方描述
clientIdStringBitgetBroker 平台 ID — 申请成功后由 BD 提供
callbackUrlStringBroker 客户回调地址 — 作为 BD 申请材料的一部分提交给 Bitget;用于 Broker 用户信息回传
rsaPublicKey(2048 bit)StringBroker 客户公钥 — 作为 BD 申请材料的一部分提交给 Bitget;基于 RSA 算法,格式规则为 RSA PKCS8 2048 位
rsaPrivateKey(2048 bit)StringBroker 客户私钥 — 基于 RSA 算法;格式规则为 RSA PKCS8 2048 位;由 Broker 自行保管,无需提供给 Bitget

请妥善保管私钥

rsaPrivateKey 必须由 Broker 一方安全保存,切勿提供给 Bitget 或任何第三方。一旦私钥泄露,他人可解密用户的 API Key 信息并伪造签名。

代码示例(Java)

下面是签名和 RSA 加密解密的代码示例,均基于 Java 实现。

工具类

签名以及 RSA 加密/解密都基于下面的工具类实现。

Code
package xxx; import org.springframework.util.Base64Utils; import javax.crypto.Cipher; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.TreeSet; public class RsaUtil { // 使用公钥进行 RSA 加密 public static String encryptRSA(String plaintext, String publicKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKey)); byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8)); return Base64Utils.encodeToString(encryptedBytes); } // 使用私钥进行 RSA 解密 public static String decryptRSA(String encryptedData, String privateKey) throws Exception { Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKey)); byte[] encryptedBytes = Base64Utils.decodeFromString(encryptedData); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes, StandardCharsets.UTF_8); } /** * 解码 PublicKey * * @param key * @return */ public static PublicKey getPublicKey(String key) throws Exception { byte[] byteKey = org.apache.commons.codec.binary.Base64.decodeBase64(key); X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(byteKey); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePublic(x509EncodedKeySpec); } /** * 解码 PrivateKey * * @param key * @return */ public static PrivateKey getPrivateKey(String key) throws Exception { byte[] byteKey = org.apache.commons.codec.binary.Base64.decodeBase64(key); PKCS8EncodedKeySpec x509EncodedKeySpec = new PKCS8EncodedKeySpec(byteKey); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); return keyFactory.generatePrivate(x509EncodedKeySpec); } public static boolean verify(Map<String, String> map, String publicKey, String sign) throws Exception { String srcData = getSignData(map); byte[] keyBytes = getPublicKey(publicKey).getEncoded(); X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PublicKey key = keyFactory.generatePublic(keySpec); Signature signature = Signature.getInstance("MD5withRSA"); signature.initVerify(key); signature.update(srcData.getBytes()); return signature.verify(Base64Utils.decodeFromString(sign)); } /** * 签名 * * @param data 待签名数据 * @param privateKey 私钥 * @return 签名 */ public static String sign(String data, String privateKey) throws Exception { byte[] keyBytes = getPrivateKey(privateKey).getEncoded(); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey key = keyFactory.generatePrivate(keySpec); Signature signature = Signature.getInstance("MD5withRSA"); signature.initSign(key); signature.update(data.getBytes()); return Base64Utils.encodeToString(signature.sign()); } /** * 得到签名 * * @param params 参数集合,不含 secretKey * @return */ public static String getSignData(Map<String, String> params) { StringBuilder sb = new StringBuilder(); // step1:先对请求参数排序 Set<String> keyset = params.keySet(); TreeSet<String> sortSet = new TreeSet<String>(); sortSet.addAll(keyset); Iterator<String> it = sortSet.iterator(); // step2:把参数的 key value 链接起来,secretKey 放在最后面,得到要加密的字符串 while (it.hasNext()) { String key = it.next(); String value = params.get(key); sb.append(key).append(value); } return sb.toString(); } static String publicKey = "*****"; static String privateKey = "*****"; }

签名使用示例

Code
public static void main(String[] args) throws Exception { // 生成签名 Map<String, String> map = new HashMap<>(); long l = System.currentTimeMillis(); map.put("timestamp", String.valueOf(l)); map.put("clientId", "1"); map.put("clientUserId", "123"); String sign = RsaUtil.sign(RsaUtil.getSignData(map), RsaUtil.privateKey); System.out.println(sign); }

RSA 加密和解密使用示例

Code
public static void main(String[] args) throws Exception { String xxStr = "hello world"; // encrypt String encrypted = RsaUtil.encryptRSA(xxStr, RsaUtil.publicKey); System.out.println("encrypt by publicKey: " + encrypted); // decrypt System.out.println("decrypt by privateKey: " + RsaUtil.decryptRSA(encrypted, RsaUtil.privateKey)); }

功能实现

下面是功能实现的具体过程,其中涉及到了接口、参数、签名生成规则等 OAuth 授权流程细节。

整体流程分为三步:Broker 跳转 Bitget 授权页面、Bitget 携带用户 API Key 回调 Broker 接口、Bitget 携带授权结果跳转回 Broker 页面。

1. Broker 跳转 Bitget 授权页面

从 Broker 平台跳转到 Bitget 的授权页面时,需要 Broker 在 URL 中携带以下参数。

Bitget 授权页面链接为 https://www.bitget.com/account/oauth。

参数名参数类型描述
clientUserIdStringBroker 用户 ID — 客户自定义
timestampString时间戳 — Unix 毫秒格式;请传入当前时间前后 5 分钟内的时间戳,超出范围会被认为无效请求;用户在 Bitget 页面点击授权时会校验该时间戳
clientIdStringBroker 平台 ID
signString签名 — 格式规则为 clientId[]clientUserId[]timestamp[];实际使用请参考代码示例(Java)
redirectUrlString重定向地址 — 授权完成后自动跳转的 Broker 平台链接
serialNoString随机序列号 — 1)在回调接口中,Broker 需要通过此参数校验回调接口请求的合法性;2)出于安全考虑,请将 serialNo 与 clientUserId 关联,不要在多个账户间混用;3)出于安全考虑,建议为 serialNo 设置有效期,例如 10 分钟

示例 URL(请将参数进行 URL 编码,防止参数在传输过程中转译丢失):

Code
https://www.bitget.com/account/oauth?clientUserId=123&timestamp=1691117744470&clientId=1&redirectUrl=https://broker-domain/callback/url&sign=F9zeG9oUYzqwN94kSfoFy...&serialNo=123

补充说明(可选配置)

为帮助提升用户注册转化,Bitget 支持在 OAuth 跳转链接中携带邀请码(Referral Code)。当用户通过 OAuth 跳转至 Bitget 页面后点击注册,系统会自动识别链接中携带的邀请码,并在注册页面自动填充,无需用户手动输入。

配置方式:

  1. 联系 Broker 运营或 BD,在后台配置邀请链接(长链接),例如 https://www.bitget.com/test?channelCode=abcde&vipCode=1234&languageType=1。
  2. 从邀请链接中获取邀请码参数,例如 vipCode=1234。
  3. 将该邀请码参数追加至 Bitget OAuth 跳转链接后,即可完成配置。
Code
https://www.bitget.com/account/oauth?clientUserId=123&timestamp=1691117744470&clientId=1&redirectUrl=https://broker-domain/callback/url&sign=F9zeG9oUYzqwN94kSfoFy...&serialNo=123&channelCode=abcde&vipCode=1234

2. Bitget 回调 Broker 接口

一旦用户在页面完成授权,Bitget 将自动请求 Broker 回调接口。

  • 请求类型:POST
  • 请求 URL:双方商议
  • Content-Type:application/x-www-form-urlencoded
参数名参数类型描述
openIdString加密后的 Bitget user ID
userIdStringBitget user ID — 仅白名单用户返回,非白名单用户返回为空
clientUserIdStringBroker 用户 ID
timestampString时间戳 — Unix 毫秒格式;请验证该时间与当前时间的差值是否超过 5 分钟,如超出范围请视作无效请求
signString签名 — 请通过 privateKey 解密,解密后可获得 serialNo
dataString加密后的 API Key 信息 — 请通过 privateKey 解密,解密后可获得用户 apiKey、passphrase 及 secret

其他说明

  1. 请使用 privateKey 对 sign 进行解密,并校验结果是否与 serialNo 一致,若不一致则说明请求不合法。
  2. 请使用 privateKey 对 data 进行解密,解密结果为 JSON 格式的用户 API Key 信息:
Code
{ "apiKey": "bg_xxxxxxxxxx", "passphrase": "***", "secret": "xxxxxxxxxxxxxxxxxxxxxxx" }

请妥善保管 API Key 信息

解密后得到的 apiKey、passphrase、secret 可用于操作用户的 Bitget 账户交易权限,请安全存储(如加密存储),切勿在日志、前端代码或错误信息中暴露这些信息。

Bitget 请求后,Broker 需按照如下格式返回响应参数:

Code
{ "code": "00000", "msg": "success", "requestTime": "1671258739383" }

3. Bitget 跳转回 Broker 页面

授权结果无论成功还是失败,Bitget 都会将下列参数添加至 URL,并跳转到 Broker 页面。

参数名参数类型描述
clientUserIdStringBroker 平台的用户 ID
signString签名 — 通过 publicKey 加密后的 serialNo,需要进行解密
stateString授权状态 — 通过 publicKey 加密后的 state,需要进行解密;SUCCESS 表示授权成功,FAIL 表示授权失败

示例:

Code
https://broker-domain/callback/url?sign=sahkduhas1237hkNAQGS&clientUserId=123&state=DHJSAshaj

其他说明

  1. 请使用 privateKey 对 sign 进行解密,并校验结果是否与 serialNo 一致,若不一致则说明请求不合法。
  2. 建议通过 serialNo 查询 clientUserId,并判断是否与当前 URL 中的 clientUserId 一致,若不一致则说明请求不合法。
历史数据下载指南REST API
On this page
  • 背景
  • 接入准备
    • 技术实现
    • 代码示例(Java)
  • 功能实现
    • 1. Broker 跳转 Bitget 授权页面
    • 2. Bitget 回调 Broker 接口
    • 3. Bitget 跳转回 Broker 页面