上一篇已经说明了如何引导用户授权登录,获取access_token。这样,我们就可以正式调用API了。
淘宝提供了两种调用方法,一种为http调用方法,一种为https免签调用方式。因为项目用的是第一种方法,那么在这里,我们就只介绍http的调用方法。
淘宝API采用REST风格,我们需要按照淘宝开发平台的规范拼装一个正确的URL,通过HTTP请求到http://gw.api.taobao.com/router/rest(测试环境为http://gw.api.tbsandbox.com/router/rest),就可以获取到自己需要的数据。
调用API时,需要传入系统参数和应用参数。
系统参数如下:
名称 | 类型 |
是否必须 | 描述 |
method | string |
Y |
API接口名称 |
timestamp | string |
Y |
时间戳,格式为yyyy-mm-dd HH:mm:ss,例如:2013-05-06 13:52:03。淘宝API服务端允许客户端请求时间误差为6分钟。 |
format | string |
N |
可选,指定响应格式。默认xml,目前支持格式为xml,json |
app_key | string |
Y |
TOP分配给应用的AppKey ,创建应用时可获得 |
v | string |
Y |
API协议版本,可选值:2.0。 |
sign | string |
Y |
对 API 输入参数进行 md5 加密获得,下面会介绍到sign |
sign_method | string |
Y |
参数的加密方法选择,可选值是:md5,hmac |
session | string |
N |
TOP分配给用户的SessionKey(或 Access Token),通过登陆授权获取(可参考上一篇博文) 。API 文档上 “API用户授权类型” 标识为“需要”的,调用时均要传该参数 |
应用参数如下:
名称 | 类型 |
是否必须 | 描述 |
fields | Field List |
Y |
获取到数据后,需要返回的字段。 示例值:tid,type,status,modified,orders.title,orders.oid 更多值请参考http://api.taobao.com/apidoc/api.htm?spm=0.0.0.0.yd3ygq&path=cid:5-apiId:128 |
start_modified | Date |
Y |
查询修改开始时间(修改时间跨度不能大于一天)。格式:yyyy-MM-dd HH:mm:ss |
end_modified | Date |
Y |
查询修改结束时间,必须大于修改开始时间(修改时间跨度不能大于一天),格式:yyyy-MM-dd HH:mm:ss。 |
status | string |
N |
交易状态,默认查询所有交易状态的数据,除了默认值外每次只能查询一种状态。可选值如 TRADE_NO_CREATE_PAY(没有创建支付宝交易) WAIT_BUYER_PAY(等待买家付款) 等。 |
type | string |
N |
交易类型列表,同时查询多种交易类型可用逗号分隔。默认同时查询guarantee_trade,auto_delivery,ec,code,step的5种交易类型的数据。 |
ext_type | string |
N |
可选值有ershou(二手市场的订单),service(商城服务子订单)mark(双十一大促活动异常订单)作为扩展类型筛选只能做单个ext_type查询,不能全部查询所有的ext_type类型 |
tag | string |
N |
卖家对交易的自定义分组标签,目前可选值为:time_card(点卡软件代充),fee_card(话费软件代充) |
page_no | Number |
N |
页码。取值范围:大于零的整数;默认值:1。注:必须采用倒序的分页方式(从最后一页往回取)才能避免漏单问题。 |
page_size | Number |
N |
每页条数。取值范围:1~100,默认值:40。 |
use_has_next | Boolean |
N |
是否启用has_next的分页方式,如果指定true,则返回的结果中不包含总记录数,但是会新增一个是否存在下一页的的字段,通过此种方式获取增量交易,效率在原有的基础上有80%的提升。 |
在系统参数中,我们需要传入参数的签名验证sign,淘宝开发平台服务器需要对该请求参数进行验证是否合法,方法如下:
根据参数名称(除签名和图片)将所有请求参数按照字母先后顺序排序:key + value.....key + value,再将应用的secretKey加在该字符串的前后两端。
例如,secretKey=4,将参数为foo=1,bar=2,baz=3排序为bar=2,baz=3,foo=1,参数名和参数值连接后,拼接成字符串 4bar2baz3foo14
然后再将拼接的字符串采用MD5或者HMAC加密,将加密结果转换为32位大写字符串。
最后,我们就可以将所有的参数拼接好,使用CURL库将参数POST到淘宝开发平台,获取我们需要的数据了。
具体代码如下:
设置请求参数的应用级参数 webERP / api / taobao / common / taobaoRequest.php
apiMethod = empty($value)? '' : $value;
}
/**
* 返回使用的接口名称
* @return 使用的接口名称
*/
function getApiMethod(){
return $this->apiMethod;
}
/**
* 设置应用参数值,为了适用不同的接口,参数名需要自己传入
* @param string $key 应用参数的参数名,不同接口参数名会有所不同
* @param string $value 参数的值
*/
public function set( $key, $value ){
$this->apiParams[$key] = $value;
}
/**
* 获取指定的应用参数值
* @param string $key 指定的参数名
* @return string 对应的参数值
*/
public function get( $key ){
return isset($this->apiParams[$key])? $this->apiParams[$key] : null;
}
/**
* 获取按参数名称排序后的应用级参数数组
* @return array 应用级参数数组
*/
public function getApiParams(){
//将参数按字母排序
ksort($this->apiParams);
if( $this->apiParams ){
return $this->apiParams;
}else{
return [];
}
}
/**
* 有些接口需要传送附件,获取文件的base64编码
* @param string 文件路径
* @return 文件内容的编码
*/
public function fileHandle( $file ){
//php curl的附件传送机制中,需要在文件路径前加上@
if(substr($file, 0, 1) == '@'){
$file = substr($file, 1);
$file = base64_encode( file_get_contents($file) );
}
return $file;
}
}
?>
调用API接口 webERP / api / taobao / common / taobaoClient.php
getApiMethod();//API接口名称
if($session != null){
$sysParams['session'] = $session;//access token
}
$sysParams['timestamp'] = date('Y-m-d H:i:s');//时间戳
$sysParams['format'] = 'json'; // 指定响应格式,支持的格式有json,xml
$sysParams['app_key'] = $this->$appKey;
$sysParams['v'] = $this->apiVersion;
$sysParams['sign_method'] = 'md5';//参数的加密方法选择,可选值是:md5,hmac
//应用级参数
$apiParams = array();
$apiParams = $request->getApiParams();
//系统参数,签名验证sign
$sysParams['sign'] = $this->generateSign(array_merge($sysParams, $apiParams ));
$requestUrl = $this->gateWayUrl . '?' . http_build_query($sysParams);
//获取数据
try{
$resp = $this->curl($requestUrl, $apiParams);
}catch(Exception $e){
$result->code = $e->getcode();
$result->zh_desc = "curl发送http请求失败";
$result->en_desc = $e->getMessge();
}
//解析返回结果
$respObject = json_decode($resp); // 解析json格式数据
$respWellFormed = false;
if( null != $respObject){
$respWellFormed = true;
foreach ( $respObject as $propKey => $propValue) {
$respObject = $propValue;
}
}
if(false === $respWellFormed){
$result->code = 1;
$result->zh_desc = "api返回数据错误或程序无法解析返回参数";
$result->en_desc = "HTTP_RESPONSE_NOT_WELL_FORMED";
return $result;
}
return $respObject;
}
/**
* 生成验证签名sign
* 根据参数名称(除签名和图片)将所有请求参数按照字母先后顺序排序,
* 再将应用的secretKey加在该字符串的前后两端,
* 然后再将拼接的字符串采用MD5或者HMAC加密,将加密结果转换为32位大写字符串。
* @param array 请求参数数组
* @return array 加密后的签名
*/
private function generateSign( $params ){
if( $params != null){
ksort($params);
$stringToBeSigned = $this->secretKey;
foreach ($params as $key => $value) {
$stringToBeSigned .= "$key$value";
}
$stringToBeSigned .= $this->secretKey;
}else{
$stringToBeSigned = $this->secretKey;
$stringToBeSigned .= $this->secretKey;
}
//注意:根据系统参数sign_method设置的加密的方法
return strtoupper( md5($stringToBeSigned) );
}
/**
* 使用CURL库,做HTTP请求数据
* @param string 请求访问的地址
* @param array 访问所需的应用级参数
* @return json 返回的数据结果
*/
public function curl($url, $postFields = null){
//使用curl库
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);//需要获取的URL
curl_setopt($ch, CURLOPT_FAILONERROR, false);//不显示HTTP状态码
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//获取的信息以文件流的形式返回
//https免签调用方式
if( strlen($url) >5 && strtolower(substr($url, 0, 5)) == 'https'){
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, fasle);//终止从服务器端进行验证
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
//
if( isset($postFields) && 0 > count($postFields) ){
curl_setopt($ch, CURLOPT_POST, ture);//以POST方式传送
$postMultipart = false;
//判断是否有附件传送
foreach ($postFields as $key => $value) {
if( '@' == substr($value, 0, 1)){
$postMultipart = true;
break;
}
}
unset($key, $value);
if( $postMultipart ){
curl_setopt($ch, CURLOPT_POSTFIELD, $postFields);
}else{
curl_setopt($ch, CURLOPT_POSTFIELD, http_build_query($postFields));
}
}
$response = curl_exec($ch);
if( curl_errno($ch) ){
throw new Exception(curl_errno($ch), 0);
}else{
$httpStatusCode = curl_getinfo($ch, CURLOPT_HTTP_CODE);
if(200 != $httpStatusCode){
throw new Exception($response, $httpStatusCode);
}
}
curl_close($ch);
return $response;
}
}
?>
setApiMethod('taobao.trades.sold.increment.get');
//根据淘宝要求的该接口的应用参数,设置各个参数值
$fields = 'seller_nick, buyer_nick, title, type, created, tid,buyer_rate,can_rate,status, payment, discount_fee, adjust_fee, post_fee, total_fee, pay_time, end_time, modified, consign_time, buyer_obtain_point_fee, point_fee, real_point_fee, received_payment,num, price, cod_fee, cod_status, shipping_type, receiver_name, receiver_state, receiver_city, receiver_district, receiver_address, receiver_zip, receiver_mobile, receiver_phone,alipay_id,alipay_no,has_buyer_message,credit_card_fee,step_trade_status,step_paid_fee,mark_desc,trade_source,seller_flag,is_part_consign, orders.title, orders.price, orders.num, orders.sku_id, orders.refund_status, orders.status, orders.oid, orders.total_fee, orders.payment, orders.discount_fee, orders.adjust_fee, orders.sku_properties_name, orders.outer_sku_id, orders.refund_id,orders.end_time,orders.consign_time,orders.shipping_type,orders.logistics_company,orders.invoice_no';
$request->set('fields',$fields);
$request->set('start_modified',$start_date);
$request->set('end_modified',$end_date);
$page_size = 20;
$request->set('page_size', $page_size);//每页20条记录
$request->set('use_has_next', 'true');//分页获取
$page_no = 1;
while(true){
$request->set('page_no', $page_no);//获取第page_no页数据
$response = $taobao->execute($request,$access_token);
echo '';
var_dump($response);//输出返回结果,可根据自己需要做其他操作
//获取错误,停止获取
if( isset($response->code) ){
break;
}
//判断是否还存在下一页,如果还存在,则继续请求数据
if( $response->has_next ){
$page_no++;
}else{
break;
}
}
?>