php微信支付之APP支付方法
更新時間:2015年03月04日 16:17:32 作者:OSC首席鍵客
這篇文章主要介紹了php微信支付之APP支付方法,實例分析了php微信支付接口文件及使用技巧,需要的朋友可以參考下
本文實例講述了微信開放平臺移動應(yīng)用集成微信支付功能。分享給大家供大家參考。具體分析如下:
WechatAppPay文件代碼如下:
復(fù)制代碼 代碼如下:
<?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ù)進(jìn)來
*
* @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ù)再次拼接成查詢字符串,值需要進(jìn)行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運(yùn)算
*
* @param array $arr
* @return string
*/
protected function sha1Sign($arr)
{
ksort($arr);
return sha1( $this->arrayToString($arr) );
}
}
希望本文所述對大家的php程序設(shè)計有所幫助。
您可能感興趣的文章:
- PHP微信支付開發(fā)實例
- 微信支付PHP SDK之微信公眾號支付代碼詳解
- PHP實現(xiàn)微信支付(jsapi支付)流程步驟詳解
- ThinkPHP實現(xiàn)微信支付(jsapi支付)流程教程詳解
- 微信小程序 支付功能實現(xiàn)PHP實例詳解
- PHP實現(xiàn)QQ、微信和支付寶三合一收款碼實例代碼
- 微信小程序與php 實現(xiàn)微信支付的簡單實例
- ThinkPHP框架實現(xiàn)的微信支付接口開發(fā)完整示例
- ThinkPHP框架整合微信支付之JSAPI模式圖文詳解
- ThinkPHP框架整合微信支付之Native 掃碼支付模式一圖文詳解
- ThinkPHP框架整合微信支付之Native 掃碼支付模式二圖文詳解
- PHP實現(xiàn)的微信APP支付功能示例【基于TP5框架】
相關(guān)文章
PHP+mysql+ajax輕量級聊天室實現(xiàn)方法詳解
這篇文章主要介紹了PHP+mysql+ajax輕量級聊天室實現(xiàn)方法,結(jié)合實例形式分析了php+mysql實現(xiàn)實時聊天室功能的具體步驟與相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2016-10-10PHP封裝的遠(yuǎn)程抓取網(wǎng)站圖片并保存功能類
這篇文章主要介紹了PHP封裝的遠(yuǎn)程抓取網(wǎng)站圖片并保存功能類,結(jié)合實例形式分析了php抓取遠(yuǎn)程圖片封裝類的定義與簡單使用方法,涉及php正則匹配與文件讀寫相關(guān)操作技巧,需要的朋友可以參考下2018-06-06php中使用parse_url()對網(wǎng)址進(jìn)行解析的實現(xiàn)代碼(parse_url詳解)
parse_url用來解析一個 URL 并返回一個關(guān)聯(lián)數(shù)組,包含在 URL 中出現(xiàn)的各種組成部分2012-01-012020最新版 PhpStudy V8.1版本下載安裝使用詳解
這篇文章主要介紹了2020最新版 PhpStudy V8.1版本下載安裝使用詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10