溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

laravel下微信支付接入,三種支付模式

發(fā)布時(shí)間:2020-07-03 22:22:18 來源:網(wǎng)絡(luò) 閱讀:3562 作者:liang3391 欄目:web開發(fā)
      1. (掃碼模式二,微信瀏覽器內(nèi)部支付(jsapi模式),手機(jī)端瀏覽器支付 (H5支付或者wap支付)
      1. 先進(jìn)微信https://pay.weixin.qq.com/index.php做參數(shù)配置工作
      1. 產(chǎn)品中心--開發(fā)者配置
      1. A 支付授權(quán)目錄(支付發(fā)起的頁面url 必須精確到最后一個(gè)目錄/下 必須有 / 否則不行)
      1. http://www.qq.com/abd/sdfs/1.html 就要在后臺(tái)配置http://www.qq.com/abd/sdfs/
      1. 如果url是http://www.qq.com/abd/sdfs?1.html 那就把url改成 http://www.qq.com/abd/sdfs/?1.html 否則驗(yàn)證不通過無法調(diào)用微信支付
      1. B 回調(diào)地址 就是付款完成了微信會(huì)回調(diào)你的url告訴你處理結(jié)果(我這里沒用上,微信死活不回調(diào)我,我就js輪詢主動(dòng)去查詢微信那邊的訂單狀態(tài)做處理)
      1. C H5支付需要開通 填寫頂級(jí)域名即可
      1. 1.掃碼模式二
      1. //微信支付
      1. $wxpay = new Wxpay();
      1. $order_info['body']='畫品購買';
      1. $order_info['order_number']=$order_id;
      1. if($_SERVER['HTTP_HOST']=='www.qq.cn'){
      1. $order_info['money']=$money;//畫品總價(jià)
      1. }else{
      1. $order_info['money']='1';
      1. }
      1. $order_info['id']=$order_id;
      1. $result=$wxpay->do_nativepay($order_info);
      1. if($result){
      1. //這個(gè)if里面的就是自己定義的內(nèi)容,比如生成二維碼之后你要插入一條數(shù)據(jù)進(jìn)入數(shù)據(jù)庫之類 上面
      1. // 組裝是必須要有的 下面這個(gè)是自己自定義的
      1. $data['url']=$result;
      1. $data['order_id']=$order_id;
      1. if($_SERVER['HTTP_HOST']=='www.qq.cn'){
      1. $data['money']=$money;//畫品總價(jià)
      1. }else{
      1. $data['money']='1';
      1. }
      1. $data['pay_type']=2;
      1. }
      1. return ajax_success($data); 這里包含微信返回的支付信息
      1. 下面是在魔板和js里面進(jìn)行的處理:
      1. <img src="http://paysdk.weixin.qq.com/example/qrcode.php?data='+data.info.url+'" class="resize" style="width:70%;"> 這里就生成了二維碼可以掃碼付款
      1. setTimeout(function(){
      1. getoneorder(data.info.order_id);
      1. },2000);
      1. //微信支付輪詢js開始
      1. function getoneorder(pr){
      1. if(pr) {
      1. $.ajax({
      1. url: '/wechat/checkwxorderstatus', //這個(gè)方法是查詢微信那邊的訂單處理狀結(jié)果 因?yàn)榈幕卣{(diào)微信沒有觸發(fā).
      1. data: {order_id: pr},
      1. type: 'GET',
      1. // dataType : 'json',
      1. success: function (msg) {
      1. if (msg.status==1) {
      1. // istry = false;
      1. layer.msg('支付成功');
      1. window.location.href='/member';
      1. }else if (msg.status==2 ) {
      1. layer.msg('支付失敗');
      1. setTimeout(function () {
      1. getoneorder(pr);
      1. }, 1000);
      1. }else{ //暫未支付
      1. setTimeout(function () {
      1. getoneorder(pr);
      1. }, 1000);
      1. }
      1. },
      1. error: function () {
      1. setTimeout(function () {
      1. getoneorder(pr);
      1. }, 1000);
      1. }
      1. })
      1. }
      1. }
      1. //微信支付輪詢js結(jié)束
      1. //查詢微信的訂單狀態(tài)并處理訂單業(yè)務(wù)邏輯返回處理結(jié)果
      1. public function checkWxOrderStatus(Request $request){
      1. $data = $request->all();
      1. $order_id=$data['order_id'];
      1. $wxpay=new Wxpay();
      1. $result=$wxpay->query_order($order_id);
      1. if(!empty($result['trade_state'])&&$result['trade_state']=='SUCCESS'){//去微信查詢訂單狀態(tài)是ok
      1. $doorder=Order::doOrder($order_id,2); //傳訂單id處理訂單
      1. if($doorder=='success'){
      1. return array(
      1. 'trade_state'=>'SUCCESS',
      1. 'order_status'=>'SUCCESS',
      1. 'status'=>'1' //支付成功
      1. );
      1. }else{
      1. return array(
      1. 'trade_state'=>'SUCCESS',
      1. 'order_status'=>'FAIL',
      1. 'status'=>'2' //付款成功但是沒改訂單狀態(tài)
      1. );
      1. }
      1. }else{
      1. return array(
      1. 'trade_state'=>'FAIL',
      1. 'order_status'=>'FAIL',
      1. 'status'=>'3' //付款不成功訂單也沒修改
      1. );
      1. }
      1. }
      1. 2.微信內(nèi)部瀏覽器支付(jsapi模式)和手機(jī)瀏覽器模式參見下面合并在一起判斷處理的,我這里是是根據(jù)UA進(jìn)行判斷用戶進(jìn)入哪種支付模式,如果是微信打開的進(jìn)入第一個(gè)否則進(jìn)入第二個(gè)H5支付
      1. //手機(jī)UA判斷
      1. if($this->isWeixin()){ //微信內(nèi)部瀏覽器,這個(gè)方法網(wǎng)上很多自己搜索
      1. $wxpay = new Mobilewxpay();
      1. $order_info['uatype']='2';
      1. $order_info['body']='畫品購買';
      1. $order_info['opend_id']=Auth::user()->openid;
      1. $order_info['order_number']=$parent_order_id;
      1. //區(qū)分生產(chǎn)和測(cè)試環(huán)境的支付金額
      1. if($_SERVER['HTTP_HOST']=='www.qq.cn'){
      1. $order_info['money']=$total_money;
      1. }else{
      1. $order_info['money']='1';
      1. }
      1. $order_info['id']=$parent_order_id;
      1. $order_info['pay_type']=2;
      1. //未付款的訂單才可以進(jìn)行付款
      1. $wxpay->unifiedOrder($order_info);
      1. $resulturl = $wxpay->GetJsApiParameters($order_info);
      1. if (!empty($resulturl)){
      1. //這一步是把微信返回的json格式的數(shù)據(jù)轉(zhuǎn)換成數(shù)組
      1. $resulturl = json_decode($resulturl,true);
      1. }
      1. $order_info['resulturl']= $resulturl;
      1. }else{ //手機(jī)自帶瀏覽器
      1. $wxpay = new Mobilewxpay();
      1. $order_info['uatype']='1';
      1. $order_info['body']='畫品購買';
      1. $order_info['order_number']=$parent_order_id;
      1. //區(qū)分生產(chǎn)和測(cè)試環(huán)境的支付金額
      1. if($_SERVER['HTTP_HOST']=='www.qq.cn'){
      1. $order_info['money']=$total_money;
      1. }else{
      1. $order_info['money']='1';
      1. }
      1. $order_info['id']=$parent_order_id;
      1. //未付款的訂單才可以進(jìn)行付款
      1. $h6result= $wxpay->MobileH5Pay($order_info);
      1. $order_info['pay_type']=2;
      1. $order_info['h6resulturl']=!empty($h6result['mweb_url'])?$h6result['mweb_url']:'';
      1. }
      1. return ajax_success($order_info);
      1. 提交訂單的通過上面的ajax返回?cái)?shù)據(jù)
      1. 下面的js里面的處理:
      1. if(data.info.pay_type==2){//微信支付
      1. if(data.info.uatype == 1){//手機(jī)自帶瀏覽器H5支付走這里
      1. var h6resulturlss=data.info.h6resulturl.replace(/amp;/, "");//這里進(jìn)入了一個(gè)坑IOS手機(jī)上url會(huì)被轉(zhuǎn)義這里是處理這個(gè)情況的,請(qǐng)注意支付跳轉(zhuǎn)的url里面的&是否被轉(zhuǎn)義成& 切記大坑. 如果是賦值在a鏈接的一個(gè)鏈接的話不會(huì)有這種情況發(fā)生.如果變量賦值給js的話會(huì)有這種情況.
      1. var h6resulturl12=decodeURI(h6resulturlss);
      1. window.open(h6resulturl12);//這里是走微信支付協(xié)議調(diào)用微信彈框
      1. }else{//微信內(nèi)部瀏覽器jsapi支付走這里
      1. callpay(data.info.resulturl);//這里是呼喚微信支付彈框
      1. }
      1. setTimeout(function(){
      1. getoneorder(data.info.id);
      1. },2000);
      1. return false;
      1. }
      1. //調(diào)用微信JS api 支付
      1. function jsApiCall(pr)
      1. {
      1. WeixinJSBridge.invoke(
      1. 'getBrandWCPayRequest',
      1. pr,
      1. function(res){
      1. WeixinJSBridge.log(res.err_msg);
      1. // alert(res.err_code+res.err_desc+res.err_msg);
      1. }
      1. );
      1. }
      1. function callpay(pr)
      1. {
      1. if (typeof WeixinJSBridge == "undefined"){
      1. if( document.addEventListener ){
      1. document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
      1. }else if (document.attachEvent){
      1. document.attachEvent('WeixinJSBridgeReady', jsApiCall);
      1. document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
      1. }
      1. }else{
      1. jsApiCall(pr);
      1. }
      1. }
      1. //微信支付輪詢js開始
      1. function getoneorder(pr){
      1. if(pr) {
      1. $.ajax({
      1. url: '/wechat/checkwxorderstatus',//這里還是查詢微信那邊的訂單狀態(tài)做判斷處理
      1. data: {order_id: pr},
      1. type: 'GET',
      1. // dataType : 'json',
      1. success: function (msg) {
      1. if (msg.status==1) {
      1. // istry = false;
      1. layer.open({
      1. content: '<div class="demo-tip-box"><div class="tip-text">支付成功</div></div>'
      1. ,skin: 'msg'
      1. ,time: 2 //2秒后自動(dòng)關(guān)閉
      1. });
      1. // window.setTimeout('window.location.href="/buy/paysuccess?type=1&oid='+pr+'"',2000);
      1. window.setTimeout('window.location.href="/member/myorder"',2000);
      1. }else if (msg.status==2 ) {
      1. layer.open({
      1. content: '<div class="demo-tip-box"><div class="tip-text">支付失敗</div></div>'
      1. ,skin: 'msg'
      1. ,time: 2 //2秒后自動(dòng)關(guān)閉
      1. });
      1. setTimeout(function () {
      1. getoneorder(pr);
      1. }, 1000);
      1. }else{ //暫未支付
      1. setTimeout(function () {
      1. getoneorder(pr);
      1. }, 1000);
      1. }
      1. },
      1. error: function () {
      1. setTimeout(function () {
      1. getoneorder(pr);
      1. }, 1000);
      1. }
      1. })
      1. }
      1. }
      1. //微信支付輪詢js結(jié)束
      1. $(document).ready(function(){
      1. getoneorder();
      1. });
      1. 附上我的支付類文件 (掃描支付模式二使用的)
      1. <?php
      1. namespace App\Tools\weixin;
      1. /**
        • 微信支付
      1. */
      1. class Wxpay {
      1. //掃碼支付模式一
      1. public function do_nativepay1($productId){
      1. include_once '../app/Tools/weixin/lib/WxPay.NativePay.php';
      1. $notify = new NativePay();
      1. $url1 = $notify->GetPrePayUrl($productId);
      1. return $url1;
      1. }
      1. //掃描支付模式二
      1. public function do_nativepay($order_info) {
      1. include_once '../app/Tools/weixin/lib/WxPay.NativePay.php';
      1. $notify = new \NativePay();
      1. $input = new \WxPayUnifiedOrder();
      1. $input->SetBody($order_info['body']);
      1. $input->SetAttach("畫品購買");
      1. $input->SetOut_trade_no($order_info['id']);
      1. //$input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));
      1. if($_SERVER['HTTP_HOST']=='www.qq.cn'){
      1. $input->SetTotal_fee($order_info['money']*100);
      1. }else{
      1. $input->SetTotal_fee($order_info['money']);
      1. }
      1. $input->SetTime_start(date("YmdHis"));
      1. $input->SetTime_expire(date("YmdHis", time() + 600));
      1. $input->SetGoods_tag("test");
      1. $input->SetNotify_url('http://artflyer.qq.com/buy/getpay');
      1. // $input->SetNotify_url(url('http://artflyer.qq.com/wechat/getpay'));
      1. $input->SetTrade_type("NATIVE");
      1. $input->SetProduct_id($order_info['id']);
      1. $result = $notify->GetPayUrl($input);
      1. $url2 = $result["code_url"];
      1. return $url2;
      1. }
      1. // 支付付款
      1. public function do_wxpay($order_info) {
      1. ini_set('date.timezone', 'Asia/Shanghai');
      1. include_once '../app/Tools/weixin/lib/WxPay.JsApiPay.php';
      1. //①、獲取用戶openid
      1. $tools = new \JsApiPay();
      1. $openId = $tools->GetOpenid();
      1. //②、統(tǒng)一下單
      1. $input = new \WxPayUnifiedOrder();
      1. $input->SetBody($order_info['goods_name']);
      1. $input->SetAttach('');
      1. $input->SetOut_trade_no($order_info['order_sn']);
      1. $input->SetTotal_fee($order_info['order_amount']);
      1. $input->SetTime_start(date("YmdHis"));
      1. $input->SetTime_expire(date("YmdHis", time() + 600));
      1. $input->SetGoods_tag('');
      1. $input->SetNotify_url(url('http://artflyer.qq.com/wechat/getpay'));
      1. // $input->SetNotify_url(WxPayConfig::NOTIFY_URL);
      1. $input->SetTrade_type("JSAPI");
      1. $input->SetOpenid($openId);
      1. $order = \WxPayApi::unifiedOrder($input);
      1. $jsApiParameters = $tools->GetJsApiParameters($order);
      1. //生成帶參數(shù)的同步放回地址
      1. include_once('../app/Tools/weixin/lib/WxPay.Api.php');
      1. $url_arr = json_decode($jsApiParameters, TRUE);
      1. unset($url_arr['signType']);
      1. unset($url_arr['paySign']);
      1. $url_arr['order_sn'] = $order_info['order_sn'];
      1. $notify = new \WxPayResults();
      1. $notify->FromArray($url_arr);
      1. $sign = $notify->SetSign();
      1. $url_arr['sign'] = $sign;
      1. $return_url = \WxPayConfig::RETURN_URL . '?' . http_build_query($url_arr);
      1. //支付頁面
      1. $pay_url = \WxPayConfig::PAY_URL . '?order_sn=' . $order_info['order_sn'];
      1. include_once 'weixin.html';
      1. }
      1. // 同步回調(diào)驗(yàn)證
      1. public function do_return($arr = array()) {
      1. include_once('../app/Tools/weixin/lib/WxPay.Api.php');
      1. $notify = new \WxPayResults();
      1. if (empty($arr)) {
      1. $arr = $_GET;
      1. }
      1. $notify->FromArray($arr);
      1. if ($notify->CheckSign() == true) {
      1. return TRUE;
      1. } else {
      1. return FALSE;
      1. }
      1. }
      1. // 異步回調(diào)驗(yàn)證
      1. public function do_notify($xml) {
      1. include_once('../app/Tools/weixin/lib/WxPay.Api.php');
      1. $notify = new WxPayResults();
      1. $notify->FromXml($xml);
      1. if ($notify->CheckSign() == true) {
      1. return TRUE;
      1. } else {
      1. return FALSE;
      1. }
      1. }
      1. //xml轉(zhuǎn)化成數(shù)組
      1. public function FromXml($xml) {
      1. include_once('../app/Tools/weixin/lib/notify.php');
      1. $notify = new PayNotifyCallBack();
      1. return $notify->FromXml($xml);
      1. }
      1. /**
        • 交易查詢 查詢訂單交易狀態(tài)
        • @param string $order_sn 07073訂單號(hào)
        • @return [type] [array]
      1. */
      1. public function query_order($order_sn) {
      1. include_once '../app/Tools/weixin/lib/WxPay.Api.php';
      1. if (isset($order_sn) && $order_sn != "") {
      1. $input = new \WxPayOrderQuery();
      1. $input->SetOut_trade_no($order_sn);
      1. $result_arr = \WxPayApi::orderQuery($input);
      1. }
      1. return $result_arr;
      1. }
      1. // 退款
      1. public function wx_refund($order_info) {
      1. require_once "../app/Tools/weixin/lib/WxPay.Api.php";
      1. $input = new WxPayRefund();
      1. $input->SetTransaction_id($order_info['transaction_id']);
      1. $input->SetTotal_fee($order_info['total_fee']);
      1. $input->SetRefund_fee($order_info['refund_fee']);
      1. $input->SetOut_refund_no($order_info['batch_no']);
      1. $input->SetOp_user_id(WxPayConfig::MCHID);
      1. $res = WxPayApi::refund($input);
      1. return $res;
      1. }
      1. // 退款狀態(tài)查詢
      1. public function wx_refund_query($order_info) {
      1. require_once '../app/Tools/weixin/lib/WxPay.Api.php';
      1. $input = new WxPayRefundQuery();
      1. $input->SetTransaction_id($order_info['transaction_id']);
      1. $res = WxPayApi::refundQuery($input);
      1. return $res;
      1. }
      1. // 支付付款
      1. public function do_wappay($order_info) {
      1. include_once '../app/Tools/weixin/lib/WxPay.WapPay.php';
      1. // 統(tǒng)一下單
      1. $input = new \WxPayUnifiedOrder();
      1. $input->SetBody($order_info['goods_name']);
      1. $input->SetAttach("");
      1. $input->SetOut_trade_no($order_info['order_sn']);
      1. $input->SetTotal_fee($order_info['order_amount']);
      1. $input->SetTime_start(date("YmdHis"));
      1. $input->SetTime_expire(date("YmdHis", time() + 600));
      1. $input->SetGoods_tag("");
      1. $input->SetNotify_url(\WxPayConfig::NOTIFY_URL);
      1. $input->SetTrade_type("WAP");
      1. $input->SetProduct_id($order_info['id']);
      1. $wxpay = new \WapPay();
      1. // 預(yù)支付訂單信息
      1. $prepay_res = $wxpay->GetPrepayInfo($input);
      1. var_dump($prepay_res);
      1. $wxpay->GetWapPayUrl($prepay_res['prepayid']);
      1. }
      1. // 微信登錄
      1. public function wxlogin() {
      1. include_once '../app/Tools/weixin/lib/WxPay.JsApiPay.php';
      1. // 獲取用戶openid
      1. $tools = new JsApiPay();
      1. $data = $tools->GetOpenData();
      1. return $data;
      1. }
      1. // 獲得微信用戶信息
      1. public function wxuser($access_token, $openid) {
      1. include_once '../app/Tools/weixin/lib/WxPay.JsApiPay.php';
      1. // 獲取用戶openid
      1. $tools = new JsApiPay();
      1. $data = $tools->getUserInfo($access_token, $openid);
      1. return $data;
      1. }
      1. //將xml轉(zhuǎn)為array
      1. public function xmlToArray($xml){
      1. $array_data = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
      1. return $array_data;
      1. }
      1. /**
        • 作用:array轉(zhuǎn)xml
      1. */
      1. function arrayToXml($arr)
      1. {
      1. $xml = "<xml>";
      1. foreach ($arr as $key=>$val)
      1. {
      1. if (is_numeric($val))
      1. {
      1. $xml.="<".$key.">".$val."</".$key.">";
      1. }
      1. else
      1. $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
      1. }
      1. $xml.="</xml>";
      1. return $xml;
      1. }
      1. /*
        • 移動(dòng)端H5支付
      1. */
      1. public function mobile_h6pay(){
      1. //①、獲取用戶openid
      1. include_once '../app/Tools/weixin/lib/WxPay.JsApiPay.php';
      1. $tools = new \JsApiPay();
      1. $openId = $tools->GetOpenid();
      1. //②、統(tǒng)一下單
      1. $input = new \WxPayUnifiedOrder();
      1. $input->SetBody("test");
      1. $input->SetAttach("test");
      1. $input->SetOut_trade_no(\WxPayConfig::MCHID.date("YmdHis"));
      1. $input->SetTotal_fee("1");
      1. $input->SetTime_start(date("YmdHis"));
      1. $input->SetTime_expire(date("YmdHis", time() + 600));
      1. $input->SetGoods_tag("test");
      1. $input->SetNotify_url("http://www1.qq.cn/wechat/getpay");
      1. $input->SetTrade_type("MWEB"); //H5支付的交易類型為MWEB
      1. // $input->SetOpenid($openId); //這里要注釋掉
      1. $order = \WxPayApi::unifiedOrder($input);
      1. return $order;
      1. }
      1. }
      1. 下面這個(gè)是H5支付和微信內(nèi)部瀏覽器支付使用的類文件
      1. <?php
      1. namespace App\Tools\weixin;
      1. header('Content-type:text/html;charset=utf-8');
      1. /**微信支付
        • Class Mobilewxpay
        • @package App\Tools\weixin
      1. */
      1. class Mobilewxpay {
      1. public $APPID = 'wx811a9fc';
      1. public $MCHID = '14912';
      1. public $KEY = '68e4b3eae5b171f17fc5';
      1. public $APPSECRET = '6bce72a750664d61a3b47c';
      1. /**
      1. *
        • 拼接簽名字符串
        • @param array $urlObj
        • @return 返回已經(jīng)拼接好的字符串
      1. */
      1. function ToUrlParams($urlObj)
      1. {
      1. $buff = "";
      1. foreach ($urlObj as $k => $v)
      1. {
      1. if($k != "sign"){
      1. $buff .= $k . "=" . $v . "&";
      1. }
      1. }
      1. $buff = trim($buff, "&");
      1. return $buff;
      1. }
      1. /**
        • 統(tǒng)一下單,WxPayUnifiedOrder中out_trade_no、body、total_fee、trade_type必填
        • appid、mchid、spbill_create_ip、nonce_str不需要填入
        • @param WxPayUnifiedOrder $inputObj
        • @param int $timeOut
        • @throws WxPayException
        • @return 成功時(shí)返回,其他拋異常
      1. */
      1. function unifiedOrder($order_info,$timeOut = 6)
      1. {
      1. $datas = array();
      1. $datas['body'] = '購買';
      1. $datas['out_trade_no'] = $order_info['id'];//訂單號(hào)
      1. $datas['total_fee'] = $order_info['money'];
      1. $datas['time_start'] = date("YmdHis");
      1. $datas['time_expire'] = date("YmdHis", time() + 600);
      1. $datas['notify_url'] = 'http://artwap.qq.com/wechat/getpay';//沒有用上這個(gè)url微信死活不回調(diào)我,用的js輪詢查詢支付和訂單狀態(tài)
      1. $datas['trade_type'] = 'JSAPI';//微信內(nèi)部瀏覽器支付
      1. // $datas['openid'] = $order_info['opend_id'];
      1. $datas['openid'] = 'o_rTz0bCFLXRx5XSmE_ijh9xaC3U';
      1. $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
      1. $datas['appid'] = $this->APPID;//公眾賬號(hào)ID
      1. $datas['mch_id'] = $this->MCHID;//商戶號(hào)
      1. $datas['spbill_create_ip'] = $_SERVER['REMOTE_ADDR'];//ip
      1. $datas['nonce_str'] = $this->getNonceStr();//隨機(jī)字符串
      1. //簽名步驟一:按字典序排序參數(shù)
      1. ksort($datas);
      1. $string = $this->ToUrlParamss($datas);
      1. //簽名步驟二:在string后加入KEY
      1. $string = $string . "&key=".$this->KEY;
      1. //簽名步驟三:MD5加密
      1. $string = md5($string);
      1. //簽名步驟四:所有字符轉(zhuǎn)為大寫
      1. $result = strtoupper($string);
      1. $datas['sign'] = $result;//簽名
      1. $xml = $this->ToXml($datas);
      1. $response = $this->postXmlCurl($xml, $url, false, $timeOut);
      1. $data = $this->FromXml($response);
      1. return $data;
      1. }
      1. /**
        • 產(chǎn)生隨機(jī)字符串,不長(zhǎng)于32位
        • @param int $length
        • @return 產(chǎn)生的隨機(jī)字符串
      1. */
      1. function getNonceStr($length = 32)
      1. {
      1. $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
      1. $str ="";
      1. for ( $i = 0; $i < $length; $i++ ) {
      1. $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1);
      1. }
      1. return $str;
      1. }
      1. /**
        • 輸出xml字符
      1. **/
      1. function ToXml($datas)
      1. {
      1. $xml = "<xml>";
      1. foreach ($datas as $key=>$val)
      1. {
      1. if (is_numeric($val)){
      1. $xml.="<".$key.">".$val."</".$key.">";
      1. }else{
      1. $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
      1. }
      1. }
      1. $xml.="</xml>";
      1. return $xml;
      1. }
      1. /**
        • 格式化參數(shù)格式化成url參數(shù)
      1. */
      1. function ToUrlParamss($datas)
      1. {
      1. $buff = "";
      1. foreach ($datas as $k => $v)
      1. {
      1. if($k != "sign" && $v != "" && !is_array($v)){
      1. $buff .= $k . "=" . $v . "&";
      1. }
      1. }
      1. $buff = trim($buff, "&");
      1. return $buff;
      1. }
      1. /**
        • 以post方式提交xml到對(duì)應(yīng)的接口url
      1. *
        • @param string $xml 需要post的xml數(shù)據(jù)
        • @param string $url url
        • @param bool $useCert 是否需要證書,默認(rèn)不需要
        • @param int $second url執(zhí)行超時(shí)時(shí)間,默認(rèn)30s
      1. */
      1. function postXmlCurl($xml, $url, $useCert = false, $second = 30)
      1. {
      1. $ch = curl_init();
      1. //設(shè)置超時(shí)
      1. curl_setopt($ch, CURLOPT_TIMEOUT, $second);
      1. curl_setopt($ch,CURLOPT_URL, $url);
      1. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
      1. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false);//嚴(yán)格校驗(yàn)
      1. //設(shè)置header
      1. curl_setopt($ch, CURLOPT_HEADER, FALSE);
      1. //要求結(jié)果為字符串且輸出到屏幕上
      1. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
      1. //post提交方式
      1. curl_setopt($ch, CURLOPT_POST, TRUE);
      1. curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
      1. //運(yùn)行curl
      1. $data = curl_exec($ch);
      1. //返回結(jié)果
      1. curl_close($ch);
      1. return $data;
      1. }
      1. /**
        • 將xml轉(zhuǎn)為array
        • @param string $xml
      1. */
      1. public function FromXml($xml) {
      1. //將XML轉(zhuǎn)為array
      1. return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
      1. }
      1. /**
        • 獲取jsapi支付的參數(shù)
        • @param array $UnifiedOrderResult 統(tǒng)一支付接口返回的數(shù)據(jù)
        • @return json數(shù)據(jù),可直接填入js函數(shù)作為參數(shù)
      1. */
      1. function GetJsApiParameters($order_info,$timeOut = 6){
      1. $UnifiedOrderResult = $this->unifiedOrder($order_info,$timeOut = 6);
      1. if(!array_key_exists("appid", $UnifiedOrderResult)
      1. || !array_key_exists("prepay_id", $UnifiedOrderResult)
      1. || $UnifiedOrderResult['prepay_id'] == "")
      1. {
      1. echo $UnifiedOrderResult['err_code_des'];
      1. exit;
      1. }
      1. $da = array();
      1. $da['appId'] = $UnifiedOrderResult["appid"];
      1. $timeStamp = time();
      1. $da['timeStamp'] = "$timeStamp";
      1. $da['nonceStr'] = $this->getNonceStr();
      1. $da['package'] = "prepay_id=" . $UnifiedOrderResult['prepay_id'];
      1. $da['signType'] = 'MD5';
      1. //簽名步驟一:按字典序排序參數(shù)
      1. ksort($da);
      1. $string = $this->ToUrlParamss($da);
      1. //簽名步驟二:在string后加入KEY
      1. $string = $string . "&key=".$this->KEY;
      1. //簽名步驟三:MD5加密
      1. $string = md5($string);
      1. //簽名步驟四:所有字符轉(zhuǎn)為大寫
      1. $result = strtoupper($string);
      1. $da['paySign'] = $result;
      1. $parameters = json_encode($da);
      1. return $parameters;
      1. }
      1. /*
        • 微信H5相關(guān)處理開始
      1. */
      1. function get_client_ip() {
      1. static $realip;
      1. if (isset($_SERVER)) {
      1. if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
      1. $realip = $_SERVER["HTTP_X_FORWARDED_FOR"];
      1. } else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
      1. $realip = $_SERVER["HTTP_CLIENT_IP"];
      1. } else {
      1. $realip = $_SERVER["REMOTE_ADDR"];
      1. }
      1. } else {
      1. if (getenv("HTTP_X_FORWARDED_FOR")) {
      1. $realip = getenv("HTTP_X_FORWARDED_FOR");
      1. } else if (getenv("HTTP_CLIENT_IP")) {
      1. $realip = getenv("HTTP_CLIENT_IP");
      1. } else {
      1. $realip = getenv("REMOTE_ADDR");
      1. }
      1. }
      1. return $realip;
      1. }
      1. //H5支付開始(手機(jī)自帶瀏覽器處理)
      1. function createNoncestr( $length = 32 ){
      1. $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
      1. $str ="";
      1. for ( $i = 0; $i < $length; $i++ ) {
      1. $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
      1. }
      1. return $str;
      1. }
      1. public function getIp(){
      1. $ip = '';
      1. if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
      1. $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
      1. }elseif(isset($_SERVER['HTTP_CLIENT_IP'])){
      1. $ip = $_SERVER['HTTP_CLIENT_IP'];
      1. }else{
      1. $ip = $_SERVER['REMOTE_ADDR'];
      1. }
      1. $ip_arr = explode(',', $ip);
      1. return $ip_arr[0];
      1. }
      1. public function postXmlCurlh6($xml,$url,$second = 30){
      1. $ch = curl_init();
      1. //設(shè)置超時(shí)
      1. curl_setopt($ch, CURLOPT_TIMEOUT, $second);
      1. curl_setopt($ch,CURLOPT_URL, $url);
      1. curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,FALSE);
      1. curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,FALSE);
      1. //設(shè)置header
      1. curl_setopt($ch, CURLOPT_HEADER, FALSE);
      1. //要求結(jié)果為字符串且輸出到屏幕上
      1. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
      1. //post提交方式
      1. curl_setopt($ch, CURLOPT_POST, TRUE);
      1. curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
      1. //運(yùn)行curl
      1. $data = curl_exec($ch);
      1. //返回結(jié)果
      1. if($data){
      1. curl_close($ch);
      1. return $data;
      1. }else{
      1. $error = curl_errno($ch);
      1. curl_close($ch);
      1. echo "curl出錯(cuò),錯(cuò)誤碼:$error"."<br>";
      1. }
      1. }
      1. /**
        • 生成簽名
        • @return 簽名,本函數(shù)不覆蓋sign成員變量,如要設(shè)置簽名需要調(diào)用SetSign方法賦值
      1. */
      1. protected function MakeSign($arr) {
      1. //簽名步驟一:按字典序排序參數(shù)
      1. ksort($arr);
      1. $string = $this->ToUrlParams($arr);
      1. //簽名步驟二:在string后加入KEY
      1. $string = $string . "&key=" . $this->KEY;
      1. //簽名步驟三:MD5加密
      1. $string = md5($string);
      1. //簽名步驟四:所有字符轉(zhuǎn)為大寫
      1. $result = strtoupper($string);
      1. return $result;
      1. }
      1. public function MobileH5Pay($order_info){
      1. $headers =array();
      1. $headers[] ='Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8';
      1. $headers[] ='Connection: Keep-Alive';
      1. $headers[] ='Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.5,en;q=0.3';
      1. $headers[] ='Accept-Encoding: gzip, deflate';
      1. $headers[] ='User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:22.0) Gecko/20100101Firefox/22.0';
      1. $appid = $this->APPID; //應(yīng)用APPID
      1. $mch_id = $this->MCHID; //微信支付商戶號(hào)
      1. $key = $this->KEY; //微信商戶API密鑰
      1. $rand = rand(00000,99999);
      1. $attach='artflyer.cn';
      1. $out_trade_no = $order_info['id'];//平臺(tái)內(nèi)部訂單號(hào)
      1. $nonce_str = $this->createNoncestr();//隨機(jī)字符串
      1. $body = "artflyer.cn";//內(nèi)容
      1. $total_fee = $order_info['money']; //金額
      1. $spbill_create_ip = $this->getIp(); //IP
      1. $notify_url = "http://artwap.qq.com/wechat/getpay";//沒有用上這個(gè)url微信死活不回調(diào)我,用的js輪詢查詢支付和訂單狀態(tài)
      1. $trade_type = 'MWEB';//交易類型 因?yàn)槭莌6支付所以交易類型必須是MWEB
      1. $scene_info ='{"h6_info":{"type":"Wap","wap_url":"http://www.qq.com/wechat/getpay","wap_name":"artflyer.cn"}}';//場(chǎng)景信息 必要參數(shù)
      1. //以下信息可以不改
      1. $signA ="appid=$appid&attach=$out_trade_no&body=$body&mch_id=$mch_id&nonce_str=$nonce_str?ify_url=$notify_url&out_trade_no=$out_trade_no&scene_info=$scene_info&spbill_create_ip=$spbill_create_ip&total_fee=$total_fee&trade_type=$trade_type";
      1. $strSignTmp = $signA."&key=$key"; //拼接字符串 注意順序微信有個(gè)測(cè)試網(wǎng)址 順序按照他的來 直接點(diǎn)下面的校正測(cè)試 //包括下面XML 是否正確
      1. $sign = strtoupper(MD5($strSignTmp)); // MD5 后轉(zhuǎn)換成大寫
      1. $post_data = "<xml>
      1. <appid>$appid</appid>
      1. <mch_id>$mch_id</mch_id>
      1. <body>$body</body>
      1. <out_trade_no>$out_trade_no</out_trade_no>
      1. <total_fee>$total_fee</total_fee>
      1. <spbill_create_ip>$spbill_create_ip</spbill_create_ip>
      1. <notify_url>$notify_url</notify_url>
      1. <trade_type>$trade_type</trade_type>
      1. <scene_info>$scene_info</scene_info>
      1. <attach>$out_trade_no</attach>
      1. <nonce_str>$nonce_str</nonce_str>
      1. <sign>$sign</sign>
      1. </xml>";//拼接成XML 格式
      1. $url = "https://api.mch.weixin.qq.com/pay/unifiedorder";//微信傳參地址
      1. $dataxml = $this->postXmlCurlh6($post_data,$url,$headers); //后臺(tái)POST微信傳參地址 同時(shí)取得微信返回的參數(shù) POST 方法我寫下面了
      1. $objectxml = (array)simplexml_load_string($dataxml, 'SimpleXMLElement', LIBXML_NOCDATA); //將微信返回的XML 轉(zhuǎn)換成數(shù)組
      1. return $objectxml;
      1. }
      1. }
      1. 有問題也可以發(fā)郵件給微信技術(shù) wepayTS@tencent.com
      1. 搞的比較亂別罵...... 有問題可以QQ交流 245864009
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI