Skip to content

交易认证文档

Wenqing Yu edited this page May 26, 2016 · 1 revision

交易 API 访问认证

要进行交易 API 的访问认证,您需要将公开的访问密匙 (Access Key) 以及通过秘密密匙 (Secret Key) 签名得到的一个哈希字符串传递给交易 API。签名所采用的算法是 HMAC (Hash-based Message Authentication Code)。除了访问密匙和秘密密匙以外,您还需要传递一个“Tonce”参数。Tonce 是指以毫秒为单位的当前时间的时间戳 (Timestamp)。访问密匙和秘密密匙生成的签名通过 HTTP 基本身份验证 (HTTP Basic Authentication) 传递,Tonce 通过 HTTP 头 (HTTP Header) 传递。

详细步骤

使用如下强制的参数创建签名字符串。将键值对使用“&”符号按照下面列表的顺序连接在一起。请注意连接顺序很重要。所有的键名必须添加,但是键值可以为空 (例如 params)。

  • tonce (以毫秒为单位的时间戳,请确保您的系统时间准确)
  • accesskey (访问密匙,您可以在您的账户管理页面申请)
  • method (HTTP 请求方法,目前仅支持“post”)
  • id (JSON-RPC 请求 id)
  • method method (JSON-RPC 方法名称)
  • params (JSON-RPC 方法参数)
### Example 1 ###
	tonce=1377743828095093
	&accesskey=1d87effa-e84d-48c1-a172-0232b86305dd
	&requestmethod=post
	&id=1
	&method=getAccountInfo
	&params=
### Example 2 ###
	tonce=1377743828095093
	&accesskey=1d87effa-e84d-48c1-a172-0232b86305dd
	&requestmethod=post
	&id=1
	&method=buyOrder
	&params=500,1

使用您的秘密密匙用 HMAC 生成哈希签名。使用 sha1 作为哈希算法。

### PHP ###
hash_hmac('sha1', $signature, $secretkey)

使用 HTTP 基本身份验证传递身份验证信息。您可以通过如下两种方式实现:

  • 在网址中传递。您可以在网址中直接传递访问密匙和哈希签名
https://<accesskey>:<hash>@api.btcc.com/api_trade_v1.php
  • HTTP 认证头。计算并创建认证头 (Authorization),并和其他请求一起传递到 API。身份信息为用冒号 (:) 连接的访问密匙和哈希签名。最后的认证头的值需要用 Base64 编码。
### PHP ###
base64_encode(<accesskey>:<hash>) //PGFjY2Vzc2tleT46PGhhc2g+
# HTTP HEADER
Authorization: Basic PGFjY2Vzc2tleT46PGhhc2g+

最后您需要将 Tonce 也作为 HTTP 头传递给 API。Tonce 的值必须和您在第 1 步生成哈希签名时使用的值一致。

# HTTP HEADER
Json-Rpc-Tonce: 1377743828095093

发起 API 请求。如果有错误,API 会返回 HTTP 401 Unauthorized。

API 示例代码

点击以下链接,获取更多示例源代码: PHP: https://github.com/BTCChina/btcchina-api-php Python: https://github.com/BTCChina/btcchina-api-python Java: https://github.com/BTCChina/btcchina-api-java .NET C#: https://github.com/BTCChina/btcchina-api-csharp C++: https://github.com/BTCChina/btcchina-api-cpp JavaScript: https://github.com/BTCChina/btcchina-api-js

PHP

<?php
	function sign($method, $params = array()){
	$accessKey = "YOUR_ACCESS_KEY"; 
	$secretKey = "YOUR_SECRET_KEY"; 
	$mt = explode(' ', microtime());
	$ts = $mt[1] . substr($mt[0], 2, 6);
	$signature = urldecode(http_build_query(array(
	'tonce' => $ts,
	'accesskey' => $accessKey,
	'requestmethod' => 'post',
	'id' => 1,
	'method' => $method,
	'params' => '', //implode(',', $params),
	)));
	var_dump($signature);
	$hash = hash_hmac('sha1', $signature, $secretKey);
	return array(
	'ts' => $ts,
	'hash' => $hash,
	'auth' => base64_encode($accessKey.':'. $hash),
	);
	}
	function request($method, $params){
	$sign = sign($method, $params);
	$options = array( 
	CURLOPT_HTTPHEADER => array(
	'Authorization: Basic ' . $sign['auth'],
	'Json-Rpc-Tonce: ' . $sign['ts'],
	),
	);
	$postData = json_encode(array(
	'method' => $method,
	'params' => $params,
	'id' => 1,
	));
	print($postData);
	$headers = array(
	'Authorization: Basic ' . $sign['auth'],
	'Json-Rpc-Tonce: ' . $sign['ts'],
	); 
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_USERAGENT, 
	'Mozilla/4.0 (compatible; BTC China Trade Bot; '.php_uname('a').'; PHP/'.phpversion().')'
	);
	curl_setopt($ch, CURLOPT_URL, 'https://api.btcc.com/api_trade_v1.php');
	curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
	curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
	// run the query
	$res = curl_exec($ch);
	return $res;
	/**/
	}
	try { 
	var_dump(request('getAccountInfo', array()));
	} catch (Exception $e) { 
	echo "Error:".$e->getMessage(); 
	} 
?>

Python

#!/usr/bin/python
# -*- coding: utf-8 -*-
 
import btcchina
 
access_key="YOUR_ACCESS_KEY"
secret_key="YOUR_SECRET_KEY"
 
bc = btcchina.BTCChina(access_key,secret_key)
 
''' These methods have no arguments '''
#result = bc.get_account_info()
#print result
 
#result = bc.get_market_depth2()
#print result
 
# NOTE: for all methods shown here, the transaction ID could be set by doing
#result = bc.get_account_info(post_data={'id':'stuff'})
#print result
 
''' buy and sell require price (CNY, 5 decimals) and amount (LTC/BTC, 8 decimals) '''
#result = bc.buy(500,1)
#print result
#result = bc.sell(500,1)
#print result
 
''' cancel requires id number of order '''
#result = bc.cancel(2)
#print result
 
''' request withdrawal requires currency and amount '''
#result = bc.request_withdrawal('BTC',0.1)
#print result
 
''' get deposits requires currency. the optional "pending" defaults to true '''
#result = bc.get_deposits('BTC',pending=False)
#print result
 
''' get orders returns status for one order if ID is specified,
    otherwise returns all orders, the optional "open_only" defaults to true '''
#result = bc.get_orders(2)
#print result
#result = bc.get_orders(open_only=True)
#print result
 
''' get withdrawals returns status for one transaction if ID is specified,
    if currency is specified it returns all transactions,
    the optional "pending" defaults to true '''
#result = bc.get_withdrawals(2)
#print result
#result = bc.get_withdrawals('BTC',pending=True)
#print result
 
''' Fetch transactions by type. Default is 'all'. 
    Available types 'all | fundbtc | withdrawbtc | fundmoney | withdrawmoney | 
    refundmoney | buybtc | sellbtc | tradefee'
    Limit the number of transactions, default value is 10 '''
#result = bc.get_transactions('all',10)
#print result

''' get archived order returns a specified id order which is archived,
   the market default to "BTCCNY" and the "withdetail" default to false,if "withdetail" is specified to "true", the result will
   include the order's detail'''
#result = bc.get_archived_order(2,'btccny',False)
#print result

''' get archived orders returns the orders which order id is less than the specified "less_than_order_id",and the returned
    amount is defined in "limit",default value is 200, if "withdetail" is specified to "true", the result will include to
    orders' detail'''
#result = bc.get_archived_orders('btccny',200,10000,False)
#print result

 
#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
import time
import re
import hmac
import hashlib
import base64
import httplib
import json
 
