where(['state' => OrderState::UNPAID, 'global_order_id' => $globalOrderId, 'user_id' => $userId]) ->where('created_at', '>=', (time()-900)) ->first(); if (empty($orderMain)) { throw new ErrorCodeException(ErrorCode::ORDER_NOT_AVAILABLE, '[支付订单号]'.$globalOrderId); } $payMoney = bcmul((string)$orderMain->money, 100, 0); if (env('APP_ENV') != 'prod') { $payMoney = 1; } $user = User::select('openid')->find($userId); $result = $app->order->unify([ 'body' => '懒族生活 - 外卖下单', 'out_trade_no' => $orderMain->global_order_id, 'total_fee' => $payMoney, 'notify_url' => config('site_host') . '/wechat/notify/wxminionline', 'trade_type' => 'JSAPI', 'openid' => $user['openid'], ]); if ($result['return_code'] == 'FAIL') { throw new ErrorCodeException(ErrorCode::PAYMENT_FAIL, '[支付失败]'.$result['return_msg']); } // 返回支付参数给前端 $parameters = [ 'appId' => $result['appid'], 'timeStamp' => '' . time() . '', 'nonceStr' => uniqid(), 'package' => 'prepay_id=' . $result['prepay_id'], 'signType' => 'MD5' ]; $parameters['paySign'] = $this->signture($parameters, $config['key']); return $parameters; } catch (\Exception $e) { $this->log->event(LogLabel::ORDER_PAYMENT_LOG, ['payment_exception_msg' => $e->getMessage()]); throw new ErrorCodeException(ErrorCode::PAYMENT_FAIL, '[支付失败]'.$e->getMessage()); } } public function check() { // TODO: Implement check() method. } public function undo() { // TODO: Implement undo() method. } /** * 支付参数加签 * @param $parameters * @param $key * @return string */ private function signture($parameters, $key) { // 按字典序排序参数 ksort($parameters); // http_query $queryParams = $this->http_query($parameters); // 加入KEY $queryParams = $queryParams . "&key=" . $key; // MD5加密 $queryParams = md5($queryParams); // 字符转为大写 return strtoupper($queryParams); } /** * 参数转为http query字串 * @param $parameters * @return string */ private function http_query($parameters) { $http_query = []; foreach ($parameters as $key => $value) { $http_query[] = $key.'='.$value; } return implode('&', $http_query); } }