dimafe6/bank-id
Laravel package for working with BankID: send authentication/sign requests, collect results, and handle statuses. Includes configurable client setup, helpers, and examples for integrating BankID flows into your PHP app.
Installation
composer require dimafe6/bank-id
Ensure your server meets BankID’s technical requirements.
Configuration Publish the config file:
php artisan vendor:publish --provider="Dimafe6\BankId\BankIdServiceProvider"
Update .env with your BankID credentials (from BankID Developer Portal):
BANKID_CLIENT_ID=your_client_id
BANKID_CLIENT_SECRET=your_client_secret
BANKID_REDIRECT_URI=http://your-app.com/bankid/callback
First Use Case: Authentication Flow Trigger the BankID authentication in a controller:
use Dimafe6\BankId\Facades\BankId;
public function authenticate()
{
$authUrl = BankId::authenticate()->getUrl();
return redirect()->to($authUrl);
}
Handle the callback in a route:
Route::get('/bankid/callback', [BankIdController::class, 'callback']);
Process the response in the controller:
public function callback(Request $request)
{
$response = BankId::authenticate()->handleCallback($request);
if ($response->isSuccessful()) {
// User is authenticated; proceed with session/DB logic
$userData = $response->getUserData();
} else {
// Handle errors (e.g., redirect to retry or show message)
}
}
Verify Dependencies
config/bankid.php for additional settings (e.g., timeout, logging).// In a login controller
$auth = BankId::authenticate()
->setScope('authenticate') // Optional: Limit to specific scopes
->getUrl();
return redirect()->to($auth);
$response = BankId::authenticate()->handleCallback($request);
if ($response->isAuthenticated()) {
$user = User::firstOrCreate([
'email' => $response->getEmail(),
'name' => $response->getName(),
]);
auth()->login($user);
}
$signatureUrl = BankId::signature()
->setPersonalNumber('12345678901') // Optional: Pre-fill
->setData(['contract_id' => 123])
->getUrl();
return redirect()->to($signatureUrl);
$signatureResponse = BankId::signature()->handleCallback($request);
if ($signatureResponse->isSigned()) {
$contract = Contract::find($signatureResponse->getData('contract_id'));
$contract->markAsSigned();
}
$verification = BankId::verifyIdentity()
->setPersonalNumber('12345678901')
->getUrl();
return redirect()->to($verification);
$verification = BankId::verifyIdentity()->handleCallback($request);
if ($verification->isVerified()) {
$user->update(['verified_at' => now()]);
}
$request->session()->put('bankid_state', $auth->getState());
// Later, resume the flow:
$auth = BankId::authenticate()->setState($request->session()->get('bankid_state'));
BankId facade:
// In a service provider
$this->app->extend('bankid', function ($bankid) {
$bankid->setCustomParams(['theme' => 'dark']);
return $bankid;
});
Route::post('/bankid/webhook', function (Request $request) {
$event = BankId::webhook()->handle($request);
if ($event->isSignature()) {
// Process signature event
}
});
use Illuminate\Cache\RateLimiter;
RateLimiter::for('bankid', function ($request) {
return Limit::perMinute(5)->by($request->user()?->id);
});
// In controller:
if (RateLimiter::tooManyAttempts($request, 'bankid')) {
abort(429, 'Too many BankID requests');
}
Redirect URI Mismatch
invalid_redirect_uri.BANKID_REDIRECT_URI in .env exactly matches the URI registered in the BankID Developer Portal.error field in the callback response for details.State Parameter Missing
state parameter:
$auth = BankId::authenticate()->setState($request->session()->get('bankid_state'));
Personal Number Validation
personalNumber format causes failures.YYYYMMDDXXXX):
if (!preg_match('/^\d{10,12}$/', $personalNumber)) {
throw new \InvalidArgumentException('Invalid personal number');
}
Token Expiry
access_token) expire quickly.$token = BankId::authenticate()->getAccessToken();
Cache::put('bankid_token', $token, now()->addMinutes(5));
Logging and Debugging
config/bankid.php:
'debug' => env('BANKID_DEBUG', false),
\Log::debug('BankID Response', $response->toArray());
Environment-Specific Settings
.env to switch between sandbox and production:
BANKID_ENV=sandbox # or 'production'
config/bankid.php:
'environment' => env('BANKID_ENV', 'production'),
Custom Headers
BankId::setHeaders(['X-Forwarded-For' => $request->ip()]);
Timeouts
'timeout' => 30, // seconds
Custom Responses
BankIdResponse class to add domain-specific data:
namespace App\Services;
use Dimafe6\BankId\Responses\BankIdResponse;
class CustomBankIdResponse extends BankIdResponse
{
public function getContractId()
{
return $this->data['contract_id'] ?? null;
}
}
$this->app->bind(
Dimafe6\BankId\Contracts\BankIdResponse::class,
App\Services\CustomBankIdResponse::class
);
Mocking for Testing
How can I help you explore Laravel packages today?