diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9fbb9af
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+# Created by .ignore support plugin (hsz.mobi)
+### Example user template template
+### Example user template
+
+# IntelliJ project files
+.idea
+.idea/misc.xml
+.idea/vcs.xml
+
+*.iml
+out
+gen
+vendor/
diff --git a/LICENSE b/LICENSE
index 20efd1b..afbac21 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
The MIT License (MIT)
-Copyright (c) 2015
+Copyright (c) 2016
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,5 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-
+SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index 7ef97f4..7b8c807 100755
--- a/README.md
+++ b/README.md
@@ -1,5 +1,229 @@
-# php-anticaptcha
+
+
Anticaptcha PHP SDK
-PHP client for Anticaptcha services.
+
+ This library will help you to recognize any captcha via specific services.
+ Easy to install. Easy to use.
+
+
+ packages.org
+ ·
+ anti-captcha.com
+
+
-See examples in the folder example.
\ No newline at end of file
+---
+
+[](https://packagist.org/packages/reilag/php-anticaptcha)
+[](https://packagist.org/packages/reilag/php-anticaptcha)
+[](https://packagist.org/packages/reilag/php-anticaptcha)
+
+---
+
+
+PHP client for [anti-captcha.com](http://getcaptchasolution.com/zi0d4paljn) service.
+This client supports resolving captcha types:
+ - [Captcha from image](#recognize-captcha-from-image)
+ - [reCaptcha V2](#recognize-recaptcha-v2-with-proxy-or-without-invisible)
+ - [Invisible reCaptcha](#recognize-recaptcha-v2-with-proxy-or-without-invisible)
+ - [reCaptcha V2 Enterprise](#recognize-recaptcha-v2-enterprise-with-proxy-or-without)
+ - [reCaptcha V3](#recognize-captcha-from-image)
+ - [reCaptcha V3 Enterprise](#recognize-recaptcha-v3-or-v3-enterprise)
+ - [Turnstile](#recognize-turnstile)
+
+To Do:
+ - FunCaptcha
+ - GeeTest captcha
+ - Solving HCaptcha
+
+
+### Install
+
+You can add Anticaptcha as a dependency using the **composer.phar** CLI:
+```bash
+# Install Composer (if need)
+curl -sS https://getcomposer.org/installer | php
+
+# Add dependency
+composer require reilag/php-anticaptcha:^2.2.0
+```
+
+
+After installing, you need to require Composer's autoloader:
+```php
+require 'vendor/autoload.php';
+```
+
+You can find some examples at [/example](/example) path.
+
+### Create Client
+```php
+use AntiCaptcha\AntiCaptcha;
+
+// Your API key
+$apiKey = '*********** API_KEY **************';
+
+$antiCaptchaClient = new AntiCaptcha(
+ AntiCaptcha::SERVICE_ANTICAPTCHA,
+ [
+ 'api_key' => $apiKey,
+ 'debug' => true
+ ]
+);
+```
+
+
+
+### Recognize captcha from image
+
+```php
+use AntiCaptcha\AntiCaptcha;
+
+// Get file content
+$image = file_get_contents(realpath(dirname(__FILE__)) . '/images/image.jpg');
+
+$imageText = $antiCaptchaClient->recognizeImage($image, null, ['phrase' => 0, 'numeric' => 0], 'en');
+
+echo $imageText;
+```
+
+
+
+### Recognize reCaptcha V2 (with Proxy or without, Invisible)
+
+```php
+$task = new \AntiCaptcha\Task\RecaptchaV2Task(
+ "http://makeawebsitehub.com/recaptcha/test.php", // <-- target website address
+ "6LfI9IsUAAAAAKuvopU0hfY8pWADfR_mogXokIIZ" // <-- recaptcha key from target website
+);
+
+// Value of 'data-s' parameter. Applies only to Recaptchas on Google web sites.
+$task->setRecaptchaDataSValue("some data s-value")
+
+// Specify whether or not reCaptcha is invisible. This will render an appropriate widget for our workers.
+$task->setIsInvisible(true);
+
+// To use Proxy, use this function
+$task->setProxy(
+ "8.8.8.8",
+ 1234,
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116",
+ "http",
+ "login",
+ "password",
+ // also you can add cookie
+ "cookiename1=cookievalue1; cookiename2=cookievalue2"
+);
+
+$response = $antiCaptchaClient->recognizeTask($task);
+
+echo $response['gRecaptchaResponse'];
+```
+
+
+### Recognize reCaptcha V2 Enterprise (with Proxy or without)
+
+```php
+$task = new \AntiCaptcha\Task\RecaptchaV2EnterpriseTask(
+ "http://makeawebsitehub.com/recaptcha/test.php", // <-- target website address
+ "6LfI9IsUAAAAAKuvopU0hfY8pWADfR_mogXokIIZ" // <-- recaptcha key from target website
+);
+
+// Additional array parameters enterprisePayload
+$task->setEnterprisePayload([
+ "s" => "SOME_ADDITIONAL_TOKEN"
+]);
+
+// To use Proxy
+$task->setProxy(
+ "8.8.8.8",
+ 1234,
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116",
+ "http",
+ "login",
+ "password",
+ // also you can add cookie
+ "cookiename1=cookievalue1; cookiename2=cookievalue2"
+);
+
+$response = $antiCaptchaClient->recognizeTask($task);
+
+echo $response['gRecaptchaResponse'];
+```
+
+
+
+### Recognize reCaptcha V3 (or V3 Enterprise)
+
+```php
+$task = new \AntiCaptcha\Task\RecaptchaV3Task(
+ "http://makeawebsitehub.com/recaptcha/test.php", // target website address
+ "6LfI9IsUAAAAAKuvopU0hfY8pWADfR_mogXokIIZ", // recaptcha key from target website
+
+ // Filters workers with a particular score. It can have one of the following values:
+ // 0.3, 0.7, 0.9
+ "0.3"
+);
+
+// Recaptcha's "action" value. Website owners use this parameter to define what users are doing on the page.
+$task->setPageAction("myaction");
+
+// As V3 Enterprise is virtually the same as V3 non-Enterprise, we decided to roll out it’s support within the usual V3 tasks.
+// Set this flag to "true" if you need this V3 solved with Enterprise API. Default value is "false" and
+// Recaptcha is solved with non-enterprise API.
+$reCaptchaV3Task->setIsEnterprise(true);
+
+$response = $antiCaptchaClient->recognizeTask($task);
+
+echo $response['gRecaptchaResponse']; // Return 3AHJ_VuvYIBNBW5yyv0zRYJ75VkOKvhKj9_xGBJKnQimF72rfoq3Iy-DyGHMwLAo6a3
+```
+
+
+
+### Recognize Turnstile
+
+```php
+$task = new \AntiCaptcha\Task\TurnstileTask(
+ // Address of a target web page. Can be located anywhere on the web site, even in a member area.
+ // Our workers don't navigate there but simulate the visit instead.
+ "http://makeawebsitehub.com/recaptcha/test.php",
+ // Turnstile sitekey
+ "6LfI9IsUAAAAAKuvopU0hfY8pWADfR_mogXokIIZ"
+);
+
+// Optional "action" parameter.
+$task->setAction("myaction");
+
+// If you need setup proxy
+$task->setProxy(
+ "8.8.8.8",
+ 1234,
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0",
+ "http",
+ "login",
+ "password",
+ null // also you can add cookie
+);
+
+$response = $antiCaptchaClient->recognizeTask($task);
+
+// Token string required for interacting with the submit form on the target website.
+echo $response['token']; // 0.vtJqmZnvobaUzK2i2PyKaSqHELYtBZfRoPwMvLMdA81WL_9G0vCO3y2VQVIeVplG0mxYF7uX.......
+
+// User-Agent of worker's browser. Use it when you submit the response token.
+echo $response['userAgent']; // Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0
+```
+
+
+
+### Get balance
+```php
+use AntiCaptcha\AntiCaptcha;
+
+$apiKey = '*********** API_KEY **************';
+
+$service = new \AntiCaptcha\Service\AntiCaptcha($apiKey);
+$antiCaptchaClient = new \AntiCaptcha\AntiCaptcha($service);
+
+echo "Your Balance is: " . $antiCaptchaClient->balance() . "\n";
+```
diff --git a/composer.json b/composer.json
index b3c2eec..5635d18 100755
--- a/composer.json
+++ b/composer.json
@@ -1,21 +1,26 @@
{
- "name": "sidcomua/php-anticaptcha",
+ "name": "reilag/php-anticaptcha",
+ "version": "2.2.0",
"type": "library",
- "description": "Anticaptcha",
- "keywords": ["anticaptcha", "php", "antigate", "rucaptcha"],
- "homepage": "https://github.com/sidcomua/php-anticaptcha",
+ "description": "AntiCaptcha - Is PHP Library for working with Anticapthca services",
+ "keywords": ["php", "anticaptcha", "anti-captcha", "antigate", "rucaptcha"],
+ "homepage": "https://github.com/reilag/php-anticaptcha",
"license": "MIT",
"authors": [
{
- "name" : "SID"
+ "name": "Tymchyk Maksym",
+ "email": "reilag69@gmail.com"
}
],
"require": {
- "php": ">=5.4.0",
- "guzzlehttp/guzzle": ">=6",
- "psr/log": "~1"
+ "php": ">=7.2.6",
+ "guzzlehttp/guzzle": "^7.0.1",
+ "psr/log": "~1",
+ "ext-json": "*"
},
"autoload": {
- "classmap": ["src/"]
+ "psr-4": {
+ "AntiCaptcha\\": "src/"
+ }
}
}
\ No newline at end of file
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..dc924d5
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,453 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "511eaaddf07ea88c1ec167399adde269",
+ "packages": [
+ {
+ "name": "guzzlehttp/guzzle",
+ "version": "7.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle.git",
+ "reference": "7008573787b430c1c1f650e3722d9bba59967628"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7008573787b430c1c1f650e3722d9bba59967628",
+ "reference": "7008573787b430c1c1f650e3722d9bba59967628",
+ "shasum": ""
+ },
+ "require": {
+ "ext-json": "*",
+ "guzzlehttp/promises": "^1.4",
+ "guzzlehttp/psr7": "^1.7 || ^2.0",
+ "php": "^7.2.5 || ^8.0",
+ "psr/http-client": "^1.0"
+ },
+ "provide": {
+ "psr/http-client-implementation": "1.0"
+ },
+ "require-dev": {
+ "bamarni/composer-bin-plugin": "^1.4.1",
+ "ext-curl": "*",
+ "php-http/client-integration-tests": "^3.0",
+ "phpunit/phpunit": "^8.5.5 || ^9.3.5",
+ "psr/log": "^1.1"
+ },
+ "suggest": {
+ "ext-curl": "Required for CURL handler support",
+ "ext-intl": "Required for Internationalized Domain Name (IDN) support",
+ "psr/log": "Required for using the Log middleware"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "7.3-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Márk Sági-Kazár",
+ "email": "mark.sagikazar@gmail.com",
+ "homepage": "https://sagikazarmark.hu"
+ }
+ ],
+ "description": "Guzzle is a PHP HTTP client library",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "psr-18",
+ "psr-7",
+ "rest",
+ "web service"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/guzzle/issues",
+ "source": "https://github.com/guzzle/guzzle/tree/7.3.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/GrahamCampbell",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/Nyholm",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/alexeyshockov",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/gmponos",
+ "type": "github"
+ }
+ ],
+ "time": "2021-03-23T11:33:13+00:00"
+ },
+ {
+ "name": "guzzlehttp/promises",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/promises.git",
+ "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/promises/zipball/8e7d04f1f6450fef59366c399cfad4b9383aa30d",
+ "reference": "8e7d04f1f6450fef59366c399cfad4b9383aa30d",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.5"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "^4.4 || ^5.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Promise\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ }
+ ],
+ "description": "Guzzle promises library",
+ "keywords": [
+ "promise"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/promises/issues",
+ "source": "https://github.com/guzzle/promises/tree/1.4.1"
+ },
+ "time": "2021-03-07T09:25:29+00:00"
+ },
+ {
+ "name": "guzzlehttp/psr7",
+ "version": "1.8.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/psr7.git",
+ "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/psr7/zipball/35ea11d335fd638b5882ff1725228b3d35496ab1",
+ "reference": "35ea11d335fd638b5882ff1725228b3d35496ab1",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4.0",
+ "psr/http-message": "~1.0",
+ "ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
+ },
+ "provide": {
+ "psr/http-message-implementation": "1.0"
+ },
+ "require-dev": {
+ "ext-zlib": "*",
+ "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10"
+ },
+ "suggest": {
+ "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.7-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "GuzzleHttp\\Psr7\\": "src/"
+ },
+ "files": [
+ "src/functions_include.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Tobias Schultze",
+ "homepage": "https://github.com/Tobion"
+ }
+ ],
+ "description": "PSR-7 message implementation that also provides common utility methods",
+ "keywords": [
+ "http",
+ "message",
+ "psr-7",
+ "request",
+ "response",
+ "stream",
+ "uri",
+ "url"
+ ],
+ "support": {
+ "issues": "https://github.com/guzzle/psr7/issues",
+ "source": "https://github.com/guzzle/psr7/tree/1.8.1"
+ },
+ "time": "2021-03-21T16:25:00+00:00"
+ },
+ {
+ "name": "psr/http-client",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-client.git",
+ "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
+ "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.0 || ^8.0",
+ "psr/http-message": "^1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Client\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP clients",
+ "homepage": "https://github.com/php-fig/http-client",
+ "keywords": [
+ "http",
+ "http-client",
+ "psr",
+ "psr-18"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-client/tree/master"
+ },
+ "time": "2020-06-29T06:28:15+00:00"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-message/tree/master"
+ },
+ "time": "2016-08-06T14:39:51+00:00"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.1.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
+ "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/log/tree/1.1.3"
+ },
+ "time": "2020-03-23T09:12:05+00:00"
+ },
+ {
+ "name": "ralouphie/getallheaders",
+ "version": "3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ralouphie/getallheaders.git",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
+ "reference": "120b605dfeb996808c31b6477290a714d356e822",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.6"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.1",
+ "phpunit/phpunit": "^5 || ^6.5"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/getallheaders.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ralph Khattar",
+ "email": "ralph.khattar@gmail.com"
+ }
+ ],
+ "description": "A polyfill for getallheaders.",
+ "support": {
+ "issues": "https://github.com/ralouphie/getallheaders/issues",
+ "source": "https://github.com/ralouphie/getallheaders/tree/develop"
+ },
+ "time": "2019-03-08T08:55:37+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=7.2.5"
+ },
+ "platform-dev": [],
+ "plugin-api-version": "2.0.0"
+}
diff --git a/composer.phar b/composer.phar
new file mode 100644
index 0000000..e8b9647
Binary files /dev/null and b/composer.phar differ
diff --git a/example/balance.php b/example/balance.php
index 0006bdd..8bde581 100755
--- a/example/balance.php
+++ b/example/balance.php
@@ -3,10 +3,20 @@
require_once realpath(dirname(dirname(__FILE__))) . '/vendor/autoload.php';
-$apiKey = '*********** API_KEY **************';
+use AntiCaptcha\AntiCaptcha;
+use AntiCaptcha\Service\AntiCaptcha as AntiCaptchaService;
+use AntiCaptcha\Exception\AntiCaptchaException;
-$service = new \Anticaptcha\Service\Antigate($apiKey);
+$apiKey = '********** API_KEY *************';
-$ac = new \Anticaptcha\Anticaptcha($service);
+$service = new AntiCaptchaService($apiKey);
-echo $ac->balance();
\ No newline at end of file
+try {
+ $ac = new AntiCaptcha($service, [
+ 'debug' => true
+ ]);
+
+ echo "Your Balance is: " . $ac->balance() . "\n";
+} catch (AntiCaptchaException $exception) {
+ echo 'Error:' . $exception->getMessage();
+}
\ No newline at end of file
diff --git a/example/recognize-image.php b/example/recognize-image.php
new file mode 100755
index 0000000..ce0f4d3
--- /dev/null
+++ b/example/recognize-image.php
@@ -0,0 +1,20 @@
+ $apiKey, 'debug' => true]);
+
+ // Request image to recognise and waiting for response
+ echo $ac->recognizeImage($image, null, ['phrase' => 0, 'numeric' => 0], 'en');
+} catch (AntiCaptchaException $exception) {
+ echo 'Error:' . $exception->getMessage();
+}
\ No newline at end of file
diff --git a/example/recognize-recaptcha-v2-enterprise.php b/example/recognize-recaptcha-v2-enterprise.php
new file mode 100755
index 0000000..790a3f9
--- /dev/null
+++ b/example/recognize-recaptcha-v2-enterprise.php
@@ -0,0 +1,39 @@
+ $apiKey, 'debug' => true]);
+
+ $task = new RecaptchaV2EnterpriseTask(
+ "http://makeawebsitehub.com/recaptcha/test.php", // <-- target website address
+ "6LfI9IsUAAAAAKuvopU0hfY8pWADfR_mogXokIIZ" // <-- recaptcha key from target website
+ );
+
+ $task->setEnterprisePayload([
+ "s" => "SOME_ADDITIONAL_TOKEN"
+ ]);
+
+ // If you need setup proxy
+ $task->setProxy(
+ "8.8.8.8",
+ 1234,
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116",
+ "http",
+ "login",
+ "password",
+ null // also you can add cookie
+ );
+
+ $response = $acClient->recognizeTask($task);
+
+ echo $response['gRecaptchaResponse'];
+} catch (AntiCaptchaException $exception) {
+ echo 'Error:' . $exception->getMessage();
+}
\ No newline at end of file
diff --git a/example/recognize-recaptcha-v2.php b/example/recognize-recaptcha-v2.php
new file mode 100755
index 0000000..53e1f14
--- /dev/null
+++ b/example/recognize-recaptcha-v2.php
@@ -0,0 +1,35 @@
+ $apiKey, 'debug' => true]);
+
+ $task = new RecaptchaV2Task(
+ "http://makeawebsitehub.com/recaptcha/test.php", // <-- target website address
+ "6LfI9IsUAAAAAKuvopU0hfY8pWADfR_mogXokIIZ" // <-- recaptcha key from target website
+ );
+
+ // If you need setup proxy
+ $task->setProxy(
+ "8.8.8.8",
+ 1234,
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116",
+ "http",
+ "login",
+ "password",
+ null // also you can add cookie
+ );
+
+ $response = $acClient->recognizeTask($task);
+
+ echo $response['gRecaptchaResponse'];
+} catch (AntiCaptchaException $exception) {
+ echo 'Error:' . $exception->getMessage();
+}
\ No newline at end of file
diff --git a/example/recognize-recaptcha-v3.php b/example/recognize-recaptcha-v3.php
new file mode 100755
index 0000000..e478f9b
--- /dev/null
+++ b/example/recognize-recaptcha-v3.php
@@ -0,0 +1,35 @@
+ $apiKey, 'debug' => true]);
+
+ $task = new RecaptchaV3Task(
+ "http://makeawebsitehub.com/recaptcha/test.php", // target website address
+ "6LfI9IsUAAAAAKuvopU0hfY8pWADfR_mogXokIIZ", // recaptcha key from target website
+
+ // Filters workers with a particular score. It can have one of the following values:
+ // 0.3, 0.7, 0.9
+ "0.3"
+ );
+
+ // Recaptcha's "action" value. Website owners use this parameter to define what users are doing on the page.
+ $task->setPageAction("myaction");
+
+ // Set this flag to "true" if you need this V3 solved with Enterprise API. Default value is "false" and
+ // Recaptcha is solved with non-enterprise API.
+ $task->setIsEnterprise(false);
+
+ $response = $acClient->recognizeTask($task);
+
+ echo $response['gRecaptchaResponse'];
+} catch (AntiCaptchaException $exception) {
+ echo 'Error:' . $exception->getMessage();
+}
\ No newline at end of file
diff --git a/example/recognize-turnstile.php b/example/recognize-turnstile.php
new file mode 100755
index 0000000..747014f
--- /dev/null
+++ b/example/recognize-turnstile.php
@@ -0,0 +1,45 @@
+ $apiKey, 'debug' => true]);
+
+ $task = new TurnstileTask(
+ // Address of a target web page. Can be located anywhere on the web site, even in a member area.
+ // Our workers don't navigate there but simulate the visit instead.
+ "http://makeawebsitehub.com/recaptcha/test.php",
+ // Turnstile sitekey
+ "6LfI9IsUAAAAAKuvopU0hfY8pWADfR_mogXokIIZ"
+ );
+
+ // If you need setup proxy
+ $task->setProxy(
+ "8.8.8.8",
+ 1234,
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116",
+ "http",
+ "login",
+ "password",
+ null // also you can add cookie
+ );
+
+ // Optional "action" parameter.
+ $task->setAction("myaction");
+
+ $response = $acClient->recognizeTask($task);
+
+ // Token string required for interacting with the submit form on the target website.
+ echo $response['token']; // 0.vtJqmZnvobaUzK2i2PyKaSqHELYtBZfRoPwMvLMdA81WL_9G0vCO3y2VQVIeVplG0mxYF7uX.......
+
+ // User-Agent of worker's browser. Use it when you submit the response token.
+ echo $response['userAgent']; // Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:102.0) Gecko/20100101 Firefox/102.0
+} catch (AntiCaptchaException $exception) {
+ echo 'Error:' . $exception->getMessage();
+}
\ No newline at end of file
diff --git a/example/recognize.php b/example/recognize.php
deleted file mode 100755
index 92b389f..0000000
--- a/example/recognize.php
+++ /dev/null
@@ -1,14 +0,0 @@
- $apiKey, 'debug' => true]);
-
-echo $ac->recognize($image, null, ['phrase' => 0, 'numeric' => 0]);
\ No newline at end of file
diff --git a/src/AntiCaptcha.php b/src/AntiCaptcha.php
new file mode 100755
index 0000000..20b80fc
--- /dev/null
+++ b/src/AntiCaptcha.php
@@ -0,0 +1,343 @@
+ 5,
+
+ // time between requesting of captcha solving
+ 'timeout_ready' => 3,
+
+ // timeout of captcha solving
+ 'timeout_max' => 300,
+ ];
+
+ /**
+ * Constants list
+ */
+ const SERVICE_ANTICAPTCHA = 'AntiCaptcha';
+
+ /**
+ * Captcha service list
+ *
+ * @var array
+ */
+ protected static $serviceMap = [
+ self::SERVICE_ANTICAPTCHA,
+ ];
+
+ /**
+ * AntiCaptcha constructor.
+ * @param string|AbstractService $service
+ * @param array $options
+ *
+ * @throws AntiCaptchaException
+ * @throws InvalidAntiCaptchaServiceException
+ */
+ public function __construct($service, array $options = [])
+ {
+ if (is_string($service)) {
+ if (false === in_array($service, self::$serviceMap)) {
+ throw new InvalidAntiCaptchaServiceException($service);
+ }
+
+ $serviceNamespace = '\\AntiCaptcha\\Service\\' . $service;
+ $service = new $serviceNamespace;
+ }
+
+ if ($service) {
+ $this->setService($service);
+
+ if (!empty($options['api_key'])) {
+ $this->getService()->setApiKey($options['api_key']);
+ unset($options['api_key']);
+ }
+ }
+
+ if (!empty($options)) {
+ $this->options = array_merge($this->options, $options);
+ }
+
+ if (!empty($options['debug'])) {
+ $this->debugMod = true;
+ $this->setLogger(new Logger);
+ }
+
+ // set Http Client
+ $this->setClient(new GuzzleClient);
+ }
+
+
+ /**
+ * Setup Anti captcha service provider.
+ * @param AbstractService $service
+ *
+ * @return $this
+ */
+ public function setService(AbstractService $service)
+ {
+ $this->service = $service;
+
+ return $this;
+ }
+
+
+ /**
+ * Method getService description.
+ *
+ * @return AbstractService
+ */
+ public function getService()
+ {
+ return $this->service;
+ }
+
+ /**
+ * Set your custom Logger
+ * @param AbstractLogger $logger
+ *
+ * @return AntiCaptcha
+ */
+ public function setLogger(AbstractLogger $logger)
+ {
+ $this->logger = $logger;
+
+ return $this;
+ }
+
+ /**
+ * HttpClient.
+ * @param $client
+ *
+ * @return AntiCaptcha
+ */
+ public function setClient($client)
+ {
+ $this->client = $client;
+
+ return $this;
+ }
+
+ /**
+ * @param $debugString
+ */
+ protected function debug($debugString)
+ {
+ if ($this->debugMod && $this->logger) {
+ $this->logger->debug($debugString);
+ }
+ }
+
+ /**
+ * Method balance description.
+ *
+ * @return mixed
+ * @throws AntiCaptchaException
+ */
+ public function balance()
+ {
+ $this->debug('check balance ...');
+ $response = $this->sendRequest('/getBalance');
+
+ return $response['balance'];
+ }
+
+
+ /**
+ * Method to recognize image request.
+ *
+ * @param $image
+ * @param ?string $url
+ * @param array $params
+ * @param string $languagePool
+ *
+ * @return ?string
+ * @throws AntiCaptchaException
+ */
+ public function recognizeImage($image, $url = null, $params = [], $languagePool = 'en')
+ {
+ if (null !== $url) {
+ $request = $this->client->request('GET', $url);
+ $image = $request->getBody();
+ }
+
+ $requestParams = [
+ 'task' => array_merge([
+ 'type' => 'ImageToTextTask',
+ 'body' => base64_encode($image),
+ 'phrase' => false,
+ 'case' => false,
+ 'numeric' => 0,
+ 'math' => false,
+ 'minLength' => 0,
+ 'maxLength' => 0
+ ], $params),
+ 'languagePool' => $languagePool
+ ];
+
+ $body = $this->sendRequest('/createTask', $requestParams);
+
+ $taskId = $body['taskId'];
+
+ if (empty($taskId)) {
+ throw new AntiCaptchaException('Did not created task');
+ }
+
+ $captchaResponse = $this->getResult($taskId);
+
+ return $captchaResponse['solution']['text'];
+ }
+
+ /**
+ * @param AbstractTask $task
+ * @return mixed
+ *
+ * @throws AntiCaptchaException
+ * @throws \GuzzleHttp\Exception\GuzzleException
+ */
+ public function recognizeTask(AbstractTask $task)
+ {
+ $requestParams = [
+ 'task' => $task->getTaskParams()
+ ];
+
+ $requestParams = array_merge($requestParams, $task->otherRequestParams());
+
+ $body = $this->sendRequest('/createTask', $requestParams);
+ $taskId = $body['taskId'];
+
+ if (empty($taskId)) {
+ throw new AntiCaptchaException('Did not created task');
+ }
+
+ $captchaResponse = $this->getResult($taskId);
+
+ return $captchaResponse['solution'];
+ }
+
+
+ /**
+ * Method getResult description.
+ * @param $taskId
+ *
+ * @return array
+ * @throws AntiCaptchaException
+ */
+ protected function getResult($taskId)
+ {
+ $this->debug('captcha sent, got task ID: ' . $taskId);
+
+ // Delay, before first captcha check
+ $this->debug('waiting for ' . $this->options['timeout_start'] . ' seconds');
+ sleep($this->options['timeout_start']);
+
+ $waitTime = 0;
+
+ while (true) {
+ $response = $this->sendRequest('/getTaskResult', [
+ 'taskId' => $taskId,
+ ]);
+
+ if ($response['status'] === 'ready') {
+ return $response;
+
+ }
+
+ $this->debug('captcha is not ready yet');
+
+ $waitTime += $this->options['timeout_ready'];
+
+ if ($waitTime > $this->options['timeout_max']) {
+ $this->debug('timelimit (' . $this->options['timeout_max'] . ') hit');
+ throw new AntiCaptchaException('Timeout of resolving captcha');
+ }
+
+ $this->debug('waiting for ' . $this->options['timeout_ready'] . ' seconds');
+ sleep($this->options['timeout_ready']);
+ }
+ }
+
+
+ /**
+ * @param string $action
+ * @param array $requestParams
+ * @return array
+ *
+ * @throws AntiCaptchaException
+ * @throws \GuzzleHttp\Exception\GuzzleException
+ */
+ protected function sendRequest($action, $requestParams = [])
+ {
+ $url = $this->getService()->getApiUrl() . $action;
+
+ $this->debug('request to: ' . $url);
+
+ $result = $this->client->post($url, [
+ 'body' => json_encode(array_merge($this->getBasicParams(), $requestParams)),
+ 'headers' => [
+ 'Content-Type' => 'application/json'
+ ]
+ ]);
+
+ $this->debug('response with status: ' . $result->getStatusCode());
+ $responseBody = $result->getBody()->getContents();
+ $this->debug('response with body: ' . $responseBody);
+
+ return $this->resolveResponse($responseBody);
+ }
+
+ /**
+ * @return array
+ */
+ protected function getBasicParams(): array
+ {
+ return array_merge([
+ 'clientKey' => $this->getService()->getApiKey(),
+ ], $this->getService()->getParams());
+ }
+
+
+ /**
+ * @param ResponseInterface $response
+ * @return array
+ *
+ * @throws AntiCaptchaException
+ */
+ protected function resolveResponse($body)
+ {
+ $data = json_decode($body, true);
+
+ if ($data['errorId'] !== 0) {
+ throw new AntiCaptchaException($data['errorDescription'], $data['errorCode']);
+ }
+
+ return $data;
+ }
+}
diff --git a/src/Anticaptcha/Anticaptcha.php b/src/Anticaptcha/Anticaptcha.php
deleted file mode 100755
index e6c3ed7..0000000
--- a/src/Anticaptcha/Anticaptcha.php
+++ /dev/null
@@ -1,222 +0,0 @@
- 3, // задержка между опросами статуса капчи
- 'timeout_max' => 120, // время ожидания ввода капчи
- ];
-
- public function __construct($service = null, $options = [])
- {
- if (is_string($service)) {
- $serviceName = ucfirst(strtolower($service));
- $serviceNamespace = __NAMESPACE__ . '\\Service\\' . $serviceName;
- $service = new $serviceNamespace;
-
- if (!class_exists($serviceNamespace, false)) {
- throw new Exception('Anticaptcha service provider ' . $service . ' not found!');
- }
- }
-
- if ($service) {
- $this->setService($service);
-
- if (!empty($options['api_key'])) {
- $this->getService()->setApiKey($options['api_key']);
- unset($options['api_key']);
- }
- }
-
- if (!empty($options)) {
- $this->options = array_merge($this->options, $options);
- }
-
- if (!empty($options['debug'])) {
- // set Logger
- $this->setLogger(new Logger);
- }
-
- // set Http Client
- $this->setClient(new Client);
- }
-
- /*
- * Anticaptcah service provider
- */
- public function setService(AbstractService $service)
- {
- $this->service = $service;
-
- return $this;
- }
-
- public function getService()
- {
- return $this->service;
- }
-
- /*
- * Logger
- */
- public function setLogger(AbstractLogger $logger)
- {
- $this->logger = $logger;
-
- return $this;
- }
-
- /*
- * HttpClient
- */
- public function setClient($client)
- {
- $this->client = $client;
-
- return $this;
- }
-
- public function balance()
- {
- $this->logger->debug("check ballans ...");
-
- $url = $this->getService()->getApiUrl() . '/res.php';
- $this->logger->debug('connect to: ' . $url);
-
- $request = $this->client->request('GET', $url, [
- 'query' => [
- 'key' => $this->getService()->getApiKey(),
- 'action' => 'getbalance'
- ]
- ]);
-
- $body = $request->getBody();
-
- $this->logger->debug('result: ' . $body);
-
- if (strpos($body, 'ERROR') !== false) {
- throw new Exception($body);
- }
-
- return $body;
- }
-
- public function recognize($image, $url = null, $params = [])
- {
- // скачиваем картинку
- if (null !== $url) {
- $request = $this->client->request('GET', $url);
- $image = $request->getBody();
- }
-
- if (!empty($params)) {
- $this->getService()->setParams($params);
- }
-
- // отправляем картинку на сервер антикаптчи
- $captcha_id = $this->sendImage($image);
-
- // получаем результат
- if (!empty($captcha_id)) {
- return $this->getResult($captcha_id);
- }
- }
-
- protected function sendImage($image)
- {
- $postfields = [
- 'form_params' => [
- 'key' => $this->getService()->getApiKey(),
- 'method' => 'base64',
- 'body' => base64_encode($image),
- ]
- ];
-
- foreach ($this->getService()->getParams() as $key => $val) {
- $postfields['form_params'][$key] = (string) $val;
- }
-
- $url = $this->getService()->getApiUrl() . '/in.php';
-
- $result = $this->client->request('POST', $url, $postfields);
- $body = $result->getBody();
-
- if (stripos($body, 'ERROR') !== false) {
- throw new Exception($body);
- }
-
- if (stripos($body, 'html') !== false) {
- throw new Exception('Anticaptcha server returned error!');
- }
-
- if (stripos($body, 'OK') !== false) {
- $ex = explode("|", $body);
- if (trim($ex[0]) == 'OK') {
- return !empty($ex[1]) ? $ex[1] : null; // возвращаем captcha_id
- }
- }
- }
-
- protected function getResult($captcha_id)
- {
- $this->logger->debug('captcha sent, got captcha ID: ' . $captcha_id);
-
- // задержка перед первым опросом результата каптчи
- $this->logger->debug('waiting for 10 seconds');
- sleep(10);
-
- // максимальное время опроса результата каптчи
- $waittime = 0;
-
- while(true) {
- $request = $this->client->request('GET', $this->getService()->getApiUrl() . '/res.php', [
- 'query' => [
- 'key' => $this->getService()->getApiKey(),
- 'action' => 'get',
- 'id' => $captcha_id,
- ]
- ]);
-
- $body = $request->getBody();
-
- if (strpos($body, 'ERROR') !== false) {
- throw new Exception("Anticaptcha server returned error: $body");
- }
-
- if ($body == "CAPCHA_NOT_READY") {
- $this->logger->debug('captcha is not ready yet');
-
- $waittime += $this->options['timeout_ready'];
-
- if ($waittime > $this->options['timeout_max']) {
- $this->logger->debug('timelimit (' . $this->options['timeout_max'] . ') hit');
- break;
- }
-
- $this->logger->debug('waiting for ' . $this->options['timeout_ready'] . ' seconds');
- sleep($this->options['timeout_ready']);
- }
- else {
- $ex = explode('|', $body);
-
- if (trim($ex[0]) == 'OK') {
- $this->logger->debug('result: ' . $body);
- return trim($ex[1]);
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Anticaptcha/ExceptionAnticaptcha.php b/src/Anticaptcha/ExceptionAnticaptcha.php
deleted file mode 100755
index 655c2cf..0000000
--- a/src/Anticaptcha/ExceptionAnticaptcha.php
+++ /dev/null
@@ -1,7 +0,0 @@
- 0, // 0 либо 1 - флаг "в капче 2 и более слов"
- 'regsense' => 0, // 0 либо 1 - флаг "регистр букв в капче имеет значение"
- 'numeric' => 0, // 0 либо 1 - флаг "капча состоит только из цифр"
- 'calc' => 0, // 0 либо 1 - помечает что цифры на капче должны быть сплюсованы
- 'min_len' => 0, // 0 (без ограничений), любая другая цифра указывает минимальную длину текста капчи
- 'max_len' => 0, // 0 (без ограничений), любая другая цифра указывает максимальную длину текста капчи
- ];
-
- public function __construct($api_key = null, $api_url = null)
- {
- $this->setApiKey($api_key);
-
- if (null !== $api_url) {
- $this->setApiUrl($api_url);
- }
- }
-
- /*
- * @param string $api_key
- */
- public function setApiKey($api_key)
- {
- $this->api_key = $api_key;
-
- return $this;
- }
-
- /*
- * @return string
- */
- public function getApiKey()
- {
- return $this->api_key;
- }
-
- /*
- * @param string $api_url
- */
- public function setApiUrl($api_url)
- {
- $this->api_url = $api_url;
-
- return $this;
- }
-
- /*
- * @return string
- */
- public function getApiUrl()
- {
- return rtrim($this->api_url, '/');
- }
-
- /*
- * @param array $params
- */
- public function setParams($params)
- {
- $this->params = array_merge($this->params, $params);
-
- return $this;
- }
-
- /*
- * @return array
- */
- public function getParams()
- {
- return $this->params;
- }
-}
\ No newline at end of file
diff --git a/src/Anticaptcha/Service/Antigate.php b/src/Anticaptcha/Service/Antigate.php
deleted file mode 100755
index d6b23ed..0000000
--- a/src/Anticaptcha/Service/Antigate.php
+++ /dev/null
@@ -1,9 +0,0 @@
-errorCode = $apiErrorCode;
+
+ parent::__construct($message, 0);
+ }
+}
diff --git a/src/Exception/InvalidAntiCaptchaServiceException.php b/src/Exception/InvalidAntiCaptchaServiceException.php
new file mode 100644
index 0000000..0ed33e5
--- /dev/null
+++ b/src/Exception/InvalidAntiCaptchaServiceException.php
@@ -0,0 +1,24 @@
+proxyParams);
+ }
+
+ /**
+ * @param string $proxyAddress
+ * @param string $proxyPort
+ * @param string $userAgent
+ * @param string $proxyType
+ * @param ?string $proxyLogin
+ * @param ?string $proxyPassword
+ * @param ?string $cookies
+ *
+ * @return void
+ */
+ public function setProxy(
+ string $proxyAddress,
+ string $proxyPort,
+ string $userAgent,
+ string $proxyType = 'http',
+ string $proxyLogin = null,
+ string $proxyPassword = null,
+ string $cookies = null
+ )
+ {
+ $this->proxyParams['proxyType'] = $proxyType;
+ $this->proxyParams['proxyAddress'] = $proxyAddress;
+ $this->proxyParams['proxyPort'] = $proxyPort;
+ $this->proxyParams['userAgent'] = $userAgent;
+
+ if (!empty($proxyLogin)) {
+ $this->proxyParams['proxyLogin'] = $proxyLogin;
+ }
+
+ if (!empty($proxyPassword)) {
+ $this->proxyParams['proxyPassword'] = $proxyPassword;
+ }
+
+ if (!empty($cookies)) {
+ $this->proxyParams['cookies'] = $cookies;
+ }
+ }
+}
diff --git a/src/Logger.php b/src/Logger.php
new file mode 100755
index 0000000..b6df1c5
--- /dev/null
+++ b/src/Logger.php
@@ -0,0 +1,23 @@
+ 0, // 0 or 1 - флаг "в капче 2 и более слов"
+ 'regsense' => 0, // 0 or 1 - флаг "регистр букв в капче имеет значение"
+ 'numeric' => 0, // 0 or 1 - флаг "капча состоит только из цифр"
+ 'calc' => 0, // 0 or 1 - помечает что цифры на капче должны быть сплюсованы
+ 'min_len' => 0, // 0 (без ограничений), любая другая цифра указывает минимальную длину текста капчи
+ 'max_len' => 0, // 0 (без ограничений), любая другая цифра указывает максимальную длину текста капчи
+ ];
+
+ /**
+ * AbstractService constructor.
+ * @param null $apiKey
+ * @param null $apiUrl
+ */
+ public function __construct($apiKey = null, $apiUrl = null)
+ {
+ $this->setApiKey($apiKey);
+
+ if (null !== $apiUrl) {
+ $this->setApiUrl($apiUrl);
+ }
+ }
+
+ /**
+ * Method setApiKey description.
+ * @param $apiKey
+ *
+ * @return $this
+ */
+ public function setApiKey($apiKey)
+ {
+ $this->apiKey = $apiKey;
+
+ return $this;
+ }
+
+ /**
+ * Method getApiKey description.
+ *
+ * @return string
+ */
+ public function getApiKey()
+ {
+ return $this->apiKey;
+ }
+
+ /**
+ * Method setApiUrl description.
+ * @param $apiUrl
+ *
+ * @return $this
+ */
+ public function setApiUrl($apiUrl)
+ {
+ $this->apiUrl = $apiUrl;
+
+ return $this;
+ }
+
+ /**
+ * Method getApiUrl description.
+ *
+ * @return string
+ */
+ public function getApiUrl()
+ {
+ return rtrim($this->apiUrl, '/');
+ }
+
+ /**
+ * Method setParams description.
+ * @param array $params
+ *
+ * @return $this
+ */
+ public function setParams($params)
+ {
+ $this->params = array_merge($this->params, $params);
+
+ return $this;
+ }
+
+ /**
+ * Method getParams description.
+ *
+ * @return array
+ */
+ public function getParams()
+ {
+ return $this->params;
+ }
+}
\ No newline at end of file
diff --git a/src/Service/AntiCaptcha.php b/src/Service/AntiCaptcha.php
new file mode 100644
index 0000000..95f72f8
--- /dev/null
+++ b/src/Service/AntiCaptcha.php
@@ -0,0 +1,25 @@
+params, [
+ 'softId' => 791
+ ]);
+ }
+}
diff --git a/src/Task/AbstractTask.php b/src/Task/AbstractTask.php
new file mode 100644
index 0000000..36bd297
--- /dev/null
+++ b/src/Task/AbstractTask.php
@@ -0,0 +1,22 @@
+websiteUrl = $websiteUrl;
+ $this->websiteKey = $websiteKey;
+ }
+
+ public function setEnterprisePayload(array $enterprisePayload)
+ {
+ $this->enterprisePayload = $enterprisePayload;
+ }
+
+ public function setApiDomain(string $apiDomain)
+ {
+ $this->apiDomain = $apiDomain;
+ }
+
+ /**
+ * @return array
+ */
+ public function getTaskParams()
+ {
+ $data = [];
+
+ $data['type'] = $this->useProxy() ? 'RecaptchaV2EnterpriseTask' : 'RecaptchaV2EnterpriseTaskProxyless';
+ $data['websiteURL'] = $this->websiteUrl;
+ $data['websiteKey'] = $this->websiteKey;
+
+ if (!is_null($this->enterprisePayload)) {
+ $data['enterprisePayload'] = $this->enterprisePayload;
+ }
+
+ if (!is_null($this->apiDomain)) {
+ $data['apiDomain'] = $this->apiDomain;
+ }
+
+ if ($this->useProxy()) {
+ $data = array_merge($data, $this->proxyParams);
+ }
+
+ return $data;
+ }
+
+ /**
+ * @return array
+ */
+ public function otherRequestParams()
+ {
+ return [];
+ }
+}
diff --git a/src/Task/RecaptchaV2Task.php b/src/Task/RecaptchaV2Task.php
new file mode 100644
index 0000000..224eeb9
--- /dev/null
+++ b/src/Task/RecaptchaV2Task.php
@@ -0,0 +1,82 @@
+websiteUrl = $websiteUrl;
+ $this->websiteKey = $websiteKey;
+ }
+
+
+ public function setIsInvisible(bool $isInvisible)
+ {
+ $this->isInvisible = $isInvisible;
+ }
+
+ public function setRecaptchaDataSValue($recaptchaDataSValue)
+ {
+ $this->recaptchaDataSValue = $recaptchaDataSValue;
+ }
+
+ /**
+ * @return array
+ */
+ public function getTaskParams()
+ {
+ $data = [];
+
+ $data['type'] = $this->useProxy() ? 'RecaptchaV2Task' : 'RecaptchaV2TaskProxyless';
+ $data['websiteURL'] = $this->websiteUrl;
+ $data['websiteKey'] = $this->websiteKey;
+
+ if (!is_null($this->recaptchaDataSValue)) {
+ $data['recaptchaDataSValue'] = $this->recaptchaDataSValue;
+ }
+
+ if (!is_null($this->isInvisible)) {
+ $data['isInvisible'] = $this->isInvisible;
+ }
+
+ if ($this->useProxy()) {
+ $data = array_merge($data, $this->proxyParams);
+ }
+
+ return $data;
+ }
+
+ /**
+ * @return array
+ */
+ public function otherRequestParams()
+ {
+ return [];
+ }
+}
diff --git a/src/Task/RecaptchaV3Task.php b/src/Task/RecaptchaV3Task.php
new file mode 100644
index 0000000..85b2b43
--- /dev/null
+++ b/src/Task/RecaptchaV3Task.php
@@ -0,0 +1,100 @@
+websiteUrl = $websiteUrl;
+ $this->websiteKey = $websiteKey;
+ $this->setMinScore($minScore);
+ }
+
+
+ public function setMinScore(string $minScore)
+ {
+ if (!in_array($minScore, ['0.3', '0.7', '0.9'])) {
+ throw new \Exception('Min Score must be one of 0.3, 0.7 or 0.9');
+ }
+ $this->minScore = $minScore;
+ }
+
+ public function setPageAction(string $pageAction)
+ {
+ $this->pageAction = $pageAction;
+ }
+
+ public function setIsEnterprise(bool $isEnterprise)
+ {
+ $this->isEnterprise = $isEnterprise;
+ }
+
+ public function setApiDomain(string $apiDomain)
+ {
+ $this->apiDomain = $apiDomain;
+ }
+
+
+ /**
+ * @return array
+ */
+ public function getTaskParams()
+ {
+ $data = [];
+
+ $data['type'] = 'RecaptchaV3TaskProxyless';
+ $data['websiteURL'] = $this->websiteUrl;
+ $data['websiteKey'] = $this->websiteKey;
+ $data['minScore'] = floatval($this->minScore);
+
+ if (!is_null($this->pageAction)) {
+ $data['pageAction'] = $this->pageAction;
+ }
+
+ if (!is_null($this->isEnterprise)) {
+ $data['isEnterprise'] = $this->isEnterprise;
+ }
+
+ if (!is_null($this->apiDomain)) {
+ $data['apiDomain'] = $this->apiDomain;
+ }
+
+ return $data;
+ }
+
+ /**
+ * @return array
+ */
+ public function otherRequestParams()
+ {
+ return [];
+ }
+}
diff --git a/src/Task/TurnstileTask.php b/src/Task/TurnstileTask.php
new file mode 100644
index 0000000..7bdbee4
--- /dev/null
+++ b/src/Task/TurnstileTask.php
@@ -0,0 +1,73 @@
+websiteUrl = $websiteUrl;
+ $this->websiteKey = $websiteKey;
+ }
+
+ /**
+ * Optional "action" parameter
+ *
+ * @param string $action
+ *
+ * @return void
+ */
+ public function setAction(string $action)
+ {
+ $this->action = $action;
+ }
+
+
+ /**
+ * @return array
+ */
+ public function getTaskParams()
+ {
+ $data = [];
+
+ $data['type'] = $this->useProxy() ? 'TurnstileTask' : 'TurnstileTaskProxyless';
+ $data['websiteURL'] = $this->websiteUrl;
+ $data['websiteKey'] = $this->websiteKey;
+
+ if (!is_null($this->action)) {
+ $data['action'] = $this->action;
+ }
+
+ if ($this->useProxy()) {
+ $data = array_merge($data, $this->proxyParams);
+ }
+
+ return $data;
+ }
+
+ /**
+ * @return array
+ */
+ public function otherRequestParams()
+ {
+ return [];
+ }
+}