Tree il y a 2 mois
Parent
commit
b981cbbf46

+ 1 - 1
app/Http/Controllers/Api/AegPayController.php

@@ -12,7 +12,7 @@ use Illuminate\Support\Facades\Log;
 
 class AegPayController implements PayMentInterFace
 {
-    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIp, $AdId, $eventType)
+    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIp, $AdId, $eventType, $pay_method = '')
     {
         $logic = new AegPayLogic();
         $res = $logic->pay_order($userId, $payAmt, $userPhone, $userEmail, $userName, $GiftsID, $buyIp, $AdId, $eventType);

+ 1 - 1
app/Http/Controllers/Api/CryptoController.php

@@ -19,7 +19,7 @@ use Illuminate\Support\Facades\Redis;
 class CryptoController implements PayMentInterFace
 {
     private $retryTimes=0;
-    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType)
+    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method = '')
     {
 
         $logic = new CryptoLogic();

+ 1 - 1
app/Http/Controllers/Api/GoopagoController.php

@@ -20,7 +20,7 @@ use Illuminate\Support\Facades\Redis;
 class GoopagoController implements PayMentInterFace
 {
     private $retryTimes=0;
-    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType)
+    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method = '')
     {
 
         $logic = new GoopagoLogic();

+ 3 - 2
app/Http/Controllers/Api/PaymentEntryController.php

@@ -22,6 +22,7 @@ class PaymentEntryController {
         $userEmail = $request->input('userEmail');
         $userPhone = $request->input('userPhone');
         $pay_type = (int)$request->input('pay_type');
+        $pay_method = $request->input('pay_method', '');
         $GiftsID = (int)$request->input('GiftsID');
         $AdId = $request->input('AdId');
         $eventType = $request->input('eventType');//俄罗斯支付传递特别参数
@@ -69,7 +70,7 @@ class PaymentEntryController {
 
         $service = PayMentService::pay_order($payServiceString);
 
-        $result = $service->pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType);
+        $result = $service->pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
 
         //出现错误,再试一次
         if($result['code']!=200&&$result['msg']!='needphone'){
@@ -91,7 +92,7 @@ class PaymentEntryController {
 
             $service = PayMentService::pay_order($payServiceString);
 
-            $result = $service->pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType);
+            $result = $service->pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
         }
 
         return $result;

+ 1 - 1
app/Http/Controllers/Api/SitoBankController.php

@@ -21,7 +21,7 @@ use Illuminate\Support\Facades\Redis;
 class SitoBankController implements PayMentInterFace
 {
     private $retryTimes=0;
-    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType)
+    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method = '')
     {
 
         $logic = new SitoBankLogic();

+ 130 - 0
app/Http/Controllers/Api/WiwiPayController.php

@@ -0,0 +1,130 @@
+<?php
+
+namespace App\Http\Controllers\Api;
+
+use App\Http\logic\api\WiwiPayLogic;
+use App\Http\logic\api\WiwiPayCashierLogic;
+use App\Inter\PayMentInterFace;
+use App\Notification\TelegramBot;
+use App\Services\WiwiPay;
+use App\Util;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Log;
+use Illuminate\Support\Facades\Redis;
+
+class WiwiPayController implements PayMentInterFace
+{
+    private $retryTimes = 0;
+
+    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method = '')
+    {
+        $logic = new WiwiPayLogic();
+        try {
+            $res = $logic->pay_order($userId, $payAmt, $userPhone, $userEmail, $userName, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
+        } catch (\Exception $exception) {
+            Redis::set("PayErro_WiwiPay", 1);
+            Redis::expire("PayErro_WiwiPay", 600);
+            Util::WriteLog('WiwiPay_error', $exception->getMessage() . json_encode($logic->result ?? []));
+
+            TelegramBot::getDefault()->sendProgramNotify("WiwiPay Except ", $exception->getMessage(), $exception);
+            return apiReturnFail($logic->getError());
+        }
+
+        if (!empty($res) && isset($res['status']) && $res['status'] > 0) {
+            $data = [
+                'content' => urldecode($res['payUrl'] ?? $res['url'] ?? ''),
+                'money' => $payAmt,
+                'prdOrdNo' => $res['mchOrderNo'],
+            ];
+            return apiReturnSuc($data);
+        } else if ($res == false) {
+            return apiReturnFail($logic->getError());
+        } else {
+            if ($this->retryTimes > 0) {
+                Redis::set("PayErro_WiwiPay", 1);
+                Redis::expire("PayErro_WiwiPay", 600);
+                TelegramBot::getDefault()->sendProgramNotify("WiwiPay 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('WiwiPay', "WiwiPay回调订单\n" . $payload);
+
+        $service = new WiwiPay();
+        
+        try {
+            $verify = $service->verifySign($post);
+        } catch (\Exception $e) {
+            Util::WriteLog('WiwiPay', '验签失败:' . $e->getMessage());
+            return 'fail';
+        }
+
+        if (!$verify) {
+            Util::WriteLog('WiwiPay', '签名错误');
+            return 'fail';
+        }
+
+        $order_sn = @$post['mchOrderNo'];
+        $logic = new WiwiPayLogic();
+        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_WiwiPay", 1);
+            Redis::expire("PayErro_WiwiPay", 600);
+            TelegramBot::getDefault()->sendProgramNotify("WiwiPay 订单回调执行 异常 ", json_encode($post), $exception);
+            Util::WriteLog("WiwiPay_error", $post);
+            return '{"success":false,"message":"商户自定义出错信息"}';
+        }
+    }
+
+    public function sync_notify(Request $request)
+    {
+        Log::info('WiwiPay同步回调');
+        echo 'WiwiPay同步回调';
+    }
+
+    // 提现异步回调
+    public function cash_notify(Request $request)
+    {
+        $post = $request->all();
+        $payload = json_encode($post);
+
+        Util::WriteLog('WiwiPay', "WiwiPay cash 异步回调\n" . $payload);
+
+        $service = new WiwiPay();
+        
+        try {
+            $verify = $service->verifySign($post);
+        } catch (\Exception $e) {
+            Util::WriteLog('WiwiPay cash', '验签失败:' . $e->getMessage());
+            return 'fail';
+        }
+
+        if (!$verify) {
+            Util::WriteLog('WiwiPay cash', '签名错误');
+            return 'fail';
+        }
+
+        $logic = new WiwiPayCashierLogic();
+        try {
+            return $logic->notify($post);
+        } catch (\Exception $exception) {
+            TelegramBot::getDefault()->sendProgramNotify("WiwiPay 提现异步回调执行 异常 ", json_encode($post), $exception);
+            Util::WriteLog("WiwiPay_error", $post);
+            return '{"success":false,"message":"商户自定义出错信息"}';
+        }
+    }
+}

+ 3 - 18
app/Http/Controllers/Game/PaymentEntryController.php

@@ -22,7 +22,8 @@ class PaymentEntryController {
         $userName = $request->input('userName');
         $userEmail = $request->input('userEmail');
         $userPhone = $request->input('userPhone');
-        $pay_type = (int)$request->input('pay_type');
+        $pay_type = (int)$request->input('pay_type',28);
+        $pay_method = $request->input('pay_method', 'cashapp');
         $GiftsID = (int)$request->input('GiftsID');
         $AdId = $request->input('AdId');
         $eventType = $request->input('eventType');
@@ -33,7 +34,6 @@ class PaymentEntryController {
         $where[] = ['status', 1];
         $where[] = ['id', $pay_type];
 
-        if(env('CONFIG_24680_NFTD_99',0)==0)if($request->globalUser->Channel==99&&$GiftsID>0)return apiReturnFail(['web.payment.paytype_error','PayType ERROR']);
 
         $query = DB::table('agent.dbo.admin_configs')->where($where)->value('config_key');
 
@@ -43,29 +43,14 @@ class PaymentEntryController {
         $channel = $request->globalUser->Channel;
         $payServiceString = PayMentService::getServiceByPayMethod($query, $channel);
 
-        if(env('CONFIG_24680_CURRENCY','')=='BRL') {
-            //探测cpf是否存在
-            $info = DB::table(TableName::QPAccountsDB() . 'AccountWithDrawInfo')
-                ->where('UserID', $userId)
-                ->select('PixNum')
-                ->first();
-            $cpf = $info->PixNum ?? "";
-            if (empty($cpf)) {
-                $paychannel = DB::table('agent.dbo.admin_configs')->where('status', 1)->where('sort', '>', 0)->where('cpf_first', 0)->where('type', 'pay')->select('config_key')->first();
-                if ($paychannel) {
-                    $payServiceString = $paychannel->config_key;
-                }
-//            select * from admin_configs where status=1 and sort>0 and cpf_first=0 and type='pay'
-            }
 
-        }
         Log::info('channel', [
             'string' => $payServiceString
         ]);
         $service = PayMentService::pay_order($payServiceString);
 
         if(isset($AdId)&&!empty($AdId))Redis::set('user_ad_'.$userId,$AdId);
-        $result = $service->pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType);
+        $result = $service->pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID, $buyIP, $AdId, $eventType, $pay_method);
         return $result;
     }
     // 新支付总入口---区分签名

+ 131 - 0
app/Http/logic/api/WiwiPayCashierLogic.php

@@ -0,0 +1,131 @@
+<?php
+
+namespace App\Http\logic\api;
+
+use App\Http\helper\NumConfig;
+use App\Inter\CashierInterFace;
+use App\Models\PrivateMail;
+use App\Services\WiwiPay;
+use App\Services\PayConfig;
+use App\Util;
+use Illuminate\Support\Facades\DB;
+use Illuminate\Support\Facades\Log;
+
+class WiwiPayCashierLogic implements CashierInterFace
+{
+    const AGENT = 99; // 需要根据实际情况修改
+    protected $agent = 99;
+
+    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';    // 订单不存在
+
+        $service = new WiwiPay();
+        $config = $service->config;
+
+        // 构建提现请求参数
+        $params = [
+            "mchNo" => $service->mchNo,
+            "mchOrderNo" => $OrderId,
+            "amount" => intval($amount),
+            "currency" => $config['currency'] ?? "usd",
+            "accountName" => $accountName,
+            "accountNo" => $phone, // 根据实际情况调整
+            "notifyUrl" => $config['cashNotify'] ?? $config['notify'] ?? '',
+            "timestamp" => round(microtime(true) * 1000),
+            "signType" => $config['signType'] ?? "MD5"
+        ];
+
+        // 签名
+        $signedParams = $service->sign($params);
+
+        $url = $config['cash_url'] ?? $service->apiUrl;
+
+        Log::info('WiwiPay 提现参数:', $signedParams);
+        
+        try {
+            $result = $service->curlPost($url, $signedParams);
+        } catch (\Exception $exception) {
+            Log::info('WiwiPay 提现请求异常:', [$exception->getMessage()]);
+            return 'fail';
+        }
+
+        Log::info('WiwiPay 提现结果:', [$result ?? "no result"]);
+
+        try {
+            $data = \GuzzleHttp\json_decode($result, true);
+        } catch (\Exception $e) {
+            Util::WriteLog("WiwiPay_error", [$result, $e->getMessage(), $e->getTraceAsString()]);
+            return 'fail';
+        }
+
+        if (isset($data['status'])) {
+            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);
+
+                $data = [
+                    'updated_at' => date('Y-m-d H:i:s'),
+                    'State' => 5,
+                ];
+                DB::connection('write')->table('QPAccountsDB.dbo.OrderWithDraw')->where('RecordID', $RecordID)->update($data);
+            }
+            return 'fail';
+        }
+    }
+
+    public function notify($post)
+    {
+        $OrderId = $post['mchOrderNo'] ?? '';
+        
+        Util::WriteLog('WiwiPay', 'WiwiPay 提现回调:' . json_encode($post));
+
+        // 查询订单号
+        $query = DB::connection('write')->table('QPAccountsDB.dbo.OrderWithDraw')->where('OrderID', $OrderId)->first();
+        if (!$query) {
+            return 'fail';    // 订单不存在
+        }
+
+        $orderStatus = $post['status'] ?? $post['orderStatus'] ?? '';
+
+        if ($orderStatus == 'SUCCESS' || $orderStatus == 'PAID' || $orderStatus == 2) {
+            // 订单成功
+            $data = [
+                'updated_at' => date('Y-m-d H:i:s'),
+                'State' => 2,
+            ];
+            DB::connection('write')->table('QPAccountsDB.dbo.OrderWithDraw')->where('OrderID', $OrderId)->update($data);
+            
+            Util::WriteLog('WiwiPay', 'WiwiPay 提现成功:' . $OrderId);
+            return 'SUCCESS';
+        } else if ($orderStatus == 'REJECTED' || $orderStatus == 'FAILED' || $orderStatus == 3) {
+            // 订单失败,退还金币
+            $msg = 'Liquidation failure';
+            $WithDraw = $query->WithDraw + $query->ServiceFee;
+            $bonus = '30000,' . $WithDraw;
+
+            PrivateMail::failMail($query->UserID, $OrderId, $WithDraw, $msg, $bonus);
+
+            $data = [
+                'updated_at' => date('Y-m-d H:i:s'),
+                'State' => 5,
+            ];
+            DB::connection('write')->table('QPAccountsDB.dbo.OrderWithDraw')->where('OrderID', $OrderId)->update($data);
+            
+            Util::WriteLog('WiwiPay', 'WiwiPay 提现失败:' . $OrderId);
+            return 'SUCCESS';
+        } else {
+            // 处理中
+            Util::WriteLog('WiwiPay', 'WiwiPay 提现处理中:' . $OrderId . ' status:' . $orderStatus);
+            return 'SUCCESS';
+        }
+    }
+}

+ 155 - 0
app/Http/logic/api/WiwiPayLogic.php

@@ -0,0 +1,155 @@
+<?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\Services\WiwiPay;
+use App\Services\CreateLog;
+use App\Util;
+use Illuminate\Support\Facades\DB;
+
+class WiwiPayLogic 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 WiwiPay();
+        $config = $service->config;
+
+        $order_sn = CreateOrder::order_sn($userId);
+
+        // 生成订单信息
+        $logic = new OrderLogic();
+        $amount = $pay_amount * NumConfig::NUM_VALUE;
+        $logic->orderCreate($order_sn, $amount, 'WiwiPay', $userId, '', $GiftsID, $AdId, $eventType);
+
+        // 构建支付请求参数
+        $params = [
+            "mchNo" => $service->mchNo,
+            "mchOrderNo" => $order_sn,
+            "amount" => 499,
+            "currency" => $config['currency'] ?? "usd",
+            "wayCode" => !empty($pay_method) ? $pay_method : ($config['wayCode'] ?? "cashapp"),
+            "clientIp" => $buyIP,
+            "notifyUrl" => $config['notify'] ?? '',
+            "returnUrl" => $config['return'] ?? '',
+            "expiredTime" => 1800,
+            "wayParam" => [
+//                "deviceId" => $userId,
+                "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);
+        $this->result = compact('result', 'signedParams', 'url');
+        
+        Util::WriteLog('WiwiPay', 'WiwiPay支付请求' . $url . " | " . $request_extra);
+        Util::WriteLog('WiwiPay', 'WiwiPay支付结果' . $result);
+        
+        try {
+            $data = \GuzzleHttp\json_decode($result, true);
+        } catch (\Exception $e) {
+            Util::WriteLog("WiwiPay_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('WiwiPay', '订单不存在');
+                return '{"success":false,"message":"订单不存在"}';
+            }
+
+            if ((!empty($order->pay_at) || !empty($order->finished_at))) {
+                return 'SUCCESS';
+            }
+
+            $body = [
+                'payment_sn' => $post['orderNo'] ?? $post['platformOrderNo'] ?? '',
+                'updated_at' => date('Y-m-d H:i:s'),
+            ];
+
+            $apply_data = [
+                'order_id' => $order->id,
+                'payment_sn' => $post['orderNo'] ?? $post['platformOrderNo'] ?? '',
+                'payment_code' => 'WiwiPay',
+                'return' => \GuzzleHttp\json_encode($post),
+                'is_error' => 0,
+                'created_at' => date('Y-m-d H:i:s'),
+                'updated_at' => date('Y-m-d H:i:s'),
+            ];
+
+            $ordStatus = $post['status'] ?? $post['orderStatus'] ?? '';
+            $GiftsID = $order->GiftsID ?: '';
+            $userID = $order->user_id ?: '';
+            $AdId = $order->AdId ?: '';
+            $eventType = $order->eventType ?: '';
+            $payAmt = (int)($post['amount'] ?? $post['orderAmount'] ?? 0);
+
+            // 订单成功状态判断(根据实际API调整)
+            if ($ordStatus == 'SUCCESS' || $ordStatus == 2 || $ordStatus == 'PAID') {
+                $body['pay_at'] = date('Y-m-d H:i:s');
+                $body['finished_at'] = date('Y-m-d H:i:s');
+                $body['status'] = 2;
+
+                DB::connection('write')->table('agent.dbo.order')->where('id', $order->id)->update($body);
+                DB::connection('write')->table('agent.dbo.apply_record')->insert($apply_data);
+
+                // 处理订单完成后的业务逻辑
+                $logic = new OrderLogic();
+                $logic->orderFinished($order->id, $order->order_sn, $GiftsID, $userID, $AdId, $eventType, $payAmt);
+
+                return 'SUCCESS';
+            } else {
+                Util::WriteLog('WiwiPay', '订单状态异常:' . $ordStatus);
+                return '{"success":false,"message":"订单状态异常"}';
+            }
+        } catch (\Exception $exception) {
+            Util::WriteLog("WiwiPay_error", $exception->getMessage());
+            throw $exception;
+        }
+    }
+}

+ 1 - 1
app/Inter/PayMentInterFace.php

@@ -4,6 +4,6 @@ namespace App\Inter;
 
 interface PayMentInterFace
 {
-    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID,$buyIP,$AdId,$eventType);
+    public function pay_order($userId, $payAmt, $userName, $userEmail, $userPhone, $GiftsID,$buyIP,$AdId,$eventType,$pay_method='');
 
 }