class BTCChina():
    def __init__(self,access=None,secret=None):
        self.access_key=access
        self.secret_key=secret
        self.conn=httplib.HTTPSConnection("api.btcchina.com")
 
    def _get_tonce(self):
        return int(time.time()*1000000)
 
    def _get_params_hash(self,pdict):
        pstring=""
        # The order of params is critical for calculating a correct hash
        fields=['tonce','accesskey','requestmethod','id','method','params']
        for f in fields:
            if pdict[f]:
                if f == 'params':
                    # Convert list to string, then strip brackets and spaces
                    # probably a cleaner way to do this
                    param_string=re.sub("[\[\] ]","",str(pdict[f]))
                    param_string=re.sub("'",'',param_string)
                    param_string=re.sub("True",'1',param_string)
                    param_string=re.sub("False",'',param_string)
                    param_string=re.sub("None",'',param_string)
                    pstring+=f+'='+param_string+'&'
                else:
                    pstring+=f+'='+str(pdict[f])+'&'
            else:
                pstring+=f+'=&'
        pstring=pstring.strip('&')
 
        # now with correctly ordered param string, calculate hash
        phash = hmac.new(self.secret_key, pstring, hashlib.sha1).hexdigest()
        return phash
 
    def _private_request(self,post_data):
        #fill in common post_data parameters
        tonce=self._get_tonce()
        post_data['tonce']=tonce
        post_data['accesskey']=self.access_key
        post_data['requestmethod']='post'
 
        # If ID is not passed as a key of post_data, just use tonce
        if not 'id' in post_data:
            post_data['id']=tonce

        pd_hash=self._get_params_hash(post_data)
 
        # must use b64 encode        
        auth_string='Basic '+base64.b64encode(self.access_key+':'+pd_hash)
        headers={'Authorization':auth_string,'Json-Rpc-Tonce':tonce}
 
        #post_data dictionary passed as JSON        
        self.conn.request("POST",'/api_trade_v1.php',json.dumps(post_data),headers)
        response = self.conn.getresponse()
 
        # check response code, ID, and existence of 'result' or 'error'
        # before passing a dict of results
        if response.status == 200:
            # this might fail if non-json data is returned
            resp_dict = json.loads(response.read())
 
            # The id's may need to be used by the calling application,
            # but for now, check and discard from the return dict
            if str(resp_dict['id']) == str(post_data['id']):
                if 'result' in resp_dict:
                    return resp_dict['result']
                elif 'error' in resp_dict:
                    return resp_dict['error']
        else:
            # not great error handling....
            print "status:",response.status
            print "reason:",response.reason
 
        return None
 
    def get_account_info(self,post_data={}):
        post_data['method']='getAccountInfo'
        post_data['params']=[]
        return self._private_request(post_data)
 
    def get_market_depth2(self,limit=10, market="btccny", post_data={}):
        post_data['method']='getMarketDepth2'
        post_data['params']=[limit, market]
        return self._private_request(post_data)
 
    def buy(self, price, amount, market="btccny", post_data={}):
        amountStr = "{0:.4f}".format(round(amount,4))
        post_data['method']='buyOrder2'
        if price == None:
            priceStr = None
        else:
            priceStr = "{0:.4f}".format(round(price,4))
        post_data['params']=[priceStr, amountStr, market]
        return self._private_request(post_data)
 
    def sell(self, price, amount, market="btccny", post_data={}):
        amountStr = "{0:.4f}".format(round(amount,4))
        post_data['method']='sellOrder2'
        if price == None:
            priceStr = None
        else:
            priceStr = "{0:.4f}".format(round(price,4))
        post_data['params']=[priceStr, amountStr, market]
        return self._private_request(post_data)
 
    def cancel(self,order_id, market = "btccny", post_data={}):
        post_data['method']='cancelOrder'
        post_data['params']=[order_id, market]
        return self._private_request(post_data)
 
    def request_withdrawal(self,currency,amount,post_data={}):
        post_data['method']='requestWithdrawal'
        post_data['params']=[currency,amount]
        return self._private_request(post_data)
 
    def get_deposits(self,currency='BTC',pending=True,post_data={}):
        post_data['method']='getDeposits'
        post_data['params']=[currency,pending]
        return self._private_request(post_data)
 
    def get_orders(self,id=None,open_only=True,market="btccny",details=True,post_data={}):
        # this combines getOrder and getOrders
        if id is None:
            post_data['method']='getOrders'
            post_data['params']=[open_only, market]
        else:
            post_data['method']='getOrder'
            post_data['params']=[id, market,details]
        return self._private_request(post_data)
 
    def get_withdrawals(self,id='BTC',pending=True,post_data={}):
        # this combines getWithdrawal and getWithdrawals
        try:
            id = int(id)
            post_data['method']='getWithdrawal'
            post_data['params']=[id]
        except:
            post_data['method']='getWithdrawals'
            post_data['params']=[id,pending]
        return self._private_request(post_data)
 
    def get_transactions(self,trans_type='all',limit=10,post_data={}):
        post_data['method']='getTransactions'
        post_data['params']=[trans_type,limit]
        return self._private_request(post_data)

    def get_archived_order(self,id,market='btccny',withdetail=False,post_data={}):
    	post_data['method']='getArchivedOrder'
    	post_data['params']=[id,market,withdetail]
    	return self._private_request(post_data)

    def get_archived_orders(self,market='btccny',limit=200,less_than_order_id=0,withdetail=False,post_data={}):
    	post_data['method']='getArchivedOrders'
    	post_data['params']=[market,limit,less_than_order_id,withdetail]
    	return self._private_request(post_data)

JAVA

    import javax.crypto.spec.SecretKeySpec;
	import javax.crypto.Mac;
	import javax.net.ssl.HttpsURLConnection;
	import java.io.BufferedReader;
	import java.io.DataOutputStream;
	import java.io.InputStreamReader;
	import java.net.URL;
	import javax.xml.bind.DatatypeConverter;
	class BTCCApiAuthentication{
	private static final String ACCESS_KEY = "YOUR_ACCESS_KEY";
	private static final String SECRET_KEY = "YOUR_SECRET_KEY";
	private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1";
	public static String getSignature(String data,String key) throws Exception {
	// get an hmac_sha1 key from the raw key bytes
	SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), HMAC_SHA1_ALGORITHM);
	// get an hmac_sha1 Mac instance and initialize with the signing key
	Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
	mac.init(signingKey);
	// compute the hmac on input data bytes
	byte[] rawHmac = mac.doFinal(data.getBytes());
	return bytArrayToHex(rawHmac); 
	}
	private static String bytArrayToHex(byte[] a) {
	StringBuilder sb = new StringBuilder();
	for(byte b: a)
	sb.append(String.format("%02x", b&0xff));
	return sb.toString();
	}
	public static void main(String args[]) throws Exception{
	String tonce = ""+(System.currentTimeMillis() * 1000);
	String params = "tonce="+tonce.toString()+"&accesskey="+ACCESS_KEY+"&requestmethod=post&id=1&method=getAccountInfo&params=";
	String hash = getSignature(params, SECRET_KEY);
	String url = "https://api.btcc.com/api_trade_v1.php";
	URL obj = new URL(url);
	HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
	String userpass = ACCESS_KEY + ":" + hash;
	String basicAuth = "Basic " + DatatypeConverter.printBase64Binary(userpass.getBytes());
	//add reuqest header
	con.setRequestMethod("POST");
	con.setRequestProperty("Json-Rpc-Tonce", tonce.toString());
	con.setRequestProperty ("Authorization", basicAuth);
	String postdata = "{\"method\": \"getAccountInfo\", \"params\": [], \"id\": 1}";
	// Send post request
	con.setDoOutput(true);
	DataOutputStream wr = new DataOutputStream(con.getOutputStream());
	wr.writeBytes(postdata);
	wr.flush();
	wr.close();
	int responseCode = con.getResponseCode();
	System.out.println("\nSending 'POST' request to URL : " + url);
	System.out.println("Post parameters : " + postdata);
	System.out.println("Response Code : " + responseCode);
	BufferedReader in = new BufferedReader(
	new InputStreamReader(con.getInputStream()));
	String inputLine;
	StringBuffer response = new StringBuffer();
	while ((inputLine = in.readLine()) != null) {
	response.append(inputLine);
	}
	in.close();
	//print result
	System.out.println(response.toString());
	}
}

.NET C#

    using System;
	using System.Net;
	using System.Text;
	using System.Collections.Specialized;
	using System.Collections.Generic;
	using System.Security.Cryptography;
	using System.IO;
	using System.Net.Security;
	using System.Security.Cryptography.X509Certificates; 
	namespace BTCCApiAuthentication {
	class MainClass {
	public static void Main (string[] args) {
	// For https.
	ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
	// Enter your personal API access key and secret here
	string accessKey = "YOUR_ACCESS_KEY";
	string secretKey = "YOUR_SECRET_KEY";
	string method = "getAccountInfo";
	TimeSpan timeSpan = DateTime.UtcNow - new DateTime (1970, 1, 1);
	long milliSeconds = Convert.ToInt64(timeSpan.TotalMilliseconds * 1000);
	string tonce = Convert.ToString(milliSeconds);
	NameValueCollection parameters = new NameValueCollection() { 
	{ "tonce", tonce },
	{ "accesskey", accessKey },
	{ "requestmethod", "post" },
	{ "id", "1" },
	{ "method", method },
	{ "params", "" }
	};
	string paramsHash = GetHMACSHA1Hash(secretKey, BuildQueryString(parameters));
	string base64String = Convert.ToBase64String(
	Encoding.ASCII.GetBytes(accessKey + ':' + paramsHash));
	string url = "https://api.btcc.com/api_trade_v1.php";
	string postData = "{\"method\": \"" + method + "\", \"params\": [], \"id\": 1}";
	SendPostByWebRequest(url, base64String, tonce, postData);
	}
	private static void SendPostByWebClient(string url, string base64,
	string tonce, string postData) {
	using (WebClient client = new WebClient()) {
	client.Headers["Content-type"] = "application/json-rpc";
	client.Headers["Authorization"] = "Basic " + base64;
	client.Headers["Json-Rpc-Tonce"] = tonce;
	try {
	byte[] response = client.UploadData(
	url, "POST", Encoding.Default.GetBytes(postData));
	Console.WriteLine("\nResponse: {0}", Encoding.UTF8.GetString(response));
	} catch (System.Net.WebException ex) {
	Console.WriteLine(ex.Message);
	}
	}
	}
	public static void SendPostByWebRequest(string url, string base64,
	string tonce, string postData) {
	WebRequest webRequest = WebRequest.Create(url);
	//WebRequest webRequest = HttpWebRequest.Create(url);
	if (webRequest == null) {
	Console.WriteLine("Failed to create web request for url: " + url);
	return;
	}
	byte[] bytes = Encoding.ASCII.GetBytes(postData);
	webRequest.Method = "POST";
	webRequest.ContentType = "application/json-rpc";
	webRequest.ContentLength = bytes.Length;
	webRequest.Headers["Authorization"] = "Basic " + base64;
	webRequest.Headers["Json-Rpc-Tonce"] = tonce;
	try {
	// Send the json authentication post request
	using (Stream dataStream = webRequest.GetRequestStream()) {
	dataStream.Write(bytes, 0, bytes.Length);
	dataStream.Close();
	}
	// Get authentication response
	using (WebResponse response = webRequest.GetResponse()) {
	using (var stream = response.GetResponseStream()) {
	using (var reader = new StreamReader(stream)) {
	Console.WriteLine("Response: " + reader.ReadToEnd());
	}
	}
	}
	} catch (WebException ex) {
	Console.WriteLine(ex.Message);
	}
	}
	private static string BuildQueryString(NameValueCollection parameters) {
	List<string> keyValues = new List<string>();
	foreach (string key in parameters) {
	keyValues.Add(key + "=" + parameters[key]);
	}
	return String.Join("&", keyValues.ToArray());
	}
	private static string GetHMACSHA1Hash(string secret_key, string input) {
	HMACSHA1 hmacsha1 = new HMACSHA1(Encoding.ASCII.GetBytes(secret_key));
	MemoryStream stream = new MemoryStream(Encoding.ASCII.GetBytes(input));
	byte[] hashData = hmacsha1.ComputeHash(stream);
	// Format as hexadecimal string.
	StringBuilder hashBuilder = new StringBuilder();
	foreach (byte data in hashData) {
	hashBuilder.Append(data.ToString("x2"));
	}
	return hashBuilder.ToString();
	}
  }
}

