Tutorial API

Cara Solve Callback reCAPTCHA v2 Menggunakan API

Beberapa situs menerapkan reCAPTCHA v2 dengan callback function alih-alih field tersembunyi g-recaptcha-response standar. Saat Anda solve CAPTCHA dan memasukkan token ke field tersembunyi, tidak ada yang terjadi — halaman mengabaikannya karena situs mengharapkan Anda memanggil JavaScript function dengan token tersebut.

Panduan ini menunjukkan cara mendeteksi reCAPTCHA v2 berbasis callback, solve via API CaptchaAI, dan invoke callback dengan benar. Panggilan API identik dengan reCAPTCHA v2 standar — hanya langkah inject token yang berbeda.

Baru mengenal reCAPTCHA v2? Mulailah dengan Cara Solve reCAPTCHA v2 Menggunakan API untuk alur standar, lalu kembali ke sini untuk varian callback.


Prasyarat

Item Detail
API key CaptchaAI Dapatkan dari captchaai.com/api.php. String 32 karakter.
URL halaman target URL lengkap tempat widget reCAPTCHA v2 dimuat.
Sitekey reCAPTCHA v2 Kunci publik yang terkait dengan instance widget.
Browser automation tool Selenium, Puppeteer, atau Playwright — Anda membutuhkan eksekusi JavaScript untuk invoke callback.
Nama callback function Fungsi JavaScript yang diharapkan situs untuk menerima token.

Cara Mengidentifikasi Implementasi Callback

reCAPTCHA v2 standar menulis token yang diselesaikan ke textarea tersembunyi g-recaptcha-response. Implementasi callback melewati itu dan memanggil JavaScript function secara langsung. Berikut cara membedakannya.

Metode 1: Periksa atribut data-callback

Periksa div widget reCAPTCHA di source halaman:

<div class="g-recaptcha"
     data-sitekey="6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
     data-callback="SubmitToken">
</div>

Jika data-callback ada, situs menggunakan callback. Nilainya (SubmitToken) adalah nama function yang Anda butuhkan.

Metode 2: Periksa panggilan grecaptcha.render()

Cari JavaScript halaman untuk grecaptcha.render:

grecaptcha.render('recaptcha-container', {
  sitekey: '6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-',
  callback: userVerified
});

Properti callback memberikan nama function. Dalam hal ini, userVerified.

Metode 3: Periksa konfigurasi reCAPTCHA internal

Buka konsol browser di halaman target dan jalankan:

___grecaptcha_cfg.clients[0]

Navigasikan pohon objek untuk menemukan properti callback. Path pastinya berbeda di setiap situs — mungkin clients[0].aa.l.callback atau lainnya tergantung versi reCAPTCHA dan minifikasinya. Jika halaman memiliki beberapa instance reCAPTCHA, cek clients[1], clients[2], dll.

Script Deteksi Cepat

Jalankan ini di konsol browser untuk menemukan nama callback secara otomatis:

// Check data-callback attributes
document.querySelectorAll('[data-callback]').forEach(el => {
  console.log('data-callback:', el.getAttribute('data-callback'));
});

// Check internal config
if (typeof ___grecaptcha_cfg !== 'undefined') {
  Object.keys(___grecaptcha_cfg.clients).forEach(key => {
    const client = ___grecaptcha_cfg.clients[key];
    console.log(`Client ${key}:`, JSON.stringify(client, null, 2));
  });
}

Perbedaan Callback Solve vs v2 Standar

Panggilan API ke CaptchaAI identik. Satu-satunya perbedaan adalah apa yang Anda lakukan dengan token setelah diterima.

Langkah v2 Standar v2 Callback
1. Submit ke CaptchaAI method=userrecaptcha + sitekey + pageurl Sama
2. Poll hasil action=get + captcha ID Sama
3. Terima token Format token sama Sama
4. Inject token Set nilai field g-recaptcha-response Invoke callback function dengan token
5. Submit form Trigger form submission Biasanya otomatis — callback menanganinya

