2
0
Tree 3 тижнів тому
батько
коміт
b3769df511

+ 149 - 0
app/Http/Controllers/Api/AiNewPayController.php

@@ -0,0 +1,149 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Http\logic\api\AiNewPayLogic;
+use App\Http\logic\api\AiNewPayCashierLogic;
+use App\Inter\PayMentInterFace;
+use App\Notification\TelegramBot;
+use App\Services\AiNewPay;
+use App\Services\PayConfig;
+use App\Services\PayUtils;
+use App\Util;
+use App\Utility\SetNXLock;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Redis;
+
+class AiNewPayController implements PayMentInterFace
+{
+    private $retryTimes = 0;
+
+    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method = '')
+    {
+        $logic = new AiNewPayLogic();
+        try {
+            $res = $logic->pay_order($userId, $payAmt, $userPhone, $userEmail, $userName, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
+        } catch (\Exception $exception) {
+            Redis::set("PayErro_AiNewPay", 1);
+            Redis::expire("PayErro_AiNewPay", 600);
+            Util::WriteLog('AiNewPay_error', $exception->getMessage() . json_encode($logic->result ?? []));
+
+            TelegramBot::getDefault()->sendProgramNotify("AiNewPay Except ", $exception->getMessage(), $exception);
+            return apiReturnFail($logic->getError());
+        }
+
+        if (!empty($res) && isset($res['code']) && $res['code'] == 0) {
+            $data = [
+                'content' => $res['data']['cashierUrl'],
+                'money' => $payAmt,
+                'prdOrdNo' => $res['data']['mchOrderNo'],
+            ];
+            return apiReturnSuc($data);
+        } else if ($res == false) {
+            return apiReturnFail($logic->getError());
+        } else {
+            if ($this->retryTimes > 0) {
+                Redis::set("PayErro_AiNewPay", 1);
+                Redis::expire("PayErro_AiNewPay", 600);
+                TelegramBot::getDefault()->sendProgramNotify("AiNewPay RetrunFail ", $logic->getError() . " | " . json_encode($res));
+                return apiReturnFail($logic->getError());
+            } else {
+                $this->retryTimes++;
+                return $this->pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
+            }
+        }
+    }
+
+    // 支付异步回调
+    public function notify(Request $request)
+    {
+        $post = $request->all();
+        $payload = json_encode($post);
+
+        Util::WriteLog('AiNewPay', "AiNewPay回调订单\n" . $payload);
+
+        $service = new AiNewPay();
+        
+        try {
+            $verify = $service->verifySign($post);
+        } catch (\Exception $e) {
+            Util::WriteLog('AiNewPay', '验签失败:' . $e->getMessage());
+            return 'fail';
+        }
+
+        if (!$verify) {
+            Util::WriteLog('AiNewPay', '签名错误');
+            return 'fail';
+        }
+
+        $order_sn = @$post['mchOrderNo'];
+        if (empty($order_sn)) {
+            Util::WriteLog('AiNewPay', '缺少订单号');
+            return 'fail';
+        }
+
+        // 代收回调加锁,防止并发重复处理
+        $lockKey = 'pay_notify_AiNewPay_' . $order_sn;
+        if (!SetNXLock::getExclusiveLock($lockKey, 60)) {
+            Util::WriteLog('AiNewPay', '代收回调并发,订单已处理或处理中: ' . $order_sn);
+            return 'success';
+        }
+
+        $logic = new AiNewPayLogic();
+        try {
+            $redis = Redis::connection();
+            $ret = $logic->notify($post);
+            if ($ret == 'success') $redis->set($order_sn, $order_sn, 3600 * 24);
+            return $ret;
+        } catch (\Exception $exception) {
+            Redis::set("PayErro_AiNewPay", 1);
+            Redis::expire("PayErro_AiNewPay", 600);
+            TelegramBot::getDefault()->sendProgramNotify("AiNewPay 订单回调执行 异常 ", json_encode($post), $exception);
+            Util::WriteLog("AiNewPay_error", $post);
+            return '{"success":false,"message":"商户自定义出错信息"}';
+        } finally {
+            SetNXLock::release($lockKey);
+        }
+    }
+
+    public function sync_notify(Request $request)
+    {
+        Log::info('AiNewPay同步回调');
+        echo 'AiNewPay同步回调';
+    }
+
+    // 提现异步回调
+    public function cash_notify(Request $request)
+    {
+        $post = $request->all();
+        $payload = json_encode($post);
+
+        Util::WriteLog('AiNewPay', "AiNewPay cash 异步回调\n" . $payload);
+
+        $payConfigService = new PayConfig();
+        $config = $payConfigService->getConfig('AiNewPayOut');
+        $apiKey = $config['key'];
+        
+        try {
+            $verify = PayUtils::verifySign($post, $apiKey);
+        } catch (\Exception $e) {
+            Util::WriteLog('AiNewPay cash', '验签失败:' . $e->getMessage());
+            return 'fail';
+        }
+
+        if (!$verify) {
+            Util::WriteLog('AiNewPay cash', '签名错误');
+            return 'fail';
+        }
+
+        $logic = new AiNewPayCashierLogic();
+        try {
+            return $logic->notify($post);
+        } catch (\Exception $exception) {
+            TelegramBot::getDefault()->sendProgramNotify("AiNewPay 提现异步回调执行 异常 ", json_encode($post), $exception);
+            Util::WriteLog("AiNewPay_error", $post);
+            return '{"success":false,"message":"商户自定义出错信息"}';
+        }
+    }
+}

