From 55be0c18e22c24cf704bdbe03c41b9cba569e767 Mon Sep 17 00:00:00 2001 From: wong <106998207@qq.com> Date: Wed, 24 Sep 2025 14:09:27 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E4=BB=98=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/controller/PaymentService.php | 106 +++++++++++++++++- .../application/cunkebao/controller/Pay.php | 2 +- 2 files changed, 105 insertions(+), 3 deletions(-) diff --git a/Server/application/common/controller/PaymentService.php b/Server/application/common/controller/PaymentService.php index 240bb6ff..5ab7dc0d 100644 --- a/Server/application/common/controller/PaymentService.php +++ b/Server/application/common/controller/PaymentService.php @@ -33,7 +33,7 @@ class PaymentService */ public function createOrder(array $order) { - + Log::info('支付创建'); $params = [ 'service' => 'unified.trade.native', 'sign_type' => PaymentUtil::SIGN_TYPE_MD5, @@ -203,7 +203,6 @@ class PaymentService public function notify() { Log::info('支付结果异步通知'); - $rawBody = file_get_contents('php://input'); Log::info('[SwiftPass][notify] raw: ' . $rawBody); @@ -327,5 +326,108 @@ class PaymentService $dt = \DateTime::createFromFormat('YmdHis', $timeEnd, new \DateTimeZone('Asia/Shanghai')); return $dt ? $dt->getTimestamp() : 0; } + + /** + * 查询订单(威富通 unified.trade.query) + * - 入参:商户订单号或平台交易号 + * - 出参:统一 JSON 格式,包含交易状态与关键信息 + * @param array $query + * - out_trade_no: string 商户订单号(与 transaction_id 二选一) + * - transaction_id: string 平台交易号(与 out_trade_no 二选一) + * @return \think\response\Json + */ + public function queryOrder(array $query) + { + $outTradeNo = $query['out_trade_no'] ?? ($query['orderNo'] ?? ''); + $transactionId = $query['transaction_id'] ?? ''; + + if ($outTradeNo === '' && $transactionId === '') { + return json(['code' => 422, 'msg' => '缺少查询参数:out_trade_no 或 transaction_id']); + } + + $params = [ + 'service' => 'unified.trade.query', + 'mch_id' => Env::get('payment.mchId'), + 'out_trade_no' => $outTradeNo ?: null, + 'nonce_str' => PaymentUtil::generateNonceStr(), + 'sign_type' => 'MD5', + ]; + + // 过滤空值后签名 + $secret = Env::get('payment.key'); + if (empty($secret)) { + return json(['code' => 500, 'msg' => '支付密钥未配置']); + } + + $filtered = []; + foreach ($params as $k => $v) { + if ($v === '' || $v === null) continue; + $filtered[$k] = $v; + } + $filtered['sign'] = PaymentUtil::generateSign($filtered, $secret, $filtered['sign_type']); + + $url = Env::get('payment.url'); + if (empty($url)) { + return json(['code' => 500, 'msg' => '支付网关地址未配置']); + } + + // 请求网关 + $xmlBody = $this->arrayToXml($filtered); + $response = $this->postXml($url, $xmlBody); + $parsed = $this->parseXmlOrRaw($response); + + if (!is_array($parsed)) { + return json(['code' => 500, 'msg' => '响应解析失败', 'data' => $response]); + } + + if (($parsed['status'] ?? '') !== '0') { + return json(['code' => 500, 'msg' => '通信失败:' . ($parsed['message'] ?? 'unknown')]); + } + + if (($parsed['result_code'] ?? '') !== '0') { + return json(['code' => 200, 'msg' => '业务失败', 'data' => [ + 'err_code' => $parsed['err_code'] ?? '', + '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'] ?? '', + ]; + + // 若已支付,同步本地订单 + if ($tradeState === 'SUCCESS' && ($resp['out_trade_no'] ?? '') !== '') { + Db::startTrans(); + try { + /** @var Order|null $order */ + $order = Order::where('orderNo', $resp['out_trade_no'])->lock(true)->find(); + if ($order) { + $paidAt = $this->parsePayTime($resp['time_end'] ?? '') ?: time(); + if ((int)$order['status'] !== 1) { + $order->save([ + 'status' => 1, + 'transactionId' => $resp['transaction_id'] ?? '', + 'payTime' => $paidAt, + 'updateTime' => time(), + ]); + } + } + Db::commit(); + } catch (\Throwable $e) { + Db::rollback(); + Log::error('[SwiftPass][query] update order exception: ' . $e->getMessage()); + } + } + + return json(['code' => 200, 'msg' => '查询成功', 'data' => $resp]); + } } diff --git a/Server/application/cunkebao/controller/Pay.php b/Server/application/cunkebao/controller/Pay.php index 990a60de..99553f0c 100644 --- a/Server/application/cunkebao/controller/Pay.php +++ b/Server/application/cunkebao/controller/Pay.php @@ -13,7 +13,7 @@ class Pay $order = [ 'companyId' => 111, 'userId' => 111, - 'orderNo' => time() . rand(100000, 999999), + 'orderNo' => date('YmdHis') . rand(100000, 999999), 'goodsId' => 34, 'goodsName' => '测试测试', 'orderType' => 1,