源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

php微信支付之APP支付方法

  • 时间:2020-04-10 12:31 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:php微信支付之APP支付方法
本文实例讲述了微信开放平台移动应用集成微信支付功能。分享给大家供大家参考。具体分析如下: WechatAppPay文件代码如下:
[u]复制代码[/u] 代码如下:
<?php namespace common\services\WechatPay; 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程序设计有所帮助。
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部