Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Payment Module Laravel Package

codewithdiki/payment-module

A Laravel payment module for integrating and managing payment flows, with support for payment methods, transactions, and gateway configuration. Designed to plug into Laravel applications through a simple, configurable structure.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package and publish its config:
    composer require <vendor>/laravel-paypal
    php artisan vendor:publish --tag=paypal-config
    
  2. Add credentials and the new brand name to .env:
    PAYPAL_MODE=sandbox
    PAYPAL_CLIENT_ID=...
    PAYPAL_CLIENT_SECRET=...
    PAYPAL_BRAND_NAME="Acme Store"
    
  3. Look first at config/paypal.php — that is where brand_name lands in v1.6.3 — then at the package service provider to see what is bound into the container and how the client is constructed.

The fastest first use case is a single checkout flow: create an order server-side, redirect the buyer to PayPal, capture on return. The brand name is the label PayPal displays to the buyer on the PayPal-hosted pages, so setting it is a one-line config change that immediately makes the checkout look less like a generic integration.

$order = PayPal::createOrder([
    'intent' => 'CAPTURE',
    'purchase_units' => [[
        'amount' => ['currency_code' => 'USD', 'value' => '49.99'],
    ]],
]);

return redirect($order['links'][1]['href']);

Implementation Patterns

Keep brand name in config, not in code. Set it once per environment. For a single-tenant app this is the whole story: PAYPAL_BRAND_NAME in .env, config:cache, done.

Multi-tenant / white-label overrides. If one deployment serves multiple storefronts, override at runtime before building the order:

config(['paypal.brand_name' => $tenant->display_name]);

$order = app(PayPalClient::class)->createOrder($payload);

This only works reliably if the client reads config lazily. If the package resolves config in the constructor, resolve a fresh client per request (or per tenant) rather than injecting a singleton. Check the service provider binding before relying on this.

Wrap order creation in your own action/service. Don't scatter PayPal:: calls through controllers. A small CreatePayPalOrder action gives you one place to set the brand name, attach custom_id/invoice_id metadata, and normalize the response.

Capture on return, verify webhooks for truth. Redirect-based capture is fine for UX, but treat the webhook (PAYMENT.CAPTURE.COMPLETED) as the source of truth for fulfilment. Idempotency keys on capture prevent double-fulfilment on refresh.

Testing. Use the sandbox mode plus Http::fake() around the package's HTTP layer. Assert the outgoing payload includes the expected brand_name when you override it per tenant — this is the regression most likely to appear after a config refactor.

Gotchas and Tips

  • Config caching. After changing PAYPAL_BRAND_NAME, run php artisan config:cache in environments that cache config, or the old value persists. This bites people in staging constantly.
  • The brand name is display-only. It does not change the receiving business account, the statement descriptor, or the email on the receipt. Buyers still see the underlying PayPal account in some flows.
  • Not every surface honours it. Brand name appears on PayPal-hosted checkout pages; it typically does not appear on card fields rendered directly in your page, or on some alternative payment methods. Verify in the sandbox with the exact product you use.
  • Length and content limits. PayPal enforces its own constraints on the brand name; an over-long or symbol-heavy value can be rejected or silently truncated. Keep it short and plain ASCII.
  • Singleton client pitfall. If runtime config overrides appear to be ignored, it is almost always a cached client instance. Bind the client as a scoped/transient service, or instantiate it after the config override.
  • Debugging. Log the request payload (redact secrets) at the point of order creation — when the brand name looks wrong in the sandbox UI, comparing the sent payload against config is the fastest triage.
  • Extension points. Prefer publishing and editing the config file over subclassing the client; the config is the stable surface. If you need per-request brand names beyond config, wrap the client rather than patching vendor code, so upgrades to 1.6.x stay painless.
  • Upgrade note. v1.6.3 is additive — a new optional config key. No breaking changes; existing installs keep working with the previous default brand behaviour until you set the env var.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core