paymentService = $paymentService; } public function getMemberInfo(RequestInterface $request) { [$app, $prePayLog] = $this->checkToken($request->input('token', '')); $user = User::where('out_member_id', $prePayLog->out_member_id)->first(); $bankCard = null; if ($user) { $bankCard = BankCard::where('member_id', $user->member_id)->where('status', BankCard::STATUS_ACTIVE)->first(); } return $this->success([ 'name' => $user->real_name ?? '', 'card_no' => $user->card_no ?? '', 'mobile' => $user->mobile ?? '', 'bank_card_no' => $bankCard->bank_card_no ?? '', ]); } public function recharge(RequestInterface $request) { [$app, $prePayLog] = $this->checkToken($request->input('token', '')); $name = $request->input('name'); if (empty($name)) { throw new BusinessException('请输入姓名'); } $amount = $request->input('amount'); if (empty($amount)) { throw new BusinessException('请输入金额'); } if (!is_numeric($amount)) { throw new BusinessException('请输入金额'); } if ($amount <= 0) { throw new BusinessException('金额需大于0'); } $cardNo = $request->input('cardNo'); if (empty($cardNo)) { throw new BusinessException('请输入身份证号'); } $mobile = $request->input('mobile'); if (empty($mobile)) { throw new BusinessException('请输入手机号'); } $bankCardNo = $request->input('bankCardNo'); if (empty($bankCardNo)) { throw new BusinessException('请输入银行卡号'); } $memberId = $this->paymentService->generateMemberId($app->app_key, $cardNo); $user = User::where('member_id', $memberId)->first(); $bankCard = null; if ($user) { $bankCard = BankCard::where('member_id', $user->member_id)->where('bank_card_no', $bankCardNo)->where('status', BankCard::STATUS_ACTIVE)->first(); } if ($bankCard) { $outTradeNo = $prePayLog->out_order_no; $nextStep = 'confirm-pay'; $bizData = $this->paymentService->protocolPayPreRequest($this->buildPrepayParams($prePayLog->out_member_id, $outTradeNo, $bankCard->protocol, intval($amount * 100), $app)); } else { $mchOrderNo = StringHelper::generateBankCardOrderNo(); $nextStep = 'confirm-bind'; $bizData = $this->paymentService->bindCard($this->buildBindCardParams( $mchOrderNo, $prePayLog->out_member_id, $name, $cardNo, $mobile, $bankCardNo, $app )); } return $this->success([ 'nextStep' => $nextStep, 'outMemberId' => $memberId, 'bizData' => $bizData ]); } public function confirmBindCard(RequestInterface $request) { [$app, $prePayLog] = $this->checkToken($request->input('token', '')); $outMemberId = $request->input('outMemberId'); $smsNo = $request->input('smsNo'); $smsCode = $request->input('smsCode'); $bizData = $this->paymentService->bindCardConfirm($this->buildComfirmBindCardParams($outMemberId, $smsNo, $smsCode, $app)); return $this->success([ 'outMemberId' => $outMemberId, 'bizData' => $bizData ]); } public function confirmPay(RequestInterface $request) { [$app, $prePayLog] = $this->checkToken($request->input('token', '')); $outMemberId = $request->input('outMemberId'); $token = $request->input('token'); $protocol = $request->input('protocol'); $smsCode = $request->input('smsCode'); $bizData = $this->paymentService->protocolPayConfirm($this->buildConfirmPayParams($token, $protocol, $smsCode, $app)); return $this->success([ 'outMemberId' => $outMemberId, 'bizData' => ['outTradeNo' => $bizData['outTradeNo']] ]); } private function buildBindCardParams($mchOrderNo, $outMemberId, $name, $cardNo, $mobile, $bankCardNo, $app) { $params = [ 'app_id' => $app->app_id, 'timestamp' => time(), 'nonce_str' => StringHelper::getRandomString(32), 'data' => json_encode([ 'mchtOrderNo' => $mchOrderNo, 'outMemberId' => $outMemberId, 'userName' => $name, 'phoneNum' => $mobile, 'bankCardNo' => $bankCardNo, 'bankCardType' => 'debit', 'certificatesNo' => $cardNo, ]), ]; $sign = \App\Helper\Platform\Signer::sign($params, $app->app_key); $params['sign'] = $sign; return $params; } private function buildPrepayParams($outMemberId, $outTradeNo, $protocol, $amount, $app) { $params = [ 'app_id' => $app->app_id, 'timestamp' => time(), 'nonce_str' => StringHelper::getRandomString(32), 'data' => json_encode([ 'outMemberId' => $outMemberId, 'outTradeNo' => $outTradeNo, 'protocol' => $protocol, 'payAmount' => $amount, ]), ]; $sign = \App\Helper\Platform\Signer::sign($params, $app->app_key); $params['sign'] = $sign; return $params; } private function buildConfirmPayParams($token, $protocol, $smsCode, $app) { $params = [ 'app_id' => $app->app_id, 'timestamp' => time(), 'nonce_str' => StringHelper::getRandomString(32), 'data' => json_encode([ 'token' => $token, 'protocol' => $protocol, 'smsCode' => $smsCode, ]), ]; $sign = \App\Helper\Platform\Signer::sign($params, $app->app_key); $params['sign'] = $sign; return $params; } private function buildComfirmBindCardParams($outMemberId, $smsNo, $smsCode, $app) { $params = [ 'app_id' => $app->app_id, 'timestamp' => time(), 'nonce_str' => StringHelper::getRandomString(32), 'data' => json_encode([ 'outMemberId' => $outMemberId, 'smsNo' => $smsNo, 'smsCode' => $smsCode, ]), ]; $sign = \App\Helper\Platform\Signer::sign($params, $app->app_key); $params['sign'] = $sign; return $params; } public function orders(RequestInterface $request) { $page = $request->input('page', 1); $pageSize = $request->input('pageSize', 20); $token = $request->input('token'); $value = Redis::get('token:' . $token); $users = $this->getUsers(); if (empty($value) || !isset($users[$value])) { throw new UnauthorizedException(); } $offset = ($page - 1) * $pageSize; $orders = Order::query()->orderBy('id', 'desc')->offset($offset)->limit($pageSize)->get(); $protocols = $orders->pluck('protocol'); $bankCards = BankCard::whereIn('protocol', $protocols)->get(); $bankCards = $bankCards->keyBy('protocol'); $records = []; foreach ($orders as $order) { $bankCard = $bankCards[$order->protocol] ?? null; $records[] = [ 'out_order_no' => $order->out_order_no, 'payed_at' => $order->payed_at, 'status' => $order->status, 'amount' => number_format($order->amount / 100, 2, '.', ''), 'real_name' => $bankCard ? $bankCard->real_name : '', 'bank_card_no' => $bankCard ? $bankCard->bank_card_no : '', 'mobile' => $bankCard ? $bankCard->mobile : '', 'card_no' => $bankCard ? $bankCard->card_no : '', 'status_text' => $order->getStatusText(), ]; } $total = Order::query()->count(); return $this->success([ 'records' => $records, 'total' => $total, ]); } public function login(RequestInterface $request) { $username = $request->input('username'); $password = $request->input('password'); if (empty($username) || empty($password)) { throw new BusinessException('账号或密码错误'); } $users = $this->getUsers(); if (isset($users[$username]) && $users[$username] === $password) { $token = md5(microtime() . $username . $password); Redis::set('token:' . $token, $username); Redis::expire('token:' . $token, 60*60); return $this->success(['token' => $token]); } throw new BusinessException('账号或密码错误'); } private function getUsers() { return [ 'owx0tlx' => 'lSoLW28NxtMlxUazC8p', 'ioexlp2' => 'wwU8Ir3Xp0rxXssA9NV' ]; } private function checkToken($token) { $app = App::query()->orderBy('id', 'asc')->first(); return $app; if (empty($token)) { throw new BusinessException('token异常'); } $log = PrePayLog::where('token', $token)->first(); if (empty($log)) { throw new BusinessException('预支付记录不存在'); } if ($log->created_at->timestamp < time() - 5*60) { throw new BusinessException('支付超时,请重新请求'); } $order = Order::where('app_id', $log->app_id)->where('out_order_no', $log->out_order_no)->first(); if ($order) { throw new BusinessException('订单重复,请重新请求'); } $app = App::where('app_id', $log->app_id)->first(); if (empty($app)) { throw new BusinessException('应用异常'); } return [$app, $log]; } }