C++

    #include <iostream>
	#include <math.h>
	#include <netdb.h>
	#include <openssl/ssl.h>
	#include <openssl/err.h>
	#include <stdio.h>
	#include <sstream>
	#include "HMAC_SHA1.h"
	using namespace std;
	// Reference:
	// http://www.codeproject.com/Articles/22118/C-Class-Implementation-of-HMAC-SHA
	string getHmacSha1(string key, string content) {
	unsigned char digest[20];
	CHMAC_SHA1 HMAC_SHA1;
	HMAC_SHA1.HMAC_SHA1((unsigned char *) content.c_str(), content.size(),
	(unsigned char *) key.c_str(), key.size(), digest);
	stringstream output;
	char result[3];
	for (int i = 0; i < 20; i++) {
	sprintf(result, "%02x", digest[i]);
	output << result;
	}
	return output.str();
	}
	long long getMilliSeconds() {
	struct timeval start, end;
	gettimeofday( &start, NULL );
	return start.tv_sec * 1000000LL + start.tv_usec;
	}
	// Connects and gets the socket handle. Returns 0 if any errors.
	int SocketConnect(string host_name, int port) {
	struct hostent* host = gethostbyname(host_name.c_str());
	int handle = socket(AF_INET, SOCK_STREAM, 0);
	if (handle == -1) {
	cout << "Error when creating socket to " << host_name;
	return 0;
	}
	struct sockaddr_in server;
	server.sin_family = AF_INET;
	server.sin_port = htons(port);
	server.sin_addr = *((in_addr *) host->h_addr);
	bzero(&(server.sin_zero), 8);
	int error = connect(handle, (sockaddr *) &server, sizeof(sockaddr));
	if (error == -1) {
	cout << "Error when connecting " << host_name;
	return 0;
	}
	return handle;
	}
	// Establishes a SSL connection. Return false if errors.
	bool SslConnect(const string& server, int port,
	int& socket, SSL*& sslHandle, SSL_CTX*& sslContext) {
	socket = SocketConnect(server, port);
	if (socket == 0) {
	return false;
	}
	SSL_load_error_strings();
	SSL_library_init();
	// Use SSL 2 or 3, bind SSL to socket, and then do the SSL connection.
	if ((sslContext = SSL_CTX_new(SSLv23_client_method())) == NULL ||
	(sslHandle = SSL_new(sslContext)) == NULL ||
	SSL_set_fd(sslHandle, socket) != 1 ||
	SSL_connect(sslHandle) != 1) {
	ERR_print_errors_fp(stderr);
	return false;
	}
	return true;
	}
	string ReadAllFromSSL(SSL* ssl_handle) {
	const int BUCKET_READ_SIZE = 1024;
	char buffer[BUCKET_READ_SIZE];
	stringstream result;
	int received_bytes = std::numeric_limits<int>::max();
	while &##40;received_bytes >= BUCKET_READ_SIZE) {
	received_bytes = SSL_read(ssl_handle, buffer, BUCKET_READ_SIZE);
	if (received_bytes > 0) {
	buffer[received_bytes] = '\0';
	result << buffer;
	} else {
	cout << "Error when read from SSL"; // To get the error reason, use SSL_get_error.
	return "";
	}
	}
	return result.str();
	}
	string Base64Encode(const string& message) {
	// Do encoding.
	BIO* bio = BIO_new(BIO_f_base64());
	BIO* bmem = BIO_new(BIO_s_mem());
	BIO_push(bio, bmem);
	BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); // // Ignore newlines
	BIO_write(bio, message.c_str(), message.size());
	BIO_flush(bio);
	// Get results.
	char* data;
	int length = BIO_get_mem_data(bmem, &data);
	string encoded = string(data, length);
	BIO_free_all(bio);
	return encoded;
	}
	string GetBtcPostContent(const string& accessKey, const string& secretKey,
	const string& method) {
	// Get authorization token.
	long long tonce = getMilliSeconds();
	stringstream authInput;
	authInput << "tonce=" << tonce
	<< "&accesskey=" << accessKey
	<< "&requestmethod=post&id=1&method=" << method
	<< "&params=";
	string paramsHash = getHmacSha1(secretKey, authInput.str());
	string authToken = Base64Encode(accessKey + ":" + paramsHash);
	// Get post content.
	string json_content = "{\"method\": \"getAccountInfo\", \"params\": [], \"id\": 1}";
	stringstream postStream;
	postStream << "POST /api_trade_v1.php HTTP/1.1\r\n"
	<< "Content-Type: application/json-rpc\r\n"
	<< "Authorization: Basic " << authToken << "\r\n"
	<< "Json-Rpc-Tonce: " << tonce << "\r\n"
	<< "Content-Length: " << json_content.size() << "\r\n"
	<< "Host: api.btcc.com\r\n\r\n"
	<< json_content;
	string postContent = postStream.str();
	cout << "POST content: " << postStream.str() << endl;
	return postContent;
	}
	int main(int argc, char **argv) {
	string accessKey = "YOUR_ACCESS_KEY";
	string secretKey = "YOUR_SECRET_KEY";
	string method = "getAccountInfo";
	string postContent = GetBtcPostContent(accessKey, secretKey, method);
	// Start the real SSL request.
	int socket = 0;
	SSL* sslHandle = NULL;
	SSL_CTX* sslContext = NULL;
	if (SslConnect("api.btcc.com", 443, socket, sslHandle, sslContext)) {
	SSL_write(sslHandle, postContent.c_str(), postContent.size());
	string response = ReadAllFromSSL(sslHandle);
	cout << "Get response: " << response << endl;
	}
	// Cleanups no matter connect succeed or not.
	if (socket != 0) {
	close(socket);
	}
	if (sslHandle) {
	SSL_shutdown(sslHandle);
	SSL_free(sslHandle);
	}
	if (sslContext) {
	SSL_CTX_free(sslContext);
	}
	return 0;
}

交易 API v2.0.1.4

2016-01-14 交易API中新增获取归档订单的API方法:

  • getArchivedOrder
  • getArchivedOrders

交易 API v2.0.1.3

2014-11-19 将buyOrder2和sellOrder2中的amount和price参数类型由number变为string。

交易 API v2.0.1.2

2014-11-17 为getAccountInfo增加了loan参数。

交易 API v2.0.1.1

2014-10-17 更新了requestWithdrawal方法的描述。

交易 API v2.0.1

2014-08-21 为getTransactions API方法增加了两个参数: “since” and “sincetype”.

交易 API v2.0

2014-08-15 为所有市场发布了止损止盈订单API方法 :

  • buyStopOrder
  • sellStopOrder
  • getStopOrder
  • getStopOrders
  • cancelStopOrder

交易 API v1.9

2014-08-13 为 getOrder 增加了withdetail参数支持; 为 getOrders 增加了since和withdetail参数支持。

交易 API v1.8

2014-07-21 为 getAccountInfo 增加了更多的参数支持: 增加了“all”,“balance”,“frozen”和“profile”等参数支持。

交易 API v1.7

2014-07-17 增加了所有市场的iceberg订单API支持:

  • buyIcebergOrder
  • sellIcebergOrder
  • getIcebergOrder
  • getIcebergOrders
  • cancelIcebergOrder

交易 API v1.6

2014-07-10 增加了代码示例的Github链接。

交易 API v1.5.2

