The service provider you always end up writing

Every service eventually needs the same provider: bind the interfaces, register the client with its credentials, and set up whatever the framework does not do on its own.

final class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        $this->app->singleton(PaymentGateway::class, function ($app) {
            return new StripeGateway(
                $app->make(ClientInterface::class),
                config('services.stripe.key')
            );
        });

        $this->app->bind(OrderRepository::class, EloquentOrders::class);
    }
}

register may only bind — touching another service in there is the classic source of an ordering bug, because the other provider may not have run. boot runs after all providers are registered and is where anything with a dependency belongs. Keeping the singleton closure free of side effects matters more than it looks: it runs on first resolution, which in a queue worker may be an hour into the process.