zhylon/captcha-php

PHP client for server-side verification of Zhylon Captcha tokens.

Maintainers

Package info

github.com/Zhylon/zhylon-captcha-php

pkg:composer/zhylon/captcha-php

Transparency log

Statistics

Installs: 14

Dependents: 1

Suggesters: 0

Stars: 0

Open Issues: 0

v1.1.0 2026-08-24 16:27 UTC

This package is auto-updated.

Last update: 2026-08-24 16:29:02 UTC


README

Latest Stable Version Tests License

PHP client for server-side verification of Zhylon Captcha tokens.

Installation

composer require zhylon/captcha-php

Usage

use Zhylon\CaptchaPhp\CaptchaClient;

$client = new CaptchaClient(secretKey: 'your-secret-key');

$result = $client->verify($_POST['captcha_token'] ?? null);

if (! $result->success) {
    // $result->reason is one of: invalid_token, config_error, network_error
    // $result->message contains a human-readable explanation
    abort(403, $result->message);
}

CaptchaClient

Parameter Type Default Description
secretKey string Your Zhylon Captcha secret key
verifyUrl string https://captcha.zhylon.net/captcha/siteverify Verification endpoint
timeout int 5 Request timeout in seconds

CaptchaResult

Property Type Description
success bool Whether verification succeeded
reason ?string invalid_token, config_error, or network_error on failure
message ?string Human-readable explanation

Use $result->isTechnicalFailure() to distinguish infrastructure problems (config_error, network_error) from a genuinely invalid token.

Self-hosted challenge/verify proxy

If your widget's JS talks to your own domain instead of captcha.zhylon.net directly, use CaptchaProxy to forward the captcha/challenge and captcha/verify calls to the real Zhylon Captcha host. It reuses the host already configured on your CaptchaClient, so no extra configuration is needed, and it never lets an upstream failure (e.g. a misconfigured endpoint) turn into an uncaught exception — you always get back a status code and a JSON body to relay as-is.

Note: CaptchaProxy::verify() forwards the proof-of-work captcha/verify call (used to obtain a verification_token). It is unrelated to CaptchaClient::verify(), which is the server-side siteverify check performed with your secret key.

use Zhylon\CaptchaPhp\CaptchaClient;
use Zhylon\CaptchaPhp\CaptchaProxy;

$client = new CaptchaClient(secretKey: 'your-secret-key');
$proxy = CaptchaProxy::forClient($client);

Route::get('captcha/challenge', function () use ($proxy) {
    $response = $proxy->challenge(['sitekey' => request()->get('sitekey')]);

    return response()->json($response->body, $response->status);
});

Route::post('captcha/verify', function () use ($proxy) {
    $response = $proxy->verify(request()->only(['nonce', 'solve_ms', 'token']));

    return response()->json($response->body, $response->status);
});

CaptchaProxy

Parameter Type Default Description
baseUrl string https://captcha.zhylon.net Host the challenge/verify calls are forwarded to
timeout int 5 Request timeout in seconds

Use CaptchaProxy::forClient($client) to derive baseUrl automatically from an existing CaptchaClient's verifyUrl.

On an upstream failure (unreachable host, non-2xx response, or invalid JSON), challenge()/verify() return a CaptchaProxyResponse with status = 502 and a body of ['error' => '...'] instead of throwing.

Testing

composer test

License

The MIT License (MIT). See LICENSE for more information.