加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

php微信支付之APP支付方法

发布时间:2020-12-13 02:26:49 所属栏目:PHP教程 来源:网络整理
导读:《PHP实战:php微信支付之APP支付方法》要点: 本文介绍了PHP实战:php微信支付之APP支付方法,希望对您有用。如果有疑问,可以联系我们。 PHP学习 本篇章节讲解微信开放平台移动应用集成微信支付功能.供大家参考研究.具体分析如下: WechatAppPay文

《PHP实战:php微信支付之APP支付方法》要点:
本文介绍了PHP实战:php微信支付之APP支付方法,希望对您有用。如果有疑问,可以联系我们。

PHP学习本篇章节讲解微信开放平台移动应用集成微信支付功能.分享给大家供大家参考.具体分析如下:

WechatAppPay文件代码如下:

代码如下:

<?php
namespace commonservicesWechatPay;
class WechatAppPay extends WechatPayBase
{
??? //package参数
??? public $package = [];
??? //异步通知参数
??? public $notify = [];
??? //推送预支付订单参数
??? 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';
??? //生成预支付订单提交地址
??? const POST_ORDER_URL = 'https://api.weixin.qq.com/pay/genprepay?access_token=%s';
??? public function __construct()
??? {
??????? $this->file = __DIR__ . '/payAccessToken.txt';
??? }
??? /**
???? * 创建APP支付最终返回参数
???? * @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;
??? }
??? /**
???? * 验证支付成功后的通知参数
???? *
???? * @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());
??????? }
??? }
??? /**
???? * 魔术办法,给添加支付参数进来
???? *
???? * @param string $name? 参数名
???? * @param string $value? 参数值
???? */
??? public function __set($name,$value)
??? {
??????? $this->$name = $value;
??? }
??? /**
???? * 设置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;
??????????????? }
??????????? }
??????????? //文件内容为空或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'];
??? }
??? /**
???? * 取预支付会话标识
???? *
???? * @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'];
??? }
??? /**
???? * 组装预支付参数
???? *
???? * @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字段
???? *
???? * 生成规则:
???? * 1、生成sign的值signValue
???? * 2、对package参数再次拼接成查询字符串,值需要进行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);
??? }
??? /**
???? * 签名数据
???? *
???? * 生成规则:
???? * 1、字典排序,拼接成查询字符串格式,不需要urlencode
???? * 2、上一步得到的字符串最后拼接上key=paternerKey
???? * 3、MD5哈希字符串并转换成大写得到sign的值signValue
???? *
???? * @param array $data 待签名数据
???? * @return string 最终签名结果
???? */
??? protected function signData($data)
??? {
??????? ksort($data);
??????? $str = $this->arrayToString($data);
??????? $str .= "&key={$this->partnerKey}";
??????? return strtoupper( $this->signMd5($str) );
??? }
??? /**
???? * sha1签名
???? * 签名规则
???? * 1、字典排序
???? * 2、拼接查询字符串
???? * 3、sha1运算
???? *
???? * @param array $arr
???? * @return string
???? */
??? protected function sha1Sign($arr)
??? {
??????? ksort($arr);
??????? return sha1( $this->arrayToString($arr) );
??? }
}

希望本文所述对大家的php程序设计有所帮助.

《PHP实战:php微信支付之APP支付方法》是否对您有启发,欢迎查看更多与《PHP实战:php微信支付之APP支付方法》相关教程,学精学透。编程之家 52php.cn为您提供精彩教程。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读