您好,登錄后才能下訂單哦!
小編給大家分享一下php微信支付之如何實(shí)現(xiàn)APP支付,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
具體分析如下:
WechatAppPay文件代碼如下:
<?php namespace common\services\WechatPay; class WechatAppPay extends WechatPayBase { //package參數(shù) public $package = []; //異步通知參數(shù) public $notify = []; //推送預(yù)支付訂單參數(shù) protected $config = []; //存儲(chǔ)access token和獲取時(shí)間的文件 protected $file; //access token protected $accessToken; //取access token的url const ACCESS_TOKEN_URL = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s'; //生成預(yù)支付訂單提交地址 const POST_ORDER_URL = 'https://api.weixin.qq.com/pay/genprepay?access_token=%s'; public function __construct() { $this->file = __DIR__ . '/payAccessToken.txt'; } /** * 創(chuàng)建APP支付最終返回參數(shù) * @throws \Exception * @return multitype:string NULL */ public function createAppPayData() { $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) { throw new \Exception($e->getMessage()); } return $array; } /** * 驗(yàn)證支付成功后的通知參數(shù) * * @throws \Exception * @return boolean */ public function verifyNotify() { try{ $staySignStr = $this->notify; unset($staySignStr['sign']); $sign = $this->signData($staySignStr); return $this->notify['sign'] === $sign; } catch(\Exception $e) { throw new \Exception($e->getMessage()); } } /** * 魔術(shù)方法,給添加支付參數(shù)進(jìn)來(lái) * * @param string $name 參數(shù)名 * @param string $value 參數(shù)值 */ public function __set($name, $value) { $this->$name = $value; } /** * 設(shè)置access token * @param string $token * @throws \Exception * @return boolean */ public function setAccessToken() { 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']; return true; } } //文件內(nèi)容為空或access token已失效,重新獲取 $this->outputAccessTokenToFile(); } catch(\Exception $e) { throw new \Exception($e->getMessage()); } return true; } /** * 寫入access token 到文件 * @throws \Exception * @return boolean */ protected function outputAccessTokenToFile() { 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) { throw new \Exception($e->getMessage()); } return true; } /** * 取access token * * @throws \Exception * @return string */ protected function getAccessToken() { $url = sprintf(self::ACCESS_TOKEN_URL, $this->appid, $this->appSecret); $result = json_decode( $this->getUrl($url), true ); if(isset($result['errcode'])) { throw new \Exception("get access token failed:{$result['errmsg']}"); } return $result['access_token']; } /** * 取預(yù)支付會(huì)話標(biāo)識(shí) * * @throws \Exception * @return string */ protected function getPrepayid() { $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 ) { throw new \Exception($result['errmsg']); } if( !isset($result['prepayid']) ) { throw new \Exception('get prepayid failed, url request error.'); } return $result['prepayid']; } /** * 組裝預(yù)支付參數(shù) * * @throws \Exception */ protected function generateConfig() { 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) { throw new \Exception($e->getMessage()); } } /** * 生成package字段 * * 生成規(guī)則: * 1、生成sign的值signValue * 2、對(duì)package參數(shù)再次拼接成查詢字符串,值需要進(jìn)行urlencode * 3、將sign=signValue拼接到2生成的字符串后面得到最終的package字符串 * * 第2步urlencode空格需要編碼成%20而不是+ * * RFC 1738會(huì)把 空格編碼成+ * RFC 3986會(huì)把空格編碼成%20 * * @return string */ protected function generatePackage() { $this->package['sign'] = $this->signData($this->package); return http_build_query($this->package, '', '&', PHP_QUERY_RFC3986); } /** * 生成簽名 * * @return string */ protected function generateSign() { $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); } /** * 簽名數(shù)據(jù) * * 生成規(guī)則: * 1、字典排序,拼接成查詢字符串格式,不需要urlencode * 2、上一步得到的字符串最后拼接上key=paternerKey * 3、MD5哈希字符串并轉(zhuǎn)換成大寫得到sign的值signValue * * @param array $data 待簽名數(shù)據(jù) * @return string 最終簽名結(jié)果 */ protected function signData($data) { ksort($data); $str = $this->arrayToString($data); $str .= "&key={$this->partnerKey}"; return strtoupper( $this->signMd5($str) ); } /** * sha1簽名 * 簽名規(guī)則 * 1、字典排序 * 2、拼接查詢字符串 * 3、sha1運(yùn)算 * * @param array $arr * @return string */ protected function sha1Sign($arr) { ksort($arr); return sha1( $this->arrayToString($arr) ); } }
以上是“php微信支付之如何實(shí)現(xiàn)APP支付”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對(duì)大家有所幫助,如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。