+ 272 - 0
app/Http/logic/api/AiNewPayCashierLogic.php

@@ -0,0 +1,272 @@
+<?php
+
+namespace App\Http\logic\api;
+
+use App\dao\Estatisticas\RechargeWithDraw;
+use App\Http\helper\NumConfig;
+use App\Inter\CashierInterFace;
+use App\Models\PrivateMail;
+use App\Models\RecordUserDataStatistics;
+use App\Services\PayConfig;
+use App\Services\PayUtils;
+use App\Services\StoredProcedure;
+use App\Util;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Redis;
+
+class AiNewPayCashierLogic implements CashierInterFace
+{
+    const AGENT = 105; // AiNewPay代付渠道值
+    protected $agent = 105;
+
+    public function payment($RecordID, $amount, $accountName, $phone, $email, $OrderId, $PixNum, $PixType, $IFSCNumber, $BranchBank, $BankNO)
+    {
+        // 查询订单号
+        $query = DB::connection('write')->table('QPAccountsDB.dbo.OrderWithDraw')->where('RecordID', $RecordID)->first();
+        if (!$query) return 'fail';    // 订单不存在
+
+        $payConfigService = new PayConfig();
+        $config = $payConfigService->getConfig('AiNewPayOut');
+        $wayCode = [
+            1 => 'ecashapp',
+            2 => 'paypal'
+        ];
+        $wayParam = [];
+
+        if ($PixNum && strpos($PixNum, '$') !== 0) {
+            $PixNum = '$' . $PixNum;
+        }
+
+        if($PixType == 1){
+            $wayParam = ["cashtag" => $PixNum];
+        }
+        if($PixType == 2){
+            $wayParam = ["email" => $email];
+        }
+        // 构建提现请求参数
+        $params = [
+            "mchNo" => $config['mchNo'] ?? '',
+            "mchOrderNo" => $OrderId,
+            "amount" => intval($amount),
+            "currency" => $config['currency'] ?? "usd",
+            "wayCode" => $wayCode[$PixType],
+            "notifyUrl" => $config['cashNotify'],
+            "wayParam" => $wayParam,
+            "timestamp" => round(microtime(true) * 1000),
+            "signType" => $config['signType'] ?? "MD5"
+        ];
+
+        // 使用 AiNewPayOut 的 key 签名
+        $apiKey = $config['key'];
+        $signedParams = PayUtils::sign($params, $apiKey);
+
+        $url = $config['apiUrl'];
+
+        Log::info('AiNewPay 提现参数:', $signedParams);
+        
+        try {
+            $result = $this->curlPost($url, $signedParams);
+        } catch (\Exception $exception) {
+            Log::info('AiNewPay 提现请求异常:', [$exception->getMessage()]);
+            return 'fail';
+        }
+
+        Log::info('AiNewPay 提现结果:', [$result ?? "no result"]);
+
+        try {
+            $data = \GuzzleHttp\json_decode($result, true);
+        } catch (\Exception $e) {
+            Util::WriteLog("AiNewPay_error", [$result, $e->getMessage(), $e->getTraceAsString()]);
+            return 'fail';
+        }
+
+        if (isset($data['code']) && $data['code'] == 0) {
+            return $data;
+        } else {
+            if ($query->State == 5) {
+                $msg = 'Liquidation failure';
+                $WithDraw = $query->WithDraw + $query->ServiceFee;
+                $bonus = '30000,' . $WithDraw;
+
+                PrivateMail::failMail($query->UserID, $OrderId, $WithDraw, $msg, $bonus);
+
+                $withdraw_data = ['State' => 6, 'agent' => 1045, 'finishDate' => now(),'remark' => json_encode($data)];
+                DB::connection('write')->table('QPAccountsDB.dbo.OrderWithDraw')->where('OrderId', $query->OrderId)->update($withdraw_data);
+                
+                $RecordData = ['after_state' => 6, 'update_at' => now()];
+                DB::connection('write')->table('QPAccountsDB.dbo.AccountsRecord')->where('type', 1)->where('RecordID', $RecordID)->update($RecordData);
+            }
+            return 'fail';
+        }
+    }
+
+    public function notify($post)
+    {
+        if (!is_array($post)) $post = \GuzzleHttp\json_decode($post, true);
+        
+        Util::WriteLog('AiNewPay', 'AiNewPay 提现回调:' . json_encode($post));
+
+        try {
+            $OrderId = $post['mchOrderNo'] ?? '';
+            $query = DB::connection('write')->table('QPAccountsDB.dbo.OrderWithDraw')->where('OrderId', $OrderId)->first();
+
+            if (!$query) {
+                Util::WriteLog('AiNewPay','订单不存在');
+                return '{"success":true,"message":"Accepted"}';
+            }
+
+            if ($query->State != 5 && $query->State != 7) {
+                Util::WriteLog('AiNewPay',$OrderId.'_订单状态已完成');
+                return 'SUCCESS';
+            }
+
+            $agentID = DB::connection('write')->table('agent.dbo.admin_configs')
+                ->where('config_value', self::AGENT)
+                ->where('type', 'cash')
+                ->select('id')
+                ->first()->id ?? '';
+
+            $now = now();
+            $notify_data = [
+                'state' => 1,
+                'finish_at' => $now,
+                'casOrdNo' => $post['mchOrderNo'] ?? '',
+                'extra' => \GuzzleHttp\json_encode($post),
+                'created_at' => $now,
+                'updated_at' => $now,
+                'order_sn' => $OrderId,
+                'amount' => $query->WithDraw,
+            ];
+
+            $orderStatus = 0;
+            if (isset($post['state'])) {
+                if ($post['state'] == 2) {
+                    $orderStatus = 1; // 成功
+                } elseif ($post['state'] == 3) {
+                    $orderStatus = 2; // 失败
+                }
+            }
+
+            if (!$orderStatus) {
+                Util::WriteLog('AiNewPay', 'AiNewPay 提现处理中:' . $OrderId);
+                return 'success';
+            }
+
+            Util::WriteLog('AiNewPay', 'AiNewPay 提现结果:' . $OrderId . '_' . $orderStatus);
+            
+            $UserID = $query->UserID;
+            $TakeMoney = $query->WithDraw + $query->ServiceFee;
+
+
+            switch ($orderStatus) {
+                case 1: // 提现成功
+                    Util::WriteLog('AiNewPay', 'AiNewPay提现成功');
+
+                    $withdraw_data = [
+                        'State' => 2,
+                        'agent' => $agentID,
+                        'finishDate' => $now
+                    ];
+
+                    $first = DB::connection('write')->table('QPAccountsDB.dbo.UserTabData')->where('UserID', $UserID)->first();
+                    if ($first) {
+                        DB::connection('write')->table('QPAccountsDB.dbo.UserTabData')->where('UserID', $UserID)->increment('TakeMoney', $TakeMoney);
+                    } else {
+                        DB::connection('write')->table('QPAccountsDB.dbo.UserTabData')->insert(['TakeMoney' => $TakeMoney, 'UserID' => $UserID]);
+                        try {
+                            PrivateMail::praiseSendMail($UserID);
+                        } catch (\Exception $e) {
+                        }
+                    }
+
+                    $withdrawal_position_log = DB::connection('write')->table('agent.dbo.withdrawal_position_log')->where('order_sn', $OrderId)->first();
+                    if ($withdrawal_position_log) {
+                        DB::connection('write')->table('agent.dbo.withdrawal_position_log')->where('order_sn', $OrderId)->update(['take_effect' => 2, 'update_at' => date('Y-m-d H:i:s')]);
+                    }
+
+                    try {
+                        StoredProcedure::addPlatformData($UserID, 4, $TakeMoney);
+                    } catch (\Exception $exception) {
+                        Util::WriteLog('StoredProcedure', $exception);
+                    }
+
+                    $ServiceFee = $query->ServiceFee;
+                    RecordUserDataStatistics::updateOrAdd($UserID, $TakeMoney, 0, $ServiceFee);
+
+                    (new RechargeWithDraw())->withDraw($UserID, $TakeMoney);
+
+                    $redis = Redis::connection();
+                    $redis->incr('draw_' . date('Ymd') . $UserID);
+                    break;
+
+                case 2: // 提现失败
+                    $msg = 'Encomenda rejeitada pelo banco';
+                    $bonus = '30000,' . $TakeMoney;
+                    PrivateMail::failMail($query->UserID, $OrderId, $TakeMoney, $msg, $bonus);
+                    
+                    Util::WriteLog('AiNewPayEmail', [$query->UserID, $OrderId, $TakeMoney, $msg, $bonus]);
+                    $withdraw_data = ['State' => 6, 'agent' => $agentID, 'remark' => @$post['errMsg'] ?: ''];
+                    $notify_data = ['state' => 2];
+                    break;
+            }
+
+            $RecordData = [
+                'before_state' => $query->State,
+                'after_state' => $withdraw_data['State'] ?? 0,
+                'RecordID' => $query->RecordID,
+                'update_at' => date('Y-m-d H:i:s')
+            ];
+
+            DB::connection('write')->table('QPAccountsDB.dbo.AccountsRecord')->updateOrInsert(['RecordID' => $query->RecordID, 'type' => 1], $RecordData);
+            DB::connection('write')->table('QPAccountsDB.dbo.OrderWithDraw')->where('OrderId', $query->OrderId)->update($withdraw_data);
+
+            if (isset($withdraw_data['State']) && $withdraw_data['State'] == 2) {
+                StoredProcedure::user_label($UserID, 2, $TakeMoney);
+            }
+            
+            return 'success';
+
+        } catch (\Exception $exception) {
+            Util::WriteLog('AiNewPay', 'AiNewPay异步业务逻辑处理失败:' . $exception->getMessage());
+            return '{"success":false,"message":"商户自定义出错信息"}';
+        }
+    }
+
+    /**
+     * POST请求方法
+     */
+    private function curlPost($url, $payload)
+    {
+        $timeout = 20;
+        $data = json_encode($payload, JSON_UNESCAPED_UNICODE);
+        
+        $headers = [
+            'Content-Type: application/json',
+        ];
+
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_POST, 1);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
+        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+
+        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+        $result = curl_exec($ch);
+
+        if (curl_errno($ch)) {
+            $error = curl_error($ch);
+            Util::WriteLog('AiNewPay_error', 'CURL Error: ' . $error);
+            curl_close($ch);
+            return false;
+        }
+
+        curl_close($ch);
+        return $result;
+    }
+}

