You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel新手求助:如何在SmartpaySController调用PaymentController方法

How to Call getPaymentFailed from SmartpaySController in Laravel

Hey there! Since you're new to Laravel, let's walk through a couple of ways to call that method from your SmartpaySController—including a best practice that'll keep your code clean and maintainable in the long run.


You can instantiate the PaymentController and call the method directly, but you'll want to use Laravel's service container to handle any dependency injection (like your paymentRepo and quoteRepo):

use App\Http\Controllers\PaymentController;

class SmartpaySController extends Controller
{
    public function handlePaymentFailure($paymentId)
    {
        // Let Laravel's container resolve the controller with its dependencies
        $paymentController = app(PaymentController::class);
        return $paymentController->getPaymentFailed($paymentId);
    }
}

Note:

This works for quick tests, but it's not ideal long-term. Controllers are meant to handle HTTP requests directly—calling their methods from other controllers creates tight coupling and makes your code harder to test and maintain.


The better approach is to pull the business logic out of your controller into a reusable service class. This way, both PaymentController and SmartpaySController can use the same logic without duplicating code.

Step 1: Create a Payment Service

Make a new file app/Services/PaymentService.php:

namespace App\Services;

use App\Repositories\PaymentRepository;
use App\Repositories\QuoteRepository;
use Illuminate\Http\Response;

class PaymentService
{
    protected $paymentRepo;
    protected $quoteRepo;

    // Inject your repositories via constructor
    public function __construct(PaymentRepository $paymentRepo, QuoteRepository $quoteRepo)
    {
        $this->paymentRepo = $paymentRepo;
        $this->quoteRepo = $quoteRepo;
    }

    // Extract the logic from getPaymentFailed here
    public function getPaymentFailedData($paymentId)
    {
        $transactionData = $this->paymentRepo->find($paymentId);

        if (!$transactionData) {
            // Handle missing transaction (e.g., return 404)
            abort(Response::HTTP_NOT_FOUND, 'Transaction not found');
        }

        return [
            'quote' => $this->quoteRepo->getQuoteById($transactionData->quote_id),
            'metaTitle' => 'Payment failed',
            'returnMessage' => $transactionData->return_message
        ];
    }
}

Step 2: Update PaymentController to Use the Service

Modify your PaymentController to inject the service and use its method:

use App\Services\PaymentService;

class PaymentController extends Controller
{
    protected $paymentService;

    public function __construct(PaymentService $paymentService)
    {
        $this->paymentService = $paymentService;
    }

    public function getPaymentFailed($paymentId)
    {
        $data = $this->paymentService->getPaymentFailedData($paymentId);
        return view('payment::payment.quote_payment_failed', $data);
    }
}

Step 3: Use the Service in SmartpaySController

Now you can easily reuse the same logic in SmartpaySController:

use App\Services\PaymentService;

class SmartpaySController extends Controller
{
    protected $paymentService;

    public function __construct(PaymentService $paymentService)
    {
        $this->paymentService = $paymentService;
    }

    public function processSmartpayFailure($paymentId)
    {
        // Get the payment failure data from the service
        $data = $this->paymentService->getPaymentFailedData($paymentId);

        // Either return the same view as PaymentController...
        return view('payment::payment.quote_payment_failed', $data);

        // ...or use the data to render a different view for Smartpay
        // return view('smartpay.payment_failed', $data);
    }
}

Why This Is Better:

  • Single Responsibility: Controllers handle HTTP requests, services handle business logic.
  • Reusability: Any other controller or class can use this service later without duplicating code.
  • Testability: Service classes are easier to unit test than controller methods tied to HTTP requests.

Option 3: Redirect to the PaymentController Route (If Applicable)

If you've already defined a route for getPaymentFailed, you can just redirect to that route instead of calling the method directly:

First, make sure your route exists in routes/web.php or routes/api.php:

Route::get('/payment/failed/{paymentId}', [PaymentController::class, 'getPaymentFailed'])->name('payment.failed');

Then in SmartpaySController:

public function redirectToFailurePage($paymentId)
{
    return redirect()->route('payment.failed', ['paymentId' => $paymentId]);
}

This is great if you just need to send the user to the existing payment failure page without modifying the logic.


内容的提问来源于stack exchange,提问作者Mayuri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:22:47