一、参数配置
这里有两个配置
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(); }