app_id = $app->app_id; $order->order_no = $params['outTradeNo']; $order->member_id = $user->member_id; $order->out_member_id = $params['outMemberId'] ?? ''; $order->out_order_no = $params['outOrderNo'] ?? ''; $order->amount = $params['payAmount'] ?? 0; $order->notify_url = $params['notifyUrl'] ?? ''; $order->order_info = json_encode($params['orderInfo'] ?? [], JSON_UNESCAPED_UNICODE); return $order; } public function handlePayResult(Result $result, Order $order) { if ($result->get('payState') === '00') { $order->status = Order::STATUS_PAYED; $order->fee = $result->get('procedureFee', 0); $order->pay_order_no = $result->get('transactionNo', ''); $order->channel_order_no = $result->get('channelOrder', ''); $order->payed_at = date('Y-m-d H:i:s'); $order->save(); } elseif ($result->get('payState') === '01') { $order->status = Order::STATUS_FAILED; $order->error_code = '01'; $order->error_msg = '支付失败'; $order->payed_at = date('Y-m-d H:i:s'); $order->save(); } } public function handleRefundResult(Result $result, RefundOrder $order) { if ($result->get('refundState') === '00') { $order->status = RefundOrder::STATUS_REFUND_SUCCESS; $order->fee = $result->get('procedureFee', 0); $order->refunded_at = date('Y-m-d H:i:s'); $order->save(); } elseif ($result->get('refundState') === '01') { $order->status = RefundOrder::STATUS_REFUND_FAILED; $order->error_code = '01'; $order->error_msg = '处理失败'; $order->refunded_at = date('Y-m-d H:i:s'); $order->save(); } } public function protocolPayPreRequest($params) { $req = new ProtocolPayPreRequest($params); $app = $req->getApp(); $data = $req->getData(); if ($data['payAmount'] > 3000) { throw new BusinessException('超出限额'); } $order = Order::where('app_id', $app->app_id)->where('out_order_no', $data['outOrderNo'])->first(); if ($order) { throw new BusinessException('订单重复'); } $data['outTradeNo'] = StringHelper::generateOrderNo(); $result = Api::protocolPayPre($data); $user = User::where('app_id', $app->app_id)->where('out_member_id', $data['outMemberId'])->first(); if (!$user) { throw new BusinessException('用户不存在'); } $order = $this->createOrder($app, $data, $user); if (!$result->isSuccess()) { $order->status = Order::STATUS_APPLY_FAIL; $order->save(); throw new BusinessException($result->getMessage()); } $order->token = $result->get('token', ''); $order->protocol = $result->get('protocol', ''); $order->status = Order::STATUS_WAIT_PAY; $order->save(); return $result->getData(); } public function protocolPayConfirm($params) { $req = new ProtocolPayConfirmRequest($params); $app = $req->getApp(); $data = $req->getData(); $order = Order::where('app_id', $app->app_id) ->where('token', $data['token']) ->where('protocol', $data['protocol']) ->first(); if (!$order) { throw new BusinessException('订单不存在'); } $result = Api::protocolPayConfirm($req->getData()); if (!$result->isSuccess()) { $order->status = Order::STATUS_FAILED; $order->error_code = $result->getCode(); $order->error_msg = $result->getMessage(); $order->payed_at = date('Y-m-d H:i:s'); $order->save(); throw new BusinessException($result->getMessage()); } // 00 01 03 $this->handlePayResult($result, $order); return $result->getData(); } public function bindCard($params) { $req = new BindCardRequest($params); $app = $req->getApp(); $reqData = $req->getData(); $memberId = $this->generateMemberId($app->app_key, $reqData['certificatesNo']); $reqData['memberId'] = $memberId; $bankCard = BankCard::where('app_id', $app->app_id) ->where('member_id', $memberId) ->where('bank_card_no', $reqData['bankCardNo']) ->where('status', BankCard::STATUS_ACTIVE) ->first(); if ($bankCard) { throw new BusinessException('该卡已绑定'); } $result = Api::bindCard($reqData); if (!$result->isSuccess()) { throw new BusinessException($result->getMessage()); } $user = User::where('member_id', $memberId)->first(); if (!$user) { $user = new User(); $user->member_id = $memberId; $user->out_member_id = $reqData['outMemberId']; $user->app_id = $app->app_id; $user->real_name = $reqData['userName']; $user->card_no = $reqData['certificatesNo']; $user->mobile = $reqData['phoneNum']; $user->save(); } if ($user && empty($user->out_member_id)) { $user->out_member_id = $reqData['outMemberId']; $user->save(); } if ($user && $user->out_member_id && $user->out_member_id != $reqData['outMemberId']) { throw new BusinessException('身份证号重复!'); } $bankCard = new BankCard(); $bankCard->member_id = $memberId; $bankCard->out_member_id = $reqData['outMemberId']; $bankCard->app_id = $app->app_id; $bankCard->real_name = $reqData['userName']; $bankCard->card_no = $reqData['certificatesNo']; $bankCard->mobile = $reqData['phoneNum']; $bankCard->sms_no = $result->get('smsNo', ''); $bankCard->bank_card_no = $reqData['bankCardNo']; $bankCard->bank_card_type = $reqData['bankCardType']; $bankCard->protocol = $result->get('protocol', ''); $bankCard->expired = $reqData['expired'] ?? ''; $bankCard->cvn = $reqData['cvn'] ?? ''; $bankCard->status = BankCard::STATUS_WAIT_CONFIRM; $bankCard->save(); return array_merge($result->getData(), ['memberId' => $memberId]); } public function bindCardConfirm($params) { $req = new BindCardConfirmRequest($params); $app = $req->getApp(); $reqData = $req->getData(); $bankCard = BankCard::where('app_id', $app->app_id) ->where('out_member_id', $reqData['outMemberId']) ->where('sms_no', $reqData['smsNo']) ->where('status', BankCard::STATUS_WAIT_CONFIRM) ->first(); if (!$bankCard) { throw new BusinessException('绑卡申请不存在'); } $reqData['memberId'] = $bankCard->member_id; $result = Api::bindCardConfirm($reqData); if (!$result->isSuccess()) { throw new BusinessException($result->getMessage()); } $bankCard->status = BankCard::STATUS_ACTIVE; $bankCard->protocol = $result->get('protocol', ''); $bankCard->save(); return $result->getData(); } public function refundQuery($params) { $req = new RefundQueryRequest($params); $data = $req->getData(); $result = Api::refundQuery($data); if (!$result->isSuccess()) { throw new BusinessException($result->getMessage()); } $order = RefundOrder::where('out_refund_order_no', $result->get('outRefundNo')) ->where('status', RefundOrder::STATUS_APPLY_SUCCESS) ->first(); if ($order) { $this->handleRefundResult($result, $order); } return $result->getData([ 'outRefundNo', 'transactionNo', 'amount', 'refundAmount', 'refundState' ]); } public function paymentQuery($params) { $req = new PaymentQueryRequest($params); $data = $req->getData(); $result = Api::paymentQuery($data); if (!$result->isSuccess()) { throw new BusinessException($result->getMessage()); } $order = Order::where('out_order_no', $result->get('outTradeNo')) ->where('status', Order::STATUS_WAIT_PAY) ->first(); if ($order) { $this->handlePayResult($result, $order); } return $result->getData([ 'outTradeNo', 'transactionNo', 'payState', 'procedureFee', 'amount' ]); } public function unBindCard($params) { $req = new UnBindCardRequest($params); $app = $req->getApp(); $reqData = $req->getData(); $bankCard = BankCard::where('app_id', $app->app_id) ->where('member_id', $reqData['memberId']) ->where('protocol', $reqData['protocol']) ->where('status', BankCard::STATUS_ACTIVE) ->first(); if (!$bankCard) { throw new BusinessException('绑卡不存在'); } $result = Api::unBindCard($reqData); if (!$result->isSuccess()) { throw new BusinessException($result->getMessage()); } $bankCard->status = BankCard::STATUS_UNBIND; $bankCard->save(); return $result->getData(); } public function refund($params) { $req = new RefundRequest($params); $app = $req->getApp(); $data = $req->getData(); $refundOrder = new RefundOrder(); $refundOrder->app_id = $app->app_id; $refundOrder->out_order_no = $data['outTradeNo'] ?: ''; $refundOrder->out_refund_order_no = $data['outRefundNo'] ?: ''; $refundOrder->order_amount = $data['amount'] ?: ''; $refundOrder->refund_amount = $data['refundAmount'] ?: ''; $refundOrder->remark = $data['remark'] ?: ''; $refundOrder->notify_url = $data['notifyUrl'] ?: ''; $result = Api::refund($data); if (!$result->isSuccess()) { $refundOrder->status = RefundOrder::STATUS_APPLY_FAILED; $refundOrder->error_code = $result->getCode(); $refundOrder->error_msg = $result->getMessage(); $refundOrder->save(); throw new BusinessException($result->getMessage()); } $refundOrder->status = RefundOrder::STATUS_APPLY_SUCCESS; $refundOrder->save(); return $result->getData(); } public function payment($params) { $req = new PaymentRequest($params); $app = $req->getApp(); $reqData = $req->getData(); if (!$reqData['outOrderNo']) { throw new BusinessException('订单号错误'); } if (!$reqData['outMemberId']) { throw new BusinessException('用户ID不能为空'); } if (isset($reqData['amount'])) { if (!is_numeric($reqData['amount'])) { throw new BusinessException('请输入金额'); } if ($reqData['amount'] < 100 || $reqData['amount'] > 300000) { throw new BusinessException('充值金额必须为100~300000'); } } if (!$reqData['notifyUrl']) { throw new BusinessException('通知地址不能为空'); } $log = PrePayLog::where('app_id', $app->app_id)->where('out_order_no', $reqData['outOrderNo'])->first(); $order = Order::where('app_id', $app->app_id)->where('out_order_no', $reqData['outOrderNo'])->first(); if ($log || $order) { throw new BusinessException('订单重复'); } $token = md5(microtime(true) . json_encode($reqData) . $app->app_id . $app->app_key); $log = new PrePayLog(); $log->app_id = $app->app_id; $log->out_order_no = $reqData['outOrderNo']; $log->amount = $reqData['amount'] ?: 0; $log->out_member_id = $reqData['outMemberId']; $log->notify_url = $reqData['notifyUrl']; $log->redirect_url = $reqData['redirectUrl'] ?? ''; $log->token = $token; $log->save(); return ['payUrl' => env('WEB_HOST') . '/payment.html?token=' . $token]; } public function query($params) { $req = new PaymentQueryRequest($params); $data = $req->getData(); $app = $req->getApp(); if (empty($data['outOrderNo'])) { throw new BusinessException('订单号不能为空'); } $order = Order::where('app_id', $app->app_id)->where('out_order_no', $data['outOrderNo'])->first(); if (!$order) { throw new BusinessException('订单不存在'); } $result = Api::paymentQuery(['outTradeNo' => $order->order_no]); if (!$result->isSuccess()) { throw new BusinessException($result->getMessage()); } $this->handlePayResult($result, $order); return [ 'outOrderNo' => $data['outOrderNo'], 'orderNo' => $order->order_no, 'payState' => $result->get('payState'), 'amount' => $result->get('amount'), ]; } }