Penting: Jangan set g-recaptcha-response pada implementasi berbasis callback. Halaman mengabaikan field tersebut dan menunggu callback function dipanggil. Set field tanpa invoke callback membuat CAPTCHA tampak belum solved.


Aliran penyelesaian

Page → extract sitekey + pageurl + callback name
                    ↓
      POST to in.php (method=userrecaptcha)
                    ↓
           receive captcha ID
                    ↓
         wait 15–20 seconds
                    ↓
      GET res.php (action=get, id=…)
          ↓                    ↓
   CAPCHA_NOT_READY       status=1 → token
    (wait 5s, retry)            ↓
                     invoke callback(token)
                              ↓
               site processes token automatically

Implementasi Python (Selenium)

import time
import requests
from selenium import webdriver
from selenium.webdriver.common.by import By

API_KEY = "YOUR_CAPTCHAAI_API_KEY"
SITEKEY = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
PAGE_URL = "https://staging.example.com/qa-login"
CALLBACK_NAME = "SubmitToken"  # The callback function name from the page

SUBMIT_URL = "https://ocr.captchaai.com/in.php"
RESULT_URL = "https://ocr.captchaai.com/res.php"


def solve_recaptcha_v2(api_key, sitekey, pageurl):
    """Submit a reCAPTCHA v2 task and return the solved token."""

    # Step 1: Submit the captcha
    submit_resp = requests.post(
        SUBMIT_URL,
        data={
            "key": api_key,
            "method": "userrecaptcha",
            "googlekey": sitekey,
            "pageurl": pageurl,
            "json": 1,
        },
        timeout=30,
    )
    submit_resp.raise_for_status()
    submit_data = submit_resp.json()

    if submit_data.get("status") != 1:
        raise RuntimeError(f"Submit failed: {submit_data}")

    captcha_id = submit_data["request"]
    print(f"Task created — captcha ID: {captcha_id}")

    # Step 2: Wait before first poll
    time.sleep(15)

    # Step 3: Poll for result
    for _ in range(60):
        result_resp = requests.get(
            RESULT_URL,
            params={
                "key": api_key,
                "action": "get",
                "id": captcha_id,
                "json": 1,
            },
            timeout=30,
        )
        result_resp.raise_for_status()
        result_data = result_resp.json()

        if result_data.get("request") == "CAPCHA_NOT_READY":
            time.sleep(5)
            continue

        if result_data.get("status") == 1:
            return result_data["request"]

        raise RuntimeError(f"Polling error: {result_data}")

    raise TimeoutError("reCAPTCHA v2 solve timed out")


def detect_callback_name(driver):
    """Detect the reCAPTCHA callback function name from the page."""

    # Try data-callback attribute first
    callback = driver.execute_script("""
        const el = document.querySelector('[data-callback]');
        if (el) return el.getAttribute('data-callback');
        return null;
    """)
    if callback:
        return callback

    # Try internal reCAPTCHA config
    callback = driver.execute_script("""
        if (typeof ___grecaptcha_cfg === 'undefined') return null;
        const clients = ___grecaptcha_cfg.clients;
        for (const key of Object.keys(clients)) {
            const client = clients[key];
            // Walk the object tree to find a callback function
            const json = JSON.stringify(client);
            const match = json.match(/"callback":"(\\w+)"/);
            if (match) return match[1];
        }
        return null;
    """)
    return callback


# Main workflow
driver = webdriver.Chrome()
driver.get(PAGE_URL)

# Detect the callback name (or use the known name)
detected = detect_callback_name(driver)
callback_name = detected or CALLBACK_NAME
print(f"Using callback: {callback_name}")

# Solve the CAPTCHA
token = solve_recaptcha_v2(API_KEY, SITEKEY, PAGE_URL)
print(f"Solved token: {token[:80]}...")