+ 193 - 0
app/Http/logic/api/AiNewPayLogic.php

@@ -0,0 +1,193 @@
+<?php
+
+namespace App\Http\logic\api;
+
+use App\dao\Pay\AccountPayInfo;
+use App\dao\Pay\PayController;
+use App\Facade\TableName;
+use App\Http\helper\CreateOrder;
+use App\Http\helper\NumConfig;
+use App\Jobs\Order;
+use App\Notification\TelegramBot;
+use App\Services\OrderServices;
+use App\Services\PayConfig;
+use App\Services\AiNewPay;
+use App\Services\CreateLog;
+use App\Util;
+use Illuminate\Support\Facades\DB;
+
+class AiNewPayLogic extends BaseApiLogic
+{
+    public $result;
+
+    public function pay_order($userId, $pay_amount, $userPhone, $userEmail, $userName, $GiftsID, $buyIP, $AdId, $eventType, $pay_method = '')
+    {
+        $dao = new AccountPayInfo();
+        [$userPhone, $userName, $userEmail] = $dao->payInfo($userId);
+
+//        $pay_amount = (int)$pay_amount;
+        
+        // 礼包类型验证
+        $PayVerify = new PayController();
+        $pay_amount = $PayVerify->verify($userId, $GiftsID, $pay_amount);
+        if ($PayVerify->verify($userId, $GiftsID, $pay_amount) === false) {
+            $this->error = $PayVerify->getError();
+            return false;
+        }
+        if ($pay_amount < 0) {
+            $this->error = 'Payment error_4';
+            return false;
+        }
+
+        $service = new AiNewPay();
+        $config = $service->config;
+
+        $order_sn = CreateOrder::order_sn($userId);
+
+        // 生成订单信息
+        $logic = new OrderLogic();
+        $amount = (int) round($pay_amount * NumConfig::NUM_VALUE) ;
+        $logic->orderCreate($order_sn, $amount, 'AiNewPay', $userId, $pay_method, $GiftsID, $AdId, $eventType);
+
+        $payMethods = [
+            1 => 'cashapp',
+            2 => 'paypal',
+            4 => 'apple',
+            8 => 'google',
+        ];
+
+        $wwMethod = @$payMethods[$pay_method];
+
+        // 构建支付请求参数
+        $params = [
+            "mchNo" => $service->mchNo,
+            "mchOrderNo" => $order_sn,
+            "amount" => $amount,
+            "currency" => $config['currency'] ?? "usd",
+            "wayCode" => $wwMethod??($config['wayCode'] ?? "cashapp"),
+            "clientIp" => $buyIP,
+            "notifyUrl" => $config['notify'] ?? '',
+            "returnUrl" => $config['return'] ?? '',
+            "expiredTime" => 1800,
+            "wayParam" => [
+                "clientId" => $userId
+            ],
+            "timestamp" => round(microtime(true) * 1000), // 13位时间戳
+            "signType" => $config['signType'] ?? "MD5"
+        ];
+
+        // 签名
+        $signedParams = $service->sign($params);
+
+        // 生成用户请求信息日志
+        $request_extra = \GuzzleHttp\json_encode($signedParams);
+        CreateLog::pay_request($userPhone, $request_extra, $order_sn, $userEmail, $userId, $userName);
+
+        $url = $service->apiUrl;
+
+        $result = $service->curlPost($url, $signedParams);
+        $rresult = compact('result', 'signedParams', 'url');
+        
+        Util::WriteLog('AiNewPay', 'AiNewPay支付请求' . $url . " | " . $request_extra);
+        Util::WriteLog('AiNewPay', 'AiNewPay支付结果' . json_encode($rresult));
+        
+        try {
+            $data = \GuzzleHttp\json_decode($result, true);
+        } catch (\Exception $e) {
+            Util::WriteLog("AiNewPay_error", [$result, $e->getMessage(), $e->getTraceAsString()]);
+            $this->error = 'Payment processing error';
+            return false;
+        }
+        
+        return $data;
+    }
+
+    public function notify($post)
+    {
+        $order_sn = $post['mchOrderNo'];
+
+        try {
+            // 查询订单信息
+            $order = DB::connection('write')->table('agent.dbo.order')->where('order_sn', $order_sn)->first();
+
+            if (!$order) {
+                Util::WriteLog('AiNewPay', '订单不存在');
+                return '{"success":false,"message":"订单不存在"}';
+            }
+
+            if ((!empty($order->pay_at) || !empty($order->finished_at))) {
+                return 'success';
+            }
+
+            $body = [
+                'payment_sn' => $post['orderNo'] ?? $post['channelOrderNo'] ?? '',
+                'updated_at' => date('Y-m-d H:i:s'),
+            ];
+
+            // 支付订单状态: 0-订单生成 1-支付中 2-支付成功 3-支付失败 4-已撤销 5-已退款 6-订单关闭
+            $ordStatus = $post['state'] ??'';
+            $GiftsID = $order->GiftsID ?: '';
+            $userID = $order->user_id ?: '';
+            $AdId = $order->AdId ?: '';
+            $eventType = $order->eventType ?: '';
+            $post['amount'] = $post['realAmount']??$post['amount'];
+            $payAmt = round(intval($post['amount'])/100,2);
+
+            switch ($ordStatus) {
+                case 2:    // 支付成功
+
+                    $body['pay_status'] = 1;
+                    $body['pay_at'] = date('Y-m-d H:i:s');
+                    $body['finished_at'] = date('Y-m-d H:i:s');
+                    $body['amount'] = (int) round($payAmt * NumConfig::NUM_VALUE);
+                    $config = (new PayConfig())->getConfig('AiNewPay');
+                    $body['payment_fee']=$body['amount']*$config['payin_fee'];
+                    try {
+                        $service = new OrderServices();
+
+                        if (intval($order->amount) != $body['amount']) {
+                            $body['GiftsID'] = 0;
+                            $body['amount'] = (int) round($payAmt * NumConfig::NUM_VALUE);
+                            $Recharge = $payAmt;
+                            $give = 0;
+                            $favorable_price = $Recharge + $give;
+                            $czReason = 1;
+                            $cjReason = 45;
+                        } else {
+                            [$give, $favorable_price, $Recharge, $czReason, $cjReason] = $service->getPayInfo($GiftsID, $userID, $payAmt);
+                        }
+
+                        [$Score] = $service->addRecord($userID, $payAmt, $favorable_price, $order_sn, $GiftsID, $Recharge, $czReason, $give, $cjReason, $AdId, $eventType);
+                        Order::dispatch([$userID, $payAmt, $Score, $favorable_price, $GiftsID, $order_sn]);
+
+                    }catch (\Exception $exception) {
+                        Util::WriteLog("AiNewPay_error", $exception->getMessage());
+                    }
+
+                    break;
+                case 3:    // 支付失败
+                    $body['pay_status'] = 2;
+                    $apply_data['is_error'] = 1;
+                    break;
+            }
+
+            $order_up = DB::connection('write')->table('agent.dbo.order')
+                ->where('order_sn', $order_sn)
+                ->update($body);
+
+            if (($order_up) != true) {
+                Util::WriteLog('AiNewPay','订单更新失败');
+                return '{"success":false,"message":"商户自定义出错信息"}';
+            }
+
+            Util::WriteLog("AiNewPay", 'success');
+
+            return 'success';
+
+
+        } catch (\Exception $exception) {
+            Util::WriteLog("AiNewPay_error", $exception->getMessage());
+            throw $exception;
+        }
+    }
+}

