php微信支付之APP支付方法
本文实例讲述了微信开放平台移动应用集成微信支付功能。分享给大家供大家参考。具体分析如下:
WechatAppPay文件代码如下:
<?php namespacecommon\services\WechatPay; classWechatAppPayextendsWechatPayBase { //package参数 public$package=[]; //异步通知参数 public$notify=[]; //推送预支付订单参数 protected$config=[]; //存储accesstoken和获取时间的文件 protected$file; //accesstoken protected$accessToken; //取accesstoken的url constACCESS_TOKEN_URL='https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s'; //生成预支付订单提交地址 constPOST_ORDER_URL='https://api.weixin.qq.com/pay/genprepay?access_token=%s'; publicfunction__construct() { $this->file=__DIR__.'/payAccessToken.txt'; } /** *创建APP支付最终返回参数 *@throws\Exception *@returnmultitype:stringNULL */ publicfunctioncreateAppPayData() { $this->generateConfig(); $prepayid=$this->getPrepayid(); try{ $array=[ 'appid'=>$this->appid, 'appkey'=>$this->paySignkey, 'noncestr'=>$this->getRandomStr(), 'package'=>'Sign=WXPay', 'partnerid'=>$this->partnerId, 'prepayid'=>$prepayid, 'timestamp'=>(string)time(), ]; $array['sign']=$this->sha1Sign($array); unset($array['appkey']); }catch(\Exception$e){ thrownew\Exception($e->getMessage()); } return$array; } /** *验证支付成功后的通知参数 * *@throws\Exception *@returnboolean */ publicfunctionverifyNotify() { try{ $staySignStr=$this->notify; unset($staySignStr['sign']); $sign=$this->signData($staySignStr); return$this->notify['sign']===$sign; }catch(\Exception$e){ thrownew\Exception($e->getMessage()); } } /** *魔术方法,给添加支付参数进来 * *@paramstring$name 参数名 *@paramstring$value 参数值 */ publicfunction__set($name,$value) { $this->$name=$value; } /** *设置accesstoken *@paramstring$token *@throws\Exception *@returnboolean */ publicfunctionsetAccessToken() { try{ if(!file_exists($this->file)||!is_file($this->file)){ $f=fopen($this->file,'a'); fclose($f); } $content=file_get_contents($this->file); if(!empty($content)){ $info=json_decode($content,true); if(time()-$info['getTime']<7150){ $this->accessToken=$info['accessToken']; returntrue; } } //文件内容为空或accesstoken已失效,重新获取 $this->outputAccessTokenToFile(); }catch(\Exception$e){ thrownew\Exception($e->getMessage()); } returntrue; } /** *写入accesstoken到文件 *@throws\Exception *@returnboolean */ protectedfunctionoutputAccessTokenToFile() { try{ $f=fopen($this->file,'wb'); $token=[ 'accessToken'=>$this->getAccessToken(), 'getTime'=>time(), ]; flock($f,LOCK_EX); fwrite($f,json_encode($token)); flock($f,LOCK_UN); fclose($f); $this->accessToken=$token['accessToken']; }catch(\Exception$e){ thrownew\Exception($e->getMessage()); } returntrue; } /** *取accesstoken * *@throws\Exception *@returnstring */ protectedfunctiongetAccessToken() { $url=sprintf(self::ACCESS_TOKEN_URL,$this->appid,$this->appSecret); $result=json_decode($this->getUrl($url),true); if(isset($result['errcode'])){ thrownew\Exception("getaccesstokenfailed:{$result['errmsg']}"); } return$result['access_token']; } /** *取预支付会话标识 * *@throws\Exception *@returnstring */ protectedfunctiongetPrepayid() { $data=json_encode($this->config); $url=sprintf(self::POST_ORDER_URL,$this->accessToken); $result=json_decode($this->postUrl($url,$data),true); if(isset($result['errcode'])&&$result['errcode']!=0){ thrownew\Exception($result['errmsg']); } if(!isset($result['prepayid'])){ thrownew\Exception('getprepayidfailed,urlrequesterror.'); } return$result['prepayid']; } /** *组装预支付参数 * *@throws\Exception */ protectedfunctiongenerateConfig() { try{ $this->config=[ 'appid'=>$this->appid, 'traceid'=>$this->traceid, 'noncestr'=>$this->getRandomStr(), 'timestamp'=>time(), 'package'=>$this->generatePackage(), 'sign_method'=>$this->sign_method, ]; $this->config['app_signature']=$this->generateSign(); }catch(\Exception$e){ thrownew\Exception($e->getMessage()); } } /** *生成package字段 * *生成规则: *1、生成sign的值signValue *2、对package参数再次拼接成查询字符串,值需要进行urlencode *3、将sign=signValue拼接到2生成的字符串后面得到最终的package字符串 * *第2步urlencode空格需要编码成%20而不是+ * *RFC1738会把空格编码成+ *RFC3986会把空格编码成%20 * *@returnstring */ protectedfunctiongeneratePackage() { $this->package['sign']=$this->signData($this->package); returnhttp_build_query($this->package,'','&',PHP_QUERY_RFC3986); } /** *生成签名 * *@returnstring */ protectedfunctiongenerateSign() { $signArray=[ 'appid'=>$this->appid, 'appkey'=>$this->paySignkey, 'noncestr'=>$this->config['noncestr'], 'package'=>$this->config['package'], 'timestamp'=>$this->config['timestamp'], 'traceid'=>$this->traceid, ]; return$this->sha1Sign($signArray); } /** *签名数据 * *生成规则: *1、字典排序,拼接成查询字符串格式,不需要urlencode *2、上一步得到的字符串最后拼接上key=paternerKey *3、MD5哈希字符串并转换成大写得到sign的值signValue * *@paramarray$data待签名数据 *@returnstring最终签名结果 */ protectedfunctionsignData($data) { ksort($data); $str=$this->arrayToString($data); $str.="&key={$this->partnerKey}"; returnstrtoupper($this->signMd5($str)); } /** *sha1签名 *签名规则 *1、字典排序 *2、拼接查询字符串 *3、sha1运算 * *@paramarray$arr *@returnstring */ protectedfunctionsha1Sign($arr) { ksort($arr); returnsha1($this->arrayToString($arr)); } }
希望本文所述对大家的php程序设计有所帮助。