jeffersongoncalves/laravel-trustpilot
Laravel package for integrating Trustpilot into your application. Connect to the Trustpilot API to manage business units, retrieve reviews, and send review invitations through a clean, config-driven interface built for Laravel.
Install the package and publish its config:
composer require <vendor>/trustpilot
php artisan vendor:publish --tag=trustpilot-config
Add the required environment variables to .env:
TRUSTPILOT_API_KEY=your-public-api-key
TRUSTPILOT_API_SECRET=your-private-api-secret
TRUSTPILOT_BUSINESS_UNIT_ID=your-default-business-unit-id
Look first at config/trustpilot.php — it defines credentials, the default business unit, and token cache settings. Then review the package’s main service class or facade (often Trustpilot) to see the available resource methods: businessUnits(), reviews(), invitations(), and tags().
A good first use case: render your Trustpilot profile and latest public reviews on a marketing page. Resolve the client from the container, call businessUnits()->get() using the configured default unit, and reviews()->latest() to fetch recent reviews. Cache the result for a few minutes to avoid unnecessary API calls.
Inject the package client into controllers, jobs, or dedicated service classes rather than using the facade everywhere. This keeps your code testable and makes it easy to swap or mock the client later.
use Vendor\Trustpilot\Trustpilot;
class TrustpilotWidgetController
{
public function __construct(private Trustpilot $trustpilot) {}
public function index()
{
$profile = cache()->remember('tp.profile', 3600, fn () =>
$this->trustpilot->businessUnits()->get()
);
$reviews = cache()->remember('tp.latest-reviews', 600, fn () =>
$this->trustpilot->reviews()->latest()
);
return view('trustpilot.widget', compact('profile', 'reviews'));
}
}
Use the default business unit for most read operations. Pass an explicit business unit ID only when you manage multiple brands or need to query a different unit.
For private operations such as replying to reviews, listing private reviews, managing tags, or sending invitations, wrap calls in queued jobs. These actions are side-effecting, may be rate-limited, and should not block web requests.
class ReplyToTrustpilotReview implements ShouldQueue
{
use InteractsWithQueue, Queueable;
public function __construct(
public string $reviewId,
public string $comment
) {}
public function handle(Trustpilot $trustpilot): void
{
$trustpilot->reviews()->reply($this->reviewId, $this->comment);
}
}
For invitations, keep template IDs in config or a database table rather than hard-coding them. Use invitations()->email() for direct email invitations and invitations()->link() when you need to generate a shareable invitation URL.
When adding or removing tags, prefer batch operations if the package exposes them; otherwise dispatch one job per review to stay within rate limits.
Catch TrustpilotException at the boundaries where you call the package. Inspect the exception’s status code to distinguish auth failures (401/403), missing resources (404), validation errors (400/422), and rate limits (429). Retry 429 and 5xx responses with backoff; do not retry 4xx client errors.
Token caching: Private endpoints use a cached client-credentials bearer token. In multi-server setups, use a shared cache store (Redis, Memcached, or database) so each node does not request its own token. If you rotate API credentials, clear the token cache or wait for expiry. In local development, a stale token can cause confusing 401s — run php artisan cache:clear after changing .env.
Credentials are not interchangeable: Public endpoints only need the API key. Private endpoints need both the key and secret. A missing secret often surfaces as a 401 on review replies or private review listing, even though public review fetching still works. Double-check the config if only private calls fail.
Default business unit: Methods that omit a business unit ID rely on TRUSTPILOT_BUSINESS_UNIT_ID. If it is missing or invalid, calls fail at runtime. Validate it during deployment and consider failing fast in a service provider if the package is expected to be used.
Review replies are not editable: You can reply and delete a reply, but you cannot edit an existing reply. Deleting a reply is permanent. Build your admin UI accordingly — warn users before deletion and avoid offering an “edit reply” action.
Invitation templates: Template IDs come from the Trustpilot business UI. The package sends the template ID through, but it does not validate it. A wrong template ID may return a 400 or 404. Keep template IDs in config and test with a single recipient before sending bulk invitations.
Rate limits and retries: Trustpilot enforces rate limits. Because the package throws TrustpilotException on any non-2xx response, implement retry logic in your jobs using Laravel’s retryUntil or backoff methods. Log the response body from the exception when debugging — the status code alone may not explain validation failures.
Testing: Wrap the package client behind your own interface or service class so you can bind a fake in tests. If the package provides a fake or HTTP client swap, use it; otherwise, mock your wrapper. Avoid calling the real API in test suites.
Extension points: The config file is the main extension point for credentials, default business unit, and cache settings. If you need custom HTTP behaviour (timeouts, proxies, logging), check whether the package exposes a configurable HTTP client or base URL. For local integration tests, you may be able to point the base URL at a mock server via config.
Error visibility: TrustpilotException is thrown for all non-2xx responses. In production, report these exceptions to your error tracker but avoid leaking API response bodies to end users. In development, dump the exception message and status code to quickly identify misconfigured credentials or invalid IDs.
How can I help you explore Laravel packages today?