+ 16 - 1
app/Http/logic/api/AiPayCashierLogic.php

@@ -70,9 +70,24 @@ class AiPayCashierLogic implements CashierInterFace
 
         if (isset($data['code']) && (int)$data['code'] === 0) {
             return $data;
+        }else{
+            if ($query->State == 5) {
+                // 同步失败,发送邮件给玩家,退还金币
+                $msg = 'Withdraw Fail';
+                $WithDraw = $query->WithDraw + $query->ServiceFee;
+                $bonus = '30000,' . $WithDraw;
+
+                PrivateMail::failMail($query->UserID, $OrderId, $WithDraw, $msg, $bonus);
+
+                $withdraw_data = ['State' => 6, 'agent' => 1043, 'finishDate' => now(),'remark' => json_encode($data)];
+                DB::connection('write')->table('QPAccountsDB.dbo.OrderWithDraw')->where('OrderId', $query->OrderId)->update($withdraw_data);
+
+                $RecordData = ['after_state' => 6, 'update_at' => now()];
+                DB::connection('write')->table('QPAccountsDB.dbo.AccountsRecord')->where('type', 1)->where('RecordID', $RecordID)->update($RecordData);
+            }
+            return 'fail';
         }
 
-        return 'fail';
     }
 
     public function notify($post)

