PHP SDK
Integrate Perly churn prevention into your Laravel application with a service provider, middleware, and user resolver.
perly/perly-phpv1.0.05 minutes
Installation
composer require perly/perly-phpPublish the configuration file:
php artisan vendor:publish --tag=perly-configUsage
Set your API key in the published config file and register the middleware.
// config/perly.php
return [
'api_key' => env('PERLY_API_KEY'),
];// app/Http/Kernel.php
protected $middlewareGroups = [
'api' => [
\Perly\Http\PerlyMiddleware::class,
],
];Bind the user resolver in your service provider:
// app/Providers/AppServiceProvider.php
use Perly\Contracts\PerlyUserResolver;
use App\Perly\AppPerlyUserResolver;
public function register()
{
$this->app->bind(PerlyUserResolver::class, AppPerlyUserResolver::class);
}User Resolver
Create a resolver class that implements PerlyUserResolver. The resolve method receives the Laravel request and returns a Perly user.
// app/Perly/AppPerlyUserResolver.php
namespace App\Perly;
use Perly\Contracts\PerlyUserResolver;
use Perly\PerlyBuilder;
use Illuminate\Http\Request;
class AppPerlyUserResolver implements PerlyUserResolver
{
public function resolve(Request $request)
{
$user = $request->user();
if (!$user) {
return null;
}
return PerlyBuilder::create()
->setId($user->id)
->setMetadata([
'plan' => $user->plan,
'region' => $user->region,
'company_id' => $user->company_id,
])
->linkStripeById($user->stripe_customer_id)
->linkHubspotById($user->hubspot_contact_id)
->build();
}
}Tracking Events
Use the Perly facade anywhere in your Laravel application to track customer events.
use Perly\Facades\Perly;
// In a controller
class OnboardingController extends Controller
{
public function complete(Request $request)
{
Perly::track($request->user()->id, 'onboarding_completed');
return response()->json(['success' => true]);
}
public function exportReport(Request $request)
{
Perly::track($request->user()->id, 'report_exported', [
'format' => $request->input('format'),
]);
return response()->download($reportPath);
}
public function inviteTeamMember(Request $request)
{
Perly::track($request->user()->id, 'team_member_invited', [
'email' => $request->input('email'),
]);
return response()->json(['invited' => true]);
}
}Expansion Signals
Send signals when customers approach usage limits to drive upsell workflows.
use Perly\Facades\Perly;
// In a service or job
class UsageCheckService
{
public function checkSeatLimit(User $user): void
{
$seats = $user->company->members()->count();
$limit = $user->company->seat_limit;
if ($seats > $limit * 0.9) {
Perly::signal($user->id, 'seat_limit_near', [
'current' => $seats,
'limit' => $limit,
]);
}
}
}
// Other signal types
Perly::signal($userId, 'api_usage_high', ['current' => 9500, 'limit' => 10000]);
Perly::signal($userId, 'rate_limit_hit', ['endpoint' => '/api/search']);
Perly::signal($userId, 'storage_limit_near', ['used_gb' => 9.2, 'limit_gb' => 10]);
Perly::signal($userId, 'billing_retry_failed', ['attempt' => 3]);