+ 3 - 0
app/Services/CashService.php

@@ -14,6 +14,7 @@ use App\Http\logic\api\LQPayCashierLogic;
 use App\Http\logic\api\PPayCashierLogic;
 use App\Http\logic\api\RussiaPayCashierLogic;
 use App\Http\logic\api\SitoBankCashierLogic;
+use App\Http\logic\api\WiwiPayCashierLogic;
 use App\Http\logic\api\SmartFastColCashierLogic;
 use App\Http\logic\api\SmartFastPayCashierLogic;
 use App\Http\logic\api\SmartFastPeruCashierLogic;
@@ -45,6 +46,8 @@ class CashService
                 return new CashPayCashierLogic();
             case SitoBankCashierLogic::AGENT:
                 return new SitoBankCashierLogic();
+            case WiwiPayCashierLogic::AGENT:
+                return new WiwiPayCashierLogic();
             case AegPayCashierLogic::AGENT:
                 return new AegPayCashierLogic();
             case StanPayCashierLogic::AGENT:

+ 4 - 153
app/Services/PayMentService.php

@@ -4,36 +4,12 @@
 namespace App\Services;
 
 use App\Http\Controllers\Api\AegPayController;
-use App\Http\Controllers\Api\ApcopayController;
 use App\Http\Controllers\Api\AppleStorePayController;
