Development
Extending Paybob
The three kinds of packages you can build, and what they have in common.
Paybob can be extended without changing its own code. You build a package, a folder of PHP code that Paybob loads, and install it from the admin panel as a ZIP file.
Three kinds of package
| Package | Lives in | Does | Guide |
|---|---|---|---|
| Gateway | gateways/{slug}/ | Takes payments through one provider: an API, a wallet, a bank transfer, a QR code. | Gateway development |
| Theme | themes/{slug}/ | Styles the checkout, invoice and payment-link pages. | Theme development |
| Addon | addons/{addon-id}/ | Adds anything else: pages, settings, emails, integrations, reactions to events. | Addon development |
To connect an outside website or app instead, you don't need a package: use the Payment API, documented at developer.paybob.io.
What every package has in common
The folder name is the ID
A package's folder name is its permanent identifier, never declared inside a file: gateways/bkash-personal/, themes/midnight/, addons/sms-notifications/. Use lowercase letters, numbers and hyphens.
A namespace derived from the ID
Each package's PHP classes live in their own namespace, built from the folder name with Laravel's Str::studly():
| Package | Folder | Namespace |
|---|---|---|
| Gateway | gateways/bkash-personal/ | Gateways\BkashPersonal |
| Theme | themes/midnight/ | Themes\MidnightTheme |
| Addon | addons/sms-notifications/ | Addons\SmsNotifications |
Getting the namespace wrong is the most common reason a package isn't found.
Shipped as a ZIP with one folder
Every package is installed from a ZIP that contains exactly one top-level folder, named after the package:
my-gateway.zip
└── my-gateway/
├── ProcessPayment.php
└── assets/No Composer on the server
Paybob never runs composer install or npm install for a package. It runs on servers where that isn't possible. Ship every dependency inside your package, or use only what Paybob already includes (Laravel, Filament, Guzzle and so on).
Trusted code
Packages are PHP code that runs with full access to Paybob, its database and its secrets. There's no sandbox. Paybob checks a package's structure before installing it, but that doesn't make malicious code safe. Write packages as carefully as you'd write Paybob itself, and tell your users to install packages only from developers they trust.
The stack
Paybob is built on PHP 8.3, Laravel 13 and Filament 5, with Livewire 4 and Tailwind CSS 4. The admin panel is Filament, and customer-facing pages are Blade views. Everything you know about Laravel applies inside a package: service providers, routes, views, migrations, the HTTP client.
Rules that apply everywhere
- Never do money math with floats. Paybob does every calculation with
bcmathat 8 decimal places. Use Paybob's own calculators, such as$this->financial()in a gateway, rather than+and-on amounts. - Never write a transaction's status directly. Use the helpers Paybob gives you, such as
markAsCompleted(), so events fire, webhooks are sent and invoices are settled the same way every time. - Never expose numeric database IDs. Use the public IDs:
t_idfor transactions,i_idfor invoices,c_idfor customers,g_idfor gateways. - Keep secrets secret. Store credentials as encrypted fields, and never log them or show them to customers.
- Expect to fail safely. If your listener or hook throws, Paybob catches and logs it and carries on, but write your own error handling too.
Developing locally
Develop against a local copy of Paybob. Put your package in the matching folder (gateways/, themes/ or addons/) and it's picked up without uploading:
- Gateways appear in Gateways → Create New.
- Themes appear on the Themes page.
- Addons appear in System Settings → Addons, disabled, the next time the page loads.
When it works, ZIP the folder and test the upload on a clean installation.