2014-04-02 本次交易API更新,减少了客户端请求量和网络带宽。

  • 更新了getOrders 和 getMarketDepth2 ,现支持可将 ‘market’ 参数设置为 “ALL”。
  • 增加了分页索引,可使 getOrders 和 getTransanctions 从索引开始返回结果。

交易 API v1.5.1

2014-03-28 本次更新包含一些小的新功能的完善以及缺陷的修复。

  • 在getMarketDepth2里增加了“最新更新时间”;
  • 标准化了 market currency参数,使之符合金融行业标准;
  • getWithdrawals 和 getDeposits 返回空数组替换了原来返回Error的情况;
  • 比特币交易现支持4位小数;
  • 改进了 buyOrder2 和 sellOrder2 处理市场价(price =null)的方式;

交易 API v1.5

2014年3月18日,我们发布了比特币-莱特币(LTC/BTC)互换交易,请将货币参数修改为“ltcbtc”以进行交易。

交易 API v1.4

在API中增加对提现权限的控制。目前api权限(permission)的值为: 1-只读权限, 3-仅交易权限, 5-仅提现权限,7-交易以及提现权限

交易 API v1.3

交易 API v1.3将支持莱特币的交易,本次更新与现有的接口兼容。

更新日志:

  • 增加了对莱特币的支持,所有受影响的方法增加了新的货币参数或者市场参数(null)。如果货币参数缺失,将以BTC和BTCCNY作为默认值。
  • 增加了API密钥使用权限。
  • 交易类型现增加了 “买莱特币”,“卖莱特币”,“莱特币充值”,“莱特币提现”,“莱特币退款”,文档更新“挂单返利”,”交易费用“。
  • 比特币或莱特币提现新增状态 “cancel”, “refund”, “processing”

交易 API v1.2

交易 API v1.2 使用与 v1 相同的 URL:https://api.btcc.com/api_trade_v1.php.

###更新日志

  • 普通列表项目新增方法buyOrder2 和 sellOrder2. 该方法将返回下单后的订单号. 原方法 buyOrder 和sellOrder 已过时。

交易 API v1.1

交易 API v1.1 使用与 v1 相同的 URL:https://api.btcc.com/api_trade_v1.php.

###更新日志

  • 添加新的方法 getTransanctions。
  • getMarketDepth方法过时了,请使用getMarketDepth2。
  • 为所有 API 方法修正参数验证。
  • 更新错误代码表。

交易 API v1

交易 API 是基于 JSON-RPC 2.0 实现的。 要了解更多关于 JSON-RCP 2.0 的规范,请参考其官方文档。

错误代码

所有 API 方法调用在请求失败或遇到未知错误时会返回 JSON-RPC 错误对象。 Code Message -32000 内部错误
-32003 人民币账户余额不足
-32004 比特币账户余额不足
-32005 挂单没有找到
-32006 无效的用户
-32007 无效的货币
-32008 无效的金额
-32009 无效的钱包地址
-32010 没有找到提现记录
-32011 没有找到充值记录
-32017 无效的类型
-32018 无效的价格
-32019 无效的参数
-32025 订单已取消
-32026 订单已完成
-32062 市场深度不足以成交该市场交易
-32065 无效的货币参数
-32086 订单处理中

{   "error":{
	"code":-32003,
	"message":"Insufficient CNY balance",
	"id": 1
	}
}

返回对象

成功的方法调用会返回如下对象。这些对象的示例会在方法文档中列出。

profile

名称 类型 描述
username string 账户用户名
trade_password_enabled boolean 指示该账户是否已设置交易密码
otp_enabled boolean 指示是否已启用双重认证
trade_fee number 比特币交易手续费
trade_fee_cnyltc number 莱特币交易手续费
trade_fee_btcltc number 比特币莱特币互换交易手续费
daily_btc_limit number 账户每日比特币提现限额
daily_ltc_limit number 账户每日莱特币提现限额
btc_deposit_address string 比特币充值地址
btc_withdrawal_address string 比特币提现地址
ltc_deposit_address string 莱特币充值地址
ltc_withdrawal_address string 莱特币提现地址
api_key_permission string API交易权限, 1-只读权限, 3-仅交易权限, 5-仅提现权限,7-交易以及提现权限
balance
名称 类型 描述
currency string 货币代码
symbol string 货币符号
amount number 账户余额 (小数精度)
amount_integer string 账户余额 (整数精度)
amount_decimal integer 在使用“amount_integer”时小数点的位置

frozen

名称 类型 描述
currency string 货币代码
symbol string 货币符号
amount number 账户冻结金额 (小数精度)
amount_integer string 账户冻结金额 (整数精度)
amount_decimal integer 在使用“amount_integer”时小数点的位置

loan

名称 类型 描述
currency string 货币代码
symbol string 货币符号
amount number 账户冻结金额 (小数精度)
amount_integer string 账户冻结金额 (整数精度)
amount_decimal integer 在使用“amount_integer”时小数点的位置

order

名称 类型 描述
id integer 挂单 ID
type string 挂单类型。可能值:bid 或 ask
price number 挂单价格
currency string 货币。可能值:CNY
amount number 挂单剩余数量。如果此值小于 amount_original,说明此挂单仅有部分成交
amount_original number 初始挂单数量
date integer Unix 时间戳。自1970年1月1日以来的秒数
status string 状态。可能值:open、closed 、cancelled、pending 或 error
detail object[] 订单详情,可选返回值。返回对象数组:order_detail

withdrawal

名称 类型 描述
id integer 提现 ID
address string 比特币或者莱特币提现地址
currency string 货币代码。可能值:BTC 或 LTC
amount number 提现数量
date integer Unix 时间戳。自1970年1月1日以来的秒数
transaction string 交易 ID
status string 提现状态。可能值:pending 、completed、 processing、 cancel、refund

deposit

名称 类型 描述
id integer 存款 ID
address string 比特币或者莱特币充值地址
currency string 货币代码。可能值:BTC 或 LTC
amount number 充值数量
date integer Unix 时间戳。自1970年1月1日以来的秒数
status string 充值状态。可能值:pending 或 completed

market_depth

名称 类型 描述
bid object[] 买单对象列表。价格从高到低排列
ask object[] 卖单对象列表。价格从低到高排列

bid / ask

名称 类型 描述
price number 1 BTC 或者 LTC 的价格
amount number BTC 或者 LTC 数量

transaction

名称 类型 描述
id integer 交易 ID
type string 交易类型。'fundbtc | withdrawbtc | fundmoney | withdrawmoney |refundmoney | buybtc | sellbtc | refundbtc | tradefee | rebate | fundltc| refundltc| withdrawltc |buyltc| sellltc'
btc_amount number 成交的 BTC 数量。负数表明是从账户余额中扣减
btc_amount number 成交的 LTC 数量。负数表明是从账户余额中扣减
cny_amount number v成交的 CNY 数量。负数表明是从账户余额中扣减
date integer Unix 时间戳(自1970年1月1日以来经过的秒数)

iceberg_order

名称 类型 描述
id integer Iceberg订单号.
type string [bid|ask]
price number 买/卖 1 BTC/LTC的价格.
market string [BTCCNY|LTCCNY|LTCBTC]
amount number Iceberg订单里剩余的未成交的BTC/LTC数量.
amount_original number Iceberg订单里的BTC/LTC总量.
disclosed_amount number 公开的每笔拆分订单的BTC/LTC数量,必须小于等于iceberg订单里的BTC/LTC总量.
variance number 为了使每笔拆分订单数量不同而设置的波动率.
date integer 精确到秒的Unix时间戳,起始值为1970年1月1日.
status string [ open | closed|cancelled |error ]``

order_detail

名称 类型 描述
dateline integer Unix 时间戳.
price number 买/卖 BTC/LTC的成交单价.
amount number 成交的BTC/LTC数量.

stop_order

名称 类型 描述
id integer 止损止盈订单号.
type string [bid|ask]
stop_price number 触发止损止盈订单的BTC/LTC单价. 如果设置了追单波动价格数量/率,触发单价将由系统自动调节.
trailing_amount number 追单波动数量,设置后可动态决定止损止盈单价.
trailing_percentage number 追单波动率,设置后可动态决定止损止盈单价.
price number 由止损止盈订单触发的订单中,所下订单的BTC/LTC单价.
market string [BTCCNY|LTCCNY|LTCBTC]
amount number 由止损止盈订单触发的订单中,所下订单的BTC/LTC数量.
date integer 止损止盈订单下单时间.
status string [ open|closed|cancelled|error ]
order_id integer 由止损止盈订单触发的订单的订单号,如果止损止盈订单尚未触发或者已被取消则值为null.

API 方法

buyOrder 该方法已过时,请使用buyOrder2。

buyOrder2

下比特币/莱特币买单,买单类型包括市价单和限价单,具体请参照参数表内描述。该方法将返回订单号。

参数

名称 类型 必选? 描述 price | string | 是 | 买 1 比特币/莱特币所用人民币的价格,最多支持小数点后 2位精度。若以市价单交易,将 price 设置为 null amount | string| 是 | 要买的比特币或者莱特币数量, BTC最多支持小数点后 4 位精度, 但最小买卖额度为0.001,LTC最多支持小数点后 3 位精度 market | string| 否 | 可使用[BTCCNY],[LTCCNY],[LTCBTC] 默认值为BTCCNY