-use App\Http\Controllers\Api\BetCatPayController;
-use App\Http\Controllers\Api\BPayController;
-use App\Http\Controllers\Api\CashPayController;
-use App\Http\Controllers\Api\ClickPayController;
 use App\Http\Controllers\Api\CryptoController;
-use App\Http\Controllers\Api\FastPayController;
 use App\Http\Controllers\Api\GooglePayController;
 use App\Http\Controllers\Api\GoopagoController;
-use App\Http\Controllers\Api\HHPayColController;
-use App\Http\Controllers\Api\KaroPayController;
-use App\Http\Controllers\Api\LQPayController;
-use App\Http\Controllers\Api\NicePayController;
-use App\Http\Controllers\Api\PagsmileNewPayController;
-use App\Http\Controllers\Api\PagsmilePayController;
-use App\Http\Controllers\Api\PPayController;
-use App\Http\Controllers\Api\RussiaPayController;
 use App\Http\Controllers\Api\SitoBankController;
-use App\Http\Controllers\Api\SmartFastColController;
-use App\Http\Controllers\Api\SmartFastPayController;
-use App\Http\Controllers\Api\SmartFastPeruController;
-use App\Http\Controllers\Api\StanPayController;
-use App\Http\Controllers\Api\StarpagoBDController;
-use App\Http\Controllers\Api\TopPayController;
-use App\Http\Controllers\Api\WWPayColController;
-use App\Http\Controllers\Api\DoPayController;
-use App\Http\Controllers\Api\StarpagoController;
-use App\Http\Controllers\Api\PKpayController;
-use App\Http\Controllers\Api\ALL2payController;
+use App\Http\Controllers\Api\WiwiPayController;
 use Illuminate\Support\Facades\DB;
 use Illuminate\Support\Facades\Log;
 use Illuminate\Support\Facades\Redis;
