Skip to main content

Security

  • A billing.enabled master switch makes the whole billing surface disappear, including Cashier's own routes.

  • A scoped Content-Security-Policy covers the account hub.

  • Card capture happens on the provider's own hosted page, so no card data ever touches your app — the integration stays within PCI SAQ-A.

  • A page of the provider is opened only on a host of the provider. The driver checks the address where it reads it from the provider's answer: https, and a host it serves pages from (checkout.stripe.com, billing.stripe.com and connect.stripe.com for Stripe, www.mollie.com for Mollie). Any other address is refused and logged with its host, so the page that sends a customer to the card form decides nothing a tampered answer could move. A Stripe custom domain goes into billing.redirect_hosts.

  • Every hub and admin screen is fail-closed authorized; the admin console is gated by an ability your app defines (see Admin and support).

  • The webhook-secret guard refuses to boot in production without a signing secret where the provider signs every delivery, so its webhooks are never accepted unverified. Mollie's classic payment ping is never signed: it is authenticated by fetching the payment back, and it has to name a payment to be accepted at all.

  • A throttle on the webhook endpoints is yours to name in billing.webhook_middleware. The package reads no network address anywhere, so it keys nothing by address itself.

  • Calls to the payment provider spend from one budget per payer, billing.provider_budget, 30 calls in 10 seconds by default. One Livewire request can carry up to 50 calls on each of up to 200 components, so without a budget a single request could make the provider answer thousands of times in one payer's name, and the provider limits the whole account. Every account screen spends before it asks the provider, and a request past the budget is answered 429 first. A screen of your own on the same seams spends from the same budget, so a payer has one count, not one per screen:

    use Pushery\Billing\Contracts\Invoices;
    use Pushery\Billing\Support\ProviderCallBudget;

    app(ProviderCallBudget::class)->spend($owner);

    $page = app(Invoices::class)->recent($owner);

Report vulnerabilities privately through the security policy rather than opening a public issue.

When you need a payment-services or e-money license​

This is engineering guidance, not legal advice — the rules differ by country and change, and the responsibility for meeting them is yours. The package is built so that the safe path is the default and the regulated path cannot be reached by accident:

  • The provider holds the money. On a routed sale the payment provider holds the funds end to end; the platform never has other people's money on its own account. This is the shipped behavior and the only path the package implements.
  • Holding funds yourself is opt-in and gated. billing.marketplace.custody.platform_held is false by default, and setting it true refuses to boot unless you bind a PaymentServiceLicenseAttestation — the deliberate, code-level act of declaring that you hold the required license. Holding funds on your own account is a regulated activity in most jurisdictions, so the package will not let a flag alone turn it on.
  • No withdrawable or transferable balance. The credit ledger records a claim against future invoices, not a store of value: it has no method that pays a balance out and none that moves it between owners, and a test keeps it that way. A balance that can be recharged, withdrawn, and transferred is e-money almost everywhere, and the package does not ship one.
  • No interest on held funds. There is no yield or interest option; paying interest on customer funds is a further regulated activity the package does not offer.

A voucher is the same line one instrument further on. It stays inside the limited-network exemption only while it cannot be cashed out or handed to somebody else, so the events a voucher can carry are a closed set — issued, redeemed, expired — and a redemption always names the sale it went towards. That is what makes it a way of paying rather than a way of getting cash back, and a test asserts the set rather than trusting that nobody adds to it.

That exemption also rests on the instrument being redeemed where it was issued, and the package does not wire that limb at all. Everything above is about what a balance or a voucher can do; this is about where it is spent, and an instrument redeemable at a third party is a different question from the one answered here — one whose answer depends on arrangements only the operator makes. It is written down rather than left out precisely because nothing in the package will go red about it.

The rolling volume counter is the other half of this, and it counts both instruments: vouchers issued and paid money-credit top-ups, in each currency they were sold in, net of refunds. So "we issue no vouchers" does not make the figure moot — an installation that only sells credit is counted, warned and told it has crossed the line exactly as one that only issues vouchers is.

If your product needs any of these, that is a decision to take with a professional who knows your jurisdiction — the guards mark the line, they do not clear it for you.


← Back to the documentation index