JSON 请求示例

{"method":"buyOrder2","params":[\"500\",\"1\"],"id":1}
{"method":"buyOrder2","params":[\"500.01\",\"1.2312\",\"BTCCNY\"],"id":1}
## market order ## 
{"method":"buyOrder2","params":[null,\"1\"],"id":1}

返回

名称 类型 描述
result integer 如果下单成功,返回订单号

JSON 响应示例

{"result":12345,"id":"1"} 
cancelOrder

取消一个还未完全成交的挂单,其状态应该为“open”。

参数

名称 类型 必选? 描述
id number 要取消的挂单的 ID
market string 可选值BTCCNY、LTCCNY、LTCBTC 默认值为BTCCNY

JSON 请求示例

{"method":"cancelOrder","params":[2],"id":1}

返回

名称 类型 描述
result boolean 如果取消挂单成功,返回 true

JSON 响应示例

{"result":true,"id":"1"}

getAccountInfo

获取账户信息和余额。

参数

名称 类型 必选? 描述
类型 string 参数可以是“all”,“balance”,“frozen”, “loan”或者“profile”,默认为“all”.

JSON 请求示例

{"method":"getAccountInfo","params":[],"id":1}
## 只获取账户可用余额信息 ##
{"method":"getAccountInfo","params":["balance"],"id":1}

返回

名称 类型 描述
result object[] 包含或者是如下对象:profile, balance, frozen, loan

JSON 响应示例

{
	"result": {
	"profile": {
	"username": "btc",
	"trade_password_enabled": true,
	"otp_enabled": true,
	"trade_fee": 0,
	"trade_fee_cnyltc": 0,
	"trade_fee_btcltc": 0,
	"daily_btc_limit": 10,
	"daily_ltc_limit": 300,
	"btc_deposit_address": "123myZyM9jBYGw5EB3wWmfgJ4Mvqnu7gEu",
	"btc_withdrawal_address": "123GzXJnfugniyy7ZDw3hSjkm4tHPHzHba",
	"ltc_deposit_address": "L12ysdcsNS3ZksRrVWMSoHjJgcm5VQn2Tc",
	"ltc_withdrawal_address": "L23GzXJnfugniyy7ZDw3hSjkm4tHPHzHba",
	"api_key_permission": 3
	},
	"balance": {
	"btc": {
	"currency": "BTC",
	"symbol": "\u0e3f",
	"amount": "100.00000000",
	"amount_integer": "10000000000",
	"amount_decimal": 8
	},
	"ltc": {
	"currency": "LTC",
	"symbol": "\u0141",
	"amount": "0.00000000",
	"amount_integer": "0",
	"amount_decimal": 8
	},
	"cny": {
	"currency": "CNY",
	"symbol": "\u00a5",
	"amount": "50000.00000",
	"amount_integer": "5000000000",
	"amount_decimal": 5
	}
	},
	"frozen": {
	"btc": {
	"currency": "BTC",
	"symbol": "\u0e3f",
	"amount": "0.00000000",
	"amount_integer": "0",
	"amount_decimal": 8
	},
	"ltc": {
	"currency": "LTC",
	"symbol": "\u0141",
	"amount": "0.00000000",
	"amount_integer": "0",
	"amount_decimal": 8
	},
	"cny": {
	"currency": "CNY",
	"symbol": "\u00a5",
	"amount": "0.00000",
	"amount_integer": "0",
	"amount_decimal": 5
	}
	}
	"loan": {
	"btc": {
	"currency":"BTC",
	"symbol":"\u0e3f",
	"amount":"0.00000000",
	"amount_integer":"0",
	"amount_decimal":8
	},
	"cny":{
	"currency":"CNY",
	"symbol":"\u00a5",
	"amount":"0.00000",
	"amount_integer":"0",
	"amount_decimal":5
	}
	}
	},
	"id": "1"
}

getDeposits

获得用户全部充值记录。

参数

名称 类型 必选? 描述
currency string 目前支持“BTC”,“LTC”
pendingonly boolean 默认为“true”。如果为“true”,仅返回尚未入账的比特币或者莱特币充值

JSON 请求示例

{"method":"getDeposits","params":["BTC"],"id":1}

返回

名称 类型 描述
result object[] 包含对象:deposit

JSON 响应示例

{   "result":{
	"deposit":[{
	"id":49751,
	"address":"mufUAWHCius1jZpjB4zCUwzaRbYuwXCupC",
	"currency":"BTC",
	"amount":1,
	"date":1376910685,
	"status":"pending"
	},{
	"id":49749,
	"address":"mkrmyZyM9jBYGw5EB3wWmfgJ4Mvqnu7gEu",
	"currency":"BTC",
	"amount":2,
	"date":1376906645,
	"status":"completed"
	}]
	}
}

getMarketDepth

方法过时了,请使用getMarketDepth2。

getMarketDepth2

获得完整的市场深度。返回全部尚未成交的买单和卖单。

参数

名称 类型 必选? 描述
limit integer 限制返回的买卖单数目。默认是买单卖单各10条。
market string 可选值BTCCNY、LTCCNY、LTCBTC、ALL 默认值为BTCCNY

JSON 请求示例

## 单个市场 ##
{"method":"getMarketDepth2","params":[],"id":1}
## 所有市场 ##
{"method":"getMarketDepth2","params":[10,"ALL"],"id":1}

返回

名称 类型 描述
result object 对象数组:market_depth

JSON 响应示例

## 单个市场 ##
{  "result":{
	"market_depth":{
	"bid":[{
	"price":99,
	"amount":1
	},{
	"price":98,
	"amount":2
	}],
	"ask":[{
	"price":100,
	"amount":0.997
	},{
	"price":101,
	"amount":2
	}]}
	},
	"id":"1"
	}
	## 所有市场 ##
	{
	"result": {
	"market_depth_btccny": {
	"bid": [
	{
	"price": 2878.01,
	"amount": 1.2412
	}
	],
	"ask": [
	{
	"price": 2882,
	"amount": 0.1
	}
	],
	"date": 1396415275
	},
	"market_depth_ltccny": {
	"bid": [
	{
	"price": 78.1,
	"amount": 0.088
	}
	],
	"ask": [
	{
	"price": 78.3,
	"amount": 0.1
	}
	],
	"date": 1396415275
	},
	"market_depth_ltcbtc": {
	"bid": [
	{
	"price": 0.0272,
	"amount": 232.443
	}
	],
	"ask": [
	{
	"price": 0.0273,
	"amount": 251.578
	}
	],
	"date": 1396415276
	}
	},
	"id": "1"
}

getOrder

获得挂单状态。当withdetail设置为true的时候,可以获取此笔订单的所包含的所有交易详情。

参数

名称 类型 必选? 描述
id number 挂单 ID
market string 可选值BTCCNY、LTCCNY、LTCBTC 默认值为BTCCNY
withdetail boolean 是否返回订单内每笔交易详情。可选值true,false. 默认值为false,不返回交易详情

JSON 请求示例

{"method":"getOrder","params":[2],"id":1}

取BTCCNY市场订单号为2的订单,附带订单详情

{"method":"getOrder","params":[2,"BTCCNY",true],"id":1}

返回

名称 类型 描述
result object 返回对象:order

JSON 响应示例

{   
    "result":{
	"order":{
	"id":2,
	"type":"ask",
	"price":"46.84",
	"currency":"CNY",
	"amount":"0.00000000",
	"amount_original":"3.18400000",
	"date":1406860694,
	"status":"closed",
	"details":[{
	"dateline":"1406860696",
	"price":"46.84",
	"amount":3.184}]
	}},
	"id":"1"
}

getOrders

获得一组挂单的状态。

参数

名称 类型 必选? 描述
openonly boolean 默认为“true”。如果为“true”,仅返回还未完全成交的挂单。
market string 可选值BTCCNY、LTCCNY、LTCBTC、ALL 默认值为BTCCNY
limit integer 限制返回的交易记录数,默认为 1000。
offset integer 分页索引, 默认为 0.
since integer 限制返回交易记录的起始时间.
withdetail boolean 是否返回订单内每笔交易详情。可选值true,false. 默认值为false,不返回交易详情

JSON 请求示例

{"method":"getOrders","params":[],"id":1}
{"method":"getOrders","params":[false],"id":1}
## 返回所有市场的最近两笔订单,不管订单是否成交 ## 
{"method":"getOrders","params":[false,"ALL",2],"id":1}
## 返回所有市场的从1377671475时间点开始的最近10笔成交订单,并附带订单详情 ## 
{"method":"getOrders","params":[true,"ALL",10,0,1377671475,true],"id":1}

返回

名称 类型 描述
result object[] 对象数组:order

####JSON 响应示例

## 单个市场 ##
{   "result":{
	"order":[{
	"id":2,
	"type":"bid",
	"price":500,
	"currency":"cny",
	"amount":0.9,
	"amount_original":0.9,
	"date":1377671476,
	"status":"cancelled"
	},{
	"id":3,
	"type":"bid",
	"price":501,
	"currency":"cny",
	"amount":0.8,
	"amount_original":0.8,
	"date":1377671475,
	"status":"cancelled"
	}]
	},
	"id":"1"
}
## 所有市场 ##
{
	"result": {
	"order_btccny": [
	{
	"id": 13942927,
	"type": "bid",
	"price": "2000.00",
	"currency": "CNY",
	"amount": "0.00100000",
	"amount_original": "0.00100000",
	"date": 1396255376,
	"status": "open"
	},
	{
	"id": 13942807,
	"type": "bid",
	"price": "2000.00",
	"currency": "CNY",
	"amount": "0.00100000",
	"amount_original": "0.00100000",
	"date": 1396255245,
	"status": "open"
	}
	],
	"order_ltccny": [
	],
	"order_ltcbtc": [
	]
	},
	"id": "1"
}

getTransactions

获取交易记录。

####参数

名称 类型 必选? 描述
type string 按类型获取交易记录。默认为“all”(全部)。可用类型包括: 'all|fundbtc| withdrawbtc|withdrawbtcfee|refundbtc|fundltc | withdrawltc|withdrawltcfee|refundltc|fundmoney | withdrawmoney| withdrawmoneyfee|refundmoney|buybtc|sellbtc|buyltc|sellltc| tradefee| rebate '
limit integer 限制返回的交易记录数,默认为 10。
offset integer 分页索引, 默认为 0.
since integer 取从某一点开始的交易记录, 这一点可以是某个交易号或者Unix时间戳, 默认值为0.
sincetype string 指定since参数的类型,可以是“id”或者“time”,默认值为“time”.

####JSON 请求示例

{"method":"getTransactions","params":[],"id":1}
{"method":"getTransactions","params":["buybtc",2],"id":1}
# 取回从交易号101开始的100条交易记录 #
{"method":"getTransactions","params":["all",100,0,101,"id"],"id":1}

####返回

名称 类型 描述
result object[] transaction

####JSON 响应示例

{   "result":{"
	transaction":[{
	"id":8,
	"type":"buybtc",
	"btc_amount":"0.00100000",
	"cny_amount":"-0.10000",
	"date":1383128749
	},{
	"id":7,
	"type":"sellbtc",
	"btc_amount":"-0.00100000",
	"cny_amount":"0.10000",
	"date":1383128749
	}]
	},
	"id":"1"
}

getWithdrawal

获取提现状态。

参数

名称 类型 必选? 描述
id number 提现 ID
currency string BTC 和 LTC 默认为“BTC”

JSON 请求示例

{"method":"getWithdrawal","params":[1],"id":1}

返回

名称 类型 描述
result object 返回对象:withdrawal

JSON 响应示例

{   "result":{
	"withdrawal":{
	"id":20351,
	"address":"15MGzXJnfugniyy7ZDw3hSjkm4tHPHzHba",
	"currency":"BTC",
	"amount":0.1,
	"date":1376891209,
	"transaction":null,
	"status":"pending"
	}
	},
	"id":"1"
}

getWithdrawals

获取全部提现记录。

参数

名称 类型 必选? 描述
currency string 目前支持“BTC”,“LTC”
pendingonly boolean 默认为“true”。如果为“true”,仅返回尚未处理的提现记录

JSON Request

{"method":"getWithdrawals","params":["BTC"],"id":1}

返回

名称 类型 描述
result object[] 对象数组:withdrawal

JSON 响应示例

{   "result":{
	"withdrawal":[{
	"id":20351,
	"address":"15MGzXJnfugniyy7ZDw3hSjkm4tHPHzHba",
	"currency":"BTC",
	"amount":0.1,
	"date":1376891209,
	"transaction":null,
	"status":"pending"
	},{
	"id":20352,
	"address":"15MGzXJnfugniyy7ZDw3hSjkm4tHPHzHba",
	"currency":"BTC",
	"amount":0.1,"date":1376891268,
	"transaction":null,
	"status":"pending"
	}
	}],
	"id":"1"
}

requestWithdrawal

发起比特币提现请求,为了安全起见,本方法不提供提现地址参数,默认使用上一次提现的比特币地址。假如用户希望更改提现地址,需要首先去网站完成一笔提现,到最新更改的比特币收款地址。 提现比特币/莱特币的最小额度是0.0201.

参数

名称 类型 必选? 描述
currency string 货币代码。可能值:BTC 或 LTC
amount number 提现金额

JSON 请求示例

{"method":"requestWithdrawal","params":["BTC",0.1],"id":1}

返回

名称 类型 描述
result integer 返回提现 ID

JSON 响应示例

{"result":{"id":"20362"},"id":"1"}

sellOrder

该方法已过时,请使用sellOrder2.

sellOrder2

下比特币或莱特币卖单。卖单类型包括市价单和限价单,具体请参照参数表内描述。此方法返回订单号。

参数

名称 类型 必选? 描述
price string 卖 1 比特币,莱特币所用人民币的价格,最多支持小数点后 2 位精度。若以市价单交易,将 price 设置为 null
amount string 要卖的比特币数量, BTC最多支持小数点后 4 位精度, 但最小买卖额度为0.001,LTC最多支持小数点后 3 位精度
market string 可选值BTCCNY、LTCCNY、LTCBTC 默认值为BTCCNY

JSON 请求示例

{"method":"sellOrder2","params":[\"500\",\"1\"],"id":1}
{"method":"sellOrder2","params":[\"500.01\",\"1.231\",\"LTCCNY\"],"id":1}
## market order ## 
{"method":"sellOrder2","params":[null,\"1\"],"id":1}

返回

名称 类型 描述
result integer 如果下单成功,返回订单号

JSON 响应示例

 {"result":12345,"id":"1"}

Iceberg 订单API方法

Iceberg订单是指为了隐藏一笔较大订单而将其拆分为若干个小额订单分别下单的方法。 当一笔小额订单全部成交以后,下一笔被拆分的小额订单才会被放到市场里,如此下去,一直到整个iceberg订单完全成交。 为了更好的隐藏iceberg订单,我们引入了波动率这个参数,它可以用来控制每笔小额订单的数量波动范围。 你必须保证在下iceberg订单的时候,账户里有足够的可用余额,但是当iceberg订单下单成功以后,您的账户可用余额允许小于整个iceberg订单剩余的金额,因为iceberg订单每次只会冻结拆分的小订单的等值金额。 当一笔小额订单成交以后而你的可用余额不足以完成下一笔小额订单的时候,整个iceberg订单就会被取消。 对于每一笔小额订单,当有任何异常或错误发生的时候,整个iceberg订单也会被取消。 当你取消或者更新任何一笔小额订单的时候,整个iceberg订单也会被取消。

buyIcebergOrder

下iceberg的买单。此方法成功后返回iceberg订单号。

参数

名称 类型 必选? 描述
price number 买 1 比特币/莱特币所用的价格,BTC/CNY和LTC/CNY市场最多支持小数点后 2 位精度,LTC/BTC市场最多支持小数点后 3 位精度。假如要以市场价格交易,将 price 设置为 null.
amount number 要买的比特币或者莱特币总量, 最多支持小数点后 3 位精度.
disclosed_amount number 要买的公开的每笔拆分订单的比特币或者莱特币数量, 最多支持小数点后 3 位精度.
variance number 默认值为0,必须小于1. 作为被拆分订单数量的波动率,比如每笔拆分订单数量设置为5个,波动率为0.1时,拆分订单的实际数量为[5-50.1,5+50.1]之间的随机值.
market string 默认值为”BTCCNY”. [ BTCCNY

JSON 请求

{"method":"buyIcebergOrder","params":[500,100,5,0.2],"id":1}
## 市场价格订单 ## 
{"method":"buyIcebergOrder","params":[null,100,5,0.2],"id":1}

返回值

名称 类型 描述
result integer 下单成功后返回iceberg订单号.

JSON 响应

{"result":12345,"id":"1"}

sellIcebergOrder

下iceberg的卖单。此方法成功后返回iceberg订单号。

参数

名称 类型 必选? 描述
price number 卖 1 比特币/莱特币所用的价格,BTC/CNY和LTC/CNY市场最多支持小数点后 2 位精度,LTC/BTC市场最多支持小数点后 3 位精度。假如要以市场价格交易,将 price 设置为 null.
amount number 要卖的比特币或者莱特币总量, 最多支持小数点后 3 位精度.
disclosed_amount number 要卖的公开的每笔拆分订单的比特币或者莱特币数量, 最多支持小数点后 3 位精度.
variance number 默认值为0,必须小于1. 作为被拆分订单数量的波动率,比如每笔拆分订单数量设置为5个,波动率为0.1时,拆分订单的实际数量为[5-50.1,5+50.1]之间的随机值.
market string 默认值为”BTCCNY”. [ BTCCNY / LTCCNY / LTCBTC ]

JSON 请求

{"method":"sellIcebergOrder","params":[500,100,5,0.2],"id":1}
## 市场价格订单 ## 
{"method":"sellIcebergOrder","params":[null,100,5,0.2],"id":1}

返回值

名称 类型 描述
result integer 下单成功后返回iceberg订单号.

JSON 响应

{"result":12345,"id":"1"}

getIcebergOrder

获取一笔iceberg订单,包括所有在市场上公开过的拆分订单。

参数

名称 类型 必选? 描述
id number iceberg订单号.
market string 默认值为”BTCCNY”. [ BTCCNY|LTCCNY|LTCBTC ]

JSON 请求

{"method":"getIcebergOrder","params":[123],"id":1}

返回值

名称 类型 描述
result object[] iceberg_order

JSON响应

{   "result":
    {"iceberg_order": 
	{"id":1,
	"type":"bid",
	"price":"40.00",
	"market":"BTCCNY",
	"amount":"12.00000000",
	"amount_original":"12.00000000",
	"disclosed_amount":"5.00000000",
	"variance":"0.10",
	"date":1405412126,
	"status":"open",
	"order": [
	{"id":3301,
	"type":"bid",
	"price":"40.00",
	"currency":"CNY",
	"amount":"4.67700000",
	"amount_original":"4.67700000",
	"date":1405412126,
	"status":"open"}]}},
	"id":"1"
}

getIcebergOrders

获取多笔iceberg订单,包括每笔iceberg订单里的所有公开过的拆分订单。

参数

名称 类型 必选? 描述
limit integer 想要获取的iceberg订单的数量,默认值为1000.
offset integer 获取的订单起始索引,默认值为0.
market string 默认值为”BTCCNY”. [ BTCCNY|LTCCNY|LTCBTC ]

JSON 请求

{"method":"getIcebergOrders","params":[],"id":1}
## 获取从第11单开始的50个iceberg订单 ## 
{"method":"getIcebergOrders","params":[50, 10],"id":1}

返回值

名称 类型 描述
result object[] iceberg_order

JSON 响应

{   "result":
	{"iceberg_orders":
	[
	{"id":2,
	"type":"ask",
	"price":"40.00",
	"market":"BTCCNY",
	"amount":"0.00000000",
	"amount_original":"5.00000000",
	"disclosed_amount":"5.00000000", 
	"variance":"0.00",
	"date":1405412293,
	"status":"closed",
	"order":
	[
	{"id":3304,
	"type":"ask",
	"price":"40.00",
	"currency":"CNY",
	"amount":"0.00000000",
	"amount_original":"5.00000000",
	"date":1405412293,
	"status":"closed"}]},
	{"id":1,
	"type":"bid",
	"price":"40.00",
	"market":"BTCCNY",
	"amount":"7.00000000",
	"amount_original":"12.00000000",
	"disclosed_amount":"5.00000000",
	"variance":"0.00",
	"date":1405412292,
	"status":"open",
	"order":
	[
	{"id":3305,
	"type":"bid",
	"price":"40.00",
	"currency":"CNY",
	"amount":"5.00000000",
	"amount_original":"5.00000000",
	"date":1405412294,
	"status":"open"},
	{"id":3303,
	"type":"bid",
	"price":"40.00",
	"currency":"CNY",
	"amount":"0.00000000",
	"amount_original":"5.00000000",
	"date":1405412292,
	"status":"closed"}]}]},
	"id":"1"
}

cancelIcebergOrder

取消一个iceberg订单。如果iceberg订单已经完全成交或者被取消了,则会返回错误。与被取消的iceberg订单相关的所有订单都会被取消。

参数

名称 类型 必选? 描述
id number 要取消的iceberg订单号.
market string 默认值为”BTCCNY”. [ BTCCNY|LTCCNY|LTCBTC ]

JSON 请求

{"method":"cancelIcebergOrder","params":[1234],"id":1}

返回值

名称 类型 描述
result boolean 如果取消成功,则返回true.

JSON 响应

{"result":true,"id":"1"}

##止损止盈订单API方法 用户在止损止盈订单中设置一个“触发单价”,当市场单价达到触发单价的时候,会触发系统自动为用户下一个市价单或者限价单。 如果“price”参数没有设置,那么当市场单价达到触发单价时,被触发的订单是一个市价单。这种类型的订单也叫做“止损订单”。 如果“price”参数被设置了,那么当市场单价达到触发单价时,被触发的订单是一个以“price”作为价格的限价单。这种类型的订单也叫做“限价止损订单”。 注意,当用户下一个止损止盈订单的时候,并不会检查用户的可用余额。可用余额只有在市场单价达到触发单价,并导致被触发的订单下单时才会被检查和冻结。 追踪止损单是止损止盈单的一种。在追踪止损单中,触发单价是随着市场单价的变动而动态变化的。用户通过设置追单波动价格量(trailing_amount)或者追单波动价格率(trailing_percentage),并将触发单价(stop_price)设置为空(null),来使用追踪止损单。 当追单波动价格量被设置了以后,在一个止损卖单里,触发单价随着市场单价的上升单价量而上升相应的单价量;在止损买单里则是下降。 相似的,在一个止损卖单里,当追单波动价格率被设置了以后,触发单价随着市场价格的上升而上升到此时市场最高单价与(1-追单波动价格率)的乘积值;在止损买单里则是下降到市场最低单价与(1+追单波动价格率)的乘积值。 在止损止盈单里,下面三个值中有且仅有一个值被设置为非空:触发单价(stop_price), 追单波动价格量(trailing_amount),追单波动价格率(trailing_percentage)。

buyStopOrder

设置一个止损止盈买单。此方法返回一个止损止盈订单号。

参数

名称 类型 必选? 描述
stop_price number 触发单价,当市场成交价大于等于此价格时,会触发系统自动为用户下一个市价单或者限价单。在BTCCNY和LTCCNY市场最多允许2位小数,在LTCBTC市场最多允许4位小数。只有追单波动价格量(trailing_amount)和追单波动价格率(trailing_percentage)同时被设置为空时才可设置此参数.
price number 当市场单价达到触发单价时,被触发的订单中的单价。在BTCCNY和LTCCNY市场最多允许2位小数,在LTCBTC市场最多允许4位小数。如若要下市价单,将此参数设置为'null'.
amount number 当市场单价达到触发单价时,被触发的订单中要买的BTC/LTC数量。BTC最多允许4位小数,但最小买卖额度为0.001,LTC最多允许3位小数.
trailing_amount number 追单波动价格量,被设置后将决定触发单价。触发单价等于追单波动价格量与最低市场单价的和。其中最低市场单价指的是从此追踪止损单被创建以来的市场最低单价。只有触发单价和追单波动价格率同时被设置为空时才可设置此参数.
trailing_percentage number 追单波动价格率,被设置后将决定触发单价。触发单价等于最低市场单价*(1+追单波动价格率)。其中最低市场单价指的是从此追踪止损单被创建以来的市场最低单价。只有触发单价和追单波动价格率同时被设置为空时才可设置此参数.
market string 默认值为”BTCCNY”. [ BTCCNY|LTCCNY|LTCBTC ]

JSON 请求

## 止损止盈订单,触发后下限价买单 ##
{"method":"buyStopOrder","params":[500,500.01,0.123],"id":1}
## 止损止盈订单,触发后下市价买单 ## 
{"method":"buyStopOrder","params":[500,null,0.123],"id":1}

返回值

名称 类型 描述
result integer 如果止损止盈订单设置成功则返回止损止盈订单号.

JSON 响应

{"result":12345,"id":"1"}

sellStopOrder

设置一个止损止盈卖单。此方法返回一个止损止盈订单号。

参数

名称 类型 必选? 描述
stop_price number 触发单价,当市场成交价小于等于此价格时,会触发系统自动为用户下一个市价单或者限价单。在BTCCNY和LTCCNY市场最多允许2位小数,在LTCBTC市场最多允许4位小数。只有追单波动价格量(trailing_amount)和追单波动价格率(trailing_percentage)同时被设置为空时才可设置此参数.
price number 当市场单价达到触发单价时,被触发的订单中的单价。在BTCCNY和LTCCNY市场最多允许2位小数,在LTCBTC市场最多允许4位小数。如若要下市价单,将此参数设置为'null'.
amount number 当市场单价达到触发单价时,被触发的订单中要买的BTC/LTC数量。BTC最多允许4位小数,但最小买卖额度为0.001,LTC最多允许3位小数.
trailing_amount number 追单波动价格量,被设置后将决定触发单价。触发单价等于最高市场单价与追单波动价格量的差。其中最高市场单价指的是从此追踪止损单被创建以来的市场最高单价。只有触发单价和追单波动价格率同时被设置为空时才可设置此参数.
trailing_percentage number 追单波动价格率,被设置后将决定触发单价。触发单价等于最高市场单价*(1-追单波动价格率)。其中最高市场单价指的是从此追踪止损单被创建以来的市场最高单价。只有触发单价和追单波动价格率同时被设置为空时才可设置此参数.
market string 默认值为 “BTCCNY”. [ BTCCNY|LTCCNY|LTCBTC ]

JSON 请求

## 止损止盈订单,触发后下限价卖单 ##
	{"method":"sellStopOrder","params":[500,499.99,0.123],"id":1}
## 止损止盈订单,触发后下市价卖单 ## 
	{"method":"sellStopOrder","params":[500,null,0.123],"id":1}

返回值

名称 类型 描述
result integer 如果止损止盈订单设置成功则返回止损止盈订单号.

JSON 响应

{"result":12345,"id":"1"}

getStopOrder

获取一个止损止盈订单.

参数

名称 类型 必选? 描述
id number 止损止盈订单号.
market string 默认值为”BTCCNY”. [ BTCCNY |LTCCNY| LTCBTC ]

JSON 请求

{"method":"getStopOrder","params":[123],"id":1}
## 获取订单号为123的LTCCNY订单 ##
{"method":"getStopOrder","params":[123, "LTCCNY"],"id":1}

返回值

名称 类型 描述
result object stop_order

JSON 响应

{   "result":
	{"stop_order":
	{"id":1,
	"type":"bid",
	"stop_price":"50.00",
	"trailing_amount":"10.00000000",
	"trailing_percentage":null,
	"price":"50.00",
	"market":"LTCCNY",
	"amount":"2.00000000",
	"date":1407489603,
	"status":"open",
	"order_id":null}},
	"id":"1"
}

getStopOrders

获取一组符合筛选条件的止损止盈订单.

参数

名称 类型 必选? 描述
status string 要筛选的订单状态: [ open | closed | cancelled | error ]
type string 要筛选的订单类型: [ ask | bid ]
stop_price float 要筛选的触发单价. 对于止损止盈买单来说,将返回所有触发单价小于等于此参数的订单;对于止损止盈卖单来说,将返回所有触发单价大于等于此参数的订单.
limit integer 限制返回的订单数量,默认值为1000.
offset integer 起始分页索引,默认值为0.
market string 默认值为”BTCCNY”. [ BTCCNY |LTCCNY |LTCBTC ]

JSON 请求

{"method":"getStopOrders","params":[],"id":1}

返回值

名称 类型 描述
result object[] 对象数组:stop_order

JSON 响应

{   "result":
	{"stop_orders":
	[
	{"id":1,
	"type":"bid",
	"stop_price":"50.00",
	"trailing_amount":"10.00000000",
	"trailing_percentage":null,
	"price":"50.00",
	"market":"LTCCNY",
	"amount":"2.00000000",
	"date":1407492143,
	"status":"open",
	"order_id":null},
	{"id":2,
	"type":"bid",
	"stop_price":"44.00",
	"trailing_amount":null,
	"trailing_percentage":"0.10",
	"price":"51.00",
	"market":"LTCCNY",
	"amount":"2.00000000",
	"date":1407492144,
	"status":"open",
	"order_id":null}]},
	"id":"1"
}

cancelStopOrder

取消一个止损止盈订单. 如果订单已经成交或者已被取消则操作失败.

参数

名称 类型 必选? 描述
id number 要取消的订单号.
market string 默认值为”BTCCNY”. [ BTCCNY| LTCCNY|LTCBTC ]

JSON 请求

{"method":"cancelStopOrder","params":[123],"id":1}
	## 取消订单号为123的LTCCNY订单 ##
{"method":"cancelStopOrder","params":[123, "LTCCNY"],"id":1}

返回值

名称 类型 描述
result boolean 如果取消成功,则返回true.

JSON 响应

{"result":true,"id":"1"}

getArchivedOrder

获得一个归档订单,归档订单指的是被迁移的且订单状态不会再更改的订单。

参数

名称 类型 必选? 描述
id number 要获得的归档订单id.
market string 缺省是“BTCCNY”. [ BTCCNY | LTCCNY | LTCBTC ]
withdetail boolean 是否返回订单详细.

JSON 请求

{"method":"getArchivedOrder","params":[2,1],"id":1}

返回值

名称 类型 描述
result object order

JSON 响应

{
	"result": {
		"order": {
			"id": 2,
			"type": "ask",
			"price": "46.84",
			"currency": "CNY",
			"amount": "0.00000000",
			"amount_original": "3.18400000",
			"date": 1406860694,
			"status": "closed",
			"details": [
				{
					"dateline": "1406860696",
					"price": "46.84",
					"amount": 3.184
				}
			]
		}
	},
	"id": "1"
}

getArchivedOrders

获得多个归档订单.

参数

名称 类型 必选? 描述
market string NO 缺省是“BTCCNY”. [ BTCCNY | LTCCNY | LTCBTC | ALL]
limit integer NO 最多获得多少个订单,缺省值是200.
less_than_order_id integer NO 起始order_id,返回结果以order_id从大到小排列,缺省值是0(表示以数据库中的order_id最大值作为起始order_id).
withdetail boolean NO 是否返回此订单对应的详细信息.

JSON 请求

{"method":"getArchivedOrders","params":["BTCCNY",10,11,1],"id":1}

返回值

名称 类型 描述
result object[] 对象数组:order[]

JSON 响应

{
	"result": {
		"order": [
			{
				"id": 10,
				"type": "ask",
				"price": "2.10",
				"avg_price": "431.69",
				"currency": "CNY",
				"amount": "0.00000000",
				"amount_original": "1.00000000",
				"date": 1403077028,
				"status": "closed",
				"details": [
					{
						"dateline": "1403077029",
						"price": "479.09",
						"amount": 0.4
					},
						{
						"dateline": "1403077029",
						"price": "400.09",
						"amount": 0.6
					}
				]
			},
			{
				"id": 9,
				"type": "ask",
				"price": "2.10",
				"avg_price": 0,
				"currency": "CNY",
				"amount": "0.00000000",
				"amount_original": "1.00000000",
				"date": 1403077028,
				"status": "closed"
			}
		],
		"date": 1452253924
	},
	"id": "1"
}

API 常见问题

使用交易API时为什么会出现401 Unauthorized 错误?

  • 请校准系统时间,确保 tonce 为标准Linux16位值;
  • 确保Access Key有效;
  • 确保Params有效;请查看以下关于getAccountInfo,buyOrder2/sellOrder2以及getOrders的说明;
  • 确保HTTP Authorization Header 提交给服务器了;

getAccountInfo中参数如何配置?

Signature 哈希值为:

"tonce=<timestamp>
	&accesskey=<yourkey>
	&requestmethod=post
	&id=1
	&method=getAccountInfo
	&params="

JSON Request格式为:

{"method":"getAccountInfo","params":[],"id":1}

buyOrder2/sellOrder2 的参数如何设置?

限价单下单方式:

Signature 哈希值为:

"tonce=<timestamp>
	&accesskey=<yourkey>
	&requestmethod=post
	&id=1
	&method=buyOrder2
	&params=0.0001,0.005,LTCBTC"

JSON Request格式为: LTC/BTC

{"method":"buyOrder2","params":[0.0001,0.005,"LTCBTC"],"id":1}

LTC/CNY

{"method":"buyOrder2","params":[100.00,0.001,"LTCCNY"],"id":1}

BTC/CNY

{"method":"buyOrder2","params":[4000.00,0.005,"BTCCNY"],"id":1}

市场价下单方式:

Signature 哈希值为:
"tonce=<timestamp>
	&accesskey=<yourkey>
	&requestmethod=post
	&id=1
	&method=buyOrder2
	&params=,0.2,ltccny"

JSON Request格式为:

{"method":"buyOrder2","params":[null,0.2,"ltccny"],"id":1}

getOrders 中 参数如何配置?

Openonly 为false:

Signature 哈希值为:

"tonce=<timestamp>
	&accesskey=<yourkey>
	&requestmethod=post
	&id=1
	&method=getOrders
	&params=false,LTCCNY"

JSON Request格式为:

{"method":"getOrders","params":[false,"LTCCNY"],"id":1}

Openonly 为true:

Signature 哈希值为:

"tonce=<timestamp>
	&accesskey=<yourkey>
	&requestmethod=post
	&id=1
	&method=getOrders
	&params=true,LTCCNY"

JSON Request格式为:

{"method":"getOrders","params":[true,"LTCCNY"],"id":1}

备注: 以上实列中为“LTCCNY”(莱特币交易查询),若想查询其他类型,改为相应类型“BTCCNY”,“LTCBTC”即可。

为什么会出现403 Forbidden错误?

首先,请确认你是否有“允许交易”或者“允许提现”权限,出现该错误是因为你创建的API密钥没有交易、提现的权限,你可以新创建一个有“允许交易”或者“允许提现“的API密钥。

为什么出现”Invalid Amount”和”Invalid Price”错误?

出现这个问题是你传递的price/amount参数为0或者round(n)后为0。其中n为price、amount的精度; BTC/CNY: Price:n=2—表示人民币的精度,Amount:n=4-表示比特币售出或购买数量; LTC/CNY: Price:n=2—表示人民币的精度,Amount:n=3-表示莱特币售出或购买数量; LTC/BTC: Price:n=4—表示比特币的精度,Amount:n=3-表示莱特币售出或购买数量;

Market Data API 多久刷新一次?

每隔5秒刷新一次。

调用getMarketDepth2 查询市场深度会出现“ 503 Service Temporarily Unavailable ”错误?

可能是由于我们系统正在升级,请稍等一段时间即可进行查询。

使用API有限制么?

交易API每秒最多提交5个请求。 数据API是不能不停地连续访问的。

使用Python 时会出现 “httplib has no attribute HTTPSConnection”错误?

使用Python出现HTTPSConnection error,请确认你是否import httplib 包.

可以从哪里下载源代码?

请访问 https://github.com/BTCChina.

GETORDER返回结果的Price是下单价格还是成交价格?

GETORDER返回结果的Price是下单价格,若想查询成交价格、成交均价请查询GETTRANSACTIONS。

Clone this wiki locally