diff --git a/Server/application/common/controller/PaymentService.php b/Server/application/common/controller/PaymentService.php index 5ab7dc0d..e0bd910d 100644 --- a/Server/application/common/controller/PaymentService.php +++ b/Server/application/common/controller/PaymentService.php @@ -33,25 +33,24 @@ class PaymentService */ public function createOrder(array $order) { - Log::info('支付创建'); $params = [ - 'service' => 'unified.trade.native', - 'sign_type' => PaymentUtil::SIGN_TYPE_MD5, - 'mch_id' => Env::get('payment.mchId'), - 'out_trade_no' => $order['orderNo'], - 'body' => $order['goodsName'] ?? '', - 'total_fee' => $order['money'] ?? 0, - 'mch_create_ip' => Request::ip(), - 'notify_url' => Env::get('payment.notify_url','127.0.0.1'), - 'nonce_str' => PaymentUtil::generateNonceStr(), + 'service' => 'unified.trade.native', + 'sign_type' => PaymentUtil::SIGN_TYPE_MD5, + 'mch_id' => Env::get('payment.mchId'), + 'out_trade_no' => $order['orderNo'], + 'body' => $order['goodsName'] ?? '', + 'total_fee' => $order['money'] ?? 0, + 'mch_create_ip' => Request::ip(), + 'notify_url' => Env::get('payment.notify_url', '127.0.0.1'), + 'nonce_str' => PaymentUtil::generateNonceStr(), ]; Db::startTrans(); try { // 过滤空值签名 - $secret = Env::get('payment.key'); + $secret = Env::get('payment.key'); $params['sign_type'] = 'MD5'; - $params['sign'] = PaymentUtil::generateSign($params, $secret, 'MD5'); + $params['sign'] = PaymentUtil::generateSign($params, $secret, 'MD5'); $url = Env::get('payment.url'); if (empty($url)) { @@ -76,14 +75,14 @@ class PaymentService // XML POST 请求 - $xmlBody = $this->arrayToXml($params); + $xmlBody = $this->arrayToXml($params); $response = $this->postXml($url, $xmlBody); - $parsed = $this->parseXmlOrRaw($response); + $parsed = $this->parseXmlOrRaw($response); if ($parsed['status'] == 0 && $parsed['result_code'] == 0) { Db::commit(); - return json(['code' => 200, 'msg' => '订单创建成功','data' => $parsed['code_url']]); - }else{ + return json(['code' => 200, 'msg' => '订单创建成功', 'data' => $parsed['code_url']]); + } else { Db::rollback(); return json(['code' => 500, 'msg' => '订单创建失败:' . $parsed['err_msg']]); } @@ -95,7 +94,6 @@ class PaymentService } - /** * POST 请求(x-www-form-urlencoded) */ @@ -202,112 +200,74 @@ class PaymentService */ public function notify() { - Log::info('支付结果异步通知'); - $rawBody = file_get_contents('php://input'); - Log::info('[SwiftPass][notify] raw: ' . $rawBody); + //$rawBody = file_get_contents('php://input'); + $rawBody = ' + + + + + + + + + + + + + + + + + + + + + + + + +'; $payload = $this->parseXmlOrRaw($rawBody); if (!is_array($payload) || empty($payload)) { - Log::error('[SwiftPass][notify] parse fail'); - echo 'fail'; - return; + return json_encode(['code' => 500, 'msg' => 'XML解析错误']); } - // 基础字段 - $status = (string)($payload['status'] ?? ''); - $resultCode = (string)($payload['result_code'] ?? ''); - $outTradeNo = (string)($payload['out_trade_no'] ?? ''); - $totalFee = (int)($payload['total_fee'] ?? 0); - $mchIdNotify = (string)($payload['mch_id'] ?? ''); - $signInNotify = (string)($payload['sign'] ?? ''); - $signType = (string)($payload['sign_type'] ?? 'MD5'); - if ($status !== '0' || $resultCode !== '0') { - Log::warning('[SwiftPass][notify] business not success', $payload); - echo 'fail'; - return; + if ($payload['status'] != 0 || $payload['result_code'] != 0) { + $errMsg = (isset($payload['err_msg']) ? $payload['err_msg'] : isset($payload['err_msg'])) ? $payload['err_msg'] : '未知错误'; + return json_encode(['code' => 500, 'msg' => $errMsg]); } - // 验签 - $secret = Env::get('payment.key'); - if (empty($secret)) { - Log::error('[SwiftPass][notify] payment.key not configured'); - echo 'fail'; - return; - } - - $verifyData = $payload; - unset($verifyData['sign']); - $calcSign = PaymentUtil::generateSign($verifyData, $secret, $signType ?: 'MD5'); - if (strcasecmp($calcSign, $signInNotify) !== 0) { - Log::error('[SwiftPass][notify] sign mismatch', [ - 'calc' => $calcSign, - 'recv' => $signInNotify, - ]); - echo 'fail'; - return; - } - - // 校验商户号 - $mchIdConfig = Env::get('payment.mchId'); - if (!empty($mchIdConfig) && $mchIdConfig !== $mchIdNotify) { - Log::error('[SwiftPass][notify] mch_id mismatch', [ - 'config' => $mchIdConfig, - 'notify' => $mchIdNotify, - ]); - echo 'fail'; - return; - } // 业务处理:更新订单 Db::startTrans(); try { - /** @var Order|null $order */ - $order = Order::where('orderNo', $outTradeNo)->lock(true)->find(); + $outTradeNo = $payload['out_trade_no']; + $pay_result = $payload['pay_result']; + $time_end = $payload['time_end']; + $order = Order::where('orderNo', $outTradeNo)->find(); if (!$order) { Db::rollback(); - Log::error('[SwiftPass][notify] order not found', ['out_trade_no' => $outTradeNo]); - echo 'fail'; - return; + return json_encode(['code' => 500, 'msg' => '该订单不存在']); } - // 金额校验(单位:分) - if ((int)$order['money'] !== $totalFee) { - Db::rollback(); - Log::error('[SwiftPass][notify] amount mismatch', [ - 'order_money' => (int)$order['money'], - 'notify_fee' => $totalFee, - ]); - echo 'fail'; - return; - } - - // 幂等:已支付直接返回成功 - if ((int)$order['status'] === 1) { + if ($pay_result != 0) { + $order->payInfo = $payload['pay_info']; + $order->payType = $payload['trade_type'] == 'pay.wechat.jspay' ? 1 : 2; + $order->status = 3; + $order->save(); Db::commit(); - echo 'success'; - return; + return json_encode(['code' => 500, 'msg' => $payload['pay_info']]); } - - $transactionId = (string)($payload['transaction_id'] ?? ''); - $timeEndStr = (string)($payload['time_end'] ?? ''); - $paidAt = $this->parsePayTime($timeEndStr) ?: time(); - - $order->save([ - 'status' => 1, - 'transactionId' => $transactionId, - 'payTime' => $paidAt, - 'updateTime' => time(), - ]); - + $order->status = 1; + $order->payTime = $this->parsePayTime($time_end); + $order->save(); Db::commit(); - echo 'success'; - return; - } catch (\Throwable $e) { + return json_encode(['code' => 200, 'msg' => '付款成功']); + } catch (\Exception $e) { Db::rollback(); - Log::error('[SwiftPass][notify] exception: ' . $e->getMessage()); - echo 'fail'; - return; + return json_encode(['code' => 500, 'msg' => '付款失败' . $e->getMessage()]); } } @@ -338,7 +298,7 @@ class PaymentService */ public function queryOrder(array $query) { - $outTradeNo = $query['out_trade_no'] ?? ($query['orderNo'] ?? ''); + $outTradeNo = $query['out_trade_no'] ?? ($query['orderNo'] ?? ''); $transactionId = $query['transaction_id'] ?? ''; if ($outTradeNo === '' && $transactionId === '') { @@ -346,11 +306,11 @@ class PaymentService } $params = [ - 'service' => 'unified.trade.query', - 'mch_id' => Env::get('payment.mchId'), - 'out_trade_no' => $outTradeNo ?: null, - 'nonce_str' => PaymentUtil::generateNonceStr(), - 'sign_type' => 'MD5', + 'service' => 'unified.trade.query', + 'mch_id' => Env::get('payment.mchId'), + 'out_trade_no' => $outTradeNo ?: null, + 'nonce_str' => PaymentUtil::generateNonceStr(), + 'sign_type' => 'MD5', ]; // 过滤空值后签名 @@ -372,9 +332,9 @@ class PaymentService } // 请求网关 - $xmlBody = $this->arrayToXml($filtered); + $xmlBody = $this->arrayToXml($filtered); $response = $this->postXml($url, $xmlBody); - $parsed = $this->parseXmlOrRaw($response); + $parsed = $this->parseXmlOrRaw($response); if (!is_array($parsed)) { return json(['code' => 500, 'msg' => '响应解析失败', 'data' => $response]); @@ -387,20 +347,20 @@ class PaymentService if (($parsed['result_code'] ?? '') !== '0') { return json(['code' => 200, 'msg' => '业务失败', 'data' => [ 'err_code' => $parsed['err_code'] ?? '', - 'err_msg' => $parsed['err_msg'] ?? '', + 'err_msg' => $parsed['err_msg'] ?? '', ]]); } $tradeState = $parsed['trade_state'] ?? ''; $resp = [ - 'trade_state' => $tradeState, - 'trade_state_desc'=> $parsed['trade_state_desc'] ?? '', - 'transaction_id' => $parsed['transaction_id'] ?? '', - 'out_trade_no' => $parsed['out_trade_no'] ?? $outTradeNo, - 'total_fee' => isset($parsed['total_fee']) ? (int)$parsed['total_fee'] : null, - 'time_end' => $parsed['time_end'] ?? '', - 'buyer_logon_id' => $parsed['buyer_logon_id'] ?? '', - 'bank_type' => $parsed['bank_type'] ?? '', + 'trade_state' => $tradeState, + 'trade_state_desc' => $parsed['trade_state_desc'] ?? '', + 'transaction_id' => $parsed['transaction_id'] ?? '', + 'out_trade_no' => $parsed['out_trade_no'] ?? $outTradeNo, + 'total_fee' => isset($parsed['total_fee']) ? (int)$parsed['total_fee'] : null, + 'time_end' => $parsed['time_end'] ?? '', + 'buyer_logon_id' => $parsed['buyer_logon_id'] ?? '', + 'bank_type' => $parsed['bank_type'] ?? '', ]; // 若已支付,同步本地订单 @@ -413,10 +373,10 @@ class PaymentService $paidAt = $this->parsePayTime($resp['time_end'] ?? '') ?: time(); if ((int)$order['status'] !== 1) { $order->save([ - 'status' => 1, + 'status' => 1, 'transactionId' => $resp['transaction_id'] ?? '', - 'payTime' => $paidAt, - 'updateTime' => time(), + 'payTime' => $paidAt, + 'updateTime' => time(), ]); } } diff --git a/Server/application/common/model/Order.php b/Server/application/common/model/Order.php index c1ac3a3a..82b6b5b8 100644 --- a/Server/application/common/model/Order.php +++ b/Server/application/common/model/Order.php @@ -3,18 +3,12 @@ namespace app\common\model; use think\Model; -use think\model\concern\SoftDelete; class Order extends Model { - use SoftDelete; - // 设置数据表名 protected $name = 'order'; - // 自动写入时间戳 - protected $autoWriteTimestamp = true; - protected $createTime = 'createTime'; } \ No newline at end of file