Question: I was able to implement a `PaypalController`, with a reusable `postPayment()` method, which accepts items and their prices, and creates a Paypal payment, and redirects to a Paypal payment page.

```
class PaypalController extends Controller {

    private static $_api_context;

    private static function initialize() {
        //initialize api context
    }

    public static function postPayment($items, $currency, $description) {
        self::initialize();

        //create item list, transaction, payment objects, etc

        $payment->create(PaypalController::$_api_context);
        ...
        return redirect()->away($redirect_url); // redirect to paypal
    }
}

```

`PaypalController` is called statically by other controllers. For example, the `AuthController` might call it to request payment from the user right after the user registers to my site:

```
class AuthController extends Controller {
    public function postRegister(Request $request) {
        return PaypalController::postPayment($items, 'JPY', 'description');
    }
}

```

Basically, `PaypalController` returns a `Redirect` to `AuthController`, which also returns it, to perform the redirect to the Paypal payment page.

I was wondering if this is a good design - a controller calling a different controller, is it?

If not, what would be a better way to do this? Maybe move my code from PaypalController into custom Service Provider, or custom Helper, or something else? I am very new to Laravel, and I would appreciate some guidance.

Answer: 
No it's not a good practice. You should abstract the business logic to a service/repository class. So for example:

Create an interface as Contract:

```
namespace App\Services\Paypal;

interface PaypalInterface {

     public function PostRegister(Array $array, /*More $params if necessary*/); 
}

```

Then implement the Contract:

```
namespace App\Services\Paypal;

class PaypalService implements PaypalInterface {

    // Must match the method signature declared in the interface
    public function PostRegister(Array $array, /*$More $params if necessary*/) {

        // Do the process here
    }
}

```

Then use the contract/interface as dependency. So, in your `PaypalController` or in any other Controller you may (re)use it like:

```
namespace App\Http\Controllers;

use App\Http\Request;
use App\Services\Paypal\PaypalInterface;

class AuthController extends Controller {
    public function postPayment(Request $request, PaypalInterface $paypalService) {
        return $paypalService->postRegister($request->all());
    }
}

```

In this case, [register the binding](https://laravel.com/docs/5.2/container#binding) (interface to implementation) in a service provider (Basically in `AppServiceProvider`). That's the basic workflow. Why an interface because, Controllers (Client/Consumer classes) should talk to Contract/Interface instead of a concrete implementation.

[This article of mine may help you](http://heera.it/laravel-repository-pattern) but remember this is not the 100% decoupled, it's still coupled with `Laravel` framework and you can even more decouple the Service.

---

*Note: It's a best practice but don't blindly follow this approach for every projects/problems, just chose wisely when you should do it, it really depends on the context but don't just die for it. The current context is fine to follow this.*
This is not the right way to do it. Rember, controllers should only take a request and dispatch it to the right service, not handle buisness logic by themselves. 

This rule apply: when you need to call a controller method from another controller it smells of bad code

Instead, use a service provider and a service class to handle your paypal logic. The service class will handle the paypal logic and will be used later when you'll need it in the controllers:

```
//SERVICE CLASS
class PayPalService
{
    public function processPayment(){ //... }
}

```

The service provider is used to register the service class in the application: your're telling Laravel that when you'll need a `PayPalService` it should build and return it for you

```
//SERVICE PROVIDER: binds the creation of the service in the ioc container
class PayPalServiceProvider extends ServiceProvider
{
    public function register()
    {
        //use singleton or bind to bind the service in the ioc container
        $this->app->singleton( PayPalService::class, function()
        {
            return new PayPalService();
        });
    }
}

```

Then, when you need the `PayPalService` class you should let Laravel inject the service automatically in your controllers:

```
class AuthController extends Controller 
{   
    public function postRegister(Request $request, PayPalService $paypal) {
        return $paypal->processPayment();
    }
}

```

If you want, You could further improve this design by using an interface for the service class