$params Token delivery POST body from middleware. */ public function buildTokenDeliverySignatureString(array $params): string { return '/square/authorization/token&access_token=' . (string) ($params['access_token'] ?? '') . '&expires_at=' . (string) ($params['expires_at'] ?? '') . '&refresh_token=' . (string) ($params['refresh_token'] ?? '') . '&merchant_id=' . (string) ($params['merchant_id'] ?? ''); } /** * @param array $params */ public function verifyTokenDeliverySignature(array $params): bool { $signature = isset($params['signature']) ? (string) $params['signature'] : ''; return $this->verifySignature($this->buildTokenDeliverySignatureString($params), $signature); } /** * @param mixed $data Webhook payload data (encoded the same way middleware signs it). */ public function verifyWebhookDataSignature($data, ?string $signature): bool { $encoded = json_encode($data); if (!is_string($encoded)) { return false; } return $this->verifySignature($encoded, $signature ?? ''); } public function verifySignature(string $stringToVerify, string $signature): bool { if ($stringToVerify === '' || $signature === '') { return false; } $publicKey = openssl_pkey_get_public(self::MIDDLEWARE_PUBLIC_KEY); if ($publicKey === false) { return false; } $decodedSignature = base64_decode($signature, true); if ($decodedSignature === false) { return false; } return openssl_verify($stringToVerify, $decodedSignature, $publicKey, OPENSSL_ALGO_SHA256) === 1; } }