分享一个微擎中能用的微信H5支付类

虽然我不怎么用微擎,但是微擎作为微信开发框架确实挺成功的,而且其插件众多,为很多新手程序员提供了极大的方便。在微擎官方文档中是有支付的,但是发现很多人通过百度和社区问关于微信支付的问题,所以为了一劳永逸封装了一下H5的支付方式,方便后期使用。

类库源码:

  1. <?php
  2. /**
  3.  * Created by 波波.
  4.  * Date: 2018/7/16
  5.  * Function:微信H5支付
  6.  */
  7. if (!defined('IN_IA')) {
  8.     exit('Access Denied');
  9. }
  10. class Wxpay_EweiShopV2Model{
  11.     protected $appScrect;//微信公众平台的appscrect
  12.     protected $appId;//微信公众平台appid
  13.     protected $key;//微信商户平台配置的秘钥
  14.     protected $mch_id;//微信商户号
  15.     protected $values = array();
  16.     public function __construct($appScrect="adfasdf",$appId="wx2cf4a9fa4"$key="ucskmsdffdfgxr3movndg",$mch_id ='1492355454542'){
  17.         $this->appScrect=$appScrect;
  18.         $this->appId=$appId;
  19.         $this->key=$key;
  20.         $this->mch_id=$mch_id;
  21.     }
  22.     public function payh5($total_fee,$body,$out_trade_no,$ip){
  23.         //$ip= request()->ip();
  24.         $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
  25.         $notify_url   ='http://'.$_SERVER['HTTP_HOST'].'/index/index/notify';
  26.         $onoce_str = $this->createNoncestr();
  27.         $data["appid"] = $this->appId;
  28.         $data["body"] = $body;
  29.         $data["mch_id"] = $this->mch_id;
  30.         $data["nonce_str"] = $onoce_str;
  31.         $data["notify_url"] = $notify_url;
  32.         $data["out_trade_no"] = $out_trade_no;
  33.         $data["spbill_create_ip"] = $ip;
  34.         $data["total_fee"] = $total_fee*100;
  35.         $data["trade_type"] = "MWEB";
  36.         // $data["openid"] = $openid;
  37.         $data["scene_info"] = "{'h5_info': {'type':'Wap','wap_url':  $notify_url,'wap_name': '测试充值'}}";
  38.         $sign = $this->getSign($data);
  39.         // halt($data);
  40.         $data["sign"] = $sign;
  41.         $xml = $this->arrayToXml($data);
  42.         $response = $this->postXmlCurl($xml$url);
  43.         //将微信返回的结果xml转成数组
  44.         $response = $this->xmlToArray($response);
  45.         //请求数据,统一下单
  46.         return $response;
  47.     }
  48.     public static function getNonceStr($length = 32)
  49.     {
  50.         $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  51.         $str ="";
  52.         for ( $i = 0; $i < $length$i++ )  {
  53.             $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
  54.         }
  55.         return $str;
  56.     }
  57.     //   /*生成签名*/
  58.     public function getSign($Obj){
  59.         foreach ($Obj as $k => $v){
  60.             $Parameters[$k] = $v;
  61.         }
  62.         //签名步骤一:按字典序排序参数
  63.         ksort($Parameters);
  64.         $String = $this->formatBizQueryParaMap($Parameters, false);
  65.         //echo '【string1】'.$String.'</br>';
  66.         //签名步骤二:在string后加入KEY
  67.         $String = $String."&key=".$this->key;
  68.         //echo "【string2】".$String."</br>";
  69.         //签名步骤三:MD5加密
  70.         $String = md5($String);
  71.         //echo "【string3】 ".$String."</br>";
  72.         //签名步骤四:所有字符转为大写
  73.         $result_ = strtoupper($String);
  74.         //echo "【result】 ".$result_."</br>";
  75.         return $result_;
  76.     }
  77.     /**
  78.      *  作用:产生随机字符串,不长于32位
  79.      */
  80.     public function createNoncestr( $length = 32 ){
  81.         $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
  82.         $str ="";
  83.         for ( $i = 0; $i < $length$i++ )  {
  84.             $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
  85.         }
  86.         return $str;
  87.     }
  88.     //数组转xml
  89.     public function arrayToXml($arr){
  90.         $xml = "<xml>";
  91.         foreach ($arr as $key=>$val){
  92.             if (is_numeric($val)){
  93.                 $xml.="<".$key.">".$val."</".$key.">";
  94.             }else{
  95.                 $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
  96.             }
  97.         }
  98.         $xml.="</xml>";
  99.         return $xml;
  100.     }
  101.     /**
  102.      *  作用:将xml转为array
  103.      */
  104.     public function xmlToArray($xml){
  105.         //将XML转为array
  106.         $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  107.         return $array_data;
  108.     }
  109.     /**
  110.      *  作用:以post方式提交xml到对应的接口url
  111.      */
  112.     public function postXmlCurl($xml,$url,$second=30){
  113.         //初始化curl
  114.         $ch = curl_init();
  115.         //设置超时
  116.         curl_setopt($ch, CURLOPT_TIMEOUT, $second);
  117.         //这里设置代理,如果有的话
  118.         //curl_setopt($ch,CURLOPT_PROXY, '8.8.8.8');
  119.         //curl_setopt($ch,CURLOPT_PROXYPORT, 8080);
  120.         curl_setopt($ch,CURLOPT_URL, $url);
  121.         curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
  122.         curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
  123.         //设置header
  124.         curl_setopt($ch, CURLOPT_HEADER, FALSE);
  125.         //要求结果为字符串且输出到屏幕上
  126.         curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  127.         //post提交方式
  128.         curl_setopt($ch, CURLOPT_POST, TRUE);
  129.         curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
  130.         //运行curl
  131.         $data = curl_exec($ch);
  132.         //返回结果
  133.         if($data){
  134.             curl_close($ch);
  135.             return $data;
  136.         }else{
  137.             $error = curl_errno($ch);
  138.             echo "curl出错,错误码:$error"."<br>";
  139.             curl_close($ch);
  140.             return false;
  141.         }
  142.     }
  143.     /*
  144.     获取当前服务器的IP
  145.     */
  146.     public function get_client_ip(){
  147.         if ($_SERVER['REMOTE_ADDR']) {
  148.             $cip = $_SERVER['REMOTE_ADDR'];
  149.         } elseif (getenv("REMOTE_ADDR")) {
  150.             $cip = getenv("REMOTE_ADDR");
  151.         } elseif (getenv("HTTP_CLIENT_IP")) {
  152.             $cip = getenv("HTTP_CLIENT_IP");
  153.         } else {
  154.             $cip = "unknown";
  155.         }
  156.         return $cip;
  157.     }
  158.     /**
  159.      *  作用:格式化参数,签名过程需要使用
  160.      */
  161.     public function formatBizQueryParaMap($paraMap$urlencode){
  162.         $buff = "";
  163.         ksort($paraMap);
  164.         foreach ($paraMap as $k => $v){
  165.             if($urlencode){
  166.                 $v = urlencode($v);
  167.             }
  168.             $buff .= $k . "=" . $v . "&";
  169.         }
  170.         $reqPar;
  171.         if (strlen($buff) > 0){
  172.             $reqPar = substr($buff, 0, strlen($buff)-1);
  173.         }
  174.         return $reqPar;
  175.     }
  176.     public function MakeSign($unifiedorder)
  177.     {
  178.         $this->values=$unifiedorder;
  179.         //签名步骤一:按字典序排序参数
  180.         // ksort($this->values);
  181.         $string = $this->ToUrlParams();
  182. //      halt($string);
  183.         //签名步骤二:在string后加入KEY
  184.         $string = $string . "&key=".$this->key;
  185.         //签名步骤三:MD5加密
  186.         $string = md5($string);
  187.         //签名步骤四:所有字符转为大写
  188.         $result = strtoupper($string);
  189.         return $result;
  190.     }
  191.     public function ToUrlParams()
  192.     {
  193.         $buff = "";
  194.         foreach ($this->values as $k => $v)
  195.         {
  196.             if($k != "sign" && $v != "" && !is_array($v)){
  197.                 $buff .= $k . "=" . $v . "&";
  198.             }
  199.         }
  200.         $buff = trim($buff"&");
  201.         return $buff;
  202.     }
  203.     function array2xml($array)
  204.     {
  205.         $xml='<xml>';
  206.         foreach($array as $key=>$val){
  207.             if(is_numeric($key)){
  208.                 $key="item id=\"$key\"";
  209.             }else{
  210.                 //去掉空格,只取空格之前文字为key
  211.                 list($key,)=explode(' ',$key);
  212.             }
  213.             $xml.="<$key>";
  214.             $xml.=is_array($val)?$this->_array2xml($val):$val;
  215.             //去掉空格,只取空格之前文字为key
  216.             list($key,)=explode(' ',$key);
  217.             $xml.="</$key>";
  218.         }
  219.         $xml.="</xml>";
  220.         return $xml;
  221.     }
  222.     function xml2array($xml)
  223.     {
  224.         //禁止引用外部xml实体
  225.         libxml_disable_entity_loader(true);
  226.         $values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
  227.         return $values;
  228.     }
  229.     public  function request_post($url = ''$param = '')
  230.     {
  231.         if (emptyempty($url) || emptyempty($param)) {
  232.             return false;
  233.         }
  234.         $postUrl = $url;
  235.         $curlPost = $param;
  236.         $ch = curl_init(); //初始化curl
  237.         curl_setopt($ch, CURLOPT_URL, $postUrl); //抓取指定网页
  238.         curl_setopt($ch, CURLOPT_HEADER, 0); //设置header
  239.         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求结果为字符串且输出到屏幕上
  240.         curl_setopt($ch, CURLOPT_POST, 1); //post提交方式
  241.         curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
  242.         $data = curl_exec($ch); //运行curl
  243.         curl_close($ch);
  244.         return $data;
  245.     }
  246.     function curl_post_ssl($url$vars$second=30,$aHeader=array())
  247.     {
  248.         $ch = curl_init();
  249.         //curl_setopt($ch,CURLOPT_VERBOSE,'1');
  250.         curl_setopt($ch,CURLOPT_TIMEOUT,$second);
  251.         curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1);
  252.         curl_setopt($ch,CURLOPT_URL,$url);
  253.         curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
  254.         curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);
  255.         curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM');
  256.         curl_setopt($ch,CURLOPT_SSLCERT,'/data/cert/php.pem');
  257.         curl_setopt($ch,CURLOPT_SSLCERTPASSWD,'1234');
  258.         curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM');
  259.         curl_setopt($ch,CURLOPT_SSLKEY,'/data/cert/php_private.pem');
  260.         ifcount($aHeader) >= 1 ){
  261.             curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);
  262.         }
  263.         curl_setopt($ch,CURLOPT_POST, 1);
  264.         curl_setopt($ch,CURLOPT_POSTFIELDS,$vars);
  265.         $data = curl_exec($ch);
  266.         curl_close($ch);
  267.         if($data){
  268.             return $data;
  269.         }else{
  270.             return false;
  271.         }
  272.     }
  273. }

使用方法:

1、将类库源码下载后,可以通过配置获取查询微信支付的配置信息,然后填入类库最上方的配置中。

2、在后端控制器位置,编写以下代码:

  1. $ip = $_W['clientip'];
  2. $pay_body = "购买商品";
  3. $h5pay = m('wxpay')->payh5($order['price'],$pay_body,$order['ordersn'],$ip);
  4. $redirect_url = mobileUrl('order/pay/success',array('id'=>$orderid,'result'=>"true")); //支付成功后跳转地址
  5. $redirect_url = urlencode($_W['siteroot'].substr($redirect_url,2));
  6. if($h5pay['return_code'] == "SUCCESS"){
  7.     $pay_url = $h5pay['mweb_url']."&redirect_url=".$redirect_url;
  8. }else{
  9.     $pay_url = "#";
  10. }

3、在前端HTML页面只需要在对应按钮上添加跳转链接{$pay_url}即可。

温馨提示:H5的支付方式并非APP支付,所以在封装APP的应用中慎用。仅可通过手机浏览器调起微信支付。

 

你想把广告放到这里吗?

发表评论

您必须 登录 才能发表留言!