|
|
<?php
|
|
|
|
|
|
namespace app\api\controller;
|
|
|
|
|
|
use app\admin\model\PayMember;
|
|
|
use app\admin\model\ToBalance;
|
|
|
use app\common\controller\Api;
|
|
|
use EasyWeChat\Factory;
|
|
|
use function GuzzleHttp\Promise\inspect;
|
|
|
use think\Db;
|
|
|
use app\admin\model\User;
|
|
|
use think\Log;
|
|
|
use fast\Http;
|
|
|
use think\Validate;
|
|
|
use Exception;
|
|
|
use function EasyWeChat\Kernel\Support\generate_sign;
|
|
|
/**
|
|
|
* 支付接口
|
|
|
*/
|
|
|
class Pay extends Api
|
|
|
{
|
|
|
protected $noNeedLogin = ['payMemberNotify','paySecurityNotify','payOrderNotify'];
|
|
|
protected $noNeedRight = ['*'];
|
|
|
protected $uid = '';//token存贮uid
|
|
|
protected $order_status = [];//订单状态
|
|
|
public function _initialize()
|
|
|
{
|
|
|
parent::_initialize();
|
|
|
$this->uid = $this->auth->getUserId();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @ApiTitle (购买会员/支付订单)
|
|
|
* @ApiSummary (购买会员)
|
|
|
* @ApiMethod (POST)
|
|
|
* @ApiRoute (/api/pay/pay)
|
|
|
* @ApiHeaders (name=token, type=string, required=true, description="请求的Token")
|
|
|
*
|
|
|
* @ApiParams (name="openid", type="string", required=true, description="小程序openid")
|
|
|
* @ApiParams (name="order_sn", type="inter", required=false, description="支付订单号")
|
|
|
*
|
|
|
*/
|
|
|
public function pay(){
|
|
|
if($this->request->isPost()){
|
|
|
$openid = $this->request->post('openid');
|
|
|
$order_sn = $this->request->post('order_sn');
|
|
|
|
|
|
$rule = config('verify.pay_member');
|
|
|
$validate = new Validate($rule['rule'],$rule['msg']);
|
|
|
if (!$validate->check(['openid'=>$openid])) {
|
|
|
$this->error($validate->getError());
|
|
|
}
|
|
|
|
|
|
$hotel_url = config('verify.hotel_url');
|
|
|
if($order_sn){
|
|
|
//支付订单
|
|
|
$res = Db::name('order')->where(['order_sn'=>$order_sn,'uid'=>$this->uid])->find();
|
|
|
if($res){
|
|
|
if($res['status'] == 0){
|
|
|
//判断该房间是否已被预订
|
|
|
$res2 = $this->auth->getHouseDetailId(['house_id'=>$res['house_id']]);
|
|
|
$full_time = [];
|
|
|
foreach($res2 as $r_value){
|
|
|
if($res['book_count'] <= $r_value['book_count']){
|
|
|
//满房时间
|
|
|
array_push($full_time,$r_value['book_time']);
|
|
|
}
|
|
|
}
|
|
|
if(in_array($res['start_time'],$full_time)){
|
|
|
$this->error('该房屋已被预订');
|
|
|
}
|
|
|
$pay_order = $order_sn;
|
|
|
$notify_url = $hotel_url.'/api/pay/payOrderNotify';
|
|
|
$total_fee = $res['security_price'];
|
|
|
}else{
|
|
|
$this->error('该订单已支付过了');
|
|
|
}
|
|
|
}else{
|
|
|
$this->error('无效的订单');
|
|
|
}
|
|
|
}else{
|
|
|
//购买会员
|
|
|
$pay_order = $this->auth->genPayOrderSn('pay');//支付订单号
|
|
|
$notify_url = $hotel_url.'/api/pay/payMemberNotify';
|
|
|
$total_fee = 0.01;//会员价格暂为0.01元
|
|
|
}
|
|
|
//创建支付对象
|
|
|
$config = config('verify.wx_pay');
|
|
|
$app = Factory::payment($config);
|
|
|
$result = $app->order->unify([
|
|
|
'body' => '佛山市理想中网络科技有限公司',
|
|
|
'out_trade_no' => $pay_order,//支付订单号
|
|
|
'total_fee' => $total_fee*100,//单位分
|
|
|
'notify_url' => $notify_url, // 支付结果通知网址,如果不设置则会使用配置里的默认地址
|
|
|
'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
|
|
|
'openid' => $openid,
|
|
|
]);
|
|
|
if($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS'){
|
|
|
$params = [
|
|
|
'appId' => $config['app_id'],
|
|
|
'timeStamp' => time(),
|
|
|
'nonceStr' => $result['nonce_str'], // 统一下单返回的随机字符串
|
|
|
'package' => 'prepay_id='.$result['prepay_id'], // 统一下单Id
|
|
|
'signType' => 'MD5', // 签名方法
|
|
|
];
|
|
|
// 注意这里用的是商户平台的Key进行二次签名
|
|
|
$params['paySign'] = generate_sign($params, $config['key']);
|
|
|
$this->success('成功',$params);
|
|
|
}
|
|
|
$this->error($result['err_code_des']);
|
|
|
}else{
|
|
|
$this->error('请求方式错误');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//购买会员回调通知(无需调用)
|
|
|
public function payMemberNotify(){
|
|
|
$config = config('verify.wx_pay');
|
|
|
$app = Factory::payment($config);
|
|
|
Log::info('会员');
|
|
|
$response = $app->handlePaidNotify(function($message, $fail){
|
|
|
//return_code 表示通信状态
|
|
|
Log::info($message);
|
|
|
if ($message['return_code'] === 'SUCCESS') {
|
|
|
|
|
|
if ($message['result_code'] === 'SUCCESS') {
|
|
|
//支付成功
|
|
|
//更新成为会员
|
|
|
$userModel = new User();
|
|
|
$userModel->where('openid',$message['openid'])->update(['member'=>1]);
|
|
|
//增加记录
|
|
|
$payMemberModel = new PayMember();
|
|
|
$payMemberModel->create(['openid'=>$message['openid'],'pay_order'=>$message['out_trade_no']]);
|
|
|
}elseif($message['result_code'] === 'FAIL') {
|
|
|
//支付失败
|
|
|
}
|
|
|
} else {
|
|
|
return $fail('通信失败,请稍后再通知我');
|
|
|
}
|
|
|
return true; // 返回处理完成
|
|
|
});
|
|
|
$response->send();
|
|
|
}
|
|
|
|
|
|
//支付订单(无需调用)
|
|
|
public function payOrderNotify(){
|
|
|
$config = config('verify.wx_pay');
|
|
|
$app = Factory::payment($config);
|
|
|
$response = $app->handlePaidNotify(function($message, $fail){
|
|
|
//return_code 表示通信状态
|
|
|
if ($message['return_code'] === 'SUCCESS') {
|
|
|
|
|
|
if ($message['result_code'] === 'SUCCESS') {
|
|
|
//支付成功,更新订单状态
|
|
|
$orderModel = new \app\admin\model\Order();
|
|
|
$orderModel->where(['order_sn'=>$message['out_trade_no']])->update(['status'=>1]);
|
|
|
|
|
|
//创建订房记录
|
|
|
$this->auth->createHouseRecord($message['out_trade_no']);
|
|
|
|
|
|
//发送(预订成功)验证码
|
|
|
$this->auth->sendCodeBook($message['out_trade_no']);
|
|
|
|
|
|
}elseif($message['result_code'] === 'FAIL') {
|
|
|
//支付失败
|
|
|
}
|
|
|
} else {
|
|
|
return $fail('通信失败,请稍后再通知我');
|
|
|
}
|
|
|
return true; // 返回处理完成
|
|
|
});
|
|
|
$response->send();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @ApiTitle (支付保证金)
|
|
|
* @ApiSummary (支付保证金)
|
|
|
* @ApiMethod (POST)
|
|
|
* @ApiRoute (/api/pay/paySecurityPrice)
|
|
|
* @ApiHeaders (name=token, type=string, required=true, description="请求的Token")
|
|
|
*
|
|
|
* @ApiParams (name="openid", type="string", required=true, description="小程序openid")
|
|
|
* @ApiParams (name="house_id", type="inter", required=true, description="房屋id")
|
|
|
* @ApiParams (name="date_range", type="string", required=true, description="预定日期范围(2019-10-11,2019-10-12或者2019-10-11,2019-10-13)")
|
|
|
* @ApiParams (name="security_price", type="inter", required=true, description="保证金")
|
|
|
*/
|
|
|
public function paySecurityPrice(){
|
|
|
if($this->request->isPost()){
|
|
|
$data = $this->request->post();
|
|
|
|
|
|
$rule = config('verify.pay_security');
|
|
|
$validate = new Validate($rule['rule'],$rule['msg']);
|
|
|
if (!$validate->check($data)) {
|
|
|
$this->error($validate->getError());
|
|
|
}
|
|
|
|
|
|
//创建支付对象
|
|
|
$config = config('verify.wx_pay');
|
|
|
$app = Factory::payment($config);
|
|
|
$pay_order = $this->auth->genPayOrderSn('pay');//支付订单号
|
|
|
$hotel_url = config('verify.hotel_url');
|
|
|
$result = $app->order->unify([
|
|
|
'body' => '佛山市理想中网络科技有限公司',
|
|
|
'out_trade_no' => $pay_order,//支付订单号
|
|
|
'total_fee' => $data['security_price']*100,//单位分
|
|
|
'notify_url' => $hotel_url.'/api/pay/paySecurityNotify', // 支付结果通知网址,如果不设置则会使用配置里的默认地址
|
|
|
'trade_type' => 'JSAPI', // 请对应换成你的支付方式对应的值类型
|
|
|
'openid' => $data['openid'],
|
|
|
]);
|
|
|
|
|
|
if($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS'){
|
|
|
$params = [
|
|
|
'appId' => $config['app_id'],
|
|
|
'timeStamp' => time(),
|
|
|
'nonceStr' => $result['nonce_str'], // 统一下单返回的随机字符串
|
|
|
'package' => 'prepay_id='.$result['prepay_id'], // 统一下单Id
|
|
|
'signType' => 'MD5', // 签名方法
|
|
|
];
|
|
|
// 注意这里用的是商户平台的Key进行二次签名
|
|
|
$params['paySign'] = generate_sign($params, $config['key']);
|
|
|
//写入订单
|
|
|
$res = $this->auth->createOrder($data['house_id'],$data['date_range'],$pay_order);
|
|
|
if($res){
|
|
|
$this->success('成功',['data'=>$params,'order_sn'=>$pay_order,'order_id'=>$res['order_id']]);
|
|
|
}
|
|
|
$this->error('创建订单失败');
|
|
|
}
|
|
|
$this->error($result['err_code_des']);
|
|
|
}else{
|
|
|
$this->error('请求方式错误');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//支付保证金回调(无需调用)
|
|
|
public function paySecurityNotify(){
|
|
|
$config = config('verify.wx_pay');
|
|
|
$app = Factory::payment($config);
|
|
|
$response = $app->handlePaidNotify(function($message, $fail){
|
|
|
//return_code 表示通信状态
|
|
|
if ($message['return_code'] === 'SUCCESS') {
|
|
|
if ($message['result_code'] === 'SUCCESS') {
|
|
|
//支付成功
|
|
|
//更新成为待出行状态
|
|
|
$orderModel = new \app\admin\model\Order();
|
|
|
$orderModel->where(['order_sn'=>$message['out_trade_no']])->update(['status'=>1]);
|
|
|
|
|
|
//创建订房记录
|
|
|
$this->auth->createHouseRecord($message['out_trade_no']);
|
|
|
|
|
|
//发送(预订成功)验证码
|
|
|
$this->auth->sendCodeBook($message['out_trade_no']);
|
|
|
|
|
|
}elseif($message['result_code'] === 'FAIL') {
|
|
|
//支付失败,好像有问题
|
|
|
}
|
|
|
} else {
|
|
|
return $fail('通信失败,请稍后再通知我');
|
|
|
}
|
|
|
return true; // 返回处理完成
|
|
|
});
|
|
|
$response->send();
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @ApiTitle (更新订单号(支付订单失败后调用))
|
|
|
* @ApiSummary (更新订单号(支付订单失败后调用))
|
|
|
* @ApiMethod (POST)
|
|
|
* @ApiRoute (/api/pay/updateOrder)
|
|
|
* @ApiHeaders (name=token, type=string, required=true, description="请求的Token")
|
|
|
*
|
|
|
* @ApiParams (name="order_sn", type="inter", required=false, description="支付订单号")
|
|
|
*
|
|
|
* @ApiReturn({
|
|
|
"code": 1,
|
|
|
"msg": "成功",
|
|
|
"time": "1571812329",
|
|
|
"data": null
|
|
|
})
|
|
|
*/
|
|
|
public function updateOrder(){
|
|
|
if($this->request->isPost()){
|
|
|
$order_sn = $this->request->post('order_sn');
|
|
|
|
|
|
$rule = config('verify.order_sn');
|
|
|
$validate = new Validate($rule['rule'],$rule['msg']);
|
|
|
if (!$validate->check(['order_sn'=>$order_sn])) {
|
|
|
$this->error($validate->getError());
|
|
|
}
|
|
|
|
|
|
$orderModel = new \app\admin\model\Order();
|
|
|
$pay_order = $this->auth->genPayOrderSn('pay');//支付订单号
|
|
|
$res = $orderModel->where(['order_sn'=>$order_sn,'uid'=>$this->uid])->update(['order_sn'=>$pay_order]);
|
|
|
if($res){
|
|
|
$this->success('成功');
|
|
|
}else{
|
|
|
$this->error('失败');
|
|
|
}
|
|
|
}else{
|
|
|
$this->error('请求方式错误');
|
|
|
}
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* @ApiTitle (提现到微信零钱)
|
|
|
* @ApiSummary (提现到微信零钱)
|
|
|
* @ApiMethod (POST)
|
|
|
* @ApiRoute (/api/pay/payBalance)
|
|
|
* @ApiHeaders (name=token, type=string, required=true, description="请求的Token")
|
|
|
*
|
|
|
* @ApiParams (name="openid", type="string", required=true, description="小程序openid")
|
|
|
* @ApiParams (name="price", type="inter", required=true, description="提现金额")
|
|
|
*/
|
|
|
public function payBalance(){
|
|
|
if($this->request->isPost()){
|
|
|
$price = $this->request->post('price');
|
|
|
$openid = $this->request->post('openid');
|
|
|
|
|
|
$rule = config('verify.to_balance');
|
|
|
$validate = new Validate($rule['rule'],$rule['msg']);
|
|
|
if (!$validate->check(['price'=>$price,'openid'=>$openid])) {
|
|
|
$this->error($validate->getError());
|
|
|
}
|
|
|
|
|
|
if($price < 0.3){
|
|
|
$this->error('提现金额不能低于0.3元');
|
|
|
}
|
|
|
|
|
|
//每天提现次数不超过三次
|
|
|
$count = Db::name('to_balance')->where('uid',$this->uid)->whereTime('createtime','today')->count();
|
|
|
if($count >= 3){
|
|
|
$this->error('每天提现次数不能超过3次');
|
|
|
}
|
|
|
//查询该用户钱包金额
|
|
|
$userModel = new User();
|
|
|
$user = $userModel->where(['id'=>$this->uid])->field('id,money,nickname')->find();
|
|
|
if($price > $user['money']){
|
|
|
$this->error('钱包金额不足');
|
|
|
}
|
|
|
|
|
|
//创建支付对象
|
|
|
$config = config('verify.wx_pay');
|
|
|
$app = Factory::payment($config);
|
|
|
$balance_order = $this->auth->genPayOrderSn('balance');//提现单号
|
|
|
$result = $app->transfer->toBalance([
|
|
|
'partner_trade_no' => $balance_order, // 商户订单号,需保持唯一性(只能是字母或者数字,不能包含有符号)
|
|
|
'openid' => $openid,
|
|
|
'check_name' => 'NO_CHECK', // NO_CHECK:不校验真实姓名, FORCE_CHECK:强校验真实姓名
|
|
|
're_user_name' => '', // 如果 check_name 设置为FORCE_CHECK,则必填用户真实姓名
|
|
|
'amount' => $price*100, // 企业付款金额,单位为分
|
|
|
'desc' => '提现到零钱', // 企业付款操作说明信息。必填
|
|
|
]);
|
|
|
if($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS'){
|
|
|
//创建提现记录
|
|
|
$balanceRecordModel = new ToBalance();
|
|
|
$data['uid'] = $this->uid;
|
|
|
$data['openid'] = $openid;
|
|
|
$data['price'] = $price;
|
|
|
$data['to_order'] = $result['partner_trade_no'];
|
|
|
$balanceRecordModel->create($data);
|
|
|
//更新余额表
|
|
|
$userModel = new User();
|
|
|
$userModel->where(['id'=>$this->uid])->setDec('money',$price);
|
|
|
$this->success('成功');
|
|
|
}
|
|
|
$this->error($result['err_code_des']);
|
|
|
}else{
|
|
|
$this->error('请求方式错误');
|
|
|
}
|
|
|
}
|
|
|
} |
...
|
...
|
|