NODE ONLINE // REGION EU-CENTRAL-03 LAT 12ms UTC --:--:--
BONUS 10% up to $50 · 15% $50–$200 · 25% above $200 — credited automatically on every deposit · min $10 DEPOSIT NOW ▸
FREE New users get 50 free checks on Fast Checker CREATE ACCOUNT ▸
HOME / GUIDES / CARD CHECKER API IN PHP: CURL INTEGRATION GUIDE

Card Checker API in PHP

root@c4check:~$ cat /var/lib/guides/card-checker-api-php.md
──────────────────────────────────────────────────────────────────────────────────────────────

KEY TAKEAWAYS

  • Use cURL with connect and total timeouts.
  • Return structured errors instead of throwing on transport issues.
  • Retry only 5xx/429/transport failures.
  • Never log card data or keys.
  • Generated test numbers are checksum-valid and never chargeable.
  • Deduplicate and validate before any paid the PHP integration request.

This PHP client uses cURL with explicit timeouts and status handling — the pattern that survives production network conditions.

Client

function check_card(string $card, string $gateway): array {
    $key = getenv('CARD_CHECKER_API_KEY');
    $url = 'https://c4check.com/api/v1/api.php?' . http_build_query([
        'gateway' => $gateway,
        'cc' => $card,
        'json' => '1',
    ]);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ['X-API-Key: ' . $key],
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_TIMEOUT => 60,
    ]);
    $body = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
    $err = curl_error($ch);
    curl_close($ch);

    if ($body === false) {
        return ['status' => false, 'error' => 'transport: ' . $err];
    }
    if ($code >= 500 || $code === 429) {
        return ['status' => false, 'error' => 'retryable http ' . $code];
    }
    $data = json_decode($body, true);
    return is_array($data) ? $data : ['status' => false, 'error' => 'bad json'];
}

Retry policy

Sleep with exponential backoff on the retryable branch, cap at three attempts, and never retry a request that already returned a result. Idempotency on the server keeps repeated request IDs safe. Details in error handling.

Logging discipline

  • Log the result state and remaining balance — not the card string.
  • Mask any card reference as first-six/last-four.
  • Store the API key outside version control.

Format validation before the call: PHP Luhn guide.

PHP integrations map cleanly onto the API's minimal contract: a GET request with a header key, a JSON body, and results that should be branched on the result field rather than the HTTP status. Keep the key in an environment variable or config outside the web root, and log outcomes — never the card.

The sample below uses cURL directly, sets a bounded timeout, and returns the decoded response array.

C4CHECK API documentation with authentication and response examples
The API documentation covers authentication, request parameters, result fields and billing rules.
Dashboard where the API key and check activity are managed
Your API key, balance and checking activity live on the account dashboard.

A concrete the PHP integration example

$key = getenv("C4CHECK_KEY");
$q = http_build_query([
    "gateway" => $gateway,
    "cc" => $card,
    "json" => 1,
]);
$ch = curl_init("https://c4check.com/api/v1/api.php?" . $q);
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTPHEADER => ["X-API-Key: " . $key],
]);
$body = json_decode(curl_exec($ch), true);

Errors produce no classification and no charge, which makes a careful retry strategy effectively free. Log request identifiers and outcomes, never full card numbers or the API key itself. A machine-readable OpenAPI description is available for Postman, Insomnia and client generation. It is a small rule that changes how the PHP integration behaves at scale.

Automating the PHP integration through the API

Every response returns the current balance and the amount charged, so spend can be tracked without a second call. Add a circuit breaker: when the error rate crosses a threshold, pause the run and move the remainder to the fallback route. Idempotency is your responsibility on the calling side; networks retry, and a retry without protection can duplicate work. Errors produce no classification and no charge, which makes a careful retry strategy effectively free. Write it down; the PHP integration workflows live and die on small consistencies.

Security rules for the PHP integration

