1.引入api包javascript
2.準備參數php
//微信商戶信息
const APPID = ''; //商戶惟一標識 const MCHID = ''; //商戶收款帳號 const KEY = ''; //交易過程生成簽名的密鑰 const APPSECRET = ''; //AppSecret是APPID對應的接口密碼,用於獲取接口調用憑證access_token時使用
//判斷是否有openId public function initialize(){ if(session('?openid')){ $openid = session('openid'); }else{ $weixin=new \app\admin\controller\Weixin(); //獲取openId $weixin->getUserOpenId(); } } /** * 獲取用戶openid */ public function getUserOpenId(){ $request = Request::instance(); $method = $request->method(); $code= $request->get('code'); if(empty($code)){ $redirect_uri = urlencode("http://xxx/pay_test/public/wxpay/openid"); $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=".$this->appid."&redirect_uri=".$redirect_uri."&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect"; $this->redirect($url); }else{ // 獲取頁面受權的access_token $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$this->appid."&secret=".$this->appsecret."&code=".$code."&grant_type=authorization_code"; // 三、拉取用戶的openid $res = $this->http_curl($url,'get'); $access_token = $res["access_token"]; $openid = $res['openid']; if($openid){ //拉取成功 session('openid',$openid,'think'); session('access_token',$access_token,'think'); $this->redirect('/pay_test/public/wxpay'); }else{ //拉取失敗 $this->error("openid拉取失敗!"); } } } /** * $url 接口url * $type 請求類型 * $res 返回數據類型 * $arr post請求參數 */ public function http_curl($url, $type='get', $res='json', $arr=' '){ // 一、初始化curl $ch = curl_init(); // 二、設置curl參數,默認get方法請求的 curl_setopt($ch, CURLOPT_URL, $url); // 設置url curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 返回 //post方法請求 if($type == 'post') { curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $arr); } // 三、採集(抓取) $output = curl_exec($ch); if($res == 'json') { if(curl_errno($ch)) { // 請求失敗,返回錯誤信息 return curl_error($ch); }else { return json_decode($output, true); } } // 四、關閉curl curl_close($ch); }
4.統一下單前端
//統一下單 public function pay(){ $request = Request::instance(); //付款金額(分) $price = 1; $openid = session('openid'); if(!empty($openid)){ //微信支付生成 ini_set('date.timezone','Asia/Shanghai'); require_once "../extend/wxpay/lib/WxPay.Api.php"; include_once "../extend/wxpay/example/WxPay.JsApiPay.php"; require_once '../extend/wxpay/example/log.php'; require_once '../extend/wxpay/example/WxPay.Config.php'; $wxpay = new \WxPayApi(); $tools = new \JsApiPay(); $out_trade_no = "".date('YmdHis') . str_pad(mt_rand(1, 99999), 5, '0', STR_PAD_LEFT); //付款後回調地址 $notifyurl="http://xxx/pay_test/public/wxpay/redata"; //統一下單 $input = new \WxPayUnifiedOrder(); //商品描述 $input->SetBody("測試訂單"); //商戶訂單號 $input->SetOut_trade_no($out_trade_no); //附加數據 $input->SetAttach("測試附加數據"); //標價金額 $input->SetTotal_fee($price); //交易起始時間 $input->SetTime_start(date("YmdHis")); //交易結束時間 $input->SetTime_expire(date("YmdHis", time() + 600)); //訂單優惠標記 $input->SetGoods_tag("測試優惠標記"); //通知地址 $input->SetNotify_url($notifyurl); //交易類型 $input->SetTrade_type("JSAPI"); //用戶標識 $input->SetOpenid($openid); $config = new \WxPayConfig(); //獲取統一下單數據 $wxdata = $wxpay->unifiedOrder($config,$input); $jsApiParameters = $tools->GetJsApiParameters($wxdata); return ["code"=>0,"data"=>$jsApiParameters,"out_trade_no"=>$out_trade_no,"price"=>$price]; }else{ return ["code"=>-1,"msg"=>"openid不能爲空"]; } }
5.jsapi支付
//微信支付JsApi public function index(){ //統一下單 $data = $this->pay(); //返回數據 $redata= $data['data']; //字符串轉數組 $redata = json_decode($redata); foreach($redata as $k=>$val){ //獲取package if( $k == "package"){ $targer = $val; } //獲取nonceStr if($k == 'nonceStr'){ $noncestr = $val; } //獲取paySign if($k == 'paySign'){ $sign = $val; } //獲取timeStamp if($k == 'timeStamp'){ $time = $val; } } $out_trade_no = $data['out_trade_no']; $price = $data['price']; $this->assign('out_trade_no',$out_trade_no); $this->assign('price',$price); $this->assign('package',$targer); $this->assign('noncestr',$noncestr); $this->assign('sign',$sign); $this->assign('time',$time); return view('index'); }
<script src="/pay_test/public/static/admin/js/jquery-3.1.1.min.js" type="text/javascript"></script> <script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> <script> var nonceStr = "{$noncestr}"; var time = "{$time}"; var paySign = "{$sign}"; var package = "{$package}"; var out_trade_no = "{$out_trade_no}"; var price = "{$price}"; </script> <script> function onBridgeReady(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId":"xxx", //公衆號名稱,由商戶傳入 "timeStamp":time, //時間戳,自1970年以來的秒數 "nonceStr":nonceStr, //隨機串 "package":package, "signType":"MD5", //微信簽名方式: "paySign":paySign //微信簽名 }, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok" ){ // 使用以上方式判斷前端返回,微信團隊鄭重提示:res.err_msg將在用戶支付成功後返回ok,但並不保證它絕對可靠 location.href = "http://xxx/redata?sign="+paySign+"&price="+price; } }); } 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(); } </script>
public function redata(){
$get_data = request()->get(); //接收微信返回信息 $redata = file_get_contents("php://input"); //服務器根目錄 define('BASE_PATH',$_SERVER['DOCUMENT_ROOT']); //文件目錄 $dir = BASE_PATH.'/pay_test/public/uploads/admin/wxpay/'.date("Ymd")."/"; //文件名 $filepath = date('Y-m-d h:i:s', time())."txt"; //判斷是否有該目錄 if(!file_exists($dir)){ //建立目錄 mkdir($dir,0777,true); } //寫入接收到的信息 file_put_contents($dir.$filepath,$redata,FILE_APPEND); //獲取文件中信息,轉爲字符串 $data = file_get_contents($dir.$filepath); //轉爲數組 $redata_array = (array)simplexml_load_string($data, 'SimpleXMLElement', LIBXML_NOCDATA); var_dump($redata_array); return '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>'; }