laravel-stripe maintained by dominservice
Laravel Stripe
Stripe integration package for Laravel projects that need a practical repository-based API for:
- Checkout Sessions
- Customers
- Products and Prices
- Refunds
- Stripe Connect onboarding
- webhook verification
- country-aware payment method selection
Laravel 10-13 on PHP 8.1+.
Features
- repository-style Stripe API wrapper,
- Checkout Session creation with support for Stripe-hosted checkout parameters,
- customer, product, price and invoice helpers,
- Stripe Connect support for Express onboarding flows,
- webhook signature verification middleware,
- currency normalization and minimum amount validation,
- payment method selection helper based on customer country and presentment currency,
- optional policy filters for customer type, MCC / branch, project type and explicit allow / deny lists.
Compatibility
Current compatibility targets:
- Laravel 10 on PHP 8.1+
- Laravel 11 on PHP 8.2+
- Laravel 12 on PHP 8.2+
- Laravel 13 on PHP 8.3+
Installation
composer require dominservice/laravel-stripe
Add your Stripe credentials in .env:
STRIPE_KEY=pk_live_xxx
STRIPE_SECRET=sk_live_xxx
STRIPE_WEBHOOK_CHECKOUT=whsec_xxx
Publish config:
php artisan vendor:publish --provider="Dominservice\\LaraStripe\\ServiceProvider" --tag=stripe
Publish migrations:
php artisan vendor:publish --provider="Dominservice\\LaraStripe\\ServiceProvider" --tag=stripe-migrations
Run migrations:
php artisan migrate
Configuration
Main configuration file:
config/stripe.php
Important sections:
stripe.keystripe.secretstripe.webhooks.*stripe.currenciesstripe.minimum_charge_amountsstripe.zero_decimal_currenciesstripe.three_decimal_currenciesstripe.payment_method_policies
Allowed currencies
If your application only supports specific currencies, list them in:
'currencies' => ['PLN', 'EUR', 'USD', 'GBP'],
If a currency is not declared there, helper validation will reject it.
User model mapping
Check whether the package config matches your project:
stripe.modelstripe.email_keystripe.name_key
Webhooks
Attach the middleware stripe.verify:{name} to routes that receive Stripe webhook calls.
Example:
Route::middleware(['stripe.verify:checkout'])->group(function () {
Route::post('/webhook/payments', [WebhookController::class, 'payments']);
});
{name} maps to:
config('stripe.webhooks.signing_secrets.checkout')
Basic Usage
use Dominservice\LaraStripe\Client as StripeClient;
$stripe = new StripeClient();
Create a customer
$customer = $stripe->customers()
->setName($user->name)
->setEmail($user->email)
->setPhone($user->phone)
->setAddress([
'country' => 'PL',
'city' => 'Warszawa',
'postal_code' => '00-000',
'line1' => 'ul. Kopernika 1/2',
])
->create($user);
Create a product with price
$productStripe = $stripe->products()
->setName($product->name)
->setActive(true)
->setExtendPricesCurrency('pln')
->setExtendPricesUnitAmount((float) $amount)
->setExtendPricesBillingScheme('per_unit')
->create($product);
Create a Checkout Session
$session = $stripe->checkoutSessions()
->setSuccessUrl(route('payment.afterTransaction', $order->ulid) . '?session_id={CHECKOUT_SESSION_ID}')
->setCancelUrl(route('payment.canceled', $order->ulid))
->setMode('payment')
->setClientReferenceId($order->ulid)
->setCustomer($customer->id)
->setLineItems([
[
'price' => $productStripe->default_price->id,
'quantity' => 1,
],
])
->create();
Stripe Checkout Support
The package allows passing Stripe Checkout parameters such as:
allow_promotion_codesautomatic_taxbilling_address_collectioncancel_urlconsent_collectioncustomer_creationcustomer_updateinvoice_creationlocalepayment_method_collectionpayment_method_configurationpayment_method_optionspayment_method_typesphone_number_collectionshipping_address_collectionsuccess_urltax_id_collectionui_mode
These are handled in the Checkout Session repository and forwarded to Stripe if valid.
Currency Helpers
Normalize currency code
use Dominservice\LaraStripe\Helpers\PaymentHelper;
$currency = PaymentHelper::normalizeCurrencyCode('eur', true); // eur
Validate and normalize amount
$unitAmount = PaymentHelper::getValidAmount('EUR', 49.99); // 4999
The helper:
- validates configured currencies,
- handles zero-decimal and three-decimal currencies,
- validates Stripe minimum charge amounts.
Payment Methods by Country
The package contains a helper that can build manual payment_method_types for Stripe Checkout.
use Dominservice\LaraStripe\Helpers\PaymentHelper;
$methods = PaymentHelper::getPaymentMethodsByCountry('PL', 'PLN');
// ['card', 'blik', 'klarna', 'p24', 'paypal']
Another example:
$methods = PaymentHelper::getPaymentMethodsByCountry('DE', 'EUR');
// ['card', 'klarna', 'paypal', 'sepa_debit']
What the helper currently does
It:
- always keeps
card, - adds methods supported for the customer country,
- applies presentment currency restrictions,
- excludes deprecated methods such as
giropayandsofort, - optionally filters by project policies.
Current optional third argument
$methods = PaymentHelper::getPaymentMethodsByCountry('PL', 'PLN', [
'customer_type' => 'private',
'mcc' => '7991',
'project_type' => 'travel',
'allowed_methods' => ['card', 'blik', 'paypal'],
'forbidden_methods' => ['klarna'],
]);
Supported context keys:
customer_typemccproject_typebusiness_typeallowed_methodsforbidden_methods
This third argument is optional. If you do not pass it, older integrations keep working as before.
Payment Method Policies
The policy layer is configured in:
stripe.payment_method_policies
It is optional by design. If you leave it empty, the helper falls back to country + currency only.
1. Allowed methods for project / business type
'allowed_methods_by_project_type' => [
'travel' => ['card', 'paypal'],
'hotel' => ['card', 'paypal', 'klarna'],
'saas' => ['card', 'paypal', 'sepa_debit'],
],
If your project prefers business_type naming, the package also supports:
'allowed_methods_by_business_type' => [
'tourism' => ['card', 'paypal'],
'saas' => ['card', 'paypal', 'sepa_debit'],
],
2. Forbidden methods for project / business type
'forbidden_methods_by_project_type' => [
'travel' => ['p24'],
],
The same alias exists for:
'forbidden_methods_by_business_type' => [
'regulated' => ['klarna'],
],
3. Forbidden methods for customer type
By default the package excludes klarna for:
'customer_type' => 'company'
because Klarna does not support B2B flows in the same way as private consumer checkout.
4. Forbidden MCC by payment method
The package now ships with a default MCC restriction map for p24, based on the current Stripe documentation.
This matters especially for projects in categories such as:
- travel agencies,
- tour operators,
- hotels,
- transport,
- software,
- healthcare,
- advertising,
- real estate,
- gambling,
- higher education.
The restriction list is configurable, so the host project can override or extend it.
5. Forbidden methods by MCC / branch
If the host project prefers a category-first policy view instead of the
method-first forbidden_mcc_by_method, it can also define:
'forbidden_methods_by_mcc' => [
'4722' => ['p24'],
'7011-7012' => ['p24'],
],
Both policy styles can coexist. The helper merges them.
Backward compatibility
All policy layers are optional:
- if you do not configure project type policies, nothing changes,
- if you do not configure business type policies, nothing changes,
- if you do not pass
customer_type, no customer-type filtering happens, - if you do not pass
mcc, MCC rules are not evaluated, - if you do not pass allow / deny lists, they are ignored.
This keeps older integrations working without forced refactors.
Stripe Connect
The package supports the base repositories required for Stripe Connect onboarding:
accounts()accountLinks()loginLinks()
Typical platform flow:
use Dominservice\LaraStripe\Client as StripeClient;
$stripe = new StripeClient();
$account = $stripe->accounts()
->setType('express')
->setCountry('PL')
->setEmail($expert->email)
->setCapabilities([
'transfers' => ['requested' => true],
])
->create($expert);
$onboarding = $stripe->accountLinks()
->setAccount($account->id)
->setRefreshUrl(route('expert.billing.refresh'))
->setReturnUrl(route('expert.billing.return'))
->setType('account_onboarding')
->create();
$loginLink = $stripe->loginLinks()->create($account->id);
For marketplace split payments handled on the platform account, create Checkout Sessions with:
payment_intent_data.application_fee_amountpayment_intent_data.transfer_data.destination
Notes for DominPress-family Projects
This package is already useful for:
- public booking flows such as 44Islands,
- marketplace and panel billing flows,
- future SaaS-style projects in the DominPress family,
- DPS-related projects that need:
- Checkout Sessions,
- Connect onboarding,
- invoice-compatible payment metadata,
- project-specific payment method policies.
For projects with strongly regulated payment availability, the host application should pass:
- customer country,
- presentment currency,
- customer type,
- MCC,
- project type or business type.
That gives the helper enough context to avoid showing methods that should not be available.
Recommended Host-Project Strategy
For Checkout-based implementations:
- collect billing country in the public form,
- determine presentment currency before session creation,
- pass
customer_typeif the checkout distinguishes private vs company, - pass
mccorproject_typeif the business has method restrictions, - build
payment_method_typesthroughPaymentHelper::getPaymentMethodsByCountry(...).
This is especially relevant when a single codebase serves:
- public tourism booking,
- B2B SaaS checkout,
- expert / partner payouts through Connect.
Support
Support this project (Ko-fi)
If this package saves you time, consider buying me a coffee:
https://ko-fi.com/dominservice
Thank you.
License
MIT