Anankke/SSPanel-UIM · error · App\Services\Gateway\Cryptomus\RequestBuilderException
curl_error($curl)
Error message
curl_error($curl)
What it means
This exception is thrown when the cURL call to the Cryptomus API fails at the transport level: curl_exec() returned false, so no HTTP response was ever received. The exception message is the raw libcurl error string (e.g. "Could not resolve host: api.cryptomus.com", "Connection timed out", "SSL certificate problem") and the code is curl_getinfo(CURLINFO_HTTP_CODE), which is 0 because the request never completed. Note that RequestBuilder sets no CURLOPT_CONNECTTIMEOUT/CURLOPT_TIMEOUT, so a hung connection only ends when PHP's max_execution_time aborts the script.
Source
Thrown at src/Services/Gateway/Cryptomus/RequestBuilder.php:57
'sign: ' . md5(base64_encode($body) . $this->secretKey),
];
curl_setopt_array(
$curl,
[
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => 1,
],
);
$response = curl_exec($curl);
$responseCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($response === false) {
throw new RequestBuilderException(curl_error($curl), $responseCode, $uri);
}
if ($response !== '') {
$json = json_decode($response, true);
if ($json === null) {
throw new RequestBuilderException(json_last_error_msg(), $responseCode, $uri);
}
if ($responseCode !== 200 || ($json['state'] !== null && $json['state'] !== 0)) {
if (isset($json['message']) && $json['message'] !== '') {
throw new RequestBuilderException($json['message'], $responseCode, $uri);
}
if (isset($json['errors']) && $json['errors'] !== []) {
throw new RequestBuilderException('Validation error', $responseCode, $uri, $json['errors']);
}
}
View on GitHub (pinned to d55a607191)
Solutions
- From the same host, run: curl -v https://api.cryptomus.com/payment-services to confirm whether the failure is DNS, TCP, or TLS — the exception message mirrors this output.
- If the error mentions SSL certificates, set curl.cainfo / openssl.cafile in php.ini to an up-to-date cacert.pem (https://curl.se/ca/).
- Ensure the environment allows outbound HTTPS to api.cryptomus.com (firewall/egress rules, DNS resolver working, proxy env vars correct or unset if unused).
- Add CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT to the curl_setopt_array call so network hangs fail fast instead of burning max_execution_time.
- Retry with backoff on exception code 0 — transport failures are frequently transient.
Example fix
// before
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => 1,
]);
// after
curl_setopt_array($curl, [
CURLOPT_URL => $url,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $body,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_CONNECTTIMEOUT => 5,
CURLOPT_TIMEOUT => 30,
]);
// caller:
try {
$rb->sendRequest('v1/payment', $data);
} catch (RequestBuilderException $e) {
if ($e->getCode() === 0) { /* transport failure: retry with backoff */ }
} Defensive patterns
Strategy: retry
Validate before calling
// Before constructing RequestBuilder, fail fast on obviously bad config
$secretKey = trim((string) config('cryptomus_key'));
$merchantUuid = trim((string) config('cryptomus_uuid'));
if ($secretKey === '' || $merchantUuid === '') {
throw new InvalidArgumentException('Cryptomus secret key / merchant UUID not configured');
}
// Optional cheap connectivity probe (skips the full payment call)
if (gethostbyname('api.cryptomus.com') === 'api.cryptomus.com') {
throw new RuntimeException('Cannot resolve api.cryptomus.com — check DNS/egress');
} Try / catch
try {
$result = $rb->sendRequest('v1/payment', $data);
} catch (App\Services\Gateway\Cryptomus\RequestBuilderException $e) {
if ($e->getCode() === 0) {
// transport-level curl failure ($e->getMessage() is the curl_error string)
// safe to retry with exponential backoff: 1s, 2s, 4s
return retryWithBackoff(fn () => $rb->sendRequest('v1/payment', $data), 3);
}
throw $e; // real API response — do not blind-retry
} Prevention
- Set CURLOPT_CONNECTTIMEOUT and CURLOPT_TIMEOUT in the builder so hung sockets fail fast instead of stalling the request.
- Monitor exception code 0 separately from HTTP codes — it identifies network problems you can alert or retry on.
- Keep the PHP CA bundle current (curl.cainfo pointing at an up-to-date cacert.pem) on all deployment hosts.
- Verify outbound HTTPS to api.cryptomus.com is allowed when provisioning new servers/containers.
When it happens
Trigger: sendRequest() POSTing to https://api.cryptomus.com/<uri> when: DNS for api.cryptomus.com cannot be resolved; the host or an intermediate firewall drops the TCP connection (timed out / connection refused); TLS negotiation fails (missing/outdated CA bundle on old PHP/cURL builds, e.g. "SSL certificate problem: unable to get local issuer certificate"); the server runs in an environment with no outbound internet (local dev, CI container, restricted production egress); a misconfigured HTTPS proxy env var (http_proxy/HTTPS_PROXY) makes curl dial the wrong host.
Common situations: Panel deployed on a VPS/hosting box with blocked outbound traffic to crypto-related domains; localhost/CI testing without network access; PHP 7.x with an outdated cacert.pem (CRYPTOMus requires TLS to api.cryptomus.com); IPv6-preferring hosts where AAAA lookup fails; corporate proxy not configured into curl.
Related errors
- json_last_error_msg()
- $msg_response->getBody()->getContents()
- $response->getBody()->getContents()
- $msg_response->getBody()->getContents()
AI-assisted analysis of Anankke/SSPanel-UIM@d55a607191 (2026-08-21).
Data as JSON: /api/errors/389e3415545e83c0.
Report an issue: GitHub.