溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

關于微信H5支付(微信內支付 和 跳連接支付)

發(fā)布時間:2020-02-29 17:21:45 來源:網絡 閱讀:879 作者:kangjunfei 欄目:web開發(fā)

好久沒有更新博客,最近做項目遇到了微信支付,整理一下需求,目的一個活動頁面需要調微信支付!
應用框架THINKPHP5.1

注意:微信支付 需要注意 如果是h6頁面調取支付的話,需要靜默一個登錄狀態(tài)獲取code,這樣才可以保證支付調取的參數(shù)openid正常,這里的坑填了好久,微信內瀏覽器h6用戶輸入完手機號登錄后,頁面存cookie信息,有時候會不更新獲取的openid 導致“下單賬號和支付賬號不一致,請核對”;

微信內瀏覽器刷新頁面用jq執(zhí)行: window.location.href = location.href+'?time='+((new Date()).getTime());

直接上代碼:前端
function get_form(){
var price1 =$(".get_price1").val();
var price2 =$(".get_price2").val();
var price3 =$(".get_price3").val();
var price4 =$(".get_price4").val();
var pid =$(".pid").val();
var username =$(".username").val();
var mobile =$(".mobile").val();
var address =$(".address").val();

    if(!username && !mobile && !address){
        layer.alert('收貨人信息不能為空');
        return false;
    }
    $.post("home/get_from",//get_from 是后臺請求支付的邏輯
            {"price1":price1,"price2":price2,"price3":price3,"price4":price4,"username":username,"mobile":mobile,"address":address,"pid":pid},function(apiConfig){
           console.log(apiConfig);

        var ua = navigator.userAgent.toLowerCase();//獲取判斷用的對象是微信內還是外部
        if (ua.match(/MicroMessenger/i) == "micromessenger") {
           //內部
            WeixinJSBridge.invoke(
                    'getBrandWCPayRequest', {
                        "appId":apiConfig.appId,     //公眾號名稱,由商戶傳入
                        "timeStamp":apiConfig.timeStamp,         //時間戳,自1970年以來的秒數(shù)
                        "nonceStr":apiConfig.nonceStr, //隨機串
                        "package":apiConfig.package,
                        "signType":apiConfig.signType,         //微信簽名方式:
                        "paySign":apiConfig.paySign //微信簽名
                    },
                    function(res){
                        if(res.err_msg == "get_brand_wcpay_request:ok" ){

                            window.location.href ="方法路徑"
                        }
                    });

            if (typeof WeixinJSBridge == "undefined"){
                if( document.addEventListener ){
                    document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
                }else if (document.attachEvent){
                    document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
                    document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
                }
            }else{
                onBridgeReady();
            }

        }else{

     //外部
            var url="支付成功跳轉";
            window.location.href =apiConfig.mweb_url+"&redirect_url="+url;

        }

    });
}

后端代碼:
靜默登錄 請求頁面的時候通過tp5 redirect重置路由
再進入頁面的方法里 查找有沒有openid
$sa = Cookie::get('kj_phone');
$uid =$sa['id'];//用戶id
$userAgent = $_SERVER['HTTP_USER_AGENT']; // 判斷是 公眾號支付還是外部網址支付
if (strpos($userAgent, 'MicroMessenger')) { // 公眾號支付
$uid =$sa['id'];//用戶id
$open_id= Cache::get($uid);
// print_r($open_id);
if(empty($open_id)){
$this->redirect("https://open.weixin.qq.com/connect/oauth3/authorize?appid=Appid&redirect_uri=頁面進入后先通過get_open方法獲得code獲取openid&response_type=code&scope=snsapi_base&state=1#wechat_redirect");

          }

      }

get_open方法
public function get_open(){

    $code1=empty($_GET['code']) ? '' : $_GET['code'];

    $sa =Cookie::get('kj_phone');

   // $appId ='appId ';
    //$secret ='secret';
    $get_token_url = 'https://api.weixin.qq.com/sns/oauth3/access_token?appid=Appid&secret=secre&code=' . $code1 . '&grant_type=authorization_code';
    $json_obj = $this->http_request($get_token_url);
    $json_obj = json_decode($json_obj,true);
    $openid = empty($json_obj['openid']) ? "" : $json_obj['openid'];

    $uid =$sa['id'];//用戶id

    Cache::set($uid,$openid,3600);
    if($code1 == ''){

        $this->redirect('重定向到渲染頁面');
    }
    if(!empty($open_id)){
        $this->redirect('重定向到渲染頁面');
    }else{

        $this->redirect('重定向到渲染頁面');
    }

}

get_from:
public function get_from(){
if(request()->isPost()){
$data =input("post.");// 前端傳過來的數(shù)據(jù) 自己寫邏輯吧

             $userAgent = $_SERVER['HTTP_USER_AGENT']; // 判斷是 公眾號支付還是外部網址支付

             if (strpos($userAgent, 'MicroMessenger')) { // 公眾號支付

                 $sa = Cookie::get('kj_phone');
                 $uid =$sa['id'];//用戶id
                 $open_id= Cache::get($uid);
                 //print_r($open_id);exit;
                 $return = $this->weixinapp($open_id,$body,$order_id,$price,$attact);
                 return $return;
             }else{

                 $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
                 $parameters = array(
                     'appid' => "小程序ID", //小程序ID
                     'mch_id' => "商戶號", //商戶號
                     'attach'=>$attact,
                     'nonce_str' => $this->createNoncestr(), //隨機字符串
                     'body' =>$body, //商品描述
                     'out_trade_no' =>$order_id,//商戶訂單號
                     'total_fee' => $price * 100, //總金額 單位 分
                     'spbill_create_ip' => '111111', //終端IP
                     'notify_url' => '回調地址', //通知地址  確保外網能正常訪問
                     'trade_type' => 'MWEB'//交易類型
                 );

                 //統(tǒng)一下單簽名
                 $parameters['sign'] = $this->getSign($parameters);

                 $xmlData = $this->arrayToXml($parameters);

                 $return = $this->xmlToArray($this->postXmlCurl($xmlData, $url, 60));

                 return $return;
             }

        }

    }
}

