get('area_id'); $payment_type = (int)($request->get('pay_type', self::PATMENT_TYPE_MINIAPP));//支付方式 if (!in_array($payment_type, array_keys(self::$paymentTypeMaps))) return $this->errorNoValidation('支付方式不对'); $is_deposit = AreaSetting::where('area_id', $area_id)->value('is_deposit'); $user_id = $this->user->id; if ($user_id != 3) { if (!(int)$is_deposit) { return $this->errorNoValidation('该区域免押金骑行'); } } $result = $refundLogRepository->byUserIdCheckUserIsRefundOk_alipay_wxapp($user_id); //查询退款 if (!$result['status']) { if ($result['code'] === 'REFUNDNOTEXIST') { //交易退款查询失败 //发起退款 $refund = $refundLogRepository->byUserIdUserRefundNoModel($user_id); $order = $depositOrderRepository->byIdGetModel($refund->deposit_id); switch ($refund['pay_type']) { case RefundLog::PAY_TYPE_WECHAT: //微信 $payment = Factory::payment(wechat_pay_config(self::$MERCHANT)); // 微信支付 $coderesult = $payment->refund->byOutTradeNumber($order->no, $refund->no, wechat_fee($order->pay_money), wechat_fee($refund->pay_money), [ // 可在此处传入其他参数,详细参数见微信支付文档 'refund_desc' => '用户申请退回押金', 'notify_url' => config('app.url') . '/api/payments/wechat-refund-notify/' . self::$MERCHANT['id'], ]); break; case RefundLog::PAY_TYPE_ALIPAYMINI: //支付宝 $no = $order->no; $money = $order->pay_money; $data = alipay_mini_config(self::$MERCHANT)->payment()->common()->refund($no, $money); if ($data->fundChange == 'Y') { $coderesult['return_code'] = 'SUCCESS'; $coderesult['result_code'] = 'SUCCESS'; //支付宝没有退款异步回调 这里写下 $order->is_refund = DepositOrder::REFUND_OK; $order->save(); $order->refund_order_callback(); //押金退款订单回调 } else { $coderesult['return_code'] = 'ERROE'; $coderesult['result_code'] = 'ERROE'; $coderesult['err_code_des'] = "调用失败,原因:可能已经退款 请确认"; } break; case RefundLog::PAY_TYPE_ALIPAYMINI_CREDIT: $money = $order->pay_money; $alipayobj1 = new Alipay(); $resultdata = $alipayobj1->zijidongjieJiedong($result['data']); // 预授权解冻 if ($resultdata->status == 'SUCCESS' && $resultdata->amount == $money) { $coderesult['return_code'] = 'SUCCESS'; $coderesult['result_code'] = 'SUCCESS'; //支付宝没有退款异步回调 这里写下 $order->is_refund = DepositOrder::REFUND_OK; $order->save(); $order->refund_order_callback(); //押金退款订单回调 } else { $coderesult['return_code'] = 'ERROE'; $coderesult['result_code'] = 'ERROE'; $coderesult['err_code_des'] = json_encode($resultdata); } break; default: return $this->errorNoValidation('退款类型错误'); } if ($coderesult['return_code'] === 'SUCCESS' && $coderesult['result_code'] === 'SUCCESS') { // 判断是否有免押金卡 $re = CouponsUserBag::query()->where('user_id', $user_id) ->where('coupon_type', CouponsUserBag::COUPON_TYPE_DEPOSIT_FREE) ->where('valid_end_time', '<=', Carbon::now()->toDateTimeString()) ->where('status', CouponsUserBag::STATUS_OK)->exists(); if ($re) { //是否有免押金劵 User::where('id', $user_id)->update([ 'deposit_money' => 0, 'is_deposit' => User::DEPOSIT_OK, 'deposit_type' => User::DEPOSIT_COUPON ]); } else { $deposit_expire_time = Carbon::parse($this->user->deposit_expire_time); if (Carbon::now()->gte($deposit_expire_time)) { // 免押金卡已经过期 User::where('id', $user_id)->update([ 'deposit_money' => 0, 'is_deposit' => User::DEPOSIT_NO, 'deposit_type' => User::DEPOSIT_TYPE_NO ]); } else { // 免押金卡未过期 User::where('id', $user_id)->update([ 'deposit_money' => 0, 'is_deposit' => User::DEPOSIT_OK, 'deposit_type' => User::DEPOSIT_CARD ]); } } } else { $refund->result = $coderesult['err_code_des']; $refund->save(); return $this->errorNoValidation($refund->result); } } else { return $this->errorNoValidation($result['msg']); } } $cache_key = "DEPOSIT_ORDER_{$user_id}"; if (Cache::has($cache_key)) { return $this->errorNoValidation('您提交的太频繁了,请一会再提交!'); } Cache::put($cache_key, 1, Carbon::now()->addSeconds(5)); $order = $depositOrderRepository->byUserIdGetUserDepositOrder($user_id); if ($order) { return $this->errorNoValidation('您已经缴纳押金!'); } $money = AreaSetting::where('area_id', $area_id)->value('deposit'); // 开启一个数据库事务 switch (self::$SOURCE_TYPE) { case self::SOURCE_TYPE_WECHAT: $source_type = DepositOrder::PAY_TYPE_WECHAT; break; case self::SOURCE_TYPE_ALIPAY: if ($payment_type == self::PATMENT_TYPE_MINIAPP) { $source_type = DepositOrder::PAY_TYPE_ALIPAYMINI; } elseif ($payment_type == self::PATMENT_TYPE_ALIPAY_CARD) { $source_type = DepositOrder::PAY_TYPE_ALIPAYMINI_CREDIT; } break; } $data = [ 'money' => $money, 'user_id' => $user_id, 'no' => DepositOrder::makeNo(self::$ORDER_TAG), 'rno' => DepositOrder::makeNo(self::$ORDER_TAG), 'area_id' => $area_id, 'pay_status' => DepositOrder::PAY_STATUS_NO, 'pay_money' => $money, 'pay_type' => $source_type, 'merchant_id' => self::$MERCHANT_ID ]; $order = DepositOrder::create($data); if (!$order) { return $this->errorNoValidation('订单错误'); } $this->dispatch(new CloseOrderJob($order, Carbon::now()->addMinutes(30))); $auth = $this->user->auth; $userauth = userAuthinfo(self::$MERCHANT, $user_id); if ($userauth['code'] != 1) { return $this->errorNoValidation($userauth['msg']); } switch (self::$SOURCE_TYPE) { case self::SOURCE_TYPE_WECHAT: //DepositOrder::PAY_TYPE_WECHAT // 微信支付 $payment = Factory::payment(wechat_pay_config(self::$MERCHANT)); $result = $payment->order->unify([ 'body' => "用户缴纳押金-" . self::$MERCHANT['wxapp_name'], 'out_trade_no' => $order->no, 'trade_type' => 'JSAPI', // 必须为JSAPI 'openid' => $userauth['data']['credential'], // 这里的openid为付款人的openid 'total_fee' => wechat_fee($order->pay_money), // 总价 'attach' => makeNoTag(DepositOrder::NO_TAG) ]); // 如果成功生成统一下单的订单,那么进行二次签名 if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') { // 二次签名的参数必须与下面相同 $params = [ 'appId' => $auth['identifier'], 'timeStamp' => time(), 'nonceStr' => $result['nonce_str'], 'package' => 'prepay_id=' . $result['prepay_id'], 'signType' => 'MD5', ]; $params['paySign'] = generate_sign($params, self::$MERCHANT['pay_key']); return $this->response->array($params); } break; case self::SOURCE_TYPE_ALIPAY: //DepositOrder::PAY_TYPE_ALIPAYMINI if ($payment_type == self::PATMENT_TYPE_MINIAPP) { //支付宝支付 $money = $order->pay_money; $result = alipay_mini_pay(self::$MERCHANT, "用户缴纳押金-" . self::$MERCHANT['wxapp_name'], $order->no, $money, $userauth['data']['credential']); if ($result['code'] != 1) { return $this->errorNoValidation($result['msg']); } $response['tradeNo'] = $result['data']->tradeNo; //获取支付宝订单号 return $this->response->array($response); } elseif ($payment_type == self::PATMENT_TYPE_ALIPAY_CARD) { //支付宝预授权资金冻结免押认证 $merchant = self::$MERCHANT; $alipayobj = new Alipay(); $money = $order->pay_money; $data = [ //公共参数 'appId' => $merchant['alipaymini_appId'], 'rsaPrivateKey' => $merchant['alipaymini_merchantPrivateKey'], // 'appCertPath' => base_path() . '/storage/app/public/merchant/' . $merchant['alipaymini_merchantCertPath'], // 'alipayCertPath' => base_path() . '/storage/app/public/merchant/' . $merchant['alipaymini_alipayCertPath'], // 'rootCertPath' => base_path() . '/storage/app/public/merchant/' . $merchant['alipaymini_alipayRootCertPath'], 'appCertPath' => base_path() . '/database/zhifubao/' . $merchant['alipaymini_merchantCertPath'], 'alipayCertPath' => base_path() . '/database/zhifubao/' . $merchant['alipaymini_alipayCertPath'], 'rootCertPath' => base_path() . '/database/zhifubao/' . $merchant['alipaymini_alipayRootCertPath'], //异步回调 'notify_url' => config('app.url') . '/api/alipay_yushouquan/' . $merchant['id'], //请求参数 'out_order_no' => $order->no, //商户授权资金订单号 , 'out_request_no' => $order->rno,//商户本次资金操作的请求流水号,用于标示请求流水的唯一性 'order_title' => '预授权用户骑行押金', 'amount' => $money, 'product_code' => 'PRE_AUTH_ONLINE', 'payee_user_id' => $merchant['alipaymini_pid'], ]; $result = $alipayobj->zijidongjie_cret($data); // 证书公钥 $response['tradeNo'] = $result; //获取支付宝订单号 return $this->response->array($response); } break; default: return $this->errorNoValidation('没有有效的支付方式'); } return $this->errorNoValidation('下单失败'); } catch (\Exception $exception) { Log::error($exception); return $this->errorException($exception->getMessage()); } } /** * 退押金 队列 * @param OrderRepository $orderRepository * @param RentOrderRepository $rentOrderRepository * @param RefundLogRepository $refundLogRepository * @param PunishmentOrderRepository $punishmentOrderRepository * Author: Mead */ public function refundJob(Request $request, OrderRepository $orderRepository, RentOrderRepository $rentOrderRepository, RefundLogRepository $refundLogRepository, PunishmentOrderRepository $punishmentOrderRepository, UserRepository $userRepository) { try { $user_id = $this->user->id; if (!$userRepository->byIdCheckStatusOk($user_id)) { return $this->errorNoValidation('账号状态异常,暂不能退款!'); } // 有未结账的订单是能不能退 if ($orderRepository->byUserIdCheckIsExistNoPayOrder($this->user->id)) { return $this->errorNoValidation('您有未结算的订单,暂不能退款!'); } if ($rentOrderRepository->byUserIdCheckIsExistRideOrder($this->user->id)) { return $this->errorNoValidation('您有未完成的租车订单,请先处理'); } if ($rentOrderRepository->byUserIdCheckIsExistNoPayOrder($this->user->id)) { return $this->errorNoValidation('您有未支付的租车订单,请先处理'); } $punish = $punishmentOrderRepository->checkNoPayModel($this->user->id); if (!$punish) return $this->errorNoValidation('您有罚单未支付,请先处理'); if ((int)$this->user->deposit_type === User::DEPOSIT_CARD) { return $this->errorNoValidation('押金类型为免押金卡,不能退还押金'); } $order = DepositOrder::where('user_id', $this->user->id)->where('pay_status', DepositOrder::PAY_STATUS_OK)->where('is_refund', DepositOrder::REFUND_NO)->orderBy('id', 'desc')->first(); if (!$order) { return $this->errorNoValidation('你还没有缴纳押金'); } if (RefundLog::where('deposit_id', $order->id)->where('pay_status', RefundLog::PAY_STATUS_WAIT)->exists()) { return $this->response()->array([ 'type' => 2 ]); } if (RefundLog::where('deposit_id', $order->id)->where('pay_status', RefundLog::PAY_STATUS_NO)->exists()) { $result = $refundLogRepository->byUserIdCheckUserIsRefundOk($this->user->id); if (!$result['status'] && $result['code'] !== 'REFUNDNOTEXIST') { return $this->errorNoValidation($result['msg']); } } $cache_key = "REFUND_DEPOSIT_ORDER_{$user_id}"; if (Cache::has($cache_key)) { return $this->errorNoValidation('您提交的太频繁了,请一会再提交!'); } Cache::put($cache_key, 1, Carbon::now()->addSeconds(5)); $refund = DB::transaction(function () use ($order) { $refund = RefundLog::firstOrCreate([ 'deposit_id' => $order->id, 'user_id' => $this->user->id, ], [ 'no' => RefundLog::makeNo(self::$ORDER_TAG), 'money' => $order->pay_money, 'type' => RefundLog::TYPE_USER, 'is_check_status' => RefundLog::CHECK_STATUS_OK, 'area_id' => $order->area_id, 'pay_type' => $order->pay_type, 'pay_money' => $order->pay_money, 'pay_status' => RefundLog::PAY_STATUS_WAIT, 'merchant_id' => self::$MERCHANT_ID ]); // 修改用户押金 return $refund; }); // $this->dispatch(new DepositRefundJob($refund, Carbon::now()->addMinutes(5))); $this->dispatch(new DepositRefundJob($refund, Carbon::now()->addMinutes(1))); return $this->response()->array([ 'type' => 1 ]); // return $this->errorNoValidation($refund->result); } catch (\Exception $exception) { return $this->exception($exception); } } /** * 退还押金 马上 * @param DepositOrderRepository $depositOrderRepository * User: Mead */ public function refund(Request $request, OrderRepository $orderRepository, RentOrderRepository $rentOrderRepository, RefundLogRepository $refundLogRepository, PunishmentOrderRepository $punishmentOrderRepository, UserRepository $userRepository) { try { $user_id = $this->user->id; if (!$userRepository->byIdCheckStatusOk($user_id)) { return $this->errorNoValidation('账号状态异常,暂不能退款!'); } // 有未结账的订单是能不能退 if ($orderRepository->byUserIdCheckIsExistNoPayOrder($this->user->id)) { return $this->errorNoValidation('您有未结算的订单,暂不能退款!'); } if ($rentOrderRepository->byUserIdCheckIsExistRideOrder($this->user->id)) { return $this->errorNoValidation('您有未完成的租车订单,请先处理'); } if ($rentOrderRepository->byUserIdCheckIsExistNoPayOrder($this->user->id)) { return $this->errorNoValidation('您有未支付的租车订单,请先处理'); } $punish = $punishmentOrderRepository->checkNoPayModel($this->user->id); if (!$punish) return $this->errorNoValidation('您有罚单未支付,请先处理'); if ((int)$this->user->deposit_type === User::DEPOSIT_CARD) { return $this->errorNoValidation('押金类型为免押金卡,不能退还押金'); } $order = DepositOrder::where('user_id', $this->user->id)->where('pay_status', DepositOrder::PAY_STATUS_OK)->where('is_refund', DepositOrder::REFUND_NO)->orderBy('id', 'desc')->first(); if (!$order) { return $this->errorNoValidation('你还没有缴纳押金'); } if (RefundLog::where('deposit_id', $order->id)->where('pay_status', RefundLog::PAY_STATUS_NO)->where('pay_type', DepositOrder::PAY_TYPE_WECHAT)->exists()) { $result = $refundLogRepository->byUserIdCheckUserIsRefundOk($this->user->id); if (!$result['status'] && $result['code'] !== 'REFUNDNOTEXIST') { return $this->errorNoValidation($result['msg']); } } $cache_key = "REFUND_DEPOSIT_ORDER_{$user_id}"; if (Cache::has($cache_key)) { return $this->errorNoValidation('您提交的太频繁了,请一会再提交!'); } Cache::put($cache_key, 1, Carbon::now()->addSeconds(5)); $refund = DB::transaction(function () use ($order) { $refund = RefundLog::firstOrCreate([ 'deposit_id' => $order->id, 'user_id' => $this->user->id, ], [ 'no' => RefundLog::makeNo(self::$ORDER_TAG), 'money' => $order->pay_money, 'type' => RefundLog::TYPE_USER, 'is_check_status' => RefundLog::CHECK_STATUS_OK, 'area_id' => $order->area_id, 'pay_type' => $order->pay_type, 'pay_money' => $order->pay_money, 'pay_status' => RefundLog::PAY_STATUS_NO, 'merchant_id' => self::$MERCHANT_ID ]); // 修改用户押金 if ((int)$refund->pay_status === RefundLog::PAY_STATUS_WAIT) { $refund->pay_status = RefundLog::PAY_STATUS_NO; $refund->type = RefundLog::TYPE_USER_SPEED; $refund->save(); } return $refund; }); switch ($order->pay_type) { case DepositOrder::PAY_TYPE_WECHAT: //用的是支付押金时候的支付方式 $payment = Factory::payment(wechat_pay_config(self::$MERCHANT)); // 微信支付 $result = $payment->refund->byOutTradeNumber($order->no, $refund->no, wechat_fee($order->pay_money), wechat_fee($refund->pay_money), [ // 可在此处传入其他参数,详细参数见微信支付文档 'refund_desc' => '用户申请退回押金', 'notify_url' => config('app.url') . '/api/payments/wechat-refund-notify/' . self::$MERCHANT['id'], ]); break; case DepositOrder::PAY_TYPE_ALIPAYMINI: //用的是支付押金时候的支付方式 原路退回 $no = $order->no; $money = $order->pay_money; $data = alipay_mini_config(self::$MERCHANT)->payment()->common()->optional("out_request_no", $refund->no)->refund($no, $money); if ($data->fundChange == 'Y') { $result['return_code'] = 'SUCCESS'; $result['result_code'] = 'SUCCESS'; //支付宝没有退款异步回调 这里写下 $order->is_refund = DepositOrder::REFUND_OK; $order->save(); $order->refund_order_callback(); //押金退款订单回调 } else { $result['return_code'] = 'ERROE'; $result['result_code'] = 'ERROE'; $result['err_code_des'] = "调用失败,原因:可能已经退款 请确认"; } break; case DepositOrder::PAY_TYPE_ALIPAYMINI_CREDIT: //支付宝押金预授权解冻 $money = $order->pay_money; $merchant = self::$MERCHANT; $alipayobj = new Alipay(); $data = AlipayYushouquanJiedong($merchant, $order->no, $order->rno); $resultdata = $alipayobj->AlipayQueryYushouquan($data); // 预授权查询 if(!empty($resultdata->code) && $resultdata->code==10000 && $resultdata->status=='SUCCESS') { if ($resultdata->rest_amount == '0.00') { return $this->errorNoValidation('已经解冻完所有金额!!'); } }else{ return $this->errorNoValidation($resultdata->sub_msg); } $data = AlipayYushouquanJiedongQingqiu($data, $resultdata->auth_no, $refund->no, $resultdata->rest_amount); $resultdata = $alipayobj->zijidongjieJiedong($data); // 预授权解冻 if ($resultdata === false) { return $this->errorNoValidation('预授权解冻失败,请联系管理员'); } if ($resultdata->status == 'SUCCESS' && $resultdata->amount == $money) { $result['return_code'] = 'SUCCESS'; $result['result_code'] = 'SUCCESS'; $order->is_refund = DepositOrder::REFUND_OK; $order->save(); $order->refund_order_callback(); //押金退款订单回调 } else { $result['return_code'] = 'ERROE'; $result['result_code'] = 'ERROE'; $result['err_code_des'] = json_encode($resultdata); } break; default: return $this->errorNoValidation('退款方式错误'); } if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') { // 判断是否有免押金卡 $re = CouponsUserBag::query()->where('user_id', $user_id) ->where('coupon_type', CouponsUserBag::COUPON_TYPE_DEPOSIT_FREE) ->where('valid_end_time', '<=', Carbon::now()->toDateTimeString()) ->where('status', CouponsUserBag::STATUS_OK)->exists(); if ($re) { //是否有免押金劵 User::where('id', $user_id)->update([ 'deposit_money' => 0, 'is_deposit' => User::DEPOSIT_OK, 'deposit_type' => User::DEPOSIT_COUPON ]); } else { $deposit_expire_time = Carbon::parse($this->user->deposit_expire_time); if (Carbon::now()->gte($deposit_expire_time)) { // 免押金卡已经过期 User::where('id', $this->user->id)->update([ 'deposit_money' => 0, 'is_deposit' => User::DEPOSIT_NO, 'deposit_type' => User::DEPOSIT_TYPE_NO ]); } else { // 免押金卡未过期 User::where('id', $this->user->id)->update([ 'deposit_money' => 0, 'is_deposit' => User::DEPOSIT_OK, 'deposit_type' => User::DEPOSIT_CARD ]); } } return $this->response->array([ 'is_refund_status' => true ]); } else { $refund->result = $result['err_code_des']; } $refund->save(); return $this->errorNoValidation($refund->result); } catch (\Exception $exception) { return $this->exception($exception); } } }