Skip to content

HomeDocsDeveloperPHP

Developer

PHP

Mint Reqio HS256 identity tokens on a PHP server using firebase/php-jwt. Compatible with Laravel, Symfony, and plain PHP.

The snippet below is exactly what the dashboard generates under Project > Settings > Identity when you choose PHP. Copy it from the dashboard to get your real project ID and audience URL pre-filled.

Before you start

  • A Reqio project
  • A signing secret generated at Project > Settings > Identity
  1. Install firebase/php-jwt

    Install

    composer require firebase/php-jwt
  2. Mint a token

    <?php
    // composer require firebase/php-jwt
    use Firebase\JWT\JWT;
     
    $now = time();
    $payload = [
        "sub"    => $user->id,
        "email"  => $user->email,
        "traits" => [
            // amount in cents; interval is "month" | "year"
            "plan" => $user->plan,
            "amount" => $user->planAmount,
            "interval" => $user->billingInterval,
            // optional CRM enrichment: 0-100 health, CRM account id, ISO renewal
            "healthScore" => $account->healthScore,
            "accountId" => $account->crmId,
            "renewalAt" => $account->renewalAt,
        ],
        "aud"    => "https://reqio.app/p/YOUR_PROJECT_ID",
        "iat"    => $now,
        "exp"    => $now + 300,
    ];
    $token = JWT::encode($payload, $_ENV["REQIO_SECRET"], "HS256");

    Replace YOUR_PROJECT_ID with your project ID, or copy the full snippet from the dashboard where the audience URL is pre-filled.

    Framework-specific examples:

    <?php
     
    namespace App\Http\Controllers;
     
    use Firebase\JWT\JWT;
    use Illuminate\Http\Request;
     
    class PageController extends Controller
    {
        public function index(Request $request)
        {
            $user = $request->user();
            $now  = time();
     
            $token = JWT::encode(
                [
                    "sub"    => (string) $user->id,
                    "email"  => $user->email,
                    "traits" => [
                        "plan" => $user->plan,
                        "amount" => $user->plan_amount,
                        "interval" => $user->billing_interval,
                    ],
                    "aud"    => config("services.reqio.audience"),
                    "iat"    => $now,
                    "exp"    => $now + 300,
                ],
                config("services.reqio.secret"),
                "HS256"
            );
     
            return view("page", compact("token"));
        }
    }
    {{-- resources/views/page.blade.php --}}
    <script
      src="https://reqio.app/widget.js"
      data-project-id="{{ config('services.reqio.project_id') }}"
      data-identity-token="{{ $token }}"
      async
    ></script>

    Store the audience URL in services.reqio.audience in config/services.php so you do not hardcode it.

  3. Set the environment variable

    Set REQIO_SECRET to the signing secret from Project > Settings > Identity > Reveal secret. Store it in your environment (.env file, server config, or secrets manager) and never echo it into responses.

    Environment variable

    REQIO_SECRET=your-signing-secret
  4. Pass the token to the widget

    For server-rendered templates, pass the token via data-identity-token:

    <script
      src="https://reqio.app/widget.js"
      data-project-id="YOUR_PROJECT_ID"
      data-identity-token="<?= htmlspecialchars($token) ?>"
      async
    ></script>

    For SPAs where the user authenticates after the initial page load, call window.Reqio.identify() from JavaScript after login:

    window.Reqio.identify(token);

Traits reference

planstring
Plan name on your billing system, e.g. "pro".
amountint
Recurring charge as billed, in cents. For annual plans send the full annual total; Reqio divides by 12 to derive the monthly value.
interval"month" | "year"
Billing cadence for amount.

CRM enrichment

healthScoreint (0-100)
CRM account-health score. Reqio clamps out-of-range values.
accountIdstring
Your CRM's external account id. Not displayed, a matching key for a future CRM sync (email first, accountId fallback).
renewalAtstring (ISO 8601 date)
Next renewal date. Unparseable values are dropped by Reqio.

Security

Store REQIO_SECRET in your environment and never echo it into responses. The JWT is short-lived and audience-bound to one project, limiting the blast radius of a leaked token. The signing secret must never leave your server.