# Invoke the callback with the token
driver.execute_script(f"{callback_name}(arguments[0]);", token)
print("Callback invoked — site should process the token automatically")

# Wait for the page to process
time.sleep(3)
driver.quit()

Yang dilakukan kode ini:

  1. Submit sitekey dan pageurl ke in.php dengan method=userrecaptcha — identik dengan v2 standar.
  2. Poll res.php setiap 5 detik hingga token siap.
  3. Deteksi nama callback function dari DOM halaman.
  4. Invoke callback function dengan solved token menggunakan execute_script.
  5. JavaScript situs menangani sisanya — form submission, validasi, atau page redirect.

Implementasi Node.js (Puppeteer)

const puppeteer = require("puppeteer");

const API_KEY = "YOUR_CAPTCHAAI_API_KEY";
const SITEKEY = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-";
const PAGE_URL = "https://staging.example.com/qa-login";
const CALLBACK_NAME = "SubmitToken";

const SUBMIT_URL = "https://ocr.captchaai.com/in.php";
const RESULT_URL = "https://ocr.captchaai.com/res.php";

function sleep(ms) {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function solveRecaptchaV2(apiKey, sitekey, pageurl) {
  // Step 1: Submit the captcha
  const submitResp = await fetch(SUBMIT_URL, {
    method: "POST",
    headers: { "Content-Type": "application/x-www-form-urlencoded" },
    body: new URLSearchParams({
      key: apiKey,
      method: "userrecaptcha",
      googlekey: sitekey,
      pageurl: pageurl,
      json: "1",
    }),
  });

  const submitData = await submitResp.json();
  if (submitData.status !== 1) {
    throw new Error(`Submit failed: ${JSON.stringify(submitData)}`);
  }

  const captchaId = submitData.request;
  console.log(`Task created — captcha ID: ${captchaId}`);

  // Step 2: Wait before first poll
  await sleep(15_000);

  // Step 3: Poll for result
  for (let i = 0; i < 60; i++) {
    const resultResp = await fetch(
      `${RESULT_URL}?${new URLSearchParams({
        key: apiKey,
        action: "get",
        id: captchaId,
        json: "1",
      })}`
    );

    const resultData = await resultResp.json();

    if (resultData.request === "CAPCHA_NOT_READY") {
      await sleep(5_000);
      continue;
    }

    if (resultData.status === 1) {
      return resultData.request;
    }

    throw new Error(`Polling error: ${JSON.stringify(resultData)}`);
  }

  throw new Error("reCAPTCHA v2 solve timed out");
}

async function detectCallbackName(page) {
  return page.evaluate(() => {
    // Try data-callback attribute
    const el = document.querySelector("[data-callback]");
    if (el) return el.getAttribute("data-callback");

    // Try internal config
    if (typeof ___grecaptcha_cfg !== "undefined") {
      const clients = ___grecaptcha_cfg.clients;
      for (const key of Object.keys(clients)) {
        const json = JSON.stringify(clients[key]);
        const match = json.match(/"callback":"(\w+)"/);
        if (match) return match[1];
      }
    }

    return null;
  });
}

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();
  await page.goto(PAGE_URL, { waitUntil: "networkidle2" });

  // Detect callback
  const detected = await detectCallbackName(page);
  const callbackName = detected || CALLBACK_NAME;
  console.log(`Using callback: ${callbackName}`);

  // Solve the CAPTCHA
  const token = await solveRecaptchaV2(API_KEY, SITEKEY, PAGE_URL);
  console.log(`Solved token: ${token.slice(0, 80)}...`);

  // Invoke the callback
  await page.evaluate(
    (name, tkn) => {
      window[name](tkn);
    },
    callbackName,
    token
  );
  console.log("Callback invoked — site should process the token automatically");

  await sleep(3_000);
  await browser.close();
})();

Implementasi PHP

Panggilan API sama di PHP. Invoke callback memerlukan browser context, jadi contoh ini hanya mencakup solving sisi server. Gunakan headless browser tool (mis. PHP WebDriver) untuk langkah inject.

