Browse Source

微信支付 及 支付回调

醉梦人间三千年 5 months ago
parent
commit
9ced05b440

+ 2 - 3
app/Http/Controllers/Frontend/Client/Wechat/PaymentController.php

@@ -35,9 +35,8 @@ class PaymentController extends Controller
     /**
      * @throws \Throwable
      */
-    public function notify(): false|\Psr\Http\Message\ResponseInterface
+    public function notify(): JsonResponse
     {
-        $result = $this->service->notify();
-        return $result;
+        return $this->service->notify();
     }
 }

+ 54 - 20
app/Http/Services/Frontend/Client/Wechat/PaymentService.php

@@ -10,18 +10,17 @@ namespace App\Http\Services\Frontend\Client\Wechat;
 
 use App\Http\Services\Service;
 use App\Models\Member\User;
-use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
-use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
-use EasyWeChat\Kernel\Exceptions\RuntimeException;
+use App\Models\Service\Order;
+use EasyWeChat\Pay\Application;
 use EasyWeChat\Pay\Message;
 use Exception;
-use Faker\Provider\Payment;
+use Illuminate\Support\Carbon;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Log;
 use Overtrue\LaravelWeChat\EasyWeChat;
 use Symfony\Contracts\HttpClient\Exception\TransportExceptionInterface;
 use Throwable;
-use EasyWeChat\Pay\Application;
+
 
 class PaymentService extends Service
 {
@@ -31,7 +30,15 @@ class PaymentService extends Service
     public function payment(array $params)
     {
         try {
+            $order_id = $params['order_id'];
+            !$order_id && self::error('订单异常');
+            // 查询订单详情
+            $order = Order::query()->find($order_id);
+            !$order && self::error('订单错误');
+            $order->status === 1 && self::error('订单已支付');
+            $order->status && self::error('订单状态异常');
 
+            // 获取用户Openid
             $openid = User::query()->where('id', Auth::id())->value('openid');
             $pay = EasyWeChat::pay();
             $merchant = $pay->getMerchant();
@@ -42,14 +49,16 @@ class PaymentService extends Service
             $config = EasyWeChat::pay()->getConfig();
             $app = new Application($config);
 
+            $openid = 'oBxIn6qjN6YCjz1iElb5NDfBdYaM';
+
             $response = $app->getClient()->postJson("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi", [
                 "mchid" => (string)$merchant->getMerchantId(), // <---- 请修改为您的商户号
-                "out_trade_no" => uniqid('native') . rand(1, 1000), // "native12177525012012070352333'.rand(1,1000).'",
+                "out_trade_no" => $order->order_sn, //uniqid('native') . rand(1, 1000), // "native12177525012012070352333'.rand(1,1000).'",
                 "appid" => $app->getConfig()->get('app_id'), // <---- 请修改为服务号的 appid
-                "description" => "Image形象店-深圳腾大-QQ公仔",
+                "description" => $order->project_name,
                 "notify_url" => env('BACKEND_URL') . env('WECHAT_PAYMENT_NOTIFY_URL'),
                 "amount" => [
-                    "total" => 1,
+                    "total" => intval(round($order->pay_price * 100)),
                     "currency" => "CNY"
                 ],
                 "payer" => [
@@ -66,22 +75,34 @@ class PaymentService extends Service
                 'timeStamp' => (string)time(), // 时间戳
                 'nonceStr' => uniqid(), // 随机字符串
                 'package' => 'prepay_id=' . $prepayId, // prepay_id
-                'signType' => 'RSA', // 签名类型,默认为 MD5
+//                'signType' => 'RSA', // 签名类型,默认为 MD5
             ];
-            // 对参数进行排序并拼接成字符串
-            ksort($sign);
-            $stringA = urldecode(http_build_query($sign));
-            $privateKey  =file_get_contents( $config['private_key']); // 拼接 key
 
+            $privateKey = file_get_contents($config['private_key']); // 拼接 key
 
+
+            // 对参数进行排序并拼接成字符串
+//            ksort($sign);
+            $stringA = implode('\n', array_values($sign)) . '\n';
             // 使用 OpenSSL 生成签名
-            openssl_sign($stringA, $signature, $privateKey, OPENSSL_ALGO_SHA256);
+//            openssl_sign($stringA, $signature, $privateKey, OPENSSL_ALGO_SHA256);
+            $greeting = <<<EOD
+{$sign['appId']}
+{$sign['timeStamp']}
+{$sign['nonceStr']}
+{$sign['package']}
+
+EOD;
+            openssl_sign($greeting, $signature, $privateKey, OPENSSL_ALGO_SHA256);
 
             $sign['paySign'] = base64_encode($signature); // 生成签名
+            $sign['signType'] = 'RSA'; // 签名类型,默认为 MD5
+
             return $sign;
 
         } catch (\Exception $e) {
-            return response()->json(['error' => $e->getMessage()], 500);
+            self::error($e->getMessage());
+//            return response()->json(['error' => $e->getMessage()], 500);
         }
 //        $app = EasyWeChat::pay();
 //
@@ -102,25 +123,38 @@ class PaymentService extends Service
     /**
      * @throws Throwable
      */
-    public function notify(): false|\Psr\Http\Message\ResponseInterface
+    public function notify(): \Illuminate\Http\JsonResponse
     {
         try {
             $pay = EasyWeChat::pay();
             $server = $pay->getServer();
             $server->handlePaid(function (Message $message, \Closure $next) {
+                $out_trade_no = $message['out_trade_no'];
+                if ($message['trade_state'] === 'SUCCESS') {
+                    $order = Order::query()->where('order_sn', $out_trade_no)->first();
+                    Log::log('INFO', '$order', $order->toArray());
+
+                    if ($order->status === 0) {
+                        $order->status = 1;
+                        $order->transaction_id = $message['transaction_id'];
+                        $order->pay_time = Carbon::parse($message['success_time'])->timestamp;
+                        $order->save();
+                    }
+                }
                 // $message->out_trade_no 获取商户订单号
                 // $message->payer['openid'] 获取支付者 openid
                 // 🚨🚨🚨 注意:推送信息不一定靠谱哈,请务必验证
                 // 建议是拿订单号调用微信支付查询接口,以查询到的订单状态为准
-                Log::log('success', 'payNotify', (array)$message);
+//                Log::log('INFO', 'payNotify', (array)$message);
                 return $next($message);
             });
 
-// 默认返回 ['code' => 'SUCCESS', 'message' => '成功']
-            return $server->serve();
+            // 默认返回 ['code' => 'SUCCESS', 'message' => '成功']
+            $res = $server->serve();
+            return response()->json(json_decode($res->getBody()->getContents(), true), $res->getStatusCode());
         } catch (Exception $e) {
             Log::log('error', $e->getMessage());
-            return false;
+            return response()->json(['code' => 'FAIL', "message" => "失败"], 500);
         }
 
     }

+ 3 - 1
routes/api.php

@@ -44,7 +44,9 @@ Route::prefix('client')->group(function () {
 
         Route::get('/signature', [ClientWechatAuthenticatedController::class, 'signature']);
         # 支付
-        Route::get('/payment', [\App\Http\Controllers\Frontend\Client\Wechat\PaymentController::class, 'payment']);
+        Route::middleware(['auth:sanctum'])->group(function () {
+            Route::get('/payment', [\App\Http\Controllers\Frontend\Client\Wechat\PaymentController::class, 'payment']);
+        });
         Route::post('/payment/notify', [\App\Http\Controllers\Frontend\Client\Wechat\PaymentController::class, 'notify']);
 
     });