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

Laravel Referrals Laravel Package

bkfdev/laravel-referrals

A Laravel package for adding referral programs to your app: generate referral codes and shareable links, track invited sign-ups, attribute conversions, and reward referrers. A simple way to build invite-based growth into any Laravel project.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the package and publish its assets before writing any referral logic:

composer require <vendor>/<package>
php artisan vendor:publish --provider="<Vendor>\<Package>\<Package>ServiceProvider"
php artisan migrate

Publishing typically yields a config file (cookie name, lifetime, link expiry, short-link driver) and a migration adding the referral_links table. Check the migration first — it is the fastest way to understand the package's data model, and in v1.1.1 you should confirm the short_link_id column is present and nullable.

Where to look first, in order:

  1. The ReferralLink model — the central object you will query and pass around.
  2. The trait you add to your User model (commonly HasReferralLinks) — this defines the relationship API you will actually call.
  3. The config file — especially the short-link section, since v1.1.1 wires referral links to short links.

First use case: give every user a shareable referral URL.

$link = $user->createReferralLink();      // or ReferralLink::create([...])
return $link->url;                        // full referral URL

Capture the incoming referral on your landing route, stash it (session or cookie), and consume it at registration. That end-to-end path — create → capture → attribute — is the smallest thing worth building before you touch anything else.

Implementation Patterns

Create links through the relationship, not the model directly. Using $user->referralLinks()->create([...]) guarantees the owner foreign key is set correctly and keeps your code working if the package adds owner scoping later.

Treat short_link_id as optional enrichment. The v1.1.1 addition links a referral record to a short link row. The pattern that holds up:

$link = $user->createReferralLink();

if ($shortLink = $link->shortLink) {      // relation added in 1.1.1
    return $shortLink->url;               // short, shareable
}

return $link->url;                        // fallback: long-form URL

Always code the fallback branch. Existing rows created before v1.1.1 will have a null short_link_id, and so will rows created when short-link generation fails or is disabled.

Eager load the short link anywhere you render lists. A dashboard showing a user's links will otherwise fire one query per row the moment you access $link->shortLink. Use $user->referralLinks()->with('shortLink')->get().

Resolve the short link at render time, not at capture time. The referral token in your URL is what you attribute on; the short link is just a transport. Keep the redirect handler reading the referral token/id, so swapping or regenerating a short link never breaks attribution.

Attribution flow that stays simple:

  • Landing route: validate the referral parameter, store the referral id in a signed cookie with the configured lifetime.
  • Registration: read the cookie, attach referred_by (or whatever your schema calls it), then clear the cookie so a later signup on the same browser doesn't inherit it.
  • Fire your own domain event after attribution rather than burying side effects in the controller — you will want to replay or test it.

Integrate through a service, not the controller. Wrap "create a referral link and, if configured, mint a short link" in a small ReferralLinkService. That is the single seam where the package's behaviour meets your business rules, and the place you'll edit if a future release changes the short-link contract.

Gotchas and Tips

Run the migration before deploying code that reads short_link_id. A nullable column added in a minor release is easy to miss; if your code touches $link->shortLink against an un-migrated database you get a "column not found" error deep in a view, which is a miserable way to discover it. Deploy migrations first, code second.

Existing referral links will not be backfilled. v1.1.1 adds the column but almost certainly doesn't retroactively shorten historical links. If users have already shared long URLs, that's fine — but don't advertise "short links" as universal until you either backfill via a queued job or regenerate short links on demand.

Short-link creation can fail independently. Third-party shorteners have rate limits, API keys, and outages. Because short_link_id is nullable, the intended design is graceful degradation. Catch failures, log them, persist the referral link anyway, and serve the long URL.

Don't expose the short link's numeric id. short_link_id is an internal foreign key. Keep it out of API resources and JSON payloads; expose the short link's URL, not its primary key.

Watch for silent config drift. If the package reads shortener credentials from its published config, a stale config file after an upgrade means your new setting is ignored — config('...') quietly returns the old default. When short links stop generating after a deploy, php artisan config:clear and diffing the published config against the package's current one is the first move.

Cookies and session both bite in edge cases. Referral cookies fail in cross-domain and strict-tracking-prevention contexts, and session-based capture fails across devices. Decide deliberately which you support and document the loss. A referral id echoed on the registration form as a hidden field is a useful third fallback.

Use the extension points before you fork. Link generation and URL formatting are usually overridable via config or a bound interface. If you need custom slugs, vanity tokens, or a different shortener, check for a binding or a make:/generate: config key before patching vendor code.

Test the null-short-link path explicitly. Write the feature test where the shortener is unavailable, because that is the branch that runs in production at the worst possible moment and the one least likely to be covered by the package's own suite.

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.
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin