使用 composer安装
$ composer require overtrue/wechat:~4.0 -vvv
1、前端部分
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
{include file="public/css"/}
{include file="public/js"/}
<title>卡券充值</title>
</head>
<body>
<style>
.login-form {
padding-left: .6rem;
padding-right: .6rem;
}
.login-form .bui-list{
border-top: none;
margin-bottom: .7rem;
}
.login-form > .bui-btn{
margin-bottom: .3rem;
}
.bui-list>[class*=bui-btn]:last-child {
}
.login-form .bui-label{
width: 0.5rem;
margin-right: .2rem;
}
.login-form .bui-input {
height: .6rem;
background: none;
}
.bui-check{
}
</style>
<div class="bui-page page-form">
<header class="bui-bar">
<div class="bui-bar">
<div class="bui-bar-left">
<a class="bui-btn" onclick="bui.back();"><i class="icon-back"></i></a>
</div>
<div class="bui-bar-main">卡券充值</div>
<div class="bui-bar-right">
</div>
</div>
</header>
<main id="main">
<div class="login-form" style="padding: 20px">
<ul class="bui-list">
<li class="bui-btn bui-box clearactive" style="border: 1px solid #bfbfbf;padding-bottom: .13rem;padding-top:.13rem;">
<label class="bui-label" for="card_number"><i class="icon-qia301" style="font-size: 18px"></i></label>
<div class="span1" >
<div class="bui-input user-input" >
<input id="card_number" type="Number" placeholder="请输入卡号">
</div>
</div>
</li>
</ul>
<div class="bui-interval">
<div class="bui-panel">
<div class="bui-panel-head bui-box-center"><div class="span1">实际充值金额:¥<b id="cprice"></b> </div></div>
<div class="bui-panel-main">
<!-- 示例搜索过滤 -->
<div class="bui-filter bui-fluid-space-4">
{foreach($data as $v)}
<div class="span1" >
<input style="height: 46px;line-height: 46px;font-weight: bold" class="bui-check" type="radio" name="price" uncheck="¥{$v.price}" check="¥{$v.price}" value="{$v.price}" onclick="check_price(this)">
</div>
{/foreach}
<!-- <div class="span1">-->
<!-- <input style="height: 46px;line-height: 46px;font-weight: bold" class="bui-check" type="radio" name="price" uncheck="其他" check="其他" value="other" id="other">-->
<!-- </div>-->
</div>
<div class="bui-filter bui-fluid-space-2" style="display: none" id="other_price">
<ul class="bui-list">
<li class="bui-btn bui-box " style="border: 1px solid #bfbfbf;padding-bottom: .13rem;padding-top:.13rem;">
<label class="bui-label" ><i class="icon-chongzhizhongxin" style="font-size: 18px"></i></label>
<div class="span1" >
<div class="bui-input user-input" >
<input name="input_price" id="input_price" type="Number" placeholder="充值金额">
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
<div class="container-y">
<div class="bui-box-space">
<div class="span1">
<div class="bui-btn round primary" id="chongzhi" >确定充值</div>
</div>
</div>
</div>
</div>
</div>
</main>
{:widget('Widget/foot')}
</div>
<script>
var price="";
var payjson={};
bui.ready(function(){
$("#other").click(function () {
$("#other_price").show();
});
// 确认密码
$("#input_price").bind('input propertychange',function (e) {
price=e.target.value;
$("#cprice").text(price)
});
$("#chongzhi").click(function () {
var card_number=$("#card_number").val();
if(card_number==""){
bui.hint({ appendTo: "#main", content: "<i class='icon-infofill'></i>请输入卡号!", position: "top", showClose: true, autoClose: false });
return;
}
if(price==""){
bui.hint({ appendTo: "#main", content: "<i class='icon-infofill'></i>请输入充值金额!", position: "top", showClose: true, autoClose: false });
return;
}
bui.ajax({
url: "{:url('mobile/Pay/jsapi')}",
method:'POST',
data: {
card_number:card_number,
price:price
}
}).then(function(res){
if(res.code===300){
bui.alert(res.msg);
return;
}else{
payjson=res.json;
callpay()
}
},function(res,status){
})
})
});
function check_price(data) {
$("#other_price").hide();
price=data.value;
$("#cprice").text(price)
}
function jsApiCall()
{
WeixinJSBridge.invoke(
'getBrandWCPayRequest',payjson,
function(res){
if(res.err_msg == "get_brand_wcpay_request:ok" ) {
// 使用以上方式判断前端返回,微信团队郑重提示:
// res.err_msg将在用户支付成功后返回
// ok,但并不保证它绝对可靠。
bui.alert("恭喜充值成功!")
}
}
);
}
function callpay()
{
if (typeof WeixinJSBridge == "undefined"){
if( document.addEventListener ){
document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);
}else if (document.attachEvent){
document.attachEvent('WeixinJSBridgeReady', jsApiCall);
document.attachEvent('onWeixinJSBridgeReady', jsApiCall);
}
}else{
jsApiCall();
}
}
</script>
</body>
</html>
2、php后台部分
<?php
/**
* Create by: 逍遥
* Phone: 17074790441
* Contact: qq:596607010
* Site: http://www.net561.com
* Date: 2019/10/28
* Time: 21:11
*/
namespace app\mobile\controller;
use think\facade\App;
use think\Controller;
use EasyWeChat\Factory;
use think\Request;
use think\facade\Session;
class Pay extends Controller
{
protected $uid;
protected $beforeActionList = [
'_first'
];
public function _first(){
//检查session是否存在
if(!Session::get('wx_uid')){
$domain=\think\facade\Request::root(true);
$appId = config('app.wx.appid');
// 回调的url
$redirect_uri = urlencode($domain."/Login/index");
//跳转微信回调到redirect_uri获取code
$url ="https://open.weixin.qq.com/connect/oauth2/authorize?appid=$appId&redirect_uri=$redirect_uri&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect";
$this->redirect($url);
}
$this->uid=Session::get('wx_uid');
}
public function jsapi(Request $request)
{
//查询卡号是否存在
$card_number=$request->post('card_number');
$price=$request->post('price');
$ds=$price;
$find=model('CCard')->where('number','eq',$card_number)->where('card_type','eq',1)->find();
if(!$find){
$res=['code'=>300,'msg'=>'请输入有效卡号!'];
return json($res);
}
$user=model('CMember')->where('id',$this->uid)->find();
$config = [
// 必要配置
'app_id' =>config('app.wx_pay.appid'),
'mch_id' =>config('app.wx_pay.mchid'),
'key' =>config('app.wx_pay.key'),
'cert_path' =>APP::getRootPath().'extend/wxpay/cert/apiclient_cert.pem',
'key_path' =>APP::getRootPath().'extend/wxpay/cert/apiclient_key.pem',
'notify_url' =>config('app.wx_pay.notify_url')
];
$app= Factory::payment($config);
$order_no=order_no();
$result = $app->order->unify([
'body' => '会员充值',
'out_trade_no' => $order_no,
'total_fee' => 1,//$price*100,
'spbill_create_ip' =>$_SERVER['REMOTE_ADDR'],
'notify_url' => config('app.wx_pay.notify_url'),
'trade_type' => 'JSAPI',
'openid' => $user['openid']
]);
if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){
$gfind=model('CGuizhe')->where('price','eq',$price)->find();
if($gfind){
$day=$gfind['day'];
}else{
$day=90;
}
$jieshu=strtotime("+{$day}day",$find['jieshu']);
$order_data=[
'uid'=>$this->uid,
'order_no'=>$order_no,
'number'=>$card_number,
'price'=>$price,
'ds'=>$ds,
'jieshu'=>$jieshu,
];
model('CCardChongzhi')->save($order_data);
$prepayId = $result['prepay_id'];
$jssdk = $app->jssdk;
$json=$jssdk->bridgeConfig($prepayId);
$res=['code'=>200,'json'=>json_decode($json,true)];
}else{
$res=['code'=>300,'msg'=>'充值失败!'];
}
return json($res);
}
}
3、充值结果通知
<?php
/**
* Created by PhpStorm.
* User:逍遥QQ:596607010
* Date: 2019/2/23 0023
* Time: 14:35
*/
namespace app\mobile\controller;
use think\facade\App;
use EasyWeChat\Factory;
use think\Controller;
//微信支付回调页面
class Notify extends Controller
{
public function order_notify()
{
$config = [
// 必要配置
'app_id' =>config('app.wx_pay.appid'),
'mch_id' => config('app.wx_pay.mchid'),
'key' => config('app.wx_pay.key'),
'cert_path' =>APP::getRootPath().'extend/wxpay/cert/apiclient_cert.pem',
'key_path' =>APP::getRootPath().'extend/wxpay/cert/apiclient_key.pem',
'notify_url' =>config('app.wx_pay.notify_url')
];
$app = Factory::payment($config);
//$app= Factory::payment($config);
$response = $app->handlePaidNotify(function($message, $fail){
// 使用通知里的 "微信支付订单号" 或者 "商户订单号" 去自己的数据库找到订单
$order = $message['out_trade_no'];
$find=model("CCardChongzhi")->where('order_no','eq',$order)->find();
if (!$find || $find['status']==1) {
return true; // 告诉微信,我已经处理完了,订单没找到,别再通知我了
}
if ($message['return_code'] === 'SUCCESS') { // return_code 表示通信状态,不代表支付状态
// 用户是否支付成功
if (array_get($message, 'result_code') === 'SUCCESS') {
model("CCardChongzhi")->where('order_no','eq',$order)->update(['update_time'=>time(),'status'=>1]);
} elseif (array_get($message, 'result_code') === 'FAIL') {
return $fail('通信失败,请稍后再通知我');
}
} else {
return $fail('通信失败,请稍后再通知我');
}
return true; // 返回处理完成
});
$response->send(); // return $response;
}
}