+ 12 - 2
app/Http/logic/api/WDPayCashierLogic.php

@@ -112,7 +112,7 @@ class WDPayCashierLogic implements CashierInterFace
 
                 $withdraw_data = [
                     'State' => 6, 
-                    'agent' => $this->agent, 
+                    'agent' => 1040,
                     'finishDate' => now(),
                     'remark' => json_encode($data)
                 ];
@@ -280,11 +280,18 @@ class WDPayCashierLogic implements CashierInterFace
     private function curlPost($url, $payload)
     {
         $timeout = 20;
+
         // WDPay使用 application/x-www-form-urlencoded 格式
         $data = http_build_query($payload);
-        
+
+        // ✅ 加上真实 User-Agent
+        $userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) '
+            . 'AppleWebKit/537.36 (KHTML, like Gecko) '
+            . 'Chrome/120.0.0.0 Safari/537.36';
+
         $headers = [
             'Content-Type: application/x-www-form-urlencoded; charset=UTF-8',
+            'User-Agent: ' . $userAgent,
         ];
 
         $ch = curl_init();
@@ -298,6 +305,9 @@ class WDPayCashierLogic implements CashierInterFace
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
         curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
 
+        // ✅ 再保险:显式设置 CURLOPT_USERAGENT(防代理/转发丢失)
+        curl_setopt($ch, CURLOPT_USERAGENT, $userAgent);
+
         $result = curl_exec($ch);
         $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
 

