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