当前位置:首页 > PHP教程 > php高级应用 > 列表

php微信支付之APP支付方法

发布:smiling 来源: PHP粉丝网  添加日期:2021-05-15 15:39:35 浏览: 评论:0 

这篇文章主要介绍了php微信支付之APP支付方法,实例分析了php微信支付接口文件及使用技巧,需要的朋友可以参考下

本文实例讲述了微信开放平台移动应用集成微信支付功能。分享给大家供大家参考。具体分析如下:

WechatAppPay文件代码如下:

  1. <?php 
  2. namespace common\services\WechatPay; 
  3. class WechatAppPay extends WechatPayBase 
  4.     //package参数 
  5.     public $package = []; 
  6.     //异步通知参数 
  7.     public $notify = []; 
  8.     //推送预支付订单参数 
  9.     protected $config = []; 
  10.     //存储access token和获取时间的文件 
  11.     protected $file
  12.     //access token 
  13.     protected $accessToken
  14.     //取access token的url 
  15.     const ACCESS_TOKEN_URL = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s'
  16.     //生成预支付订单提交地址 
  17.     const POST_ORDER_URL = 'https://api.weixin.qq.com/pay/genprepay?access_token=%s'
  18.     public function __construct() 
  19.     { 
  20.         $this->file = __DIR__ . '/payAccessToken.txt'
  21.     } 
  22.     /** 
  23.      * 创建APP支付最终返回参数 
  24.      * @throws \Exception 
  25.      * @return multitype:string NULL 
  26.      */ 
  27.     public function createAppPayData() 
  28.     { 
  29.         $this->generateConfig(); 
  30.         $prepayid = $this->getPrepayid(); 
  31.         try{ 
  32.             $array = [ 
  33.                 'appid' => $this->appid, 
  34.                 'appkey' => $this->paySignkey, 
  35.                 'noncestr' => $this->getRandomStr(), 
  36.                 'package' => 'Sign=WXPay'
  37.                 'partnerid' => $this->partnerId, 
  38.                 'prepayid' => $prepayid
  39.                 'timestamp' => (string)time(), 
  40.             ]; 
  41.             $array['sign'] = $this->sha1Sign($array); 
  42.             unset($array['appkey']); 
  43.         } catch(\Exception $e) { 
  44.             throw new \Exception($e->getMessage()); 
  45.         } 
  46.         return $array
  47.     } 
  48.     /** 
  49.      * 验证支付成功后的通知参数 
  50.      * 
  51.      * @throws \Exception 
  52.      * @return boolean 
  53.      */ 
  54.     public function verifyNotify() 
  55.     { 
  56.         try{ 
  57.             $staySignStr = $this->notify; 
  58.             unset($staySignStr['sign']); 
  59.             $sign = $this->signData($staySignStr); 
  60.             return $this->notify['sign'] === $sign
  61.         } catch(\Exception $e) { 
  62.             throw new \Exception($e->getMessage()); 
  63.         } 
  64.     } 
  65.     /** 
  66.      * 魔术方法,给添加支付参数进来 
  67.      * 
  68.      * @param string $name  参数名 
  69.      * @param string $value  参数值 
  70.      */ 
  71.     public function __set($name$value
  72.     { 
  73.         $this->$name = $value
  74.     } 
  75.     /** 
  76.      * 设置access token 
  77.      * @param string $token 
  78.      * @throws \Exception 
  79.      * @return boolean 
  80.      */ 
  81.     public function setAccessToken() 
  82.     { 
  83.         try{ 
  84.             if(!file_exists($this->file) || !is_file($this->file)) { 
  85.                 $f = fopen($this->file, 'a'); 
  86.                 fclose($f); 
  87.             } 
  88.             $content = file_get_contents($this->file); 
  89.             if(!emptyempty($content)) { 
  90.                 $info = json_decode($content, true); 
  91.                 if( time() - $info['getTime'] < 7150 ) { 
  92.                     $this->accessToken = $info['accessToken']; 
  93.                     return true; 
  94.                 } 
  95.             } 
  96.             //文件内容为空或access token已失效,重新获取 
  97.             $this->outputAccessTokenToFile(); 
  98.         } catch(\Exception $e) { 
  99.             throw new \Exception($e->getMessage()); 
  100.         } 
  101.         return true; 
  102.     } 
  103.     /** 
  104.      * 写入access token 到文件 
  105.      * @throws \Exception 
  106.      * @return boolean 
  107.      */ 
  108.     protected function outputAccessTokenToFile() 
  109.     { 
  110.         try{ 
  111.             $f = fopen($this->file, 'wb'); 
  112.             $token = [ 
  113.                 'accessToken' => $this->getAccessToken(), 
  114.                 'getTime' => time(), 
  115.             ]; 
  116.             flock($f, LOCK_EX); 
  117.             fwrite($f, json_encode($token)); 
  118.             flock($f, LOCK_UN); 
  119.             fclose($f); 
  120.             $this->accessToken = $token['accessToken']; 
  121.         } catch(\Exception $e) { 
  122.             throw new \Exception($e->getMessage()); 
  123.         } 
  124.         return true; 
  125.     } 
  126.     /** 
  127.      * 取access token 
  128.      * 
  129.      * @throws \Exception 
  130.      * @return string 
  131.      */ 
  132.     protected function getAccessToken() 
  133.     { 
  134.         $url = sprintf(self::ACCESS_TOKEN_URL, $this->appid, $this->appSecret); 
  135.         $result = json_decode( $this->getUrl($url), true ); 
  136.         if(isset($result['errcode'])) { 
  137.             throw new \Exception("get access token failed:{$result['errmsg']}"); 
  138.         } 
  139.         return $result['access_token']; 
  140.     } 
  141.     /** 
  142.      * 取预支付会话标识 
  143.      * 
  144.      * @throws \Exception 
  145.      * @return string 
  146.      */ 
  147.     protected function getPrepayid() 
  148.     { 
  149.         $data = json_encode($this->config); 
  150.         $url = sprintf(self::POST_ORDER_URL, $this->accessToken); 
  151.         $result = json_decode( $this->postUrl($url$data), true ); 
  152.         if( isset($result['errcode']) && $result['errcode'] != 0 ) { 
  153.             throw new \Exception($result['errmsg']); 
  154.         } 
  155.         if( !isset($result['prepayid']) ) { 
  156.             throw new \Exception('get prepayid failed, url request error.'); 
  157.         } 
  158.         return $result['prepayid']; 
  159.     } 
  160.     /** 
  161.      * 组装预支付参数 
  162.      * 
  163.      * @throws \Exception 
  164.      */ 
  165.     protected function generateConfig() 
  166.     { 
  167.         try{ 
  168.             $this->config = [ 
  169.                     'appid' => $this->appid, 
  170.                     'traceid' => $this->traceid, 
  171.                     'noncestr' => $this->getRandomStr(), 
  172.                     'timestamp' => time(), 
  173.                     'package' => $this->generatePackage(), 
  174.                     'sign_method' => $this->sign_method, 
  175.             ]; 
  176.             $this->config['app_signature'] = $this->generateSign(); 
  177.         } catch(\Exception $e) { 
  178.             throw new \Exception($e->getMessage()); 
  179.         } 
  180.     } 
  181.     /** 
  182.      * 生成package字段 
  183.      * 
  184.      * 生成规则: 
  185.      * 1、生成sign的值signValue 
  186.      * 2、对package参数再次拼接成查询字符串,值需要进行urlencode 
  187.      * 3、将sign=signValue拼接到2生成的字符串后面得到最终的package字符串 
  188.      * 
  189.      * 第2步urlencode空格需要编码成%20而不是+ 
  190.      * 
  191.      * RFC 1738会把 空格编码成+ 
  192.      * RFC 3986会把空格编码成%20 
  193.      * 
  194.      * @return string 
  195.      */ 
  196.     protected function generatePackage() 
  197.     { 
  198.         $this->package['sign'] = $this->signData($this->package); 
  199.         return http_build_query($this->package, '''&', PHP_QUERY_RFC3986); 
  200.     } 
  201.     /** 
  202.      * 生成签名 
  203.      * 
  204.      * @return string 
  205.      */ 
  206.     protected function generateSign() 
  207.     { 
  208.         $signArray = [ 
  209.             'appid' => $this->appid, 
  210.             'appkey' => $this->paySignkey, 
  211.             'noncestr' => $this->config['noncestr'], 
  212.             'package' => $this->config['package'], 
  213.             'timestamp' => $this->config['timestamp'], 
  214.             'traceid' => $this->traceid, 
  215.         ]; 
  216.         return $this->sha1Sign($signArray); 
  217.     } 
  218.     /** 
  219.      * 签名数据 
  220.      * 
  221.      * 生成规则: 
  222.      * 1、字典排序,拼接成查询字符串格式,不需要urlencode 
  223.      * 2、上一步得到的字符串最后拼接上key=paternerKey 
  224.      * 3、MD5哈希字符串并转换成大写得到sign的值signValue 
  225.      * 
  226.      * @param array $data 待签名数据 
  227.      * @return string 最终签名结果 
  228.      */ 
  229.     protected function signData($data
  230.     { 
  231.         ksort($data); 
  232.         $str = $this->arrayToString($data); 
  233.         $str .= "&key={$this->partnerKey}"
  234.         return strtoupper$this->signMd5($str) ); 
  235.     } 
  236.     /** 
  237.      * sha1签名 
  238.      * 签名规则 
  239.      * 1、字典排序 
  240.      * 2、拼接查询字符串 
  241.      * 3、sha1运算 
  242.      * 
  243.      * @param array $arr 
  244.      * @return string 
  245.      */ 
  246.     protected function sha1Sign($arr
  247.     { 
  248.         ksort($arr); 
  249.         return sha1( $this->arrayToString($arr) ); 
  250.     } 
  251. }

Tags: php微信支付 APP支付

分享到: