微信h5支付详解php版本,非微信浏览器

最近楼主工作需要需要做微信h5支付,但是微信的狗文档,没有demo,为了帮助后来者少走弯路,决定开启此篇。

首先我们来准备一下微信h5支付必备的参数


$this->values['appid'] ='公众号appid';

$this->values['mch_id'] ='商户号';

$this->values['nonce_str'] = '32位随机字符串';

$this->values['body'] ='支付测试';

$this->values['out_trade_no'] ='商家自己的订单号';

$this->values['total_fee'] = 1;

$this->values['spbill_create_ip'] = '用户ip';//注意这个ip必须是真实ip不能写死,不然支付会不成功

$this->values['notify_url'] = '回调地址';

$this->values['trade_type'] = 'MWEB';//此类型就这样

$this->values['scene_info'] = '{"h5_info": {"type":"Wap","wap_url": "网址就是该方法的,具体说法可以看微信的文档","wap_name": "测试"}}';

//接下来有个最重要的签名

$this->values['sign'] =$this->MakeSign();//签名

以上就是微信h5支付必须传的参数,在本文后方,会把全部代码贴出来,请不要慌

接下来就进入转xml的环境,因为微信官方要求,没有法


$xm = $this->ToXml();//转xml

$url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; //这个是微信h5支付传参请求接口

$dataxml = $this->http_post($url,$xm); //我们用curl请求,

$arr = $this->FromXml($dataxml);//因为微信返回的也是xml数据,我们需要转回数组

if(!empty($arr) && $arr['return_code']=='SUCCESS' && $arr['result_code']=='SUCCESS'){

           $payurl = $arr['mweb_url'].'&redirect_url='.zmf::config('domian');//前面的mweb_url是微信返回给我们的连接,我们不能直接后端就跳转过去,这样会说缺参数。我们需要用a标签触发,或者是js跳转才能成功,后面的redirect_url 这个地址是,你成功支付还是取消支付都会跳到这个地址,当然看你业务需求,可以不要

        $this->render('index',array('url'=>$payurl));//加载页面,因为我是yii框架

}else{

    var_dump($arr['err_code_des']);//这是打印为啥请求出错的信息

}

其实微信h5支付的核心代码就这些,下面我会把我这全部代码放出来。

class WechatfiveController 
{

    public $values = array();

    public function actionCeshi(){
        $this->values['appid'] ='公众号appid';
        $this->values['mch_id'] ='商户号';
        $this->values['nonce_str'] = $this->str_rand();
        $this->values['body'] ='支付测试';
        $this->values['out_trade_no'] ='';//商家订单号
        $this->values['total_fee'] = 1;//金额,记得*100因为微信单位是分
        $this->values['spbill_create_ip'] = $this->get_client_ip();//获取ip地址
        $this->values['notify_url'] = '';//微信回调地址
        $this->values['trade_type'] = 'MWEB';
        $this->values['scene_info'] = '{"h5_info": {"type":"Wap","wap_url": "网址就是该方法的,具体说法可以看微信的文档","wap_name": "测试"}}';
        $this->values['sign'] =$this->MakeSign();//签名
        $xm = $this->ToXml();
        $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        $dataxml = $this->http_post($url,$xm);
        $arr = $this->FromXml($dataxml);
        if(!empty($arr) && $arr['return_code']=='SUCCESS' && $arr['result_code']=='SUCCESS'){
            $payurl = $arr['mweb_url'].'&redirect_url='.跳转网址;//前面的mweb_url是微信返回给我们的连接,我们不能直接后端就跳转过去,这样会说缺参数。我们需要用a标签触发,或者是js跳转才能成功,后面的redirect_url 这个地址是,你成功支付还是取消支付都会跳到这个地址,当然看你业务需求,可以不要
            $this->render('index',array('url'=>$payurl));//加载页面,因为我是yii框架
        }else{
            zmf::test($arr['err_code_des']);//这是打印为啥请求出错的信息
        }

    }



    private   function str_rand($length = 32, $char = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') {
        if(!is_int($length) || $length < 0) {
                 return false;
     }

     $string = '';
    for($i = $length; $i > 0; $i--) {
                 $string .= $char[mt_rand(0, strlen($char) - 1)];
     }

     return $string;
 }

    /**
     * 将xml转为array
     * @param string $xml
     * @throws WxPayException
     */
    private function FromXml($xml)
    {
        if(!$xml){
            throw new WxPayException("xml数据异常!");
        }
        //将XML转为array
        //禁止引用外部xml实体
        libxml_disable_entity_loader(true);
        $this->values = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $this->values;
    }

    /**
     * 生成签名
     * @return 签名,本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
     */
    private function MakeSign()
    {
        //签名步骤一:按字典序排序参数
        ksort($this->values);
        $string = $this->ToUrlParams();
        //签名步骤二:在string后加入KEY
        $string = $string . "&key=bgBoN0CzzwcKVTOijCmZmeFDdFOzyb9f";
        //签名步骤三:MD5加密
        $string = md5($string);
        //签名步骤四:所有字符转为大写
        $result = strtoupper($string);
        return $result;
    }

    /**
     * 格式化参数格式化成url参数
     */
    private function ToUrlParams()
    {
        $buff = "";
        foreach ($this->values as $k => $v)
        {
            if($k != "sign" && $v != "" && !is_array($v)){
                $buff .= $k . "=" . $v . "&";
            }
        }

        $buff = trim($buff, "&");
        return $buff;
    }

    /**
     * 输出xml字符
     * @throws WxPayException
     **/
    private function ToXml()
    {
        if(!is_array($this->values)
            || count($this->values) <= 0)
        {
            throw new WxPayException("数组数据异常!");
        }

        $xml = "<xml>";
        foreach ($this->values as $key=>$val)
        {
            if (is_numeric($val)){
                $xml.="<".$key.">".$val."</".$key.">";
            }else{
                $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
            }
        }
        $xml.="</xml>";
        return $xml;
    }

    private function http_post($url, $data) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_HEADER,0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        $res = curl_exec($ch);
        curl_close($ch);
        return $res;
    }

    private  function get_client_ip() {
        if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
            $ip = getenv('HTTP_CLIENT_IP');
        } elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
            $ip = getenv('REMOTE_ADDR');
        } elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        return preg_match ( '/[\d\.]{7,15}/', $ip, $matches ) ? $matches [0] : '';
    }




}

如果这篇文档对你有帮助,请点个赞呗,楼主用这套代码已经成功跑起h5支付,微信官方文档链接:https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_20&index=1


©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,295评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,928评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,682评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,209评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,237评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,965评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,586评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,487评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,016评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,136评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,271评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,948评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,619评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,139评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,252评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,598评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,267评论 2 358

推荐阅读更多精彩内容