//統(tǒng)一下單接口
private function weixinapp($openid,$body,$orderId,$price,$attact) {

    $unifiedorder = $this->unifiedorder($openid,$body,$orderId,$price,$attact);

    $parameters = array(
        'appId' => "appId", //小程序ID
        'timeStamp' => '' . time() . '', //時間戳
        'nonceStr' => $this->createNoncestr(), //隨機串
        'package' => 'prepay_id=' . $unifiedorder['prepay_id'], //數(shù)據(jù)包
        'signType' => 'MD5'//簽名方式
    );
    //簽名
    $parameters['paySign'] = $this->getSign($parameters);
    return $parameters;
}
//作用:產生隨機字符串,不長于32位
private function createNoncestr($length = 32) {
    $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
    $str = "";
    for ($i = 0; $i < $length; $i++) {
        $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
    }
    return $str;
}
private function getSign($Obj) {
    //halt($Obj);
    foreach ($Obj as $k => $v) {
        $Parameters[$k] = $v;
    }
    //簽名步驟一:按字典序排序參數(shù)
    ksort($Parameters);
    $String = $this->formatBizQueryParaMap($Parameters, false);
    //簽名步驟二:在string后加入KEY
    $String = $String . "&key=d18e10ad06222c972499296f1cefa481" ;
    //簽名步驟三:MD5加密
    $String = md5($String);
    //簽名步驟四:所有字符轉為大寫
    $result_ = strtoupper($String);

    return $result_;
}
///作用:格式化參數(shù),簽名過程需要使用
private function formatBizQueryParaMap($paraMap, $urlencode) {
    $buff = "";
    ksort($paraMap);
    foreach ($paraMap as $k => $v) {
        if ($urlencode) {
            $v = urlencode($v);
        }
        $buff .= $k . "=" . $v . "&";
    }
    $reqPar="";
    if (strlen($buff) > 0) {
        $reqPar = substr($buff, 0, strlen($buff) - 1);
    }
    return $reqPar;
}
//數(shù)組轉換成xml
private function arrayToXml($arr) {
    $xml = "<root>";
    foreach ($arr as $key => $val) {
        if (is_array($val)) {
            $xml .= "<" . $key . ">" . arrayToXml($val) . "</" . $key . ">";
        } else {
            $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
        }
    }
    $xml .= "</root>";
    return $xml;
}
//xml轉換成數(shù)組
private function xmlToArray($xml) {
    //禁止引用外部xml實體
    libxml_disable_entity_loader(true);
    $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
    $val = json_decode(json_encode($xmlstring), true);
    return $val;
}
function http_curl($url){//用curl傳參
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);//關閉ssl驗證
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
    curl_setopt($ch,CURLOPT_HEADER, 0);
    $output = curl_exec($ch);
    curl_close($ch);
    return json_decode($output, true);
}
private static function postXmlCurl($xml, $url, $second = 30)
{
    $ch = curl_init();
    //設置超時
    curl_setopt($ch, CURLOPT_TIMEOUT, $second);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //嚴格校驗
    //設置header
    curl_setopt($ch, CURLOPT_HEADER, FALSE);
    //要求結果為字符串且輸出到屏幕上
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    //post提交方式
    curl_setopt($ch, CURLOPT_POST, TRUE);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20);
    curl_setopt($ch, CURLOPT_TIMEOUT, 40);
    set_time_limit(0);
    //運行curl
    $data = curl_exec($ch);
    //返回結果
    if ($data) {
        curl_close($ch);
        return $data;
    } else {
        $error = curl_errno($ch);
        curl_close($ch);
        throw new WxPayException("curl出錯,錯誤碼:$error");
    }
}
//回調
private function unifiedorder($openid,$body,$orderId,$price,$attact) {

    $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
    $parameters = array(
        'appid' => "appid", //小程序ID
        'mch_id' =>"mch_id", //商戶號
        'attach'=>$attact,
        'nonce_str' => $this->createNoncestr(), //隨機字符串
        'body' => $body,
        'out_trade_no'=> $orderId,
        'total_fee' => $price * 100,
        'spbill_create_ip' => '11111111', //終端IP
        'notify_url' => 回調, //通知地址  確保外網能正常訪問
        'openid' => $openid, //用戶id
        'trade_type' => 'JSAPI'//交易類型
    );

    //統(tǒng)一下單簽名
    $parameters['sign'] = $this->getSign($parameters);
    $xmlData = $this->arrayToXml($parameters);

    $return = $this->xmlToArray($this->postXmlCurl($xmlData, $url, 60));

    return $return;
}
//回調
public function callback(){
    $xml = file_get_contents("php://input");
    // 將XML 轉換為數(shù)組
    $xml = json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA));
    $result = json_decode($xml, true);

    //如果成功返回
    if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){
        $where['order_id']=$result['out_trade_no'];
        $data_e['states']=2;
        $ud= db('hc_pr_order')->where($where)->update($data_e);
    }
    // 給微信的返回值
    if ($ud) {
        $str='<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
    }else{
        $str='<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[簽名失敗]]></return_msg></xml>';
    }
    return $str;
    return $result;
}
向AI問一下細節(jié)

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

AI