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

Paypal Laravel Package

swisstheme-sarl/paypal

A PayPal integration package for Laravel and PHP applications, offering a convenient way to connect to PayPal APIs for payments, transactions, and related workflows while simplifying configuration and usage in your project.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package with Composer, publish its config if the service provider exposes one, and add the PayPal credentials plus the new URL variables to .env:

PAYPAL_CLIENT_ID=
PAYPAL_CLIENT_SECRET=
PAYPAL_MODE=sandbox

PAYPAL_RETURN_URL="${APP_URL}/paypal/accept/sub"
PAYPAL_CANCEL_URL="${APP_URL}/paypal/cancel/sub"

As of 1.0.2, these two URLs can be supplied through environment variables. The package defaults are:

  • PAYPAL_RETURN_URL → https://parentsolo.ch/paypal/accept/sub
  • PAYPAL_CANCEL_URL → https://parentsolo.ch/paypal/cancel/sub

Look first at the published package config, the package README, and any routes/controllers it exposes for handling PayPal redirects. The first practical use case is a subscription checkout: create a PayPal subscription, redirect the customer to PayPal for approval, then handle the browser returning to your PAYPAL_RETURN_URL or PAYPAL_CANCEL_URL.

Implementation Patterns

Configure URLs per environment. Treat PAYPAL_RETURN_URL and PAYPAL_CANCEL_URL as required deployment configuration, not optional conveniences. Set them explicitly in local, staging, and production .env files. Do not rely on the package defaults unless your application actually lives at parentsolo.ch.

Define matching routes. Create GET routes that match the configured URLs, for example:

Route::get('/paypal/accept/sub', [PayPalSubscriptionController::class, 'accept'])
    ->name('paypal.accept');

Route::get('/paypal/cancel/sub', [PayPalSubscriptionController::class, 'cancel'])
    ->name('paypal.cancel');

PayPal will append query parameters such as token and usually PayerID to the return URL. Your handler should read those from the request rather than expecting an exact URL match.

Keep initiation and confirmation separate. Before redirecting to PayPal, persist the subscription or order token locally. On return, look up that local record, confirm the subscription with the PayPal API, and only then mark it active. On cancel, leave the record pending or cancelled and show a retry path.

Use tunnels for local development. PayPal cannot redirect to http://localhost. Use a public HTTPS tunnel such as ngrok, Expose, or Laravel Herd’s sharing features, then set:

PAYPAL_RETURN_URL=https://your-tunnel.example/paypal/accept/sub
PAYPAL_CANCEL_URL=https://your-tunnel.example/paypal/cancel/sub

Remember to update these when the tunnel URL changes.

Test with config overrides and HTTP fakes. In feature tests, override the package config rather than relying on .env:

config([
    'paypal.return_url' => 'https://example.test/paypal/accept/sub',
    'paypal.cancel_url' => 'https://example.test/paypal/cancel/sub',
]);

Fake PayPal API calls with Http::fake() and assert that the generated approval request contains the expected return and cancel URLs.

Treat webhooks as the source of truth. The return URL is a browser redirect and can be abandoned, refreshed, or spoofed. Use PayPal webhooks or a server-side API verification step to activate subscriptions. The return handler should be for user experience and immediate confirmation, not the only fulfilment path.

Gotchas and Tips

  • The defaults are production URLs for a specific site. If your .env is missing PAYPAL_RETURN_URL or PAYPAL_CANCEL_URL, the package may silently send users to parentsolo.ch. Add both variables to .env.example and deployment checklists.

  • Config caching hides .env changes. After editing the URL variables, run php artisan config:clear locally or php artisan config:cache during deployment. If the package reads URLs through config(), stale cached config will keep the old values.

  • Avoid calling env() directly in application code. Read the package config via config('paypal.return_url') and similar keys. Environment values should be resolved inside config files so they survive config:cache.

  • PayPal appends query parameters. Routes must accept ?token=...&PayerID=.... Do not require an exact URL, a signed URL without those parameters, or a route that rejects extra query strings.

  • Use absolute HTTPS URLs. Relative paths, http:// URLs, and URLs containing local hostnames will fail or behave inconsistently. Ensure APP_URL and tunnel URLs are accurate.

  • Watch authentication and middleware. The return route must be reachable by the customer’s browser. If it sits behind an auth guard, the session must still be valid; if it uses signed URLs, PayPal’s appended query parameters may invalidate the signature.

  • Do not fulfil solely on the return redirect. A customer can close the browser after approval. Confirm through the PayPal API or webhook before granting access.

  • Debug by logging the outgoing approval URL. When redirects fail, inspect the exact return_url and cancel_url sent to PayPal, confirm the routes exist with php artisan route:list, and check that the tunnel or domain is publicly reachable.

  • Extension point: override config at runtime. If you need dynamic URLs per tenant or flow, set the package config immediately before initiating the PayPal request:

    config([
        'paypal.return_url' => route('paypal.accept', ['tenant' => $tenant]),
        'paypal.cancel_url' => route('paypal.cancel', ['tenant' => $tenant]),
    ]);
    

    Be careful with config caching and long-running workers; prefer request-scoped overrides.

  • Version 1.0.2 is a configuration convenience, not a breaking change. Existing applications that relied on hard-coded or previously published URL config should verify precedence: environment variables may now override values that were previously set directly in the config file.

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.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log