一、參數配置
這里有兩個配置
1、微信授權的配置,要用到這幾個參數
2、是支付的設置
二、微信授權
1、原生微信接口獲取授權
public function oauth() { $code = input('code'); $wx_config = $this->config; if(empty($code)) {
//獲取code $r_url = urlencode('http://jskj.all2best.cn/index.php/api/weixinpay/oauth');//這里一定要用urlencode, $url1 = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$wx_config['app_id']}&redirect_uri={$r_url}&response_type=code&scope=snsapi_base&state=STATE#wechat_redirect"; header('location:' . $url1); exit(); }else {
//獲取用戶信息 $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$wx_config['app_id']}&secret={$wx_config['secret']}&code={$code}&grant_type=authorization_code"; $result = curl_client($url); $result = json_decode($result, true); if (isset($result['errcode'])) { throw new \Exception($result['errcode'] . $result['msg']); } // dump($result); Session::prefix('index_auth'); session('open_id',$result['openid']); } }
2、使用 easywechat接口 獲取授權
class Wxtest extends Controller { //服務端驗證 public function wx_init() { try { $app = Factory::officialAccount($this->new_config); // $app->server->push(function ($message) { // return "您好!歡迎使用 EasyWeChat!"; // }); $response = $app->server->serve(); $response->send(); exit; } catch (\Exception $e) { echo $e->getMessage(); } } //配置參數 protected $new_config = [ 'debug' => true, 'app_id' => 'appid', 'secret' => 'secret', 'token' => 'token', 'aes_key' => 'aes_key', 'response_type' => 'array',// 指定 API 調用返回結果的類型:array(default)/collection/object/raw/自定義類名 'oauth' => [ 'scopes' => ['snsapi_userinfo'], 'callback' => '/index.php/api/wxtest/oauth',//授權回調頁面 ], ]; //業務頁面 public function profile() { $app = Factory::officialAccount($this->new_config); $oauth = $app->oauth; // 未登錄 if (empty(session('wx_user'))) { session('target_url','/index.php/api/wxtest/profile'); //return $oauth->redirect(); // 這里不一定是return,如果你的框架action不是返回內容的話你就得使用 $oauth->redirect()->send(); } // 已經登錄過 $user = session('wx_user'); dump($user); //業務邏輯處理 } //授權回調頁 public function oauth() { $app = Factory::officialAccount($this->new_config); $oauth = $app->oauth; // 獲取 OAuth 授權結果用戶信息 $user = $oauth->user(); session('wx_user',$user->toArray()); $targetUrl = empty(session('target_url')) ? '/' : session('target_url'); header('location:'. $targetUrl); // 跳轉到 profile exit(); } }
scope的兩種區別:
snsapi_base:不彈出授權頁面,直接跳轉,只能獲取用戶openid
snsapi_userinfo:彈出授權頁面,可通過openid拿到昵稱、性別、所在地。並且,即使在未關注的情況下,只要用戶授權,也能獲取其信息。
redirect_uri:授權后重定向的回調鏈接地址,請使用urlencode對鏈接進行處理。(easywechat不用處理,直接填寫url即可)
二、微信支付:用的是easywechat的統一下單接口
public function wx_pay($bill_no, $amount) { //已登錄 Session::prefix('index_auth'); $openid = session('open_id');//$user->getId(); if(empty($openid)) { $this->oauth(); }$jssdk = $this->payment->jssdk;
//統一下單 $result = $this->payment->order->unify([ 'body' => 'Kingjim', 'out_trade_no' => $bill_no, 'total_fee' => (int)bcmul($amount, 100), 'notify_url' => url('index.php/api/weixinpay/notify', '', '', true), // 支付結果通知網址,如果不設置則會使用配置里的默認地址 'trade_type' => 'JSAPI', // 請對應換成你的支付方式對應的值類型 'openid' => $openid ]); //預支付訂單號prepayId, 生成支付 JS 配置 $prepayId = $result['prepay_id']; $jsApiParameters = $jssdk->bridgeConfig($prepayId); return $jsApiParameters; }
三、支付回調方法
/**
* notify_url接收通知頁面
*/
public function notify()
{
try {
$response = $this->payment->handlePaidNotify(function ($message, $fail) {
$order = (new Order())->get_order($message['out_trade_no']);
if (!$order || $order['pay_status'] == 2) { // 如果訂單不存在 或者 訂單已經支付過了
return true; // 告訴微信,我已經處理完了,訂單沒找到,別再通知我了
}
if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信狀態
if ($message['result_code'] === 'SUCCESS') {
$order['pay_status'] = 2; // 更新支付狀態
(new Order())::update($order, ['bill_no' => $message['out_trade_no']]); // 保存訂單
//添加流水
(new Flow())->add_ex($order['order_final_amount'],2,$message['out_trade_no']);
// 用戶支付失敗
} elseif ($message['result_code'] === 'FAIL') {
return $fail('通信失敗,請稍后再通知我');
}
} else {
return $fail('通信失敗,請稍后再通知我');
}
return true; // 返回處理完成
});
$response->send(); // return $response;
} catch (Exception $e) {
return tips($e->getMessage());
}
}
四、前端代碼
function onBridgeReady(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId":"wx2421b1c4370ec43b", //公眾號名稱,由商戶傳入 "timeStamp":"1395712654", //時間戳,自1970年以來的秒數 "nonceStr":"e61463f8efa94090b1f366cccfbbb444", //隨機串 "package":"prepay_id=u802345jgfjsdfgsdg888", "signType":"MD5", //微信簽名方式: "paySign":"70EA570631E4BB79628FBCA90534C63FF7FADD89" //微信簽名 }, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok" ){ // 使用以上方式判斷前端返回,微信團隊鄭重提示: //res.err_msg將在用戶支付成功后返回ok,但並不保證它絕對可靠。 } }); }
//需要先判斷是否是微信瀏覽器,並且微信內置包是否加載完成
//有時會出現當觸發事件的時候微信內置包還未加載完成,必須加上下面判斷
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(); }