beziworld / laravel-imoje
imoje (ING Pay) payment gateway for Laravel: payment links, transactions, BLIK, refunds and signed notifications.
Requires
- php: ^8.3
- ext-json: *
- guzzlehttp/guzzle: ^7.8
- illuminate/contracts: ^12.0|^13.0
- illuminate/http: ^12.0|^13.0
- illuminate/routing: ^12.0|^13.0
- illuminate/support: ^12.0|^13.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.18
- orchestra/testbench: ^10.0|^11.0
- pestphp/pest: ^3.7|^4.0
- pestphp/pest-plugin-laravel: ^3.0|^4.0
- phpstan/phpstan-strict-rules: ^2.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-04 16:36:31 UTC
README
imoje (now ING Pay) payment gateway for Laravel: payment links, direct transactions
including BLIK level 0, refunds, signed paywall forms and notifications verified with X-Imoje-Signature.
Uses the current pay.ing.pl hosts.
Installation
composer require beziworld/laravel-imoje
php artisan vendor:publish --tag=imoje-config # optional
IMOJE_MERCHANT_ID=your-merchant-id IMOJE_SERVICE_ID=63f574ed-d4ad-407e-9981-39ed7584a7b7 IMOJE_SERVICE_KEY=your-service-key IMOJE_TOKEN=your-api-token IMOJE_SANDBOX=true
All values are in the panel under Shops > Details > Integration data. The notification URL defaults to the package
route /imoje/notification.
Payment link (recommended)
use Beziworld\Imoje\Data\Customer; use Beziworld\Imoje\Data\PaymentRequest; use Beziworld\Imoje\Facades\Imoje; $payment = Imoje::createPayment(new PaymentRequest( amount: $order->total_in_grosze, orderId: $order->number, customer: new Customer($order->first_name, $order->last_name, $order->email), title: "Order {$order->number}", successReturnUrl: route('orders.thank-you', $order), failureReturnUrl: route('orders.show', $order), )); return redirect()->away($payment->url);
BLIK level 0 and direct transactions
use Beziworld\Imoje\Data\TransactionRequest; $transaction = Imoje::createTransaction(TransactionRequest::blik( amount: 4999, orderId: $order->number, customer: new Customer('Jan', 'Kowalski', 'jan@example.com'), blikCode: $request->input('blik_code'), clientIp: $request->ip(), successReturnUrl: route('orders.thank-you', $order), failureReturnUrl: route('orders.show', $order), )); // The buyer confirms in the banking app; the result arrives as a notification. // A specific bank: redirect when the API asks for it $transaction = Imoje::createTransaction(new TransactionRequest(4999, $order->number, $customer, 'pbl', 'ipko', $okUrl, $failUrl)); if ($url = $transaction->redirectUrl()) { return redirect()->away($url); }
Notifications
use Beziworld\Imoje\Events\TransactionSettled; Event::listen(function (TransactionSettled $event) { $order = Order::where('number', $event->transaction->orderId)->firstOrFail(); if (! $order->isPaid() && $event->transaction->amount === $order->total_in_grosze) { $order->markAsPaid(imojeTransactionId: $event->transaction->id); } });
Other events: TransactionStatusChanged (every transaction, including refunds) and PaymentStatusChanged (payment
link expired or cancelled). The signature (SHA-224/256/384/512) is checked over the raw body together with the
merchant and service id. imoje repeats notifications, so keep listeners idempotent.
Refunds and lookups
Imoje::refund($transactionId, 2500, 'Return'); // minor units; wait 5 s between refunds of one transaction Imoje::transaction($transactionId)->status; // TransactionStatus::Settled Imoje::payment($paymentId);
Paywall form without the REST token
$fields = Imoje::paywallFields([ 'amount' => '4999', 'currency' => 'PLN', 'orderId' => $order->number, 'customerFirstName' => 'Jan', 'customerLastName' => 'Kowalski', 'customerEmail' => 'jan@example.com', 'urlSuccess' => $okUrl, 'urlFailure' => $failUrl, ]); // POST $fields to Imoje::paywallUrl()
Exceptions
ApiException (errorCode() such as TRX-ERROR-120001, errors(), isTemporary() for HTTP 500/503/504 when the
channel is temporarily unavailable) and InvalidConfiguration, both extending ImojeException.
Development
composer install
composer ci # pint --test, phpstan (level 8), pest
Author
Created and maintained by Kamil Ćwiertnia, beziworld.eu.
- E-mail: biuro@beziworld.eu
- Issues: GitHub issues
- Security vulnerabilities: see SECURITY.md
Need help integrating payments in your shop? Get in touch through beziworld.eu.
Other packages by the author
laravel-przelewy24 · laravel-payu · laravel-paynow · laravel-tpay · laravel-autopay
License
MIT. See LICENSE.md. This package is not affiliated with ING Bank Śląski S.A.