isSuccess()Whether VettiGuard accepted the response token.
The dependency-free verifier supports cURL and PHP streams, returns a typed result object, and keeps the private site secret entirely on your server.
Place VettiGuardVerifier.php outside your public web root where possible, then require it from the form handler that performs server-side validation.
require __DIR__ . '/VettiGuardVerifier.php'; use VettiGuardSdk\VettiGuardVerifier;
The secret must come from server-side configuration. Never place it in HTML, browser JavaScript, logs, or client-visible error messages.
$verifier = new VettiGuardVerifier(
'https://api.vettiguard.com/v1/siteverify',
getenv('VETTIGUARD_SECRET_KEY') ?: '',
12
);Require success, the expected action, an allowed hostname, and the score policy that applies to the protected operation.
$result = $verifier->verify(
$_POST['vettiguard-response'] ?? '',
$_SERVER['REMOTE_ADDR'] ?? null,
'account-registration'
);
if (!$result->isSuccess()
|| $result->action() !== 'account-registration'
|| $result->hostname() !== 'example.com'
|| $result->score() < 0.50) {
http_response_code(422);
exit('Verification failed. Please try again.');
}
// Perform the protected action only here.The result object exposes the fields required to make a server-side decision.
isSuccess()Whether VettiGuard accepted the response token.
errors()Validation or transport error codes returned by the service.
action()The action bound to the original widget request.
hostname()The hostname that completed the browser challenge.
score()The server-only risk score from 0.0 to 1.0.
isScoreEnforced()Whether VettiGuard already enforced the site threshold.
challengeType()The verification mode that produced the token.
challengeVariant()The visual variant, such as identify or drag-and-drop.
toArray()The complete decoded verification payload.
This is the same source shipped in the VettiGuard application package.
<?php
declare(strict_types=1);
namespace VettiGuardSdk;
final class VerificationResult
{
public function __construct(private readonly array $payload)
{
}
public function isSuccess(): bool
{
return (bool) ($this->payload['success'] ?? false);
}
public function score(): float
{
return (float) ($this->payload['score'] ?? 0.0);
}
public function scoreThreshold(): float
{
return (float) ($this->payload['score_threshold'] ?? 0.0);
}
public function isScoreEnforced(): bool
{
return (bool) ($this->payload['score_enforced'] ?? true);
}
public function challengeType(): ?string
{
$type = $this->payload['challenge_type'] ?? null;
return is_string($type) && $type !== '' ? $type : null;
}
public function challengeVariant(): ?string
{
$variant = $this->payload['challenge_variant'] ?? null;
return is_string($variant) && $variant !== '' ? $variant : null;
}
public function challengeTimestamp(): ?string
{
$timestamp = $this->payload['challenge_ts'] ?? null;
return is_string($timestamp) && $timestamp !== '' ? $timestamp : null;
}
public function action(): ?string
{
$action = $this->payload['action'] ?? null;
return is_string($action) && $action !== '' ? $action : null;
}
public function hostname(): ?string
{
$hostname = $this->payload['hostname'] ?? null;
return is_string($hostname) && $hostname !== '' ? $hostname : null;
}
public function assessmentId(): ?string
{
$assessmentId = $this->payload['assessment_id'] ?? null;
return is_string($assessmentId) && preg_match('/^[0-9a-f-]{36}$/i', $assessmentId) === 1 ? $assessmentId : null;
}
public function errors(): array
{
$errors = $this->payload['error-codes'] ?? [];
if (is_array($errors) && $errors !== []) {
return array_values(array_map('strval', $errors));
}
$singleError = $this->payload['error'] ?? null;
return is_string($singleError) && $singleError !== '' ? [$singleError] : [];
}
public function toArray(): array
{
return $this->payload;
}
}
final class VettiGuardVerifier
{
public const PRODUCTION_API_BASE_URL = 'https://api.vettiguard.com/v1';
public const PRODUCTION_VERIFY_URL = self::PRODUCTION_API_BASE_URL . '/siteverify';
private readonly string $verifyUrl;
private readonly string $feedbackUrl;
private readonly string $secret;
private readonly int $timeoutSeconds;
public function __construct(string $verifyUrl, string $secret, int $timeoutSeconds = 10)
{
$this->verifyUrl = self::normalizeVerifyUrl($verifyUrl);
$this->feedbackUrl = preg_replace('#/siteverify$#', '/detection/feedback', $this->verifyUrl) ?: rtrim($this->verifyUrl, '/') . '/detection/feedback';
$this->secret = trim($secret);
$this->timeoutSeconds = max(1, min(60, $timeoutSeconds));
if ($this->secret === '') {
throw new \InvalidArgumentException('The CAPTCHA secret is required.');
}
}
public static function production(string $secret, int $timeoutSeconds = 10): self
{
return new self(self::PRODUCTION_VERIFY_URL, $secret, $timeoutSeconds);
}
private static function normalizeVerifyUrl(string $value): string
{
$value = rtrim(trim($value), '/');
if ($value === '') {
$value = self::PRODUCTION_VERIFY_URL;
}
$parts = parse_url($value);
if (!is_array($parts) || !in_array(strtolower((string) ($parts['scheme'] ?? '')), ['http', 'https'], true) || empty($parts['host'])) {
throw new \InvalidArgumentException('A valid verification URL is required.');
}
$host = strtolower((string) $parts['host']);
$origin = strtolower((string) $parts['scheme']) . '://' . (string) $parts['host'] . (isset($parts['port']) ? ':' . (int) $parts['port'] : '');
$versionPath = $host === 'api.vettiguard.com' ? '/v1' : '/api/v1';
$targetPath = $versionPath . '/siteverify';
$path = '/' . ltrim((string) ($parts['path'] ?? ''), '/');
$path = preg_replace('#(?:/(?:api/)?v1)+(?:/(?:challenge|solve|siteverify|mobile/(?:nonce|attest|challenge|solve|siteverify)))?$#i', $targetPath, $path) ?: $targetPath;
if (!str_ends_with(strtolower($path), strtolower($targetPath))) {
$path = rtrim($path, '/') . $targetPath;
}
return $origin . preg_replace('#/+#', '/', $path);
}
public function verify(string $responseToken, ?string $remoteIp = null, ?string $action = null): VerificationResult
{
if (trim($responseToken) === '') {
return new VerificationResult(['success' => false, 'error-codes' => ['missing-input-response']]);
}
$payload = [
'secret' => $this->secret,
'response' => trim($responseToken),
];
if ($remoteIp !== null && trim($remoteIp) !== '') $payload['remoteip'] = trim($remoteIp);
if ($action !== null && trim($action) !== '') $payload['action'] = trim($action);
$body = http_build_query($payload);
$raw = function_exists('curl_init') ? $this->requestWithCurl($body) : $this->requestWithStreams($body);
$decoded = json_decode($raw, true);
if (!is_array($decoded)) {
return new VerificationResult(['success' => false, 'error-codes' => ['invalid-verification-response']]);
}
return new VerificationResult($decoded);
}
/**
* Submit a privacy-safe customer outcome annotation for a verified assessment.
*
* @return array<string,mixed>
*/
public function submitFeedback(string $assessmentId, string $label, ?string $reasonCode = null): array
{
$assessmentId = trim($assessmentId);
$label = strtolower(trim($label));
if (preg_match('/^[0-9a-f-]{36}$/i', $assessmentId) !== 1) {
throw new \InvalidArgumentException('A valid assessment ID is required.');
}
if (!in_array($label, ['legitimate', 'abuse', 'approved_automation', 'false_positive', 'false_negative'], true)) {
throw new \InvalidArgumentException('Choose a supported detection feedback label.');
}
$payload = ['assessment_id' => $assessmentId, 'label' => $label];
if ($reasonCode !== null && trim($reasonCode) !== '') {
$normalizedReason = strtolower(trim($reasonCode));
$normalizedReason = preg_replace('/[^a-z0-9._-]+/', '-', $normalizedReason) ?: '';
if ($normalizedReason !== '') $payload['reason_code'] = substr($normalizedReason, 0, 48);
}
$body = json_encode($payload, JSON_UNESCAPED_SLASHES);
if (!is_string($body)) {
throw new \RuntimeException('Detection feedback could not be encoded.');
}
$raw = function_exists('curl_init')
? $this->requestJsonWithCurl($this->feedbackUrl, $body)
: $this->requestJsonWithStreams($this->feedbackUrl, $body);
$decoded = json_decode($raw, true);
if (!is_array($decoded)) {
return ['success' => false, 'accepted' => false, 'error' => 'invalid-feedback-response'];
}
return $decoded;
}
/** @param array<string,mixed> $event @return array<string,mixed> */
public function assessAccount(array $event): array
{
return $this->postAccountJson('/account/assess', $event);
}
/** @param array<string,mixed> $event @return array<string,mixed> */
public function assessMobileAccount(array $event, string $platform, string $appId): array
{
$event['platform'] = strtolower(trim($platform));
$event['app_id'] = trim($appId);
return $this->postAccountJson('/mobile/account/assess', $event);
}
/** @return array<string,mixed> */
public function submitAccountFeedback(string $assessmentId, string $label, ?string $reasonCode = null): array
{
$payload = ['assessment_id' => $assessmentId, 'label' => $label];
if ($reasonCode !== null && trim($reasonCode) !== '') $payload['reason_code'] = substr(preg_replace('/[^a-z0-9._-]+/', '-', strtolower(trim($reasonCode))) ?: '', 0, 48);
return $this->postAccountJson('/account/feedback', $payload);
}
/** @return array<string,mixed> */
public function submitMobileAccountFeedback(string $assessmentId, string $label, string $platform, string $appId, ?string $reasonCode = null): array
{
$payload = ['assessment_id' => $assessmentId, 'label' => $label, 'platform' => strtolower(trim($platform)), 'app_id' => trim($appId)];
if ($reasonCode !== null && trim($reasonCode) !== '') $payload['reason_code'] = substr(preg_replace('/[^a-z0-9._-]+/', '-', strtolower(trim($reasonCode))) ?: '', 0, 48);
return $this->postAccountJson('/mobile/account/feedback', $payload);
}
/** @return array<string,mixed> */
public function trustAccountDevice(string $subjectId, string $deviceId, string $action = 'trust', ?string $label = null): array
{
$payload = ['subject_id' => $subjectId, 'device_id' => $deviceId, 'action' => $action];
if ($label !== null) $payload['label'] = substr(trim($label), 0, 120);
return $this->postAccountJson('/account/trusted-device', $payload);
}
public function isPasswordBreached(string $password): bool
{
$sha1 = strtoupper(sha1($password));
$response = $this->postAccountJson('/account/password/range', ['prefix' => substr($sha1, 0, 5)]);
$suffix = substr($sha1, 5);
foreach (($response['suffixes'] ?? []) as $candidate) {
if (is_array($candidate) && hash_equals($suffix, strtoupper((string) ($candidate['suffix'] ?? '')))) return true;
}
return false;
}
public function isMobilePasswordBreached(string $password, string $platform, string $appId): bool
{
$sha1 = strtoupper(sha1($password));
$response = $this->postAccountJson('/mobile/account/password/range', ['prefix' => substr($sha1, 0, 5), 'platform' => strtolower(trim($platform)), 'app_id' => trim($appId)]);
$suffix = substr($sha1, 5);
foreach (($response['suffixes'] ?? []) as $candidate) {
if (is_array($candidate) && hash_equals($suffix, strtoupper((string) ($candidate['suffix'] ?? '')))) return true;
}
return false;
}
/** @param array<string,mixed> $event @return array<string,mixed> */
public function assessTransactionFraud(array $event): array
{
return $this->postAccountJson('/fraud/transaction/assess', $event);
}
/** @param array<string,mixed> $event @return array<string,mixed> */
public function assessSmsFraud(array $event): array
{
return $this->postAccountJson('/fraud/sms/assess', $event);
}
/** @param array<string,mixed> $event @return array<string,mixed> */
public function assessEmailFraud(array $event): array
{
return $this->postAccountJson('/fraud/email/assess', $event);
}
/** @return array<string,mixed> */
public function submitFraudFeedback(string $assessmentId, string $label, ?string $reasonCode = null): array
{
$payload = ['assessment_id' => trim($assessmentId), 'label' => strtolower(trim($label))];
if ($reasonCode !== null && trim($reasonCode) !== '') $payload['reason_code'] = substr(preg_replace('/[^a-z0-9._-]+/', '-', strtolower(trim($reasonCode))) ?: '', 0, 48);
return $this->postAccountJson('/fraud/feedback', $payload);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function startSessionIntegrity(array $context): array
{
return $this->postAccountJson('/session/start', $context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function assessSessionIntegrity(array $context): array
{
return $this->postAccountJson('/session/assess', $context);
}
/** @return array<string,mixed> */
public function revokeSessionIntegrity(string $sessionToken, string $reason = 'customer-request'): array
{
return $this->postAccountJson('/session/revoke', ['session_token' => trim($sessionToken), 'reason' => trim($reason)]);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function startMobileSessionIntegrity(array $context, string $platform, string $appId): array
{
$context['platform'] = strtolower(trim($platform));
$context['app_id'] = trim($appId);
return $this->postAccountJson('/mobile/session/start', $context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function assessMobileSessionIntegrity(array $context, string $platform, string $appId): array
{
$context['platform'] = strtolower(trim($platform));
$context['app_id'] = trim($appId);
return $this->postAccountJson('/mobile/session/assess', $context);
}
/** @return array<string,mixed> */
public function revokeMobileSessionIntegrity(string $sessionToken, string $platform, string $appId, string $reason = 'customer-request'): array
{
return $this->postAccountJson('/mobile/session/revoke', ['session_token' => trim($sessionToken), 'reason' => trim($reason), 'platform' => strtolower(trim($platform)), 'app_id' => trim($appId)]);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function assessApiProtection(array $context): array
{
return $this->postAccountJson('/api-protection/assess', $context);
}
/** @return array<string,mixed> */
public function submitApiProtectionFeedback(string $assessmentId, string $label, ?string $reasonCode = null): array
{
$payload=['assessment_id'=>trim($assessmentId),'label'=>strtolower(trim($label))];
if($reasonCode!==null&&trim($reasonCode)!=='')$payload['reason_code']=substr(preg_replace('/[^a-z0-9._-]+/','-',strtolower(trim($reasonCode)))?:'',0,80);
return $this->postAccountJson('/api-protection/feedback',$payload);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function assessMobileApiProtection(array $context, string $platform, string $appId): array
{
$context['platform']=strtolower(trim($platform));$context['app_id']=trim($appId);
return $this->postAccountJson('/mobile/api-protection/assess',$context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function submitMobileApiProtectionFeedback(array $context, string $platform, string $appId): array
{
$context['platform']=strtolower(trim($platform));$context['app_id']=trim($appId);
return $this->postAccountJson('/mobile/api-protection/feedback',$context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function checkRateLimit(array $context): array
{
return $this->postAccountJson('/rate-limit/check', $context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function checkMobileRateLimit(array $context, string $platform, string $appId): array
{
$context['platform']=strtolower(trim($platform));$context['app_id']=trim($appId);
return $this->postAccountJson('/mobile/rate-limit/check',$context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function acquireConcurrency(array $context): array
{
return $this->postAccountJson('/concurrency/acquire', $context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function renewConcurrency(array $context): array
{
return $this->postAccountJson('/concurrency/renew', $context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function releaseConcurrency(array $context): array
{
return $this->postAccountJson('/concurrency/release', $context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function acquireMobileConcurrency(array $context, string $platform, string $appId): array
{
$context['platform']=strtolower(trim($platform));$context['app_id']=trim($appId);
return $this->postAccountJson('/mobile/concurrency/acquire',$context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function renewMobileConcurrency(array $context, string $platform, string $appId): array
{
$context['platform']=strtolower(trim($platform));$context['app_id']=trim($appId);
return $this->postAccountJson('/mobile/concurrency/renew',$context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function releaseMobileConcurrency(array $context, string $platform, string $appId): array
{
$context['platform']=strtolower(trim($platform));$context['app_id']=trim($appId);
return $this->postAccountJson('/mobile/concurrency/release',$context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function admitDependency(array $context): array
{
return $this->postAccountJson('/dependency-resilience/admit', $context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function submitDependencyFeedback(array $context): array
{
return $this->postAccountJson('/dependency-resilience/feedback', $context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function admitMobileDependency(array $context, string $platform, string $appId): array
{
$context['platform']=strtolower(trim($platform));$context['app_id']=trim($appId);
return $this->postAccountJson('/mobile/dependency-resilience/admit',$context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function submitMobileDependencyFeedback(array $context, string $platform, string $appId): array
{
$context['platform']=strtolower(trim($platform));$context['app_id']=trim($appId);
return $this->postAccountJson('/mobile/dependency-resilience/feedback',$context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function orchestrateTrust(array $context): array
{
return $this->postAccountJson('/trust/orchestrate', $context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function verifyTrustReceipt(array $context): array
{
return $this->postAccountJson('/trust/receipt/verify', $context);
}
public function submitTrustOrchestrationFeedback(string $decisionId, string $label, ?string $reasonCode = null): array
{
$payload=['decision_id'=>trim($decisionId),'label'=>strtolower(trim($label))];
if($reasonCode!==null&&trim($reasonCode)!=='')$payload['reason_code']=substr(preg_replace('/[^a-z0-9._-]+/','-',strtolower(trim($reasonCode)))?:'',0,80);
return $this->postAccountJson('/trust/feedback',$payload);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function orchestrateMobileTrust(array $context, string $platform, string $appId): array
{
$context['platform']=strtolower(trim($platform));$context['app_id']=trim($appId);
return $this->postAccountJson('/mobile/trust/orchestrate',$context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function verifyMobileTrustReceipt(array $context, string $platform, string $appId): array
{
$context['platform']=strtolower(trim($platform));$context['app_id']=trim($appId);
return $this->postAccountJson('/mobile/trust/receipt/verify',$context);
}
/** @param array<string,mixed> $context @return array<string,mixed> */
public function submitMobileTrustOrchestrationFeedback(array $context, string $platform, string $appId): array
{
$context['platform']=strtolower(trim($platform));$context['app_id']=trim($appId);
return $this->postAccountJson('/mobile/trust/feedback',$context);
}
/** @param array<string,mixed> $request @return array<string,mixed> */
public function decideAtEdge(array $request): array
{
return $this->postAccountJson('/edge/decision', $request);
}
/** @param array<string,mixed> $request @return array<string,mixed> */
public function issueEdgePreclearance(array $request): array
{
return $this->postAccountJson('/edge/preclearance/issue', $request);
}
/** @param array<string,mixed> $request @return array<string,mixed> */
public function verifyEdgePreclearance(array $request): array
{
return $this->postAccountJson('/edge/preclearance/verify', $request);
}
/**
* Build an exact JSON body and HMAC headers for Ozibus-to-VettiGuard requests.
*
* @param array<string,mixed> $payload
* @return array{body:string,headers:array<string,string>}
*/
public static function signOzibusRequest(string $signingSecret, int $workspaceId, array $payload, ?int $timestamp = null): array
{
$signingSecret = trim($signingSecret);
if ($signingSecret === '' || $workspaceId < 1) throw new \InvalidArgumentException('An Ozibus signing secret and workspace ID are required.');
$body = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
if (!is_string($body)) throw new \RuntimeException('The Ozibus request could not be encoded.');
$timestamp ??= time();
$signature = hash_hmac('sha256', $timestamp . '.' . $body, $signingSecret);
return ['body'=>$body,'headers'=>[
'Content-Type'=>'application/json',
'Accept'=>'application/json',
'X-VettiGuard-Workspace'=>(string)$workspaceId,
'X-VettiGuard-Timestamp'=>(string)$timestamp,
'X-VettiGuard-Signature'=>$signature,
]];
}
/**
* Build an exact JSON body and replay-resistant HMAC headers for Agent Trust.
*
* @param array<string,mixed> $payload
* @return array{body:string,headers:array<string,string>}
*/
public static function signAgentRequest(string $agentId, string $signingSecret, array $payload, ?int $timestamp = null, ?string $nonce = null): array
{
$agentId = trim($agentId);
$signingSecret = trim($signingSecret);
if ($agentId === '' || $signingSecret === '') throw new \InvalidArgumentException('An Agent Trust identity and signing secret are required.');
$body = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
if (!is_string($body)) throw new \RuntimeException('The agent request could not be encoded.');
$timestamp ??= time();
$nonce = trim((string) $nonce);
if ($nonce === '') $nonce = rtrim(strtr(base64_encode(random_bytes(24)), '+/', '-_'), '=');
if (preg_match('/^[A-Za-z0-9_-]{16,128}$/', $nonce) !== 1) throw new \InvalidArgumentException('The agent request nonce is invalid.');
$signature = hash_hmac('sha256', $timestamp . '.' . $nonce . '.' . $body, $signingSecret);
return ['body'=>$body,'headers'=>[
'Content-Type'=>'application/json',
'Accept'=>'application/json',
'X-VettiGuard-Agent'=>$agentId,
'X-VettiGuard-Timestamp'=>(string)$timestamp,
'X-VettiGuard-Nonce'=>$nonce,
'X-VettiGuard-Signature'=>$signature,
]];
}
/** @param array<string,mixed> $payload @return array<string,mixed> */
private function postAccountJson(string $path, array $payload): array
{
$payload['secret'] = $this->secret;
$body = json_encode($payload, JSON_UNESCAPED_SLASHES);
if (!is_string($body)) throw new \RuntimeException('Account Defence request could not be encoded.');
$base = preg_replace('~/siteverify$~', '', $this->verifyUrl) ?: $this->verifyUrl;
$url = rtrim($base, '/') . $path;
$raw = function_exists('curl_init') ? $this->requestJsonWithCurl($url, $body) : $this->requestJsonWithStreams($url, $body);
$decoded = json_decode($raw, true);
return is_array($decoded) ? $decoded : ['success' => false, 'error' => 'invalid-account-defence-response'];
}
private function requestJsonWithCurl(string $url, string $body): string
{
$handle = curl_init($url);
if ($handle === false) return '{}';
curl_setopt_array($handle, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer ' . $this->secret,
'Accept: application/json',
'Content-Type: application/json',
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => min(5, $this->timeoutSeconds),
CURLOPT_TIMEOUT => $this->timeoutSeconds,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
]);
$response = curl_exec($handle);
$status = (int) curl_getinfo($handle, CURLINFO_RESPONSE_CODE);
curl_close($handle);
return is_string($response) && $status >= 200 && $status < 500 ? $response : '{}';
}
private function requestJsonWithStreams(string $url, string $body): string
{
$context = stream_context_create(['http' => [
'method' => 'POST',
'header' => implode("\r\n", [
'Authorization: Bearer ' . $this->secret,
'Accept: application/json',
'Content-Type: application/json',
]) . "\r\n",
'content' => $body,
'timeout' => $this->timeoutSeconds,
'ignore_errors' => true,
'follow_location' => 0,
]]);
$response = @file_get_contents($url, false, $context);
return is_string($response) ? $response : '{}';
}
private function requestWithCurl(string $body): string
{
$handle = curl_init($this->verifyUrl);
if ($handle === false) {
return '{}';
}
curl_setopt_array($handle, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CONNECTTIMEOUT => $this->timeoutSeconds,
CURLOPT_TIMEOUT => $this->timeoutSeconds,
CURLOPT_FOLLOWLOCATION => false,
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSL_VERIFYHOST => 2,
]);
$response = curl_exec($handle);
$status = (int) curl_getinfo($handle, CURLINFO_RESPONSE_CODE);
curl_close($handle);
return is_string($response) && $status >= 200 && $status < 500 ? $response : '{}';
}
private function requestWithStreams(string $body): string
{
$context = stream_context_create(['http' => [
'method' => 'POST',
'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
'content' => $body,
'timeout' => $this->timeoutSeconds,
'ignore_errors' => true,
'follow_location' => 0,
]]);
$response = @file_get_contents($this->verifyUrl, false, $context);
return is_string($response) ? $response : '{}';
}
}
This action may affect your integration.