From 421844895e93f952df0de601e0f8e4456eb0ad7f Mon Sep 17 00:00:00 2001 From: yinjianm Date: Thu, 19 Mar 2026 20:29:26 +0800 Subject: [PATCH] fix(payment): validate and filter unavailable methods Filter user-visible payment methods to only include supported providers and fail fast when a payment record or plugin cannot be resolved. This prevents invalid payment options from being returned by the API and avoids constructing an undefined fallback payment class. --- .../Controllers/V1/User/OrderController.php | 8 ++- app/Services/PaymentService.php | 53 ++++++++++++------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/app/Http/Controllers/V1/User/OrderController.php b/app/Http/Controllers/V1/User/OrderController.php index 9f90da1..d3ef8c0 100755 --- a/app/Http/Controllers/V1/User/OrderController.php +++ b/app/Http/Controllers/V1/User/OrderController.php @@ -173,6 +173,8 @@ class OrderController extends Controller public function getPaymentMethod() { + $availableMethods = array_flip(PaymentService::getAllPaymentMethodNames()); + $methods = Payment::select([ 'id', 'name', @@ -183,7 +185,11 @@ class OrderController extends Controller ]) ->where('enable', 1) ->orderBy('sort', 'ASC') - ->get(); + ->get() + ->filter(function ($payment) use ($availableMethods) { + return isset($availableMethods[$payment->payment]); + }) + ->values(); return $this->success($methods); } diff --git a/app/Services/PaymentService.php b/app/Services/PaymentService.php index 249be8a..9953522 100644 --- a/app/Services/PaymentService.php +++ b/app/Services/PaymentService.php @@ -13,7 +13,6 @@ class PaymentService protected $config; protected $payment; protected $pluginManager; - protected $class; public function __construct($method, $id = NULL, $uuid = NULL) { @@ -24,36 +23,50 @@ class PaymentService return; } + $payment = null; if ($id) { - $payment = Payment::find($id)->toArray(); + $payment = Payment::find($id); } - if ($uuid) { - $payment = Payment::where('uuid', $uuid)->first()->toArray(); + if (!$payment && $uuid) { + $payment = Payment::where('uuid', $uuid)->first(); + } + if (($id || $uuid) && !$payment) { + throw new ApiException(__('Payment method is not available')); } $this->config = []; - if (isset($payment)) { - $this->config = is_string($payment['config']) ? json_decode($payment['config'], true) : $payment['config']; - $this->config['enable'] = $payment['enable']; - $this->config['id'] = $payment['id']; - $this->config['uuid'] = $payment['uuid']; - $this->config['notify_domain'] = $payment['notify_domain'] ?? ''; + if ($payment) { + $config = $payment->config; + $this->config = is_string($config) ? json_decode($config, true) : ($config ?? []); + if (!is_array($this->config)) { + $this->config = []; + } + $this->config['enable'] = $payment->enable; + $this->config['id'] = $payment->id; + $this->config['uuid'] = $payment->uuid; + $this->config['notify_domain'] = $payment->notify_domain ?? ''; } $paymentMethods = $this->getAvailablePaymentMethods(); - if (isset($paymentMethods[$this->method])) { - $pluginCode = $paymentMethods[$this->method]['plugin_code']; - $paymentPlugins = $this->pluginManager->getEnabledPaymentPlugins(); - foreach ($paymentPlugins as $plugin) { - if ($plugin->getPluginCode() === $pluginCode) { - $plugin->setConfig($this->config); - $this->payment = $plugin; - return; - } + if (!isset($paymentMethods[$this->method])) { + throw new ApiException(__('Payment method is not available')); + } + + $pluginCode = $paymentMethods[$this->method]['plugin_code'] ?? null; + if (!$pluginCode) { + throw new ApiException(__('Payment method is not available')); + } + + $paymentPlugins = $this->pluginManager->getEnabledPaymentPlugins(); + foreach ($paymentPlugins as $plugin) { + if ($plugin->getPluginCode() === $pluginCode) { + $plugin->setConfig($this->config); + $this->payment = $plugin; + return; } } - $this->payment = new $this->class($this->config); + throw new ApiException(__('Payment method is not available')); } public function notify($params)