<?php
$apiKey  = "YOUR_CAPTCHAAI_API_KEY";
$sitekey = "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-";
$pageurl = "https://staging.example.com/qa-login";

// Step 1: Submit
$submit = file_get_contents("https://ocr.captchaai.com/in.php?" . http_build_query([
    "key"       => $apiKey,
    "method"    => "userrecaptcha",
    "googlekey" => $sitekey,
    "pageurl"   => $pageurl,
    "json"      => 1,
]));

$submitData = json_decode($submit, true);
if ($submitData["status"] !== 1) {
    die("Submit failed: " . $submit);
}

$captchaId = $submitData["request"];
echo "Task created — captcha ID: $captchaId\n";

// Step 2: Wait and poll
sleep(15);

for ($i = 0; $i < 60; $i++) {
    $result = file_get_contents("https://ocr.captchaai.com/res.php?" . http_build_query([
        "key"    => $apiKey,
        "action" => "get",
        "id"     => $captchaId,
        "json"   => 1,
    ]));

    $resultData = json_decode($result, true);

    if ($resultData["request"] === "CAPCHA_NOT_READY") {
        sleep(5);
        continue;
    }

    if ($resultData["status"] === 1) {
        $token = $resultData["request"];
        echo "Solved token: " . substr($token, 0, 80) . "...\n";
        // Pass $token to your browser automation to invoke the callback
        break;
    }

    die("Polling error: " . $result);
}

Setelah mendapat token di PHP, gunakan browser automation tool (mis. php-webdriver) untuk eksekusi:

SubmitToken("TOKEN_FROM_CAPTCHAAI");

Error Umum

# Error Apa yang terjadi Solusi
1 Set g-recaptcha-response bukan invoke callback Halaman mengabaikan token — form tidak pernah di-submit Temukan nama callback dan invoke dengan token
2 Nama callback function salah JavaScript error: function tidak didefinisikan Cek ulang data-callback, grecaptcha.render(), atau konfigurasi internal
3 Callback ada di client index yang berbeda Instance reCAPTCHA salah ditargetkan di halaman multi-widget Cek ___grecaptcha_cfg.clients[1], clients[2], dll.
4 Invoke callback sebelum halaman siap Function belum didefinisikan dalam page context Tunggu DOMContentLoaded atau networkidle sebelum invoke
5 Menggunakan nama yang ter-minify/obfuscate Nama callback di source rusak Gunakan runtime browser console untuk menemukan referensi function aslinya
6 Mencampur v2 callback dengan invisible v2 Beberapa implementasi invisible juga menggunakan callback Cek apakah data-size="invisible" ada — jika ya, lihat Cara Solve reCAPTCHA Invisible Menggunakan API

Pemecahan Masalah

Token solved tapi halaman tidak bereaksi

Penyebab paling umum: Anda set g-recaptcha-response alih-alih invoke callback. Cek apakah widget memiliki data-callback atau callback di grecaptcha.render(). Jika ya, Anda harus menjalankan function tersebut.

ReferenceError: SubmitToken is not defined

Callback function belum dimuat atau namanya salah. Coba:

  1. Konfirmasi nama dengan cek data-callback atau konfigurasi internal.
  2. Tunggu halaman fully loaded sebelum eksekusi.
  3. Di situs yang di-minify, function mungkin ditetapkan ke variabel — cek window.SubmitToken di konsol.

Token berfungsi di v2 standar tapi gagal di halaman ini

Anda mungkin menghadapi implementasi callback. Ikuti langkah deteksi di atas untuk konfirmasi, lalu beralih ke invoke callback.

ERROR_BAD_TOKEN_OR_PAGEURL

Pasangan sitekey/pageurl tidak valid. Ini error API, tidak terkait callback vs standar. Ekstrak ulang kedua nilai dari halaman.

Halaman memiliki beberapa widget reCAPTCHA

