搜索
首页php教程php手册ThinkPay最新微信支付公众号支付驱动分享

ThinkPay最新微信支付公众号支付驱动分享
下面分享个ThinkPay的微信支付驱动,便于大家使用,如有疑问加QQ群讨论105108204<?php <br /> // +----------------------------------------------------------------------<br> // | 零云 [ 简单 高效 卓越 ]<br> // +----------------------------------------------------------------------<br> // | Copyright (c) 2016 http://www.lingyun.net All rights reserved.<br> // +----------------------------------------------------------------------<br> // | Author: jry <br> // +----------------------------------------------------------------------<br> namespace Addons\Pay\ThinkPay\Pay\Driver;<br> <br> /**<br>  * 微信支付驱动<br>  */<br> class Wxpay extends \Addons\Pay\ThinkPay\Pay\Pay<br> {<br>     protected $gateway    = 'https://api.mch.weixin.qq.com/pay/unifiedorder';<br>     protected $orderquery = 'https://api.mch.weixin.qq.com/pay/orderquery';<br>     protected $config     = array(<br>         'appid'     => '',<br>         'appsecret' => '',<br>         'mchid'     => '',<br>         'key'       => '',<br>     );<br> <br>     public function check()<br>     {<br>         if (!$this->config['appid'] || !$this->config['appsecret'] || !$this->config['mchid'] || !$this->config['key']) {<br>             E("微信支付设置有误!");<br>         }<br>         return true;<br>     }<br> <br>     public function buildRequestForm($pay_data)<br>     {<br>         // APP支付<br>         if (C('IS_API')) {<br>             $param = array(<br>                 'appid'            => $this->config['appid'],<br>                 'mch_id'           => $this->config['mchid'],<br>                 'nonce_str'        => $this->getNonceStr(),<br>                 'body'             => $pay_data['body'],<br>                 'out_trade_no'     => $pay_data['out_trade_no'],<br>                 'total_fee'        => $pay_data['money'] * 100,<br>                 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],<br>                 'notify_url'       => $this->config['notify_url'],<br>                 'trade_type'       => 'APP',<br>             );<br> <br>             // 签名<br>             $param['sign'] = $this->MakeSign($param);<br>             $xml_param     = $this->ToXml($param);<br>             $result        = $this->FromXml($this->postXmlCurl($xml_param, $this->gateway));<br>             if ($result['return_code'] === 'SUCCESS') {<br>                 if ($this->CheckSign($result)) {<br>                     // 统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。<br>                     // 参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay<br>                     $prepayparams              = array();<br>                     $prepayparams['appid']     = $result['appid'];<br>                     $prepayparams['partnerid'] = $result['mch_id'];<br>                     $prepayparams['prepayid']  = $result['prepay_id'];<br>                     $prepayparams['noncestr']  = $result['nonce_str'];<br>                     $prepayparams['package']   = 'Sign=WXPay';<br>                     $prepayparams['timestamp'] = time();<br>                     $prepayparams['sign']      = $this->MakeSign($prepayparams); // 签名<br>                     $return['json']            = json_encode($prepayparams);<br>                     return $return;<br>                 }<br>             }<br>         } else {<br>             // 获取用户openId,微信公众号JSAPI支付必须<br>             $openId = $this->GetOpenid();<br>             $param  = array(<br>                 'appid'            => $this->config['appid'],<br>                 'mch_id'           => $this->config['mchid'],<br>                 'nonce_str'        => $this->getNonceStr(),<br>                 'body'             => $pay_data['body'],<br>                 'out_trade_no'     => $pay_data['out_trade_no'],<br>                 'total_fee'        => $pay_data['money'] * 100,<br>                 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],<br>                 'notify_url'       => $this->config['notify_url'],<br>                 'trade_type'       => 'JSAPI',<br>                 'openid'           => $openId,<br>             );<br> <br>             // 签名<br>             $param['sign'] = $this->MakeSign($param);<br>             $xml_param     = $this->ToXml($param);<br>             $result        = $this->FromXml($this->postXmlCurl($xml_param, $this->gateway));<br>             if ($result['return_code'] === 'SUCCESS') {<br>                 if ($this->CheckSign($result)) {<br>                     // 获取JSAPI所需参数<br>                     $jsApiParameters = $this->GetJsApiParameters($result);<br>                     $pay_page        =                          <br>                             <br>                                 <meta> <br>                                 <meta> <br>                                 <title>微信支付</title> <br>                                 <script><br /> //调用微信JS api 支付<br /> function jsApiCall()<br /> {<br /> WeixinJSBridge.invoke(<br /> &#039;getBrandWCPayRequest&#039;,<br /> {$jsApiParameters},<br /> function(res){<br /> WeixinJSBridge.log(res.err_msg);<br /> //alert(res.err_code+res.err_desc+res.err_msg);<br /> }<br /> );<br /> }<br /> <br /> function callpay()<br /> {<br /> if (typeof WeixinJSBridge == "undefined"){<br /> if( document.addEventListener ){<br /> document.addEventListener(&#039;WeixinJSBridgeReady&#039;, jsApiCall, false);<br /> }else if (document.attachEvent){<br /> document.attachEvent(&#039;WeixinJSBridgeReady&#039;, jsApiCall);<br /> document.attachEvent(&#039;onWeixinJSBridgeReady&#039;, jsApiCall);<br /> }<br /> }else{<br /> jsApiCall();<br /> }<br /> }<br /> </script><br>                             <br>                             <br>                                 <br><br>                                 <font><b>该笔订单支付金额为<span>{$pay_data['money']}</span>元</b></font><br><br><br>                                 <div> <br>                                     <button>立即支付</button><br>                                 </div> <br>                             <br>                             <br> EOF;<br>                     return $pay_page;<br>                 }<br>             } else {<br>                 E("微信订单错误!" . $result['return_msg']);<br>             }<br>         }<br>     }<br> <br>     /**<br>      * 异步通知验证<br>      */<br>     public function verifyNotify($notify)<br>     {<br>         //获取通知的数据<br>         if ($notify['return_code'] === 'SUCCESS') {<br>             if (!array_key_exists("transaction_id", $notify)) {<br>                 E("输入参数不正确!");<br>             }<br>             $param['transaction_id'] = $notify["transaction_id"];<br>             $param['appid']          = $this->config['appid'];<br>             $param['mch_id']         = $this->config['mchid'];<br>             $param['nonce_str']      = $this->getNonceStr();<br>             $param['sign']           = $this->MakeSign($param);<br>             $xml_param               = $this->ToXml($param);<br>             $result                  = $this->FromXml($this->postXmlCurl($xml_param, $this->orderquery));<br>             if ($this->CheckSign($result)) {<br>                 $result['status'] = ($result['result_code'] == 'SUCCESS') ? true : false;<br>                 $result['money']  = $result['total_fee'] / 100;<br>                 $this->info       = $result;<br>                 return true;<br>             }<br>         } else {<br>             E('通知错误');<br>         }<br>     }<br> <br>     /**<br>      *<br>      * 获取jsapi支付的参数<br>      * @param array $UnifiedOrderResult 统一支付接口返回的数据<br>      * @throws WxPayException<br>      *<br>      * @return json数据,可直接填入js函数作为参数<br>      */<br>     public function GetJsApiParameters($UnifiedOrderResult)<br>     {<br>         if (!array_key_exists("appid", $UnifiedOrderResult)<br>             || !array_key_exists("prepay_id", $UnifiedOrderResult)<br>             || $UnifiedOrderResult['prepay_id'] == "") {<br>             E("参数错误");<br>         }<br>         $jsapi['appId']     = $UnifiedOrderResult["appid"];<br>         $jsapi['timeStamp'] = (string) time();<br>         $jsapi['nonceStr']  = $this->getNonceStr();<br>         $jsapi['appId']     = $UnifiedOrderResult["appid"];<br>         $jsapi['package']   = "prepay_id=" . $UnifiedOrderResult['prepay_id'];<br>         $jsapi['signType']  = 'MD5';<br>         $jsapi['paySign']   = $this->MakeSign($jsapi);<br>         $parameters         = json_encode($jsapi);<br>         return $parameters;<br>     }<br> <br>     /**<br>      * 以post方式提交xml到对应的接口url<br>      *<br>      * @param string $xml  需要post的xml数据<br>      * @param string $url  url<br>      * @param bool $useCert 是否需要证书,默认不需要<br>      * @param int $second   url执行超时时间,默认30s<br>      * @throws WxPayException<br>      */<br>     private static function postXmlCurl($xml, $url, $useCert = false, $second = 30)<br>     {<br>         $ch = curl_init();<br>         //设置超时<br>         curl_setopt($ch, CURLOPT_TIMEOUT, $second);<br> <br>         //如果有配置代理这里就设置代理<br>         // if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"<br>         //             && WxPayConfig::CURL_PROXY_PORT != 0){<br>         //             curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);<br>         //             curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);<br>         //         }<br>         curl_setopt($ch, CURLOPT_URL, $url);<br>         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);<br>         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); //严格校验<br>         //设置header<br>         curl_setopt($ch, CURLOPT_HEADER, false);<br>         //要求结果为字符串且输出到屏幕上<br>         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);<br> <br>         if ($useCert == true) {<br>             //设置证书<br>             //使用证书:cert 与 key 分别属于两个.pem文件<br>             curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');<br>             curl_setopt($ch, CURLOPT_SSLCERT, WxPayConfig::SSLCERT_PATH);<br>             curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');<br>             curl_setopt($ch, CURLOPT_SSLKEY, WxPayConfig::SSLKEY_PATH);<br>         }<br>         //post提交方式<br>         curl_setopt($ch, CURLOPT_POST, true);<br>         curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);<br>         //运行curl<br>         $data = curl_exec($ch);<br>         //返回结果<br>         if ($data) {<br>             curl_close($ch);<br>             return $data;<br>         } else {<br>             $error = curl_errno($ch);<br>             curl_close($ch);<br>             E("curl出错,错误码:$error");<br>         }<br>     }<br> <br>     /*<br>      * 产生随机字符串,不长于32位<br>      * @param int $length<br>      * @return 产生的随机字符串<br>      */<br>     public static function getNonceStr($length = 32)<br>     {<br>         $chars = "abcdefghijklmnopqrstuvwxyz0123456789";<br>         $str   = "";<br>         for ($i = 0; $i              $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);<br>         }<br>         return $str;<br>     }<br> <br>     /**<br>      * 生成签名<br>      * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值<br>      */<br>     public function MakeSign($param)<br>     {<br>         //签名步骤一:按字典序排序参数<br>         ksort($param);<br>         $string = $this->ToUrlParams($param);<br>         //签名步骤二:在string后加入KEY<br>         $string = $string . "&key=" . $this->config['key'];<br>         //签名步骤三:MD5加密<br>         $string = md5($string);<br>         //签名步骤四:所有字符转为大写<br>         $result = strtoupper($string);<br>         return $result;<br>     }<br> <br>     /**<br>      *<br>      * 检测签名<br>      */<br>     public function CheckSign($param)<br>     {<br>         $sign = $this->MakeSign($param);<br>         if ($param['sign'] == $sign) {<br>             return true;<br>         } else {<br>             E("签名错误!");<br>         }<br>     }<br> <br>     /**<br>      *<br>      * 拼接签名字符串<br>      * @param array $urlObj<br>      *<br>      * @return 返回已经拼接好的字符串<br>      */<br>     public function ToUrlParams($param)<br>     {<br>         $buff = "";<br>         foreach ($param as $k => $v) {<br>             if ($k != "sign" && $v != "" && !is_array($v)) {<br>                 $buff .= $k . "=" . $v . "&";<br>             }<br>         }<br> <br>         $buff = trim($buff, "&");<br>         return $buff;<br>     }<br> <br>     /**<br>      * 输出xml字符<br>      * @throws WxPayException<br>      **/<br>     public function ToXml($param)<br>     {<br>         if (!is_array($param)<br>             || count($param)              E("数组数据异常!");<br>         }<br> <br>         $xml = "<xml>";<br>         foreach ($param as $key => $val) {<br>             if (is_numeric($val)) {<br>                 $xml .= "" . $val . "" . $key . ">";<br>             } else {<br>                 $xml .= "" . $key . ">";<br>             }<br>         }<br>         $xml .= "</xml>";<br>         return $xml;<br>     }<br> <br>     /**<br>      * 将xml转为array<br>      * @param string $xml<br>      * @throws WxPayException<br>      */<br>     public function FromXml($xml)<br>     {<br>         if (!$xml) {<br>             E("xml数据异常!");<br>         }<br>         //将XML转为array<br>         //禁止引用外部xml实体<br>         libxml_disable_entity_loader(true);<br>         $this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);<br>         return $this->values;<br>     }<br> <br>     /**<br>      *<br>      * 通过跳转获取用户的openid,跳转流程如下:<br>      * 1、设置自己需要调回的url及其其他参数,跳转到微信服务器https://open.weixin.qq.com/connect/oauth2/authorize<br>      * 2、微信服务处理完成之后会跳转回用户redirect_uri地址,此时会带上一些参数,如:code<br>      *<br>      * @return 用户的openid<br>      */<br>     public function GetOpenid()<br>     {<br>         //通过code获得openid<br>         if (!isset($_GET['code'])) {<br>             //触发微信返回code码<br>             $baseUrl = urlencode('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);<br>             $url     = $this->__CreateOauthUrlForCode($baseUrl);<br>             Header("Location: $url");<br>             exit();<br>         } else {<br>             //获取code码,以获取openid<br>             $code   = $_GET['code'];<br>             $openid = $this->getOpenidFromMp($code);<br>             return $openid;<br>         }<br>     }<br> <br>     /**<br>      *<br>      * 通过code从工作平台获取openid机器access_token<br>      * @param string $code 微信跳转回来带上的code<br>      *<br>      * @return openid<br>      */<br>     public function GetOpenidFromMp($code)<br>     {<br>         $url = $this->__CreateOauthUrlForOpenid($code);<br>         //初始化curl<br>         $ch = curl_init();<br>         //设置超时<br>         curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);<br>         curl_setopt($ch, CURLOPT_URL, $url);<br>         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);<br>         curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);<br>         curl_setopt($ch, CURLOPT_HEADER, false);<br>         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);<br>         // if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"<br>         //             && WxPayConfig::CURL_PROXY_PORT != 0){<br>         //             curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);<br>         //             curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);<br>         //         }<br>         //运行curl,结果以jason形式返回<br>         $res = curl_exec($ch);<br>         curl_close($ch);<br>         //取出openid<br>         $data       = json_decode($res, true);<br>         $this->data = $data;<br>         $openid     = $data['openid'];<br>         return $openid;<br>     }<br> <br>     /**<br>      *<br>      * 构造获取code的url连接<br>      * @param string $redirectUrl 微信服务器回跳的url,需要url编码<br>      *<br>      * @return 返回构造好的url<br>      */<br>     private function __CreateOauthUrlForCode($redirectUrl)<br>     {<br>         $urlObj["appid"]         = $this->config['appid'];<br>         $urlObj["redirect_uri"]  = "$redirectUrl";<br>         $urlObj["response_type"] = "code";<br>         $urlObj["scope"]         = "snsapi_base";<br>         $urlObj["state"]         = "#wechat_redirect";<br>         $bizString               = $this->ToUrlParams($urlObj);<br>         return "https://open.weixin.qq.com/connect/oauth2/authorize?" . $bizString;<br>     }<br> <br>     /**<br>      *<br>      * 构造获取open和access_toke的url地址<br>      * @param string $code,微信跳转带回的code<br>      *<br>      * @return 请求的url<br>      */<br>     private function __CreateOauthUrlForOpenid($code)<br>     {<br>         $urlObj["appid"]      = $this->config['appid'];<br>         $urlObj["secret"]     = $this->config['appsecret'];<br>         $urlObj["code"]       = $code;<br>         $urlObj["grant_type"] = "authorization_code";<br>         $bizString            = $this->ToUrlParams($urlObj);<br>         return "https://api.weixin.qq.com/sns/oauth2/access_token?" . $bizString;<br>     }<br> }

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中