支付宝服务窗API接口开发php版本


Posted in PHP onJuly 20, 2016

支付宝服务窗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) ){ //phpfensi.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 ); 
 } 
}

好了以上就是小编为各位整理的一篇关于支付宝服务窗API接口的开发例子,这个有前提条件的就是我们必须要申请一个权限才可以,这个官方可以申请小编就不介绍。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
php开启安全模式后禁用的函数集合
Jun 26 PHP
PHP采用get获取url汉字出现乱码的解决方法
Nov 13 PHP
php提示Failed to write session data错误的解决方法
Dec 17 PHP
php使用curl获取https请求的方法
Feb 11 PHP
php获取文件名后缀常用方法小结
Feb 24 PHP
Laravel 5框架学习之路由、控制器和视图简介
Apr 07 PHP
基于PHP给大家讲解防刷票的一些技巧
Nov 18 PHP
在WordPress中实现评论头像的自定义默认和延迟加载
Nov 24 PHP
UPUPW 更新 64 位 Apache 系列 PHP 7.0 正式版
Dec 08 PHP
thinkPHP下的widget扩展用法实例分析
Dec 26 PHP
PDO::quote讲解
Jan 29 PHP
PHP实现单文件、多个单文件、多文件上传函数的封装示例
Sep 02 PHP
PHP二维数组矩形转置实例
Jul 20 #PHP
php实现登录tplink WR882N获取IP和重启的方法
Jul 20 #PHP
PHP的AES加密算法完整实例
Jul 20 #PHP
postfixadmin忘记密码后的修改密码方法详解
Jul 20 #PHP
PHP简单日历实现方法
Jul 20 #PHP
分析PHP中单双引号的误区和双引号小隐患
Jul 19 #PHP
PHP实现数组array转换成xml的方法
Jul 19 #PHP
You might like
php生成缩略图填充白边(等比缩略图方案)
2013/12/25 PHP
php获得url参数中具有&amp;的值的方法
2014/03/05 PHP
PHP开源开发框架ZendFramework使用中常见问题说明及解决方案
2014/06/12 PHP
Zend Framework教程之动作的基类Zend_Controller_Action详解
2016/03/07 PHP
Zend Framework教程之资源(Resources)用法实例详解
2016/03/14 PHP
laravel框架实现为 Blade 模板引擎添加新文件扩展名操作示例
2020/01/25 PHP
JavaScript更改class和id的方法
2008/10/10 Javascript
javascript ajax的5种状态介绍
2014/08/18 Javascript
Egret引擎开发指南之创建项目
2014/09/03 Javascript
jQuery图片轮播滚动切换代码分享
2020/04/20 Javascript
解决js图片加载时出现404的问题
2020/11/30 Javascript
Vue.js一个文件对应一个组件实践
2016/10/27 Javascript
js实现倒计时关键代码
2017/05/05 Javascript
Node使用Nodemailer发送邮件的方法实现
2020/02/24 Javascript
[03:21]【TI9纪实】Old Boys
2019/08/23 DOTA
详解Python中的多线程编程
2015/04/09 Python
Python中@property的理解和使用示例
2019/06/11 Python
使用Matplotlib绘制不同颜色的带箭头的线实例
2020/04/17 Python
在python里使用await关键字来等另外一个协程的实例
2020/05/04 Python
Python实现给PDF添加水印的方法
2021/01/25 Python
CSS3用@font-face实现自定义英文字体
2013/09/23 HTML / CSS
HTML5 拖放(Drag 和 Drop)详解与实例代码
2017/09/14 HTML / CSS
New Balance美国官网:运动鞋和健身服装
2017/04/11 全球购物
联想印度官方网上商店:Lenovo India
2019/08/24 全球购物
什么是Smarty变量操作符?如何使用Smarty变量操作符
2014/07/18 面试题
出纳岗位职责
2013/11/09 职场文书
酒店员工职业生涯规划
2014/02/25 职场文书
敬老院标语
2014/06/27 职场文书
个人委托书
2014/07/31 职场文书
弄虚作假心得体会
2014/09/10 职场文书
2016年综治宣传月活动宣传标语口号
2016/03/16 职场文书
HTML中table表格拆分合并(colspan、rowspan)
2021/04/07 HTML / CSS
Springboot如何使用logback实现多环境配置?
2021/06/16 Java/Android
Sql Server之数据类型详解
2022/02/28 SQL Server
Java数组详细介绍及相关工具类
2022/04/14 Java/Android
VW、VH适配移动端的解决方案与常见问题
2023/05/21 HTML / CSS