+ 1 - 1
app/Http/logic/api/WiwiPayCashierLogic.php

@@ -94,7 +94,7 @@ class WiwiPayCashierLogic implements CashierInterFace
 
                 PrivateMail::failMail($query->UserID, $OrderId, $WithDraw, $msg, $bonus);
 
-                $withdraw_data = ['State' => 6, 'agent' => $this->agent, 'finishDate' => now(),'remark' => json_encode($data)];
+                $withdraw_data = ['State' => 6, 'agent' => 1039, 'finishDate' => now(),'remark' => json_encode($data)];
                 DB::connection('write')->table('QPAccountsDB.dbo.OrderWithDraw')->where('OrderId', $query->OrderId)->update($withdraw_data);
                 
                 $RecordData = ['after_state' => 6, 'update_at' => now()];

+ 93 - 0
app/Services/AiNewPay.php

@@ -0,0 +1,93 @@
+<?php
+
+namespace App\Services;
+
+use App\Util;
+
+class AiNewPay
+{
+    public $config;
+    public $key;
+    public $mchNo;
+    public $apiUrl;
+
+    public function __construct()
+    {
+        $payConfigService = new PayConfig();
+        $this->config = $payConfigService->getConfig('AiNewPay');
+        
+        $this->key = $this->config['key'] ?? '';
+        $this->mchNo = $this->config['mchNo'] ?? '';
+        $this->apiUrl = $this->config['apiUrl'];
+    }
+
+    /**
+     * 签名
+     */
+    public function sign(array $params): array
+    {
+        return PayUtils::sign($params, $this->key);
+    }
+
+    /**
+     * 验签
+     */
+    public function verifySign(array $params): bool
+    {
+        return PayUtils::verifySign($params, $this->key);
+    }
+
+    /**
+     * 生成随机字符串
+     */
+    public function getNonceStr($length = 16): string
+    {
+        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
+        $str = "";
+        for ($i = 0; $i < $length; $i++) {
+            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
+        }
+        return $str;
+    }
+
+    /**
+     * POST请求
+     */
+    public function curlPost($url, $payload)
+    {
+        $timeout = 20;
+        $data = json_encode($payload, JSON_UNESCAPED_UNICODE);
+        
+        $headers = [
+            'Content-Type: application/json',
+        ];
+
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($ch, CURLOPT_POST, 1);
+        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
+        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
+        curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
+        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
+
+        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
+        $result = curl_exec($ch);
+
+        if (curl_errno($ch)) {
+            $error = curl_error($ch);
+            Util::WriteLog('AiNewPay_error', 'CURL Error: ' . $error);
+            curl_close($ch);
+            return false;
+        }
+
+        if (strstr($result, 'code') || $httpCode != 200) {
+//            Util::WriteLog('AiNewPay_error', 'error_state_' . $httpCode . "|" . $result);
+        }
+
+        curl_close($ch);
+        return $result;
+    }
+}

