在项目中用到小程序支付,费话不多说上代码
因为我这涉及么微信的很多开发功能 所以我把公共的方法放到的公共类中
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(\'支付失败\'); } }); }); },