Integrate with Laravel
Add billing and payments to your Laravel application.
Install
composer require commet/commet-phpConfigure
COMMET_API_KEY=ck_sandbox_xxx
COMMET_WEBHOOK_SECRET=whsec_xxx<?php
namespace App\Providers;
use Commet\Commet;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function register(): void
{
$this->app->singleton(Commet::class, function () {
return new Commet(
apiKey: config('services.commet.api_key'),
environment: app()->environment('production') ? 'live' : 'sandbox',
);
});
}
}'commet' => [
'api_key' => env('COMMET_API_KEY'),
'webhook_secret' => env('COMMET_WEBHOOK_SECRET'),
],Subscribe
<?php
namespace App\Http\Controllers;
use Commet\Commet;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class BillingController extends Controller
{
public function __construct(
private Commet $commet,
) {}
public function subscribe(Request $request): JsonResponse
{
$request->validate([
'email' => 'required|email',
'external_id' => 'required|string',
]);
$this->commet->customers->create(
email: $request->input('email'),
externalId: $request->input('external_id'),
);
$subscription = $this->commet->subscriptions->create(
externalId: $request->input('external_id'),
planCode: 'pro',
);
return response()->json([
'checkout_url' => $subscription->data['checkout_url'],
]);
}
}Check Access
public function getSubscription(string $externalId): JsonResponse
{
$subscription = $this->commet->subscriptions->get(externalId: $externalId);
return response()->json([
'status' => $subscription->data['status'],
]);
}
public function checkFeature(string $feature, string $externalId): JsonResponse
{
$result = $this->commet->features->check(code: $feature, externalId: $externalId);
return response()->json([
'allowed' => $result->data['allowed'],
]);
}Track Usage
public function trackUsage(Request $request): JsonResponse
{
$request->validate([
'external_id' => 'required|string',
]);
$this->commet->usage->track(
externalId: $request->input('external_id'),
feature: 'api_calls',
value: 1,
);
return response()->json(['tracked' => true]);
}Usage is aggregated and billed at end of period.
Customer Portal
use Illuminate\Http\RedirectResponse;
public function portal(): RedirectResponse
{
$result = $this->commet->portal->getUrl(externalId: 'user_123');
return redirect($result->data['portal_url']);
}Webhooks
<?php
namespace App\Http\Controllers;
use Commet\Webhooks;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
class WebhookController extends Controller
{
public function handle(Request $request): JsonResponse
{
$webhooks = new Webhooks();
$payload = $webhooks->verifyAndParse(
rawBody: $request->getContent(),
signature: $request->header('x-commet-signature'),
secret: config('services.commet.webhook_secret'),
);
if ($payload === null) {
return response()->json(['error' => 'Invalid signature'], 401);
}
match ($payload['event']) {
'subscription.activated' => $this->handleActivated($payload),
'subscription.canceled' => $this->handleCanceled($payload),
default => null,
};
return response()->json(['ok' => true]);
}
private function handleActivated(array $payload): void
{
// handle activation
}
private function handleCanceled(array $payload): void
{
// handle cancellation
}
}Exclude the webhook route from CSRF verification:
->withMiddleware(function (Middleware $middleware) {
$middleware->validateCsrfTokens(except: [
'webhooks/commet',
]);
})Routes
<?php
use App\Http\Controllers\BillingController;
use App\Http\Controllers\WebhookController;
use Illuminate\Support\Facades\Route;
Route::post('/billing/subscribe', [BillingController::class, 'subscribe']);
Route::get('/billing/subscription/{externalId}', [BillingController::class, 'getSubscription']);
Route::get('/billing/features/{feature}/{externalId}', [BillingController::class, 'checkFeature']);
Route::post('/billing/usage', [BillingController::class, 'trackUsage']);
Route::get('/billing/portal', [BillingController::class, 'portal']);
Route::post('/webhooks/commet', [WebhookController::class, 'handle']);Related
How is this guide?