Setiap widget mungkin memiliki callbacknya sendiri. Cek setiap div g-recaptcha atau periksa ___grecaptcha_cfg.clients untuk semua instance yang terdaftar. Cocokkan widget dengan form yang Anda targetkan.

ERROR_CAPTCHA_UNSOLVABLE

Challenge tidak dapat diselesaikan. Coba lagi dengan request baru. Ini tidak spesifik untuk callback.

Untuk referensi error lengkap, lihat Error Solve reCAPTCHA v2 yang Umum.


Mengapa CaptchaAI Berfungsi untuk Ini

Faktor Detail
Panggilan API yang sama Alur submit/poll identik dengan reCAPTCHA v2 standar — tidak ada parameter tambahan yang diperlukan
Success rate 99,5%+ untuk reCAPTCHA v2 (callback dan standar menggunakan solver yang sama)
Kecepatan solve Di bawah 60 detik
Kompatibilitas token Token yang dikembalikan berfungsi dengan inject g-recaptcha-response maupun invoke callback
Harga Paket berbasis thread mulai $15/bulan untuk solve tanpa batas

Token yang dikembalikan CaptchaAI tetap sama terlepas dari cara situs mengimplementasikan reCAPTCHA v2. Perbedaannya sepenuhnya ada pada kode sisi klien — cara Anda mengirim token ke halaman.


Contoh lengkap yang dapat dijalankan

Butuh proyek kerja lengkap dengan pengaturan lingkungan, polling, percobaan ulang, dan penanganan kesalahan?

Lihat contoh lengkap yang dapat dijalankan di GitHub →


Pertanyaan Umum

Apa itu callback reCAPTCHA v2?

Callback adalah JavaScript function yang didaftarkan situs untuk menerima solved reCAPTCHA token. Daripada menulis token ke field tersembunyi g-recaptcha-response, reCAPTCHA memanggil function tersebut secara langsung. Function ini biasanya memicu form submission, validasi, atau page redirect.

Apa perbedaan callback dari reCAPTCHA v2 standar untuk API call?

Tidak ada perbedaan sama sekali. Anda mengirim request method=userrecaptcha yang sama dengan sitekey dan pageurl yang sama. Satu-satunya perbedaan adalah apa yang Anda lakukan dengan token setelah diterima — Anda invoke callback function alih-alih set nilai field.

Bagaimana menemukan nama callback function?

Tiga tempat untuk dicek: (1) atribut data-callback pada div reCAPTCHA, (2) properti callback dalam panggilan grecaptcha.render() di JavaScript halaman, (3) objek ___grecaptcha_cfg.clients[0] di browser console — navigasikan pohon untuk menemukan properti callback.

Bisakah saya menggunakan token dengan kedua metode?

Token itu sendiri berfungsi baik. Namun jika situs mengharapkan callback, set g-recaptcha-response akan diabaikan. Selalu sesuaikan metode inject dengan yang diharapkan situs.

Apakah saya perlu browser untuk invoke callback?

Ya. Callback adalah JavaScript function dalam page context. Anda memerlukan Selenium, Puppeteer, Playwright, atau tool serupa yang dapat menjalankan JavaScript di halaman target.


Mulai Solve Callback reCAPTCHA v2

  1. Dapatkan API keycaptchaai.com/api.php
  2. Deteksi nama callback — cek data-callback, grecaptcha.render(), atau konfigurasi internal
  3. Salin kode Python atau Node.js di atas — ganti placeholder dengan key, sitekey, pageurl, dan callback name Anda
  4. Jalankan — token tiba dalam waktu kurang dari 60 detik, panggilan balik diaktifkan, dan halaman memproses hasilnya
  5. Terjebak? Mulailah denganKesalahan Penyelesaian reCAPTCHA v2 yang Umumatau baca selengkapnyadokumen API CaptchaAI

Artikel Terkait

Komentar dinonaktifkan untuk artikel ini.