回顾篇:淘宝API web开发二 调用API

上一篇已经说明了如何引导用户授权登录,获取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用户授权类型” 标识为“需要”的,调用时均要传该参数
应用参数是根据不同的API而不同的,我们就以taobao.trades.sold.increment.get(增量订单)为例,来做说明。

应用参数如下:

名称

类型

是否必须

描述

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;

		}



	
	}
 ?>

现在来测试调用taobao.trade.sold.increment.get接口,代码如下webERP / api / taobao / tradeSoldIncrementGet.php
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;
    	}

    }

 ?>



你可能感兴趣的:(接口API)