在项目中用到小程序支付,费话不多说上代码
因为我这涉及么微信的很多开发功能 所以我把公共的方法放到的公共类中
WechatPublic
<?php namespace app\zhonglian\controller\wechat; use app\BaseController; use think\facade\Config; use EasyWeChat\Factory; use app\zhonglian\controller\ZhonglianPublic; class WechatPublic extends ZhonglianPublic{ public $config; //公众号配置文件 public $app; //公众号配置 public $minConfig; //小程序配置 public $wechatPay; //微信支付配置 public function __construct(){ $this->config = [ /** * 账号基本信息,请从微信公众平台/开放平台获取 */ 'app_id' => Config::get('zhonglian.wechat.AppID'), // AppID 'secret' => Config::get('zhonglian.wechat.AppSecret'), // AppSecret 'token' => Config::get('zhonglian.wechat.token'), // Token 'aes_key' => Config::get('zhonglian.wechat.aes_key'), // EncodingAESKey,安全模式与兼容模式下请一定要填写!!! 'response_type' => 'array', ]; // 小程序 $this->minConfig = [ 'app_id' => Config::get('zhonglian.minWechat.AppID'), 'secret' => Config::get('zhonglian.minWechat.AppSecret'), // 下面为可选项 // 指定 API 调用返回结果的类型:array(default)/collection/object/raw/自定义类名 'response_type' => 'array', 'log' => [ 'level' => 'debug', 'file' => __DIR__.'/wechat.log', ], ]; $this->webHost = 'https:://'.$_SERVER['HTTP_HOST']; //站点域名 //微信支付 $this->wechatPay = [ // 必要配置 'app_id' => Config::get('zhonglian.wechatPay.app_id'), 'mch_id' => Config::get('zhonglian.wechatPay.mch_id'), 'key' => Config::get('zhonglian.wechatPay.key'), // API 密钥 // 如需使用敏感接口(如退款、发送红包等)需要配置 API 证书路径(登录商户平台下载 API 证书) 'cert_path' => 'V6/wechatpay/apiclient_cert.pem', // XXX: 绝对路径!!!! 'key_path' => 'V6/wechatpay/apiclient_key.pem', // XXX: 绝对路径!!!! 'notify_url' => $this->webHost.'/zhonglian/zl/pay_notify', // 你也可以在下单时单独设置来想覆盖它 ]; $this->app = Factory::officialAccount($this->config); $this->minApp = Factory::miniProgram($this->minConfig); $this->pay = Factory::payment($this->wechatPay); } }
Pay
<?php namespace app\zhonglian\controller\wechat; use app\zhonglian\controller\wechat\WechatPublic; use app\zhonglian\model\UserAccessToken; use app\zhonglian\model\UserZhonglianOrder; use think\Controller; use EasyWeChat\Foundation\Application; use think\exception\ValidateException; use EasyWeChat\Factory; use EasyWeChat\Kernel\Messages\Text; use think\facade\Log; use app\zhonglian\validate\Pay as PayV; class Pay extends WechatPublic{ public function pay(){ if(request()->isPost()){ $data = input('post.'); try { validate(PayV::class) ->scene('pay') ->check($data); } catch (ValidateException $e) { // 验证失败 输出错误信息 return json(['code'=>10001,'msg'=>$e->getError()]); } $data['orderId'] = date('YmdHis', time()).rand(10000,99999); $data['userId'] = UserAccessToken::where('accessToken',$data['access_token'])->value('userId'); //存入数据至本地表 $res = UserZhonglianOrder::addData($data); $result = $this->pay->order->unify([ 'body' => $data['body'], 'out_trade_no' => $date['orderId'], 'total_fee' => floatval($data['total_fee'] * 100), 'spbill_create_ip' => '', // 可选,如不传该参数,SDK 将会自动获取相应 IP 地址 'notify_url' => $this->webHost.'/zhonglian/zl/pay_notify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址 'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型 'openid' => $data['openid'], ]); /*$result返回数据如下 $result = [ "return_code" => "SUCCESS", "return_msg" => "OK", "appid" => "****************", "mch_id" => ""****************",", "nonce_str" => "oYRmqEGsfV95H221", "sign" => "37DC4CB564102893FC8C09C488D2FA00", "result_code" => "SUCCESS", "prepay_id" => "wx0411540670981758f0ccc5845afd110000", "trade_type" => "JSAPI" ]; */ if($result['return_code'] != 'SUCCESS' || $result['result_code'] != 'SUCCESS'){ return json(['code'=>1,'msg'=>'获取支付订单失败']); }else{ if ($res) { $jssdk = $this->pay->jssdk; $config = $jssdk->bridgeConfig($result['prepay_id'], false); return json(['code'=>0,'data'=>$config]); } else { return json(['code'=>1,'msg'=>'创建订单失败!']); } } /*$config返回如下 [ 'appId' => 'wx9ae6b16168110e36', 'timeStamp' => '1604475465', 'nonceStr' => '5fa25a49a887b', 'package' => 'prepay_id=wx0411540670981758f0ccc5845afd110000', 'signType' => 'MD5', 'paySign' => 'A332227D36EC94B3610A86C8049F069C', ] */ } } //支付回调 public function pay_notify(){ $response = $this->pay->handlePaidNotify(function($message, $fail){ $order = Db::name('order')->where(['order'=> $message['out_trade_no']])->find(); if (!$order || $order['status']==2) { // 如果订单不存在 或者 订单已经支付过了 return true; } if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态 // 用户是否支付成功 if ($message['result_code'] === 'SUCCESS') { //成功处理操作 略
//$message['out_trade_no'] 商户订单号
// 用户支付失败 } elseif ($message['result_code'] === 'FAIL') { return true; } } else { return false; } }); return $response; }
public function get_openid() { $code = $this->request->param('code'); $res = $this->app->auth->session($code); return json($res); }
}
小程序
getUserInfo: function (e){ var that = this; if (e.detail.userInfo) { wx.login({ success: res_user => { http.Get("/zhonglian/zl/get_openid", {code:res_user.code}, function (res) { console.log(res.data) wx.setStorageSync('openid', res.data.openid); wx.setStorageSync('nickname', e.detail.userInfo.nickName); wx.setStorageSync('image', e.detail.userInfo.avatarUrl); wx.setStorageSync('sex', e.detail.userInfo.gender); that.setData({login:false}) }); } }) } else { console.log('用户拒绝了授权') wx.showToast({ title: "为了您更好的体验,请同意授权登陆", icon: 'none', duration: 2000 }); } }, pay:function (){ var that = this var formData = { access_token: '***********', total_fee: 0.01, openid: wx.getStorageSync('openid'), body: '支付产品', } http.Post("/zhonglian/zl/pay", formData, function (res) { console.log(res.data); console.log('调起支付'); wx.requestPayment({ 'timeStamp': res.data.timeStamp, 'nonceStr': res.data.nonceStr, 'package': res.data.package, 'signType':'MD5', 'paySign': res.data.paySign, 'success':function(resa){ console.log('支付成功') }, 'fail':function(err){ console.log('支付失败'); } }); }); },