支付寶服務窗API接口的開發對于許多網站要充值的朋友來講是非常的重要的,今天我們就一起來看一篇關于php版本的支付寶服務窗API接口的開發例子。
這兩天沒事要接入支付寶服務窗,看支付寶的DEMO,我的神,我怎么評價好呢?開發思路很牛逼,但是閱讀性不是很好,很阻礙簡單的開發。所以我就根據提供的API簡單的開發了點,接口還有很多不完善,有興趣的可以自己完善一下,下邊我就把代碼貼出來,有時間再寫如何使用。
- <?php
- class AlipayService{
- /**
- - 服務接口信息
- */
- public $service = null;
- /**
- - 簽名信息
- */
- public $sign = null;
- /**
- - 簽名類型
- */
- public $sign_type = null;
- /**
- - 字符集
- */
- public $charset = null;
- /**
- - 解析的biz_content數據
- */
- public $request = null;
- /**
- - 用戶openid
- */
- public $from_user_id = null;
- /**
- - 消息類型
- */
- public $msg_type = null;
- /**
- - 事件類型
- */
- public $event_type = null;
- /**
- - 行為參數
- */
- public $action_param = null;
- /**
- - 支付寶用戶信息
- */
- public $user_info = null;
- /**
- - 文本消息內容
- */
- public $text = null;
- /**
- - 圖片媒體id
- */
- public $media_id = null;
- /**
- - 圖片格式
- */
- public $format = null;
- /**
- - 是否開啟調試
- */
- private $debug = false;
- /**
- - 接口類型
- */
- private $interface_type = array(
- 'qrcode' => 'alipay.mobile.public.qrcode.create',
- 'follow' => 'alipay.mobile.public.follow.list',
- 'gis_get' => 'alipay.mobile.public.gis.get',
- 'menu_get' => 'alipay.mobile.public.menu.get',
- 'menu_add' => 'alipay.mobile.public.menu.add',
- 'down_media' => 'alipay.mobile.public.multimedia.download',
- 'menu_update' => 'alipay.mobile.public.menu.update',
- 'info_query' => 'alipay.mobile.public.info.query',
- 'info_modify' => 'alipay.mobile.public.info.modify',
- 'shortlink' => 'alipay.mobile.public.shortlink.create',
- 'label_add' => 'alipay.mobile.public.label.add',
- 'label_del' => 'alipay.mobile.public.label.delete',
- 'label_update' => 'alipay.mobile.public.label.update',
- 'label_query' => 'alipay.mobile.public.label.query',
- 'label_user_add' => 'alipay.mobile.public.label.user.add',
- 'label_user_del' => 'alipay.mobile.public.label.user.delete',
- 'label_user_query' => 'alipay.mobile.public.label.user.query',
- 'message_custom' => 'alipay.mobile.public.message.custom.send',
- 'message_total' => 'alipay.mobile.public.message.total.send',
- 'message_single' => 'alipay.mobile.public.message.single.send',
- 'message_label_send' => 'alipay.mobile.public.message.label.send',
- );
- /**
- - 私有密鑰地址,替換為你自己的
- */
- private $private_rsa_key_path ='rsa_private_key.pem';
- /**
- - 私有密鑰地址,替換為你自己的
- */
- private $public_rsa_key_path ='rsa_public_key.pem';
- /**
- - 支付寶窗的app id 替換成你自己的
- */
- private $app_id = '2015120200901652';
- /**
- - 開啟DEBUG參數
- - @params bool debug true 開啟調試 false 關閉調試
- - @author widuu <admin@widuu.com>
- */
- public function __construct( $debug = false ){
- /* 是否開啟DEBUG */
- if( $debug ) $this->debug = true;
- }
- /**
- - 獲取參數,解析請求參數
- -
- - @author widuu <admin@widuu.com>
- */
- public function get_request(){
- if( !emptyempty($_POST) ){
- // 請求的服務接口
- $this->service = $_POST['service'];
- // 獲取請求字符集
- $this->charset = $_POST['charset'];
- // 獲取請求的biz_content
- $request_biz_content = $_POST['biz_content'];
- // 加密算法
- $this->sign_type = $_POST['sign_type'];
- // 加密字符串
- $this->sign = $_POST['sign'];
- // 如果請求格式不是Utf-8 轉換格式為Utf-8
- if( strtolower($this->charset) != 'utf-8' ){
- $request_biz_content = iconv('GBK', 'utf-8', $request_biz_content);
- }
- // 解析字符串為xml
- $request_xml = @simplexml_load_string($request_biz_content, "SimpleXMLElement" , LIBXML_NOCDATA );
- // 解析為數組
- $request_array = json_decode(json_encode($request_xml),true);
- $this->request = $request_array;
- /* 解析 */
- $this->analysis($request_array);
- if($this->debug) $this->write_log('REQUEST_INFO',var_export($request_array,true));
- // 默認驗證方法
- if( $this->service == 'alipay.service.check'){
- $this->verify($_POST);
- exit();
- }
- /* 返回結果 */
- return $request_array;
- }
- }
- /**
- - 回復文本內容
- - @params string content 文本數據
- - @params bool mass ture為群發
- - @author widuu <admin@widuu.com>
- */
- public function text($content,$mass=false){
- $info['text'] = array( 'content' => $content );
- /* 組織內容 */
- $biz_content = $this->common_response('text',$info,$mass);
- /* 判斷是否為群發 */
- if($mass){
- $method = 'message_total';
- }else{
- $method = 'message_custom';
- }
- $sys_params = $this->common_system($method,$biz_content);
- $sys_params['sign'] = $this->rsa_sign($this->build_query($sys_params));
- /* 返回結果 結果是JSON數據 */
- $result = $this->response_post($sys_params);
- return $result;
- }
- /**
- - 回復圖文內容
- - @params array articles 拼接的圖文消息數組
- - @params bool mass ture為群發
- - @author widuu <admin@widuu.com>
- */
- public function articles($articles,$mass=false){
- $info['articles'] = array($articles);
- /* 組織內容 */
- $biz_content = $this->common_response('image-text',$info,$mass);
- /* 判斷是否群發 */
- if($mass){
- $method = 'message_total';
- }else{
- $method = 'message_custom';
- }
- /* 加密參數 */
- $sys_params = $this->common_system($method,$biz_content);
- /* 加密字符 */
- $sys_params['sign'] = $this->rsa_sign($this->build_query($sys_params));
- /* 返回結果 結果是JSON數據 */
- $result = $this->response_post($sys_params);
- return $result;
- }
- /**
- - 關注事件
- -
- - @author widuu <admin@widuu.com>
- */
- public function is_follow(){
- $request = $this->request;
- if( $request['MsgType'] == 'event' && $request['EventType'] == 'follow' ){
- return true;
- }else{
- return false;
- }
- }
- /**
- - 取消關注事件
- -
- - @author widuu <admin@widuu.com>
- */
- public function is_unfollow(){
- $request = $this->request;
- if( $request['MsgType'] == 'event' && $request['EventType'] == 'unfollow' ){
- return true;
- }else{
- return false;
- }
- }
- /**
- - 下載用戶發來的圖片
- - @param media_id string 圖片id
- - @param filename string 保存圖片地址和名稱
- - @author widuu <admin@widuu.com>
- */
- public function down_media($media_id,$filename){
- $sys_params = $this->common_system('down_media',array('mediaId'=>$media_id));
- $sys_params['sign'] = $this->rsa_sign($this->build_query($sys_params));
- /* 返回數據 */
- $result = $this->response_post($sys_params,true);
- $result = file_put_contents($filename, $result);
- if( $this->debug ){
- $this->write_log('SAVE_IMAGE','保存圖片'.(string)$result);
- }
- return $result;
- }
- /**
- - (添加|更新|獲取)自定義菜單
- - @param string $type (add|update|get)
- - @param array $menu 菜單數組,如果是獲取菜單可以留空
- - @author widuu <admin@widuu.com>
- */
- public function menu( $type,$menu = array() ){
- if( !in_array( $type, array('get','update','add')) ){
- if( $this->debug ){
- $this->write_log('ERROR','菜單操作方法錯誤');
- }
- return false;
- }
- /* 拼接接口方法 */
- $method = 'menu_'.$type;
- $sys_params = $this->common_system($method,$menu);
- /* 加密字符串 */
- $sys_params['sign'] = $this->rsa_sign($this->build_query($sys_params));
- /* 請求獲取結果 */
- $result = $this->response_post($sys_params);
- /* 轉義并解析JSON 數據 */
- $menu_json = json_decode(iconv('GBK', 'utf-8', $result),true);
- /* 組織接口信息 */
- $interface = 'alipay_mobile_public_'.$method.'_response';
- /* 遇到錯誤返回 */
- if( $menu_json[$interface]['code'] != 200 ){
- if( $this->debug ){
- $this->write_log('GET_MENU_ERROR',$menu_json[$interface]['msg']);
- }
- return false;
- }
- /* 根據類型不同返回不同的結果 */
- if( $type == 'get' ){
- return $menu_json[$interface]['menu_content'];
- }else{
- return $menu_json[$interface]['msg'];
- }
- }
- /**
- - POST數據方法
- - @param array params 參數數組
- - @author widuu <admin@widuu.com>
- */
- private function response_post($params,$type=false){
- // 下載媒體和請求網關
- if($down){
- $url = 'https://openfile.alipay.com/chat/multimedia.do';
- }else{
- $url = 'https://openapi.alipay.com/gateway.do';
- }
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_HEADER, 0);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
- curl_setopt($ch, CURLOPT_POST, 1);
- curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION,true);
- curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
- curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
- curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
- $curl = curl_exec($ch);
- curl_close($ch);
- return $curl;
- }
- /**
- - 拼接回復數據
- - @param string $type 回復類型
- - @param array $info 回復內容
- - @param bool $mass 是否為群發
- - @author widuu <admin@widuu.com>
- */
- private function common_response($type,$info,$mass=false){
- $request = $this->request;
- $params = array();
- // 如果不是群發
- if( !$mass ) $params['toUserId'] = $request['FromUserId'];
- $params['msgType'] = $type;
- $params['createTime'] = time();
- $content = array_merge($params,$info);
- return $content;
- }
- /**
- - 拼接加密參數
- - @param string $interface_type 接口類型
- - @param array $biz_content 返回biz_content的數組
- - @author widuu <admin@widuu.com>
- */
- private function common_system($interface_type,$biz_content){
- /* 接口集合 */
- $type = $this->interface_type;
- $method = $type[$interface_type];
- /* 公共參數 */
- $params = array (
- 'method' => $method,
- 'charset' => 'UTF-8',
- 'sign_type' => 'RSA',
- 'app_id' => $this->app_id,
- 'timestamp' => date ( 'Y-m-d H:i:s', time () ),
- 'version'=>'1.0',
- );
- /* 獲取某些接口時沒有biz_content參數 */
- if( count($biz_content) > 0 ){
- $params['biz_content'] = json_encode($biz_content);
- }
- /* 返回系統參數 */
- return $params;
- }
- /**
- - 服務驗證
- - @params array params 是自動獲的驗證信息
- - @author widuu <admin@widuu.com>
- */
- private function verify($params){
- /* 參數為空 */
- if( emptyempty($params) ){
- if( $this->debug ){
- $this->write_log('ERROR','驗證參數為空');
- }
- }
- /* 構建參數,使用字典排序再拼接字符串 */
- $query_data = $this->build_query($params);
- /* 驗證信息,有可能php版本BUG不支持驗證 */
- $verify_result = $this->ras_verify($query_data);
- /* 返回驗證結果 */
- if( $verify_result ){
- /* 取公有密鑰的字符串合并為一行 */
- $public_rsa_string = file_get_contents($this->public_rsa_key_path);
- $public_rsa_string = str_replace ( "-----BEGIN PUBLIC KEY-----", "", $public_rsa_string );
- $public_rsa_string = str_replace ( "-----END PUBLIC KEY-----", "", $public_rsa_string );
- $public_rsa_string = str_replace ( "/r", "", $public_rsa_string );
- $public_rsa_string = str_replace ( "/n", "", $public_rsa_string );
- /* 構建加密字符串 */
- $response_xml = "<success>true</success><biz_content>$public_rsa_string</biz_content>";
- /* 生成驗證信息 */
- $sign = $this->rsa_sign ( $response_xml );
- /* 構建返回數據 */
- $response = "<?xml version=/"1.0/" encoding=/"GBK/"?><alipay><response>$response_xml</response><sign>$sign</sign><sign_type>RSA</sign_type></alipay>";
- if( $this->debug ){
- $this->write_log('CHECK_RESPONSE',$response);
- }
- /* 輸出返回信息 */
- echo $response;
- exit();
- }else{
- if( $this->debug ){
- $this->write_log('ERROR','驗證失敗');
- }
- }
- }
- /**
- - 拼接為字符串函數
- - @params array params 拼接函數
- - @author widuu <admin@widuu.com>
- */
- private function build_query($params){
- /* 刪除sign字符串 */
- unset($params['sign']);
- /* 字典排序 */
- ksort($params);
- /* 拼接 */
- $query_array = array();
- foreach ($params as $k => $v) {
- $query_array[] = "$k"."="."$v";
- }
- $query_data = implode("&", $query_array);
- /* 返回拼接好的字符串 */
- return $query_data;
- }
- /**
- - 驗證加密sign,有些PHP版本不支持,不支持情況直接返回true
- - @params string query_data 加密字符串
- - @author widuu <admin@widuu.com>
- */
- private function ras_verify($query_data){
- /* 讀取公鑰文件,PEM格式 */
- $pubKey = file_get_contents($this->public_rsa_key_path);
- /* 轉換為openssl格式密鑰 */
- $res = openssl_get_publickey($pubKey);
- /* 調用openssl內置方法驗簽 */
- $result = (bool) openssl_verify($query_data, base64_decode($this->sign), $res);
- /* 釋放資源 */
- openssl_free_key($res);
- /* 有些PHP版本錯誤,直接返回true */
- if( strpos( openssl_error_string(),'PEM_read_bio' ) ){
- return true;
- }
- /* 返回驗簽結果 */
- return $result;
- }
- /**
- - 通過私有密鑰加密數據
- - @params string data 加密數據
- - @author widuu <admin@widuu.com>
- */
- private function rsa_sign($data) {
- /* 讀取私鑰 */
- $priKey = file_get_contents ( $this->private_rsa_key_path );
- /* 轉換為openssl格式密鑰 */
- $res = openssl_get_privatekey ( $priKey );
- /* 調用openssl 加密 */
- openssl_sign ( $data, $sign, $res );
- /* 釋放資源 */
- openssl_free_key ( $res );
- /* Base64加密 */
- $sign = base64_encode ( $sign );
- /* 返回加密參數 */
- return $sign;
- }
- private function analysis($params){
- switch($params['MsgType']){
- case 'image':
- $this->media_id = $params['Image']['MediaId'];
- $this->format = $params['Image']['Format'];
- break;
- case 'text':
- $this->text = $params['Text']['Content'];
- break;
- case 'event':
- $this->event_type = $params['EventType'];
- $this->action_param = $params['ActionParam'];
- break;
- default:
- break;
- }
- $this->msg_type = $params['MsgType'];
- $this->user_info = json_decode($params['UserInfo'],true);
- }
- /**
- - DEBUG 為true時的拼接字符串
- - @param string $level 自定義標識符
- - @param string $info 自定義內容
- - @param string $log_path 自定義日志路徑
- - @author widuu <admin@widuu.com>
- */
- public function write_log($level,$info,$log_path = '' ){
- if( emptyempty($log_path) ){ //Vevb.com
- $log_path = dirname ( __FILE__ ) . "/log.txt";
- }
- file_put_contents($log_path, "[$level]".date ( "Y-m-d H:i:s" ) . " " . $info . "/r/n", FILE_APPEND );
- }
- }
新聞熱點
疑難解答