Payments
Stripe, PayPal, bank transfer and account credit are built in. Payment status always comes from the provider's own notification, never from the browser returning to the site.
Connecting a gateway
Open Developers → Integrations and choose Add next to the gateway. Each connection has a name shown to clients, the currencies it accepts and the credentials below. Secrets are stored encrypted and never shown again after saving.
Stripe
- Secret key and publishable key from the Stripe dashboard (test or live keys; the mode is part of the connection).
- Webhook signing secret: create a webhook endpoint in Stripe pointing at the URL shown on the connection page,
https://your-site/webhooks/payments/{connection}, and paste the signing secret Stripe gives you. - Events to send:
checkout.session.completed,checkout.session.async_payment_succeeded,checkout.session.async_payment_failed,payment_intent.succeeded,payment_intent.payment_failed,charge.refunded,charge.dispute.created,charge.dispute.funds_withdrawn,charge.dispute.funds_reinstatedandcharge.dispute.closed.
PayPal
- Client ID and secret of a REST app from the PayPal developer dashboard, in sandbox or live mode.
- Webhook ID: create a webhook for the app pointing at
https://your-site/webhooks/payments/{connection}and enter its ID. Subscribe toCHECKOUT.ORDER.APPROVED,PAYMENT.CAPTURE.COMPLETED,PAYMENT.CAPTURE.PENDING,PAYMENT.CAPTURE.DECLINED,PAYMENT.CAPTURE.DENIED,PAYMENT.CAPTURE.REFUNDED,PAYMENT.CAPTURE.REVERSED,CUSTOMER.DISPUTE.CREATEDandCUSTOMER.DISPUTE.RESOLVED. - For reconciliation the app also needs the Transaction Search permission in the PayPal developer dashboard; without it PayPal answers 403 and the reconciliation page says so.
Bank transfer
Shows your account details on the invoice and in the client area. Staff record the payment on the invoice when the money arrives. Instructions are editable per connection.
Account credit
Clients can pay invoices from a credit balance. Credit is added by staff (refunds, goodwill, prepayments) or by the client through a credit top-up invoice paid with another gateway.
Webhooks
The connection page shows the notification address to register at the gateway. Every notification is verified with the gateway's signature or webhook ID, stored with its payload and processed once; replays are ignored, and a notification for a payment that is not known here is kept for reconciliation. If a gateway reports a payment but the invoice stays unpaid, check the address and the secret on the gateway's side and the gateway's own webhook log first; the reason a notification was rejected is written to storage/logs/laravel.log.
Refunds, disputes and failed payments
- Refunds are issued from the transaction page; the gateway is asked to refund and the ledger entry is written when it confirms.
- Disputes and chargebacks reported by the gateway are recorded against the transaction and shown with the invoice.
- Failed automatic payments are retried on the dunning schedule of the billing settings (by default one, three and five days after the first attempt) before a service is suspended.
Reconciliation
Commerce → Reconciliation compares what the gateway reports with what the ledger holds for a period: payments missing on one side, amounts or fees that differ, refunds and disputes not recorded. Stripe and PayPal are read through their APIs; any other gateway or bank account can be reconciled from a CSV statement with a column mapping you save for next time. Every item is resolved by a staff decision (record it, mark it as explained, or open a ticket); nothing is changed in the ledger automatically. A scheduled run can be enabled to reconcile each day.
Currencies and taxes
Commerce → Currencies & taxes defines the currencies clients can be billed in, exchange rates, tax rules by country or region, whether prices include tax, and the invoice numbering format. Each client has one billing currency.