@@ -44,139 +20,14 @@ class PayMentService
     {
         switch ($transport) {
 
-//            case 'pay4':
-//                return new PagsmilePayController();
-//                break;
-//
-//            case 'pay44':
-//                return new PagsmileNewPayController();
-//                break;
 
-            case 'ClickPay':
-                return new ClickPayController();
+            case 'WiwiPay':
+                return new WiwiPayController();
 
-            case 'TopPay':
-                return new TopPayController();
-
-            case 'DoPay_EP':
-                return new DoPayController('EASYPAISA');
-
-            case 'DoPay_JC':
-                return new DoPayController('JAZZCASH');
-
-            case 'Starpago_BK':
-                return new StarpagoBDController('BKASH');
-
-            case 'Starpago_NG':
-                return new StarpagoBDController('NAGAD');
-
-            case 'Starpago_EP':
-                return new StarpagoController('EASYPAISA');
-
-            case 'Starpago_JC':
-                return new StarpagoController('JAZZCASH');
-
-            case 'PKpay_EP':
-                return new PKpayController('EASY');
-
-            case 'PKpay_JC':
-                return new PKpayController('JAZZ');
-
-            case 'ALL2pay_EP':
-                return new ALL2payController('EASYPAISA');
-
-            case 'ALL2pay_JC':
-                return new ALL2payController('JAZZCASH');
-            case 'KaroPay_EP':
-                return new KaroPayController('EASYPAISA');
-
-            case 'KaroPay_JC':
-                return new KaroPayController('JAZZCASH');
-
-            case 'CashPay':
-                return new CashPayController();
-
-            case 'SitoBank':
-                return new SitoBankController();
-
-//            case 'FastPay':
-//                return new FastPayController();
-
-//            case 'NicePay':
-//                return new NicePayController();
-
-            case 'AegPay':
-                return new AegPayController();
-
-            case 'russiaPay':
-                return new RussiaPayController();
-
-            case 'StanPay':
-                return new StanPayController();
-
-            case 'SmartFastPay':
-                return new SmartFastPayController();
-
-            case 'LQPay':
-                return new LQPayController();
-
-            case 'PPay':
-                return new PPayController();
-
-            case 'SFP_Ecuador_Wallet':
-                return new SmartFastPeruController("wallet",'EC');
-            case 'SFP_Ecuador_Bank':
-                return new SmartFastPeruController("bank_transfer",'EC');
-            case 'SFP_Ecuador_MobileMoney':
-                return new SmartFastPeruController("mobile_money",'EC');
-
-
-            case 'SFP_Chile_Wallet':
-                return new SmartFastPeruController("wallet",'CL');
-            case 'SFP_Chile_Bank':
-                return new SmartFastPeruController("bank_transfer",'CL');
-            case 'SFP_Chile_CreditCard':
-                return new SmartFastPeruController("credit_card",'CL');
-
-
-            case 'SFP_PeruPay_Wallet':
-                return new SmartFastPeruController("wallet",'PE');
-            case 'SFP_PeruPay_Bank':
-                return new SmartFastPeruController("bank_transfer",'PE');
-            case 'SFP_PeruPay_CreditCard':
-                return new SmartFastPeruController("credit_card",'PE');
-            case 'SFP_PeruPay_CIP':
-                return new SmartFastPeruController("cip",'PE');
-
-
-            case 'SFP_ColPay_Bank':
-                return new SmartFastPeruController("bancolombia",'CO');
-            case 'SFP_ColPay_Efecty':
-                return new SmartFastPeruController("efecty",'CO');
-
-            case 'SFP_ColPay_Nequi':
-                return new SmartFastColController('nequi');
-
-            case 'SFP_ColPay_Transfiya':
-                return new SmartFastColController('transfiya');
-
-            case 'SFP_ColPay_PSE':
-                return new SmartFastColController('pse');
-
-            case 'DCP_Crypto':
-                return new CryptoController();
-
-            case 'HHPay':
-                return new HHPayColController();
-
-            case 'WWPay':
-                return new WWPayColController();
-
-            case 'Apcopay':
-                return new ApcopayController();
 
             case 'apple':
                 return new AppleStorePayController();
+
             case 'google':
                 return new GooglePayController();
 

+ 128 - 0
app/Services/PayUtils.php

@@ -0,0 +1,128 @@
+<?php
+
+namespace App\Services;
+
+use Exception;
+
+class PayUtils
+{
+    /**
+     * 验证签名
+     *
+     * @param array $params 参数数组(包含 sign 和 signType)
+     * @param string $key 密钥
+     * @return bool
+     */
+    public static function verifySign(array $params, string $key): bool
+    {
+        if (!isset($params['sign']) || empty(trim($params['sign']))) {
+            throw new Exception("Missing 'sign' field in parameters.");
+        }
+
+        if (!isset($params['signType']) || empty(trim($params['signType']))) {
+            throw new Exception("Missing 'signType' field in parameters.");
+        }
+
+        $sign = strtoupper($params['sign']);
+        $signType = strtoupper($params['signType']);
+
+        // 复制参数并移除 sign 字段
+        $paramsCopy = $params;
+        unset($paramsCopy['sign']);
+
+        $expectedSign = self::getSign(self::getSignStr($paramsCopy, $key), $signType);
+        return $sign === $expectedSign;
+    }
+
+    /**
+     * 对参数进行签名
+     *
+     * @param array $params 原始参数
+     * @param string $key 密钥
+     * @return array 已签名的参数数组
+     */
+    public static function sign(array $params, string $key): array
+    {
+        if (!isset($params['signType']) || empty(trim($params['signType']))) {
+            throw new Exception("Missing 'signType' field in parameters.");
+        }
+
+        $signType = strtoupper($params['signType']);
+        $signStr = self::getSignStr($params, $key);
+        $signValue = self::getSign($signStr, $signType);
+
+        $params['sign'] = $signValue;
+        return $params;
+    }
+
+    /**
+     * 根据签名类型计算签名值
+     *
+     * @param string $signStr 待签名字符串
+     * @param string $signType 签名类型 (MD5/SHA1/SHA256)
+     * @return string
+     */
+    public static function getSign(string $signStr, string $signType): string
+    {
+        switch ($signType) {
+            case 'MD5':
+                return strtoupper(md5($signStr));
+            case 'SHA1':
+                return strtoupper(sha1($signStr));
+            case 'SHA256':
+                return strtoupper(hash('sha256', $signStr));
+            default:
+                throw new Exception("Unsupported signature type: " . $signType);
+        }
+    }
+
+    /**
+     * 构建待签名字符串(排除 sign 字段,并按 key 排序)
+     *
+     * @param array $params 参数数组
+     * @param string $key 密钥
+     * @return string
+     */
+    public static function getSignStr(array $params, string $key): string
+    {
+        $sortedParams = self::sortValueRecursively($params);
+        $items = [];
+
+        foreach ($sortedParams as $k => $v) {
+            if (strtolower($k) === 'sign') {
+                continue;
+            }
+
+            if ($v === null || (is_string($v) && trim($v) === '')) {
+                continue;
+            }
+
+            if (is_array($v)) {
+                $v = json_encode($v, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
+            }
+
+            $items[] = "{$k}={$v}";
+        }
+
+        $items[] = "key={$key}";
+        return implode('&', $items);
+    }
+
+    /**
+     * 递归排序数组或关联数组
+     *
+     * @param mixed $value
+     * @return mixed
+     */
+    public static function sortValueRecursively($value)
+    {
+        if (is_array($value)) {
+            ksort($value); // 按键排序
+            foreach ($value as &$item) {
+                $item = self::sortValueRecursively($item);
+            }
+        }
+
+        return $value;
+    }
+}

+ 106 - 0
app/Services/SitoBank.php

@@ -0,0 +1,106 @@
+<?php
+
+
+namespace App\Services;
+
+
+use App\Util;
+use http\Client\Curl\User;
+use function GuzzleHttp\Psr7\build_query;
+
+class SitoBank
+{
+
+
+    public $privateKey;
+    public $publicKey;
+
+    public $config;
+    public function __construct()
+    {
+        $payConfigService = new PayConfig();
+        $this->config = $payConfigService->getConfig('SitoBank');
+
+        $this->publicKey = '-----BEGIN PUBLIC KEY-----'."\n".chunk_split($this->config['platPublicKey'], 64, "\n").'-----END PUBLIC KEY-----';
+        $this->privateKey = '-----BEGIN PRIVATE KEY-----'."\n".chunk_split($this->config['mchPrivateKey'], 64, "\n").'-----END PRIVATE KEY-----';
+
+    }
+    public function sign($msg)
+    {
+
+        if (openssl_sign($msg, $sign, $this->privateKey, OPENSSL_ALGO_SHA256)) {
+            return $sign;
+        }
+        return false;
+    }
+
+    public function verify($msg, $sign)
+    {
+        if (openssl_verify($msg, $sign, $this->publicKey, OPENSSL_ALGO_SHA256)) {
+            return true;
+        }
+        return false;
+    }
+
+
+
+    public function getNonceStr( $length = 16 ) {
+        $chars = "abcdefghijklmnopqrstuvwxyz0123456789";
+        $str = "";
+        for ( $i = 0; $i < $length; $i++ ) {
+            $str .= substr( $chars, mt_rand( 0, strlen( $chars ) - 1 ), 1 );
+        }
+        return $str;
+    }
+
+    public function curlPost($url, $payload)
+    {
+        $timeout=20;
+        $data = json_encode($payload);
+        $sign = $this->sign($data);
+        $signB64 = base64_encode($sign);
+        $headers = [
+            'X-Signature:' . $signB64,
+            'X-Account:' . $this->config['merchantCode'],
+            'Content-Type: application/json',
+        ];
+
+
+        $ch = curl_init();
+        curl_setopt($ch, CURLOPT_URL, $url);
+        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);  // 从证书中检查SSL加密算法是否存在
+        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(strstr($result,'code')){
+            Util::WriteLog('sito_error','error_state_'.$httpCode."|".$result);
+        }
+
+
+        curl_close($ch);
+        return $result;
+    }
+
+
+
+    public function notifySign($jsonStr,$sign){
+
+        return  $this->verify($jsonStr,$sign);
+
+
+    }
+
+
+
+
+
+}
+

+ 93 - 0
app/Services/WiwiPay.php

@@ -0,0 +1,93 @@
+<?php
+
+namespace App\Services;
+
+use App\Util;
+
+class WiwiPay
+{
+    public $config;
+    public $key;
+    public $mchNo;
+    public $apiUrl;
+
+    public function __construct()
+    {
+        $payConfigService = new PayConfig();
+        $this->config = $payConfigService->getConfig('WiwiPay');
+        
+        $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('WiwiPay_error', 'CURL Error: ' . $error);
+            curl_close($ch);
+            return false;
+        }
+
+        if (strstr($result, 'code') || $httpCode != 200) {
+            Util::WriteLog('WiwiPay_error', 'error_state_' . $httpCode . "|" . $result);
+        }
+
+        curl_close($ch);
+        return $result;
+    }
+}

+ 15 - 0
config/pay.php

@@ -14,4 +14,19 @@ return [
         'cashierNotify' => env('APP_URL', '').'/api/fastpay/cash_notify',
         'agentCashierNotify' => env('APP_URL', '').'/api/fastpay/cash_notify',
     ],
+
+
+    // 新增的支付方式配置示例(如wiwipay)
+    'WiwiPay' => [
+        'key' => 'dkr3T8645AH28d81hL5722J7v72cqt6b',
+        'mchNo' => '2025109626',
+        'apiUrl' => 'https://www.wiwiusonepay.com/api/pay/create',
+        'currency' => 'usd',
+        'wayCode' => 'cashapp',
+        'signType' => 'MD5',
+        'notify' => env('APP_URL', '').'/api/wiwipay/notify',
+        'return' => env('APP_URL', '').'/api/wiwipay/return',
+        'cashNotify' => env('APP_URL', '').'/api/wiwipay/payout_notify',
+        'cash_url' => env('APP_URL', '').'/api/payout/create'
+    ]
 ];

