akaunting/module-offline-payments
An Akaunting module that adds offline payment methods like cash, bank transfer, and cheque to invoices, helping businesses record manual payments and reconcile transactions without an online payment gateway.
Install into an Akaunting host app — this is a module, not a standalone package. Drop it into modules/OfflinePayments (or composer require akaunting/module-offline-payments if you use the private repo), then run:
php artisan module:enable offline-payments
php artisan module:publish offline-payments
php artisan optimize:clear
Enabling is the step people most often skip; without it, module.json isn't registered and the payment methods never appear.
Look here first — module.json (slug, version, providers), Providers/Main.php (config merge, view/translation namespace), Providers/Event.php (event listeners), Config/payments.php (the actual list of offline methods exposed to the UI), and Routes/ (admin.php for settings screens, portal.php for customer-facing use).
First useful scenario — open any invoice in the Akaunting UI → Add Payment → the modal's payment method dropdown now includes the offline methods this module registers (typically Cash, Bank Transfer, Cheque, Other). Recording one writes a Payment row against the invoice with payment_method set to the configured slug; no gateway is contacted. That's the whole value proposition: an audit trail for money received outside the app.
'cash' / 'bank_transfer'. Read from the merged config (config('payments.methods') or the module's config key) so future methods added via settings automatically show up in your reports and dropdowns.payments.methods. If you need extra fields (e.g. cheque number), listen to the payment-created event and store them in a related table rather than altering the module's migration.App\Events\Invoice\PaymentCreated, PaymentDeleted) inside your own module's Providers/Event.php. Offline payments still fire these, which makes them a good integration point for ERP sync, receipting, or ledger exports — you get "payment happened" signals without dealing with a gateway callback.offline-payments::). Publish views and override under resources/views/vendor/offline-payments/ in the host app to relabel methods, reformat the settings screen, or hide methods per company.Routes/admin.php are the place to hook extra configuration (default method, per-company toggles). Follow the existing controller/request structure so permission checks and validation stay consistent.module:enable + php artisan optimize:clear is mandatory. A stale bootstrap/cache or config cache is the #1 reason methods "disappear" from the dropdown.Payment record by their config key. Renaming a method's key later will orphan historical rows — keep keys stable and only change labels/translations.Resources/lang (or lang/), keyed by method. If a method shows as a raw key in the UI, the host locale file is missing or the module's namespace isn't registered.composer.json and re-test after each Akaunting core upgrade, since module APIs (providers, event names) shift between major versions.How can I help you explore Laravel packages today?