Commet
  • Pricing
Log InTry out
Introduction

Quickstart

Integrate with PHPIntegrate with LaravelIntegrate with Symfony

Learn

Resources

SDK ReferenceError HandlingTestingCLI

Plugins

Better Auth
DocumentationKnowledge BaseBuild with AIAPI ReferenceWebhooks

Integrate with Symfony

Add billing and payments to your Symfony application.

Install

composer require commet/commet-php

Configure

.env
COMMET_API_KEY=ck_sandbox_xxx
COMMET_WEBHOOK_SECRET=whsec_xxx
config/services.yaml
services:
    Commet\Commet:
        factory: ['@App\Factory\CommetFactory', 'create']

    App\Factory\CommetFactory:
        arguments:
            $apiKey: '%env(COMMET_API_KEY)%'
            $environment: '%kernel.environment%'
src/Factory/CommetFactory.php
<?php

namespace App\Factory;

use Commet\Commet;

class CommetFactory
{
    public function __construct(
        private string $apiKey,
        private string $environment,
    ) {}

    public function create(): Commet
    {
        return new Commet(
            apiKey: $this->apiKey,
            environment: $this->environment === 'prod' ? 'live' : 'sandbox',
        );
    }
}

Subscribe

src/Controller/BillingController.php
<?php

namespace App\Controller;

use Commet\Commet;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Attribute\Route;

class BillingController extends AbstractController
{
    public function __construct(
        private Commet $commet,
    ) {}

    #[Route('/billing/subscribe', methods: ['POST'])]
    public function subscribe(Request $request): JsonResponse
    {
        $data = $request->toArray();

        $this->commet->customers->create(
            email: $data['email'],
            externalId: $data['external_id'],
        );

        $subscription = $this->commet->subscriptions->create(
            externalId: $data['external_id'],
            planCode: 'pro',
        );

        return $this->json([
            'checkout_url' => $subscription->data['checkout_url'],
        ]);
    }
}

Check Access

src/Controller/BillingController.php
#[Route('/billing/subscription/{externalId}', methods: ['GET'])]
public function getSubscription(string $externalId): JsonResponse
{
    $subscription = $this->commet->subscriptions->get(externalId: $externalId);

    return $this->json([
        'status' => $subscription->data['status'],
    ]);
}

#[Route('/billing/features/{feature}/{externalId}', methods: ['GET'])]
public function checkFeature(string $feature, string $externalId): JsonResponse
{
    $result = $this->commet->features->check(code: $feature, externalId: $externalId);

    return $this->json([
        'allowed' => $result->data['allowed'],
    ]);
}

Track Usage

src/Controller/BillingController.php
#[Route('/billing/usage', methods: ['POST'])]
public function trackUsage(Request $request): JsonResponse
{
    $data = $request->toArray();

    $this->commet->usage->track(
        externalId: $data['external_id'],
        feature: 'api_calls',
        value: 1,
    );

    return $this->json(['tracked' => true]);
}

Usage is aggregated and billed at end of period.

Customer Portal

src/Controller/BillingController.php
use Symfony\Component\HttpFoundation\RedirectResponse;

#[Route('/billing/portal', methods: ['GET'])]
public function portal(): RedirectResponse
{
    $result = $this->commet->portal->getUrl(externalId: 'user_123');

    return $this->redirect($result->data['portal_url']);
}

Webhooks

src/Controller/WebhookController.php
<?php

namespace App\Controller;

use Commet\Webhooks;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

class WebhookController extends AbstractController
{
    public function __construct(
        #[Autowire(env: 'COMMET_WEBHOOK_SECRET')]
        private string $webhookSecret,
    ) {}

    #[Route('/webhooks/commet', methods: ['POST'])]
    public function handle(Request $request): JsonResponse|Response
    {
        $webhooks = new Webhooks();

        $payload = $webhooks->verifyAndParse(
            rawBody: $request->getContent(),
            signature: $request->headers->get('x-commet-signature'),
            secret: $this->webhookSecret,
        );

        if ($payload === null) {
            return new Response('Invalid signature', 401);
        }

        match ($payload['event']) {
            'subscription.activated' => $this->handleActivated($payload),
            'subscription.canceled' => $this->handleCanceled($payload),
            default => null,
        };

        return $this->json(['ok' => true]);
    }

    private function handleActivated(array $payload): void
    {
        // handle activation
    }

    private function handleCanceled(array $payload): void
    {
        // handle cancellation
    }
}

Related

  • Subscriptions
  • Track Usage
  • Customer Portal
  • SDK Reference

How is this guide?

Integrate with Laravel

Add billing and payments to your Laravel application.

Manage Customers

Create and manage customers using the Commet SDK and dashboard.

On this page

Install
Configure
Subscribe
Check Access
Track Usage
Customer Portal
Webhooks
Related