Laravel Billing
Billing and payments for Laravel: pluggable payment gateways, one-off payments, saved cards, subscriptions with trials and dunning, usage-based pricing, refunds, invoices and receipts, and a webhook pipeline that is the only thing allowed to change a payment’s status.
Built-in gateways: Monobank Acquiring, LiqPay, WayForPay, Hutko, Stripe, Paddle, plus a fake gateway for local development. A gateway of your own is one Billing::extend() call.
- One payment model for every gateway — a
Paymentrow is created by your app, charged through any gateway, and settled by the gateway’s webhook (or by status polling when the webhook is lost) - A plain checkout link everywhere —
payment_urlis always a redirectable URL, even for form-only gateways; a permanent pay link re-issues an expired checkout on the fly - Saved cards — the card is tokenized as a side effect of the first charge, then charged off-session
- Subscriptions — flat, per-seat and metered prices, minute-to-year intervals, trials, pause/resume, plan swaps, quotas, a retry ladder with a grace window; renewals run by the package or by the provider (Stripe Billing, Paddle)
- Refunds — full and partial through the API, plus refunds issued from a gateway’s dashboard, recorded from webhooks
- Invoices and receipts — numbered PDF documents, snapshots of seller, buyer and items at issue time
- Webhook guarantees — fail-closed signatures, amount verification, per-outcome dedup, a paid payment never reverted
- Multi-tenant — per-tenant credentials for outgoing calls and incoming webhooks, several accounts of one gateway
- No dependencies beyond
illuminate/*, Octane-safe, MySQL/MariaDB, PostgreSQL and SQLite
Quick example
Section titled “Quick example”use Fomvasss\Billing\DTO\ChargeOptions;use Fomvasss\Billing\Facades\Billing;use Fomvasss\Billing\Models\Payment;
$payment = Payment::create([ 'gateway' => 'monobank', 'amount' => 129900, // minor units — 1 299.00 'currency' => 'UAH', 'payable_type' => $order->getMorphClass(), 'payable_id' => $order->id, 'billable_type' => $user->getMorphClass(), 'billable_id' => $user->id,]);
Billing::charge($payment, new ChargeOptions(description: "Order #{$order->number}"));
return redirect($payment->payment_url);use Fomvasss\Billing\Events\PaymentSucceeded;use Illuminate\Support\Facades\Event;
Event::listen(function (PaymentSucceeded $event) { $event->payment->payable->markAsPaid(); // your Order});The browser coming back from the gateway proves nothing — fulfil orders from PaymentSucceeded, which only the verified webhook pipeline fires.
Contents
Section titled “Contents”Getting started
Usage
- Payments
- Return pages and the pay link
- Fiscal receipt items
- Refunds
- Saved cards
- Subscriptions
- Trials
- Renewals and dunning
- Usage and quotas
- Provider-managed subscriptions
- Invoices and receipts
- Webhooks
- Scheduled commands
- Tenants and multiple accounts
- Money and currencies
- Testing
Gateways
Guides
Reference