seven 1 settimana fa
parent
commit
29d2e2cda7
2 ha cambiato i file con 118 aggiunte e 49 eliminazioni
  1. 1 0
      app/Http/Controllers/admin/Wallet.php
  2. 117 49
      app/Services/PaymentOrderService.php

+ 1 - 0
app/Http/Controllers/admin/Wallet.php

@@ -287,6 +287,7 @@ class Wallet extends Controller
         // $result = SanJinService::pay(100,$order_no);
         // $result = SanJinService::payout(100,$order_no,'厦门银行','张三',1245679451259741541,SanJinService::ALIPAY_TO_ALIPAY);
         $result = PaymentOrderService::createPayout($memberId,100,SanJinService::ALIPAY_TO_ALIPAY,'支付宝','张三','1756201451');
+        PaymentOrderService::sendMessage($result['chat_id'],$result['text']);
         echo "<pre>";
         var_dump($result);
     }

+ 117 - 49
app/Services/PaymentOrderService.php

@@ -144,81 +144,149 @@ class PaymentOrderService extends BaseService
         return $msg;
     }
 
-    public static function createPayout($memberId ,$amount ,$channel ,$bank_name ,$account ,$card_no)
+    public static function createPayout($memberId, $amount, $channel, $bank_name, $account, $card_no)
     {
-
         $default_amount = $amount;
         $result = [];
         $result['chat_id'] = $memberId;
 
-        $wallet = WalletService::findOne(['member_id' => $memberId]);
-        $balance = $wallet->available_balance;
-        if (bccomp($balance, $amount, 2) < 0) {
-            $result['text'] = '您的钱包余额不足!';
-            return $result;
-        }
+        // 在调用三方支付前开始事务
+        DB::beginTransaction();
+        
+        try {
+            $wallet = WalletService::findOne(['member_id' => $memberId]);
+            if (!$wallet) {
+                $result['text'] = '钱包不存在!';
+                return $result;
+            }
+            
+            $balance = $wallet->available_balance;
+            if (bccomp($balance, $amount, 2) < 0) {
+                $result['text'] = '您的钱包余额不足!';
+                return $result;
+            }
 
-        $available_balance = bcsub($balance, $amount, 10);
-
-        $data = [];
-        $data['type'] = self::TYPE_PAYOUT;
-        $order_no = self::createOrderNo('sj'.$data['type'].'_',$memberId);
-        $data['order_no'] = $order_no;
-        $data['member_id'] = $memberId;
-        $amount = number_format($amount, 2, '.', '');
-        $data['amount'] = $amount;
-        $data['channel'] = $channel;
-        $data['bank_name'] = $bank_name;
-        $data['account'] = $account;
-        $data['card_no'] = $card_no;
-        $data['callback_url'] = SanJinService::getNotifyUrl();
-        $data['status'] = self::STATUS_STAY;
+            $available_balance = bcsub($balance, $amount, 10);
 
-        
+            $data = [];
+            $data['type'] = self::TYPE_PAYOUT;
+            $order_no = self::createOrderNo('sj'.$data['type'].'_', $memberId);
+            $data['order_no'] = $order_no;
+            $data['member_id'] = $memberId;
+            $amount = number_format($amount, 2, '.', '');
+            $data['amount'] = $amount;
+            $data['channel'] = $channel;
+            $data['bank_name'] = $bank_name;
+            $data['account'] = $account;
+            $data['card_no'] = $card_no;
+            $data['callback_url'] = SanJinService::getNotifyUrl();
+            $data['status'] = self::STATUS_STAY;
+
+            // 先预扣款(锁定资金)
+            $wallet->available_balance = $available_balance;
+            if (!$wallet->save()) {
+                DB::rollBack();
+                $result['text'] = '钱包更新失败!';
+                return $result;
+            }
+
+            // 创建待处理状态的提现记录
+            $info = self::model()::create($data);
+            $id = $info->id;
 
+            // 记录余额变动日志
+            BalanceLogService::addLog(
+                $memberId,
+                $default_amount,
+                $balance,
+                $available_balance,
+                '三方提现',
+                $id,
+                '钱宝提现'
+            );
 
-        $ret = SanJinService::payout($amount,$order_no,$bank_name,$account,$card_no);
+            // 提交事务,确保预扣款成功
+            DB::commit();
+
+        } catch (\Exception $e) {
+            // 预扣款失败,回滚事务
+            DB::rollBack();
+            $result['text'] = '系统繁忙,请稍后重试!';
+            Log::error('提现预扣款失败: ' . $e->getMessage(), [
+                'member_id' => $memberId,
+                'amount' => $amount
+            ]);
+            return $result;
+        }
 
-        if($ret['code'] == 200){
+        // 调用三方支付接口(在事务外)
+        $ret = SanJinService::payout($amount, $order_no, $bank_name, $account, $card_no);
 
+        if ($ret['code'] == 200) {
+            // 更新提现记录状态为处理中
             DB::beginTransaction();
             try {
-                $wallet->available_balance = $available_balance;
-                $wallet->save();
+                $info->status = self::STATUS_PROCESS;
+                $info->save();
+                DB::commit();
 
-                $data['status'] = self::STATUS_PROCESS;
-                $info = self::model()::create($data);
-                $id = $info->id;
+                $text = "✅ 提现申请已提交!\n\n";
+                $text .= "钱包余额:{$available_balance} RMB\n";
+                $text .= "提现金额:{$default_amount} RMB\n";
+                $text .= "⌛️请等待系统处理, 到账时间可能需要几分钟!\n";
 
+                $result['text'] = $text;
+                
+            } catch (\Exception $e) {
+                DB::rollBack();
+                // 状态更新失败,但资金已扣款且三方支付已成功
+                // 这里可以记录告警,需要人工干预
+                Log::error('提现状态更新失败: ' . $e->getMessage(), [
+                    'member_id' => $memberId,
+                    'order_no' => $order_no
+                ]);
+                $result['text'] = '提现申请已提交,系统处理中...';
+            }
+            
+        } else {
+            // 三方支付失败,需要回滚之前的预扣款
+            DB::beginTransaction();
+            try {
+                // 恢复钱包余额
+                $wallet->available_balance = $balance;
+                $wallet->save();
+                
+                // 更新提现记录状态为失败
+                $info->status = self::STATUS_FAIL;
+                $info->remark = $ret['msg'];
+                $info->save();
+                
+                // 记录退款日志
                 BalanceLogService::addLog(
                     $memberId,
                     $default_amount,
-                    $balance,
                     $available_balance,
+                    $balance,
                     '三方提现',
                     $id,
-                    '钱宝提现'
+                    '提现失败退款'
                 );
-
-                $text = "✅ 提现申请已提交!\n\n";
-                $text .= "钱包余额:{$available_balance} RMB\n";
-                $text .= "提现金额:{$default_amount} RMB\n";
-                $text .= "⌛️请等待系统处理, 到账时间可能需要几分钟!\n";
-
-                $result['text'] = $text;
+                
                 DB::commit();
-            }catch (\Exception $e) {
+                $result['text'] = $ret['msg'];
+                
+            } catch (\Exception $e) {
                 DB::rollBack();
-                $result['text'] = $e->getMessage();
-                return $result;
-                // 记录错误日志或抛出异常
+                // 回滚失败,需要记录告警,人工干预
+                Log::error('提现失败回滚异常: ' . $e->getMessage(), [
+                    'member_id' => $memberId,
+                    'order_no' => $order_no,
+                    'amount' => $amount
+                ]);
+                $result['text'] = '提现失败,请联系客服处理退款!';
             }
-            
-        }else{
-            $result['text'] = $ret['msg'];
-            return $result;
-
         }
+
         return $result;
     }