700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 支付宝手机网站即时交易 自己封装的类

支付宝手机网站即时交易 自己封装的类

时间:2023-04-16 12:31:28

相关推荐

支付宝手机网站即时交易 自己封装的类

1 <?php 2/* 3 支付宝封装类 4 采用 rsa 生成签名模式 5*/ 6class Alipay { 7 private $_config = array(); 8 private $_alipay_gateway_new = '/gateway.do?'; //支付宝网关地址(新) 9 private $_https_verify_url = '/gateway.do?service=notify_verify&'; //校验用到 10 private $_fix_config = array(); 11 12 13 public function __construct() { 14 $this->_makeFixconfig(); 15 } 16 17 //读取固定参数 18 private function _makeFixconfig() { 19 $this->_fix_config = array( 20 'service' => 'alipay.wap.create.direct.pay.by.user', 21 '_input_charset' => 'utf-8', 22 'sign_type' => 'RSA', 23 'seller_id' => '', 24 'private_key_path' => VENDOR_PATH . '/Alipay/rsa_private_key.pem',//私密key 25 'ali_public_key_path'=> VENDOR_PATH . '/Alipay/alipay_public_key.pem',//公开key 26 'cacert' => VENDOR_PATH . '/Alipay/cacert.pem',//https请求用到验证 27 'transport' => 'http', 28 'payment_type' => 1,//固定参数 29 ); 30 } 31 32 /* 33 config 需要参数 34 partner//合作身份者id,以2088开头的16位纯数字 35 notify_url//阿里处理后,异步处理url地址,http开头 36 return_url//阿里处理后,同步处理url地址 37 38 out_trade_no //订单号 39 subject//商品名称 40 total_fee//商品金额 41 42 43 */ 44 //生成配置文件,并请求 45 public function run($config) { 46 foreach ($config as $value) { 47 if(empty($value)) 48 exit('缺少必要参数'); 49 }50 51 $this->_fix_config['seller_id'] = $config['partner']; 52 53 $this->_config = array_merge($this->_fix_config,$config); 54 55 //签名,请求 56 $this->_makeSign(); 57 } 58 59 60 //生成签名信息,并发送请求 61 private function _makeSign() { 62 //获取签名需要的参数 63 $param = array( 64 '_input_charset' => trim($this->_config['_input_charset']), 65 'service' => trim($this->_config['service']), 66 'partner' => trim($this->_config['partner']), 67 'seller_id' => trim($this->_config['seller_id']), 68 'payment_type' => trim($this->_config['payment_type']), 69 'notify_url' => trim($this->_config['notify_url']), 70 'return_url' => trim($this->_config['return_url']), 71 'out_trade_no' => trim($this->_config['out_trade_no']), 72 'subject' => trim($this->_config['subject']), 73 'total_fee' => trim($this->_config['total_fee']), 74 ); 75 76 //对数组进行排序 77 ksort($param); 78 reset($param); 79 80 //读取pem信息,生成key 81 if(!file_exists($this->_config['private_key_path']) || !file_exists($this->_config['ali_public_key_path'])) 82 exit('缺少pem必要参数,请检查'); 83 84 if(!function_exists('openssl_pkey_get_private')) 85 exit('不支持openssl'); 86 87 $query_string = ''; 88 $query_string = $this->_makeSignString($param); 89 90 $private_key_info = file_get_contents($this->_config['private_key_path']); 91 92 $private_key_res= openssl_pkey_get_private($private_key_info); 93 94 $sign = ''; 95 openssl_sign($query_string, $sign, $private_key_res); 96 97 openssl_free_key($private_key_res); 98 99 //base64编码100 $param['sign'] = base64_encode($sign);101 102 //验证签名103 // $this->_checkSign($query_string,$param['sign']);104 105 $param['sign_type'] = trim($this->_config['sign_type']);106 107 //触发表单请求,使用get模拟请求会失败108 $this->_formPush($param,'确认');109 }110 111 /*112 --不能用模拟请求113 发送get请求114 $url 请求url地址115 */116 private function _makeGetHttp($url) {117 $curl = curl_init($url);118 119 // curl_setopt($curl, CURLOPT_POST, 1);120 curl_setopt($curl, CURLOPT_HEADER, 0 ); // 过滤HTTP头121 curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);// 显示输出结果122 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);//SSL证书认证123 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//严格认证124 curl_setopt($curl, CURLOPT_CAINFO,$this->_fix_config['cacert']);//证书地址125 curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');126 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);127 curl_setopt($curl, CURLOPT_USERAGENT,"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)"); 128 129 $result = curl_exec($curl);130 131 $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);132 $curlErrNo = curl_errno($curl);133 $curlErr = curl_error($curl);134 135 curl_close($curl);136 137 if ($httpCode == "0") 138die("Curl error number:" . $curlErrNo . " , Curl error details:" . $curlErr . "\r\n");139 else if ($httpCode != "200") 140die("Http code:" . $httpCode . " details:" . $result . "\r\n");141142 return $result;143 }144 145 /*146 采用表单提交147 */148 private function _formPush($para_temp,$button_name) {149 $sHtml = '<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>支付宝通信中...</title><link rel="stylesheet" href="/bootstrap/3.3.4/css/bootstrap.min.css"></head><body>';150 151 $sHtml .= '<div class="container-fluid"><div class="row" style="margin-top:200px;"><div class="col-xs-10 col-md-10 col-xs-offset-1 col-md-offset-1"><span class="btn btn-success btn-block">请稍后,连接支付宝...</span></div></div></div>';152 153 $sHtml .= "<div style='display:none;'><form id='alipaysubmit' name='alipaysubmit' action='".$this->_alipay_gateway_new."_input_charset=".trim(strtolower($this->_config['_input_charset']))."' method='get'>";154 while (list ($key, $val) = each ($para_temp)) {155 $sHtml .= "<input type='hidden' name='".$key."' value='".$val."'/>";156 }157 158 //submit按钮控件请不要含有name属性159 $sHtml = $sHtml."<input type='submit' value='".$button_name."'></form></div></body></html>";160 161 $sHtml = $sHtml."<script>document.forms['alipaysubmit'].submit();</script>";162 163 164 echo $sHtml;165 }166 167 168 /*169 构造签名字符串170 */171 private function _makeSignString($arr,$type=false) {172 $tmp_str = '';173 foreach ($arr as $key => $value) {174 if($key == 'sign' || $key == 'sign_type') 175 continue;176 $tmp_str .= $key . '=' . $value . '&';177 }178 179 return trim($tmp_str,'&');180 }181 182 /*183 验证rsa签名184 @param $data 返回的get或者post的总数组,185$sign get['sign'] 或者 post['sign']186 @returnbool187 */188 public function checkSign($data,$sign) {189 190 //处理数据191 $new_data = array();192 foreach ($data as $key => $value) {193 if($key == 'sign' || $key == 'sign_type' || $key == '_URL_' || $value == '')194 continue;195 $new_data[$key] = $value;196 }197 198 ksort($new_data);199 reset($new_data);200 201 $new_data_str = '';202 $new_data_str = $this->_makeSignString($new_data);203 204 $ali_public_key_info = file_get_contents($this->_fix_config['ali_public_key_path']);205 $ali_public_key_res = openssl_pkey_get_public($ali_public_key_info);206 207 $ali_public_key_verify = openssl_verify($new_data_str, base64_decode($sign), $ali_public_key_res);208 openssl_free_key($ali_public_key_res);209 210if(!$ali_public_key_verify)211return false;212return true;213 }214 215 216 /*217 验证url来源是否为支付宝218 @param partner 合作账号219 notify_id get|post返回的220 */221 public function checkUrlFrom($partner,$notify_id) {222 $url = $this->_https_verify_url . 'partner=' . $partner . '&notify_id=' . $notify_id;223 return $this->_makeGetHttp($url);224 }225 226 227 228 229 230 231 232 233 234 235 236}

调用案例:

通知页面不能有阻拦,比如说要登录才能进入之类的

1 /* 2 测试支付宝 3 */ 4 public function test_alipay() { 5 //引入 6 Vendor('Alipay.Alipay'); 7 8 //生成参数 9 $param = array(10 'partner' => C('PARTENR'),//2088开头的支付宝信息11 'notify_url'=> 'http://' . $_SERVER['HTTP_HOST'] . U('Leasegoods/alipay_notify_url'),//异步通知页面12 'return_url'=> 'http://' . $_SERVER['HTTP_HOST'] . U('Leasegoods/alipay_return_url'),//同步通知页面13 'out_trade_no'=> $this->_dealOrderNum(),//订单号14 'subject' => 'lxd',//商品名称15 'total_fee'=> '0.01',//商品价格16 17 );18 19 $alipay_obj = new Alipay();20 $alipay_obj->run($param);21 }

通知页面验证:

同步异步都类似,第一 校验签名;第二 校验来源;其余的就是业务之类的东西了

1 public function alipay_return_url() { 2 $info = serialize($_GET); 3 4 $data = array(); 5 //判断状态 6 if(isset($_GET) && $_GET['is_success'] == 'T') { 7 $order_index = $_GET['out_trade_no']; 8 9 //校验签名10 Vendor('Alipay.Alipay');11 $alipay_obj = new Alipay();12 $res = $alipay_obj->checkSign($_GET,$_GET['sign']);13 14 if(!$res){15 $data['type']= 'error';16 $data['info'] = '警告:服务器校验数据失败';17 $this->assign('data',$data);18 $this->display('info');die;19 }20 21 //校验来源22 $res = null;23 $res = $alipay_obj->checkUrlFrom(C('PARTENR'),$_GET['notify_id']);24 if($res == 'false'){25 $data['type']= 'error';26 $data['info'] = '错误:服务器校验来源错误';27 $this->assign('data',$data);28 $this->display('info');die;29 }30 31 //记录流水32 $alipay_log_model= M('alipay_log');33 $insert_res = $alipay_log_model->add(array('order_index' => $order_index,'type' => 'return','info' => $info));34 if(!$insert_res){35 $data['type']= 'error';36 $data['info'] = '警告:用户支付成功,服务器流水记录失败';37 $this->assign('data',$data);38 $this->display('info');die;39 }40 41 42 //接口请求成功43 if($_GET['trade_status'] == 'TRADE_FINISHED' || $_GET['trade_status'] == 'TRADE_SUCCESS') {44 45 //交易成功46 $data['type']= 'success';47 $data['info'] = '成功:交易成功,请返回';48 }else {49 5059 //交易失败60 $data['type']= 'error';61 $data['info'] = '失败:支付失败,请重试';62 }63 }else {64 //接口请求失败65 $data['type']= 'error';66 $data['info'] = '失败:服务器调用支付宝失败';67 }68 $this->assign('data',$data);69 $this->display('info');70 }

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。