+ 12 - 11
config/payTest.php

@@ -4,16 +4,17 @@
 
 return [
 
-    'pagsmilepay' => [
-        'cash_app_id' => 'B3F16E6841D342CA8CC2ADA6A4C33A42',    // 提现appid
-        'cashSecretKey' => 'PNLPqctvDz',                        // 提现秘钥
-        'app_id' => '16655639662902937',                        // 充值appid
-        'SecretKey' => 'Luxpag_sk_8852946307a55a9179831c8db05b40cbeb2e1a51460b3967ea007d2f70b89902', // 充值秘钥
-        'pay_url' => 'https://gateway-test.pagsmile.com',              // 充值请求url
-        'cash_url' => 'https://sandbox.transfersmile.com',          // 提现请求url
-        'notify' => 'http://spain.2v1.cn/api/Pagsmilepay/notify', // 支付异步回调
-        'syncNotify' => 'http://spain.2v1.cn/api/Pagsmilepay/sync_notify', // 支付同步回调
-        'cashierNotify' => 'http://spain.2v1.cn/api/Pagsmilepay/cash_notify'  // 提现异步回调
-    ],
+    'WiwiPay' => [
+        'key' => 'dkr3T8645AH28d81hL5722J7v72cqt6b',
+        'mchNo' => '2025109626',
+        'apiUrl' => 'https://www.wiwiusonepay.com/api/pay/create',
+        'currency' => 'usd',
+        'wayCode' => 'cashapp',
+        'signType' => 'MD5',
+        'notify' => env('APP_URL', '').'/api/wiwipay/notify',
+        'return' => env('APP_URL', '').'/api/wiwipay/return',
+        'cashNotify' => env('APP_URL', '').'/api/wiwipay/payout_notify',
+        'cash_url' => env('APP_URL', '').'/api/payout/create'
+    ]
 
 ];

+ 5 - 0
routes/api.php

@@ -286,6 +286,11 @@ Route::any('/clickpay/payout_notify', 'Api\ClickPayController@cash_notify');
 Route::any('/sitobank/notify', 'Api\SitoBankController@notify');
 Route::any('/sitobank/payout_notify', 'Api\SitoBankController@cash_notify');
 
+// WiwiPay支付渠道
+Route::any('/wiwipay/notify', 'Api\WiwiPayController@notify');
+Route::any('/wiwipay/payout_notify', 'Api\WiwiPayController@cash_notify');
+Route::any('/wiwipay/return', 'Api\WiwiPayController@sync_notify');
+
 
 Route::any('/russia/notify', 'Api\RussiaPayController@notify');
 Route::any('/russia/cash_notify', 'Api\RussiaPayController@cash_notify');