|
@@ -1,23 +1,22 @@
|
|
|
<?php
|
|
|
namespace app\api\controller;
|
|
|
|
|
|
+use alipay\aop\AopClient;
|
|
|
+use alipay\aop\request\AlipayTradeAppPayRequest;
|
|
|
use app\admin\model\BuyVipLogModel;
|
|
|
use app\admin\model\Cardtip;
|
|
|
-use app\api\model\QueueModel;
|
|
|
use app\api\model\UsersModel;
|
|
|
use app\common\controller\Api;
|
|
|
use app\admin\model\Equity;
|
|
|
use app\common\lib\WxPay;
|
|
|
use think\Db;
|
|
|
-use function fast\array_except;
|
|
|
|
|
|
/**
|
|
|
- * VIP接口
|
|
|
+ * 开通VIP接口
|
|
|
*/
|
|
|
class Member extends Api
|
|
|
{
|
|
|
protected $noNeedLogin = '*';
|
|
|
-
|
|
|
/**
|
|
|
* 开通VIP页面
|
|
|
*
|
|
@@ -26,10 +25,6 @@ class Member extends Api
|
|
|
* @ApiMethod (POST)
|
|
|
* @ApiRoute (/api/member/index)
|
|
|
* @ApiParams (name="user_id", type="int", required=true, description="用户id")
|
|
|
- * @ApiReturnParams (name="code", type="int", required=true, sample="200")
|
|
|
- * @ApiReturnParams (name="msg", type="string", required=true, sample="ok")
|
|
|
- * @ApiReturnParams (name="data", type="array", description="数据返回")
|
|
|
- * @ApiReturn ()
|
|
|
*/
|
|
|
public function index()
|
|
|
{
|
|
@@ -45,6 +40,7 @@ class Member extends Api
|
|
|
//头部卡片
|
|
|
$info = Cardtip::find(1);
|
|
|
$info['avatar'] = UsersModel::where('user_id', $userId)->value('user_avatar');
|
|
|
+ $info['desc'] = explode(' ', $info['desc']);
|
|
|
$this->result('ok', ['card' => $info, 'equityList' => $list], 200);
|
|
|
}
|
|
|
/**
|
|
@@ -55,21 +51,35 @@ class Member extends Api
|
|
|
* @ApiMethod (POST)
|
|
|
* @ApiRoute (/api/member/buyVip)
|
|
|
* @ApiParams (name="user_id", type="int", required=true, description="用户id")
|
|
|
- * @ApiReturnParams (name="code", type="int", required=true, sample="200")
|
|
|
- * @ApiReturnParams (name="msg", type="string", required=true, sample="ok")
|
|
|
- * @ApiReturnParams (name="data", type="array", description="数据返回")
|
|
|
- * @ApiReturn ()
|
|
|
+ * @ApiParams (name="pay_type", type="int", required=true, description="支付类型 2-微信 3-支付宝")
|
|
|
*/
|
|
|
public function buyVip()
|
|
|
{
|
|
|
$userId = $this->request->post('user_id');
|
|
|
- $amount = 68;
|
|
|
- $notify_url = config('site.httpurl').'/api/member/notify_url';
|
|
|
+ $payType = $this->request->post('pay_type');
|
|
|
|
|
|
- if (!$userId) {
|
|
|
+ $amount = 0.01;
|
|
|
+ // 微信回调
|
|
|
+ $notify_url = config('site.httpurl').'/api/member/notify_url_vip';
|
|
|
+ // 支付宝回调
|
|
|
+ $notify_url2 = config('site.httpurl').'/api/member/notify_url_vip2';
|
|
|
+
|
|
|
+ if (!$userId || !$payType) {
|
|
|
$this->result('参数错误', [], 200);
|
|
|
}
|
|
|
|
|
|
+ $user = UsersModel::get($userId);
|
|
|
+
|
|
|
+ if (!$user) {
|
|
|
+ $this->result('用户不存在', [], 100);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询剩余开通次数
|
|
|
+ $canUseOpenNum = UsersModel::where('user_id', $userId)->value('vip_use_num');
|
|
|
+ if ($canUseOpenNum == 5) {
|
|
|
+ $this->result('您本月可开通VIP的次数已用完', [], 200);
|
|
|
+ }
|
|
|
+
|
|
|
$out_trade_no = createOutTradeNo();
|
|
|
$orderInfo = array(
|
|
|
'uid' => $userId,
|
|
@@ -79,10 +89,12 @@ class Member extends Api
|
|
|
);
|
|
|
|
|
|
Db::startTrans();
|
|
|
- try {
|
|
|
- $insert = BuyVipLogModel::insert($orderInfo);
|
|
|
- if ($insert) {
|
|
|
- Db::commit();
|
|
|
+ $insert = BuyVipLogModel::insert($orderInfo);
|
|
|
+ if ($insert) {
|
|
|
+ Db::commit();
|
|
|
+ // 支付类型
|
|
|
+ // 微信支付
|
|
|
+ if ($payType == 2) {
|
|
|
$payObj = new WxPay();
|
|
|
$getPrePayInfo = $payObj->getPrePayOrder('VIP会员购买', $out_trade_no, ($amount * 100), $notify_url);
|
|
|
if ($getPrePayInfo) {
|
|
@@ -96,172 +108,203 @@ class Member extends Api
|
|
|
$this->result('支付订单发起失败,请稍后再试', [], 100);
|
|
|
}
|
|
|
}
|
|
|
- } catch (\Exception $exception) {
|
|
|
- Db::rollback();
|
|
|
- $this->result('支付订单发起失败,请稍后再试('.$exception->getMessage().')', [], 100);
|
|
|
+ // 支付宝支付
|
|
|
+ if ($payType == 3) {
|
|
|
+ $aop = new AopClient;
|
|
|
+ $aop->gatewayUrl = "https://openapi.alipay.com/gateway.do";
|
|
|
+ $aop->appId = config('alipay.app_id');
|
|
|
+ $aop->rsaPrivateKey = config('alipay.private_key');
|
|
|
+ $aop->format = "json";
|
|
|
+ $aop->charset = "utf-8";
|
|
|
+ $aop->signType = "RSA2";
|
|
|
+ $aop->alipayrsaPublicKey = config('alipay.public_key');
|
|
|
+ //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
|
|
|
+ $request = new AlipayTradeAppPayRequest();
|
|
|
+
|
|
|
+ // 订单标题
|
|
|
+ $subject = 'VIP会员购买';
|
|
|
+ // 订单详情
|
|
|
+ $body = '优享街68元VIP会员购买';
|
|
|
+
|
|
|
+ // SDK已经封装掉了公共参数,这里只需要传入业务参数
|
|
|
+ $bizcontent = json_encode([
|
|
|
+ 'body' => $body,
|
|
|
+ 'subject' => $subject,
|
|
|
+ 'out_trade_no' => $out_trade_no,
|
|
|
+ 'timeout_express' => '90m',
|
|
|
+ 'total_amount' => $amount,
|
|
|
+ 'product_code' => 'QUICK_MSECURITY_PAY'
|
|
|
+ ]);
|
|
|
+
|
|
|
+ $request->setNotifyUrl($notify_url2);
|
|
|
+ $request->setBizContent($bizcontent);
|
|
|
+ // 这里和普通的接口调用不同,使用的是sdkExecute
|
|
|
+ $response = $aop->sdkExecute($request);
|
|
|
+ // 注意:这里不需要使用htmlspecialchars进行转义,直接返回即可
|
|
|
+ // return $response;
|
|
|
+ $this->result('订单发起成功', ['payInfoString' => $response], 200);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
/**
|
|
|
- * 排队
|
|
|
- *
|
|
|
- * @ApiTitle (排队)
|
|
|
- * @ApiSummary (排队)
|
|
|
- * @ApiMethod (POST)
|
|
|
- * @ApiRoute (/api/member/queue)
|
|
|
- * @ApiParams (name="user_id", type="int", required=true, description="用户id")
|
|
|
- * @ApiParams (name="pay_type", type="int", required=true, description="支付方式:1-余额 2-微信 3-支付宝")
|
|
|
- * @ApiReturnParams (name="code", type="int", required=true, sample="200")
|
|
|
- * @ApiReturnParams (name="msg", type="string", required=true, sample="ok")
|
|
|
- * @ApiReturnParams (name="data", type="array", description="数据返回")
|
|
|
- * @ApiReturn ()
|
|
|
+ * 测试接口
|
|
|
+ * @ApiInternal
|
|
|
*/
|
|
|
- public function queue()
|
|
|
+ public function test()
|
|
|
{
|
|
|
- $userId = $this->request->post('user_id');
|
|
|
- $payType = $this->request->post('pay_type'); // 1-余额 2-微信 3-支付宝
|
|
|
- $amount = 1.2;
|
|
|
- $income = 2;
|
|
|
-
|
|
|
- if (!$userId || !$payType) {
|
|
|
- $this->result('参数错误', [], 100);
|
|
|
- }
|
|
|
-
|
|
|
- $user = UsersModel::get($userId);
|
|
|
+ $order_trade_no = $this->request->post('trade');
|
|
|
|
|
|
- if ($user->user_level == 1) {
|
|
|
- $this->result('您还不是VIP用户,不能进行排队哦', [], 100);
|
|
|
- }
|
|
|
- // 剩余总排队次数是否足够
|
|
|
- if ($user->user_line_num <= 0) {
|
|
|
- $this->result('您的排队次数不足,不能进行排队哦', [], 100);
|
|
|
- }
|
|
|
- // 每天可排队次数是否足够
|
|
|
- if ($user->can_line_num_perday <= 0) {
|
|
|
- $this->result('您每天可排队次数不足哦', [], 100);
|
|
|
- }
|
|
|
- // 今天排队次数是否足够
|
|
|
- if ($user->can_line_num_perday == $user->line_num_today) {
|
|
|
- $this->result('您今天的可排队次数已用完', [], 100);
|
|
|
+ $order = BuyVipLogModel::where('out_trade_no', $order_trade_no)->find();
|
|
|
+ if ($order) {
|
|
|
+ // 更新支付状态
|
|
|
+ $updatePayStatus = BuyVipLogModel::where('out_trade_no', $order_trade_no)
|
|
|
+ ->setField('pay_status', 1);
|
|
|
+ // 修改会员等级
|
|
|
+ $updateVipLevel = UsersModel::where('user_id', $order->uid)->setField('user_level', 2);
|
|
|
+ if ($updatePayStatus && $updateVipLevel) {
|
|
|
+ $successArray = array(
|
|
|
+ 'return_code' => 'SUCCESS',
|
|
|
+ 'return_msg' => 'OK'
|
|
|
+ );
|
|
|
+ return $this->arrayToXml($successArray);
|
|
|
+ }
|
|
|
}
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 购买会员微信支付异步回调
|
|
|
+ * @ApiInternal
|
|
|
+ */
|
|
|
+ public function notify_url_vip()
|
|
|
+ {
|
|
|
+ //获取返回的xml格式数据
|
|
|
+ $payXml = file_get_contents("php://input");
|
|
|
+ //将xml格式转化为json格式
|
|
|
+ $jsonXml = json_encode(simplexml_load_string($payXml, 'SimpleXMLElement', LIBXML_NOCDATA));
|
|
|
+ //将json格式转成数组格式
|
|
|
+ $result = json_decode($jsonXml, true);
|
|
|
|
|
|
- $nowTime = time();
|
|
|
- $startTime = strtotime(date('Y-m-d').' 09:00:00');
|
|
|
- $endTime = strtotime(date('Y-m-d').' 22:00:00');
|
|
|
-
|
|
|
- if ($startTime < $nowTime && $nowTime < $endTime) {
|
|
|
-
|
|
|
- $nowHour = date("Y-m-d H:00:00", time());
|
|
|
- $nextHour = date("Y-m-d H:i:s", strtotime("+1 hour"));
|
|
|
-
|
|
|
- //是否在本时间段内排过队
|
|
|
- $hasOnLine = QueueModel::where(['uid' => $userId, 'pay_status' => 1])
|
|
|
- ->whereTime('time', 'between', [$nowHour, $nextHour])
|
|
|
- ->find();
|
|
|
-
|
|
|
- if (!empty($hasOnLine)) {
|
|
|
- $this->result('您当前已排过队', [], 100);
|
|
|
- }
|
|
|
+ if ($result) {
|
|
|
+ //如果成功返回
|
|
|
+ if ($result['return_code'] == 'SUCCESS') {
|
|
|
+ if ($result['result_code'] == 'SUCCESS') {
|
|
|
+ // sign 值校验
|
|
|
+ // 校验时不包含返回的 sign 字段,需踢除 sign 字段
|
|
|
+ foreach($result as $k => $v) {
|
|
|
+ if ($k == 'sign') {
|
|
|
+ $sign = $result[$k];
|
|
|
+ unset($result[$k]);
|
|
|
+ };
|
|
|
+ }
|
|
|
+ //按字典排序
|
|
|
+ ksort($result);
|
|
|
+ //转为 url 键值对
|
|
|
+ $signTemp = http_build_query($result);
|
|
|
+ //md5处理,$key 为微信商户平台的 api 安全密钥
|
|
|
+ $key = 'b3ae6bbf3cc4fa017eb169ae219e2c27';
|
|
|
+ $signTemp = md5($signTemp.'&key='.$key);
|
|
|
+ //转大写得最终 sign 值
|
|
|
+ $resultSign = strtoupper($signTemp);
|
|
|
+ //如果sign值正确
|
|
|
+ if ($sign === $resultSign) {
|
|
|
+ $order = BuyVipLogModel::where('out_trade_no', $result['out_trade_no'])->find();
|
|
|
+ if ($order) {
|
|
|
+ // 更新支付状态
|
|
|
+ $updatePayStatus = BuyVipLogModel::where('out_trade_no', $result['out_trade_no'])
|
|
|
+ ->setField('pay_status', 1);
|
|
|
+ // 修改会员等级
|
|
|
+ $updateVipLevel = UsersModel::where('user_id', $order->uid)->update(['user_level' => 2]);
|
|
|
+ // 限购份数加一
|
|
|
+ $addLimitNum = UsersModel::where('user_id', $order->uid)->setInc('vip_use_num', 1);
|
|
|
+ // 增加话费优惠额度
|
|
|
+ $addChargeQuota = UsersModel::where('user_id', $order->uid)->setInc('vip_discount_quota', 100);
|
|
|
+ // 查询我的推荐人手机号
|
|
|
+ $myRecTel = UsersModel::where('user_id', $order->uid)->value('user_tjtel');
|
|
|
+ // 查询我的推荐人user_id
|
|
|
+ $myRecId = UsersModel::where('user_tel', $myRecTel)->value('user_id');
|
|
|
+ // 我加一次排队次数
|
|
|
+ $addMyQueueNum = UsersModel::where('user_id', $order->uid)->setInc('get_queue_num', 1);
|
|
|
+ // 推荐人加一次排队次数
|
|
|
+ $addRecQueueNum = UsersModel::where('user_id', $myRecId)->setInc('get_queue_num', 1);
|
|
|
|
|
|
- //当前时间段排队人数
|
|
|
- $lineNum = QueueModel::whereTime('time', 'between', [$nowHour, $nextHour])->where('pay_status',1)->count();
|
|
|
- $trade = createOutTradeNo();
|
|
|
- $lineInfo = array(
|
|
|
- 'uid' => $userId,
|
|
|
- 'trade' => $trade,
|
|
|
- 'amount' => $amount,
|
|
|
- 'line_num' => $lineNum,
|
|
|
- 'income' => $income,
|
|
|
- 'time' => date('Y-m-d H:i:s', time()),
|
|
|
- 'pay_type' => $payType
|
|
|
- );
|
|
|
- Db::startTrans();
|
|
|
- $insert = QueueModel::insert($lineInfo);
|
|
|
- if ($insert) {
|
|
|
- Db::commit();
|
|
|
- if ($payType == 1) {
|
|
|
- $this->result('订单创建成功', ['out_trade_no' => $trade, 'fee' => $amount], 200);
|
|
|
+ if ($updatePayStatus && $updateVipLevel !== false && $addLimitNum && $addChargeQuota && $addMyQueueNum && $addRecQueueNum) {
|
|
|
+ $successArray = array(
|
|
|
+ 'return_code' => 'SUCCESS',
|
|
|
+ 'return_msg' => 'OK'
|
|
|
+ );
|
|
|
+ return $this->arrayToXml($successArray);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
}
|
|
|
} else {
|
|
|
- Db::rollback();
|
|
|
- $this->result('服务器繁忙', [], 100);
|
|
|
+ return false;
|
|
|
}
|
|
|
- } else {
|
|
|
- $this->result('今日排队活动已经结束了哦', [], 100);
|
|
|
}
|
|
|
}
|
|
|
/**
|
|
|
- * 排队余额支付
|
|
|
- *
|
|
|
- * @ApiTitle (排队余额支付)
|
|
|
- * @ApiSummary (排队余额支付)
|
|
|
- * @ApiMethod (POST)
|
|
|
- * @ApiRoute (/api/member/balancePayQueue)
|
|
|
- * @ApiParams (name="user_id", type="int", required=true, description="用户id")
|
|
|
- * @ApiParams (name="fee", type="decimal", required=true, description="排队接口返回的支付金额fee字段的值")
|
|
|
- * @ApiParams (name="out_trade_no", type="string", required=true, description="排队接口返回的支付订单编号out_trade_no字段的值")
|
|
|
- * @ApiParams (name="pay_password", type="string", required=true, description="用户支付密码")
|
|
|
- * @ApiReturnParams (name="code", type="int", required=true, sample="200")
|
|
|
- * @ApiReturnParams (name="msg", type="string", required=true, sample="ok")
|
|
|
- * @ApiReturnParams (name="data", type="array", description="数据返回")
|
|
|
- * @ApiReturn ()
|
|
|
+ * 数组转xml
|
|
|
+ * @ApiInternal
|
|
|
*/
|
|
|
- public function balancePayQueue()
|
|
|
+ public function arrayToXml($arr)
|
|
|
{
|
|
|
- $userId = $this->request->post('user_id');
|
|
|
- $fee = $this->request->post('fee');
|
|
|
- $trade = $this->request->post('out_trade_no');
|
|
|
- $payPwd = $this->request->post('pay_password');
|
|
|
-
|
|
|
- if (!$userId || !$fee || !$trade || !$payPwd) {
|
|
|
- $this->result('参数错误', [], 100);
|
|
|
- }
|
|
|
-
|
|
|
- $user = UsersModel::get($userId);
|
|
|
-
|
|
|
- // 用户是否存在
|
|
|
- if (!$user) {
|
|
|
- $this->result('用户不存在', [], 100);
|
|
|
- }
|
|
|
- // 订单是否存在
|
|
|
- $order = QueueModel::where('trade', $trade)->find();
|
|
|
- if (!$order) {
|
|
|
- $this->result('订单不存在', [], 100);
|
|
|
- }
|
|
|
- if ($fee <= 0) {
|
|
|
- $this->result('请输入正确的支付金额', [], 100);
|
|
|
- }
|
|
|
- // 余额是否满足本次扣费金额
|
|
|
- if ($user->user_money < $fee) {
|
|
|
- $this->result('账户余额不足', [], 100);
|
|
|
- }
|
|
|
- // 是否设置支付密码
|
|
|
- if (empty($user->user_paypwd)) {
|
|
|
- $this->result('请先设置支付密码', [], 100);
|
|
|
- }
|
|
|
- // 支付密码是否正确
|
|
|
- if ($user->user_paypwd != $payPwd) {
|
|
|
- $this->result('支付密码错误', [], 100);
|
|
|
+ $xml = "<xml>";
|
|
|
+ foreach ($arr as $key=>$val)
|
|
|
+ {
|
|
|
+ if (is_numeric($val))
|
|
|
+ {
|
|
|
+ $xml.="<".$key.">".$val."</".$key.">";
|
|
|
+ }
|
|
|
+ else
|
|
|
+ $xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
|
|
|
}
|
|
|
- Db::startTrans();
|
|
|
- // 扣除账户余额
|
|
|
- $dec = UsersModel::where('user_id', $userId)->setDec('user_money', $fee);
|
|
|
- // 增加排队收入
|
|
|
- $amount = 2;
|
|
|
- $inc = UsersModel::where('user_id', $userId)->setInc('user_money', $amount);
|
|
|
- // 更新支付状态和支付时间
|
|
|
- $updatePayStatus = QueueModel::where('trade', $trade)
|
|
|
- ->update(['pay_status' => 1, 'pay_time' => date('Y-m-d H:i:s', time())]);
|
|
|
- // 消耗一次今日可排队次数
|
|
|
- $addPerDayQueueNum = UsersModel::where('user_id', $userId)->setInc('line_num_today', 1);
|
|
|
- // 消耗一次总排队次数
|
|
|
- $decTotalQueueNum = UsersModel::where('user_id', $userId)->setDec('user_line_num', 1);
|
|
|
-
|
|
|
- if ($dec && $inc && $updatePayStatus && $addPerDayQueueNum && $decTotalQueueNum) {
|
|
|
- Db::commit();
|
|
|
- $this->result('排队成功', [], 200);
|
|
|
- } else {
|
|
|
- Db::rollback();
|
|
|
- $this->result('支付失败,稍后再试', [], 100);
|
|
|
+ $xml.="</xml>";
|
|
|
+ return $xml;
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 购买会员支付宝支付异步回调
|
|
|
+ * @ApiInternal
|
|
|
+ */
|
|
|
+ public function notify_url_vip2()
|
|
|
+ {
|
|
|
+ $params = $this->request->post();
|
|
|
+ if (!empty($params) && $params['trade_status'] == 'TRADE_SUCCESS') {
|
|
|
+ // 验证签名
|
|
|
+ $aop = new AopClient();
|
|
|
+ $aop->alipayrsaPublicKey = config('alipay.public_key');
|
|
|
+ // 此处反转义参数中的字符,否则验签不通过
|
|
|
+ $params['fund_bill_list'] = htmlspecialchars_decode($params['fund_bill_list']);
|
|
|
+ $checkSign = $aop->rsaCheckV1($params, null, 'RSA2');
|
|
|
+ if ($checkSign) {
|
|
|
+ // 是不是向此商户号付款
|
|
|
+ if ($params['app_id'] == config('alipay.app_id')) {
|
|
|
+ // 查询订单是否存在
|
|
|
+ $order = BuyVipLogModel::where('out_trade_no', $params['out_trade_no'])->find();
|
|
|
+ if (!empty($order)) {
|
|
|
+ // 更新支付状态
|
|
|
+ $updatePayStatus = BuyVipLogModel::where('out_trade_no', $params['out_trade_no'])->setField('pay_status', 1);
|
|
|
+ // 修改会员等级
|
|
|
+ $updateVipLevel = UsersModel::where('user_id', $order->uid)->update(['user_level' => 2]);
|
|
|
+ // 限购份数加一
|
|
|
+ $addLimitNum = UsersModel::where('user_id', $order->uid)->setInc('vip_use_num', 1);
|
|
|
+ // 增加话费优惠额度
|
|
|
+ $addChargeQuota = UsersModel::where('user_id', $order->uid)->setInc('vip_discount_quota', 100);
|
|
|
+ // 查询我的推荐人手机号
|
|
|
+ $myRecTel = UsersModel::where('user_id', $order->uid)->value('user_tjtel');
|
|
|
+ // 查询我的推荐人user_id
|
|
|
+ $myRecId = UsersModel::where('user_tel', $myRecTel)->value('user_id');
|
|
|
+ // 我加一次排队次数
|
|
|
+ $addMyQueueNum = UsersModel::where('user_id', $order->uid)->setInc('get_queue_num', 1);
|
|
|
+ // 推荐人加一次排队次数
|
|
|
+ $addRecQueueNum = UsersModel::where('user_id', $myRecId)->setInc('get_queue_num', 1);
|
|
|
+ if ($updatePayStatus && $updateVipLevel !== false && $addLimitNum && $addChargeQuota && $addMyQueueNum && $addRecQueueNum) {
|
|
|
+ echo 'success';
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|