+ 4 - 0
app/Services/CashService.php

@@ -8,6 +8,7 @@ use App\Http\logic\api\WDPayCashierLogic;
 use App\Http\logic\api\CoinPayCashierLogic;
 use App\Http\logic\api\AiPayCashierLogic;
 use App\Http\logic\api\PagYeepPayCashierLogic;
+use App\Http\logic\api\AiNewPayCashierLogic;
 
 
 class CashService
@@ -32,6 +33,9 @@ class CashService
             case PagYeepPayCashierLogic::AGENT:
                 return new PagYeepPayCashierLogic();
 
+            case AiNewPayCashierLogic::AGENT:
+                return new AiNewPayCashierLogic();
+
         }
     }
 }

+ 4 - 0
app/Services/PayMentService.php

@@ -14,6 +14,7 @@ use App\Http\Controllers\Api\WDPayController;
 use App\Http\Controllers\Api\CoinPayController;
 use App\Http\Controllers\Api\AiPayController;
 use App\Http\Controllers\Api\PagYeepPayController;
+use App\Http\Controllers\Api\AiNewPayController;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Redis;
@@ -40,6 +41,9 @@ class PayMentService
             case 'PagYeepPay':
                 return new PagYeepPayController();
 
+            case 'AiNewPay':
+                return new AiNewPayController();
+
             case 'apple':
                 return new AppleStorePayController();
 

+ 5 - 0
routes/api.php

@@ -304,6 +304,11 @@ Route::any('/wiwipay/notify', 'Api\WiwiPayController@notify');
 Route::any('/wiwipay/payout_notify', 'Api\WiwiPayController@cash_notify');
 Route::any('/wiwipay/return', 'Api\WiwiPayController@sync_notify');
 
+// AiNewPay支付渠道
+Route::any('/ainewpay/notify', 'Api\AiNewPayController@notify');
+Route::any('/ainewpay/payout_notify', 'Api\AiNewPayController@cash_notify');
+Route::any('/ainewpay/return', 'Api\AiNewPayController@sync_notify');
+
 // WDPay支付渠道
 Route::any('/wdpay/notify', 'Api\WDPayController@notify');
 Route::any('/wdpay/payout_notify', 'Api\WDPayController@cash_notify');