The dashboard shows the key once and lets you rotate it at will; rotation is cheap, leaks are not. Log identifiers and outcomes, not card numbers. Debugging almost never requires a PAN. API keys are server-side secrets: they belong in environment configuration, never in URLs, logs or client bundles. Encrypted transport and account-scoped access are defaults; nothing about the integration requires changing them. Holding that line is what makes the PHP integration reliable over time.

From the PHP integration result to decision

  • Errors in the PHP integration return to the queue after the cause is fixed, because they produced no answer at all.
  • Dead results in the PHP integration route to recovery: dunning, an update-payment prompt or list cleanup.
  • In the PHP integration, live results route forward: billing, approval or completion, depending on the workflow.
  • Unknown results in the PHP integration get one fallback pass on a second route, then a defined resting state.

The honest reading of unknown is "no answer yet". The card is neither good nor bad, and the remedy is a different route, not a repeat of the same one. A live answer is evidence about the account, not a guarantee about a specific future transaction; issuer rules can change between the check and the charge. Dead results are conclusive for the moment and should never be re-checked in the same run; retries on dead cards spend balance for identical answers. In the PHP integration work, that is the difference between a signal and a guess.

Putting the PHP integration to work

Deduplicate before submitting: the same card in a list twice is billed twice if both copies classify. Start with a pilot of fifty cards. It surfaces format mismatches and routing surprises while the cost of being wrong is still measured in cents. Decide how each outcome is handled before the run starts; a triage plan written after the results arrive is usually just a spreadsheet. Treat every large list as two lists: the part that classifies on the first pass, and the remainder that needs a decision about how hard to chase. In the PHP integration work, that is the difference between a signal and a guess.

What the PHP integration cannot promise

A check does not move money, does not create a charge and does not touch the cardholder's credit file. When a proposed use cannot be explained to a compliance reviewer in one sentence, it is probably not a fit. The platform does not trade card data, and nothing in the system is designed to bypass a cardholder's consent. That distinction is what keeps the PHP integration decisions clean.

Operating the PHP integration at scale

Document the route, the batch policy and the retry rules next to each production run; six months later that note is the diagnosis. Treat provider outages as routing problems: switch routes, recover the unclassified remainder, keep the answers you already paid for. Alert on classified-rate drops, not just on errors; silent degradation is the expensive kind. A written triage table — one action per result class — keeps large runs mechanical and auditable. The habit costs nothing and removes a recurring class of mistakes.

What each the PHP integration outcome commits you to

Classified rate is the share of cards that produce a definitive answer; it is the first number to compare when switching gateways. Dead results are conclusive for the moment and should never be re-checked in the same run; retries on dead cards spend balance for identical answers. When a result contradicts other evidence, re-check once after a reasonable interval rather than assuming the checker is wrong. Two metrics describe any run: how many cards classify, and how long the pass takes. Everything else is commentary. It is a small rule that changes how the PHP integration behaves at scale.

Keep exploring the PHP integration

QUESTIONS & ANSWERS

FAQ
Why set two timeouts in cURL?

CONNECTTIMEOUT bounds connection establishment; TIMEOUT bounds the whole request — both protect your worker pool.

How do I detect a billed vs unbilled failure?

If status is false, the check did not produce a classification and is not billed.

Can I process batches in PHP?

Yes, but bound parallelism with curl_multi or a queue to respect gateway limits.

Can the PHP integration work without the CVV?

Some gateways accept number-and-expiry input and still return a classification, usually with a higher unknown rate. Whether the code is required depends on the gateway and the issuer rules behind it.

How should unknowns be handled in the PHP integration?

Unknown means the issuer gave no definitive answer, often a challenge or soft decline. The card is unclassified, not bad; give it one fallback pass on a second route, then park it rather than looping.

What throughput should be expected from the PHP integration?

Throughput comes from the provider ceiling and the concurrency configured per gateway. The safe configuration is the recommended one, approached from below, with a pilot batch to calibrate a real list.

PUT THIS INTO PRACTICE

START HERE

Open a checker, paste your list and stream live results. New accounts can fund with BTC or LTC and pay per check.

Open checkers Create account API docs