《PHP實戰(zhàn):php微信支付之APP支付方法》要點:
本文介紹了PHP實戰(zhàn):php微信支付之APP支付方法,希望對您有用。如果有疑問,可以聯(lián)系我們。
PHP學(xué)習(xí)本文實例講述了微信開放平臺移動應(yīng)用集成微信支付功能.分享給大家供大家參考.具體分析如下:
PHP學(xué)習(xí)WechatAppPay文件代碼如下:
代碼如下:
<?php
namespace common\services\WechatPay;
class WechatAppPay extends WechatPayBase
{
??? //package參數(shù)
??? public $package = [];
??? //異步通知參數(shù)
??? public $notify = [];
??? //推送預(yù)支付訂單參數(shù)
??? protected $config = [];
??? //存儲access token和獲取時間的文件
??? 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;
??? }
??? /**
???? * 驗證支付成功后的通知參數(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ù)進來
???? *
???? * @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ù)支付會話標(biāo)識
???? *
???? * @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、對package參數(shù)再次拼接成查詢字符串,值需要進行urlencode
???? * 3、將sign=signValue拼接到2生成的字符串后面得到最終的package字符串
???? *
???? * 第2步urlencode空格需要編碼成%20而不是+
???? *
???? * RFC 1738會把 空格編碼成+
???? * RFC 3986會把空格編碼成%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運算
???? *
???? * @param array $arr
???? * @return string
???? */
??? protected function sha1Sign($arr)
??? {
??????? ksort($arr);
??????? return sha1( $this->arrayToString($arr) );
??? }
}
PHP學(xué)習(xí)希望本文所述對大家的php程序設(shè)計有所幫助.
《PHP實戰(zhàn):php微信支付之APP支付方法》是否對您有啟發(fā),歡迎查看更多與《PHP實戰(zhàn):php微信支付之APP支付方法》相關(guān)教程,學(xué)精學(xué)透。維易PHP學(xué)院為您提供精彩教程。
轉(zhuǎn)載請注明本頁網(wǎng)址:
http://www.snjht.com/jiaocheng/11886.html