diff --git a/.env.example b/.env.example
new file mode 100644
index 0000000..7676c44
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,10 @@
+MODE=
+API_VERSION=
+TERMINAL_ID=
+TERMINAL_PROV_USER_ID_PAY=
+TERMINAL_PROV_USER_ID_REFUND=
+TERMINAL_PROV_USER_PASSWORD=
+TERMINAL_USER_ID=
+TERMINAL_MERCHANT_ID=
+THREED_STORE_KEY=
+
diff --git a/.gitignore b/.gitignore
index 297959a..5c0cb97 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,3 +21,5 @@ Homestead.yaml
 Homestead.json
 /.vagrant
 .phpunit.result.cache
+
+/docs
diff --git a/README.md b/README.md
index e5e878a..00f7da1 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,183 @@
-# garantipos
\ No newline at end of file
+# Garanti Pos PHP SDK
+
+Garanti bankası sanal pos işlemleri için php entegrasyon kütüphanesidir. 3D Secure, XMLPay ve İade işlemlerini kolayca
+yapabilirsiniz.
+
+Test ve canlı ortam kullanıcı bilgileri için Garanti Bankası ile iletişime geçmelisiniz.
+
+# Installation
+
+### Composer
+
+Bağımlılıkları [Composer](http://getcomposer.org/) ile yükleyebilirsiniz.
+
+```bash
+$ composer require sportakal/garantipos
+```
+
+Bağımlılıkları kullanmak için Composer'ın [autoload](https://getcomposer.org/doc/00-intro.md#autoloading) özelliğini
+kullanın.
+
+```php
+require_once('vendor/autoload.php');
+```
+
+# Usage
+
+Sanalpos kullanıcı bilgilerinizi **Options** nesnesine atayın.
+
+```php
+use Sportakal\Garantipos\Models\Options;
+
+$options = new Options();
+$options->setMode($_ENV['MODE']);
+$options->setApiVersion($_ENV['API_VERSION']);
+$options->setTerminalId($_ENV['TERMINAL_ID']);
+$options->setTerminalProvUserId($_ENV['TERMINAL_PROV_USER_ID_PAY']);
+$options->setTerminalProvUserPassword($_ENV['TERMINAL_PROV_USER_PASSWORD']);
+$options->setTerminalUserId($_ENV['TERMINAL_USER_ID']);
+$options->setTerminalMerchantId($_ENV['TERMINAL_MERCHANT_ID']);
+$options->setStoreKey($_ENV['STORE_KEY']);
+```
+
+Kart bilgilerini **Card** nesnesine atayın.
+
+```php
+$card = new Card();
+$card->setNumber('5549608789641500');
+$card->setExpireDate('0323');
+$card->setCVV2('712');
+```
+
+Müşteri bilgilerini **Customer** nesnesine atayın.
+
+```php
+$customer = new Customer();
+$customer->setIpAddress('159.146.45.34');
+$customer->setEmailAddress('portakalsinan@gmail.com');
+```
+
+Sipariş bilgilerini **Order** nesnesine atayın.
+
+```php
+$order = new Order();
+$order->setOrderID('sportakal_garantipos_' . time());
+```
+
+Adres bilgilerini **Address** nesnesine atayın.
+
+```php
+$address = new Address();
+$address->setType('B'); // B for 'billing' or S for 'shipping'
+$address->setName('Sinan');
+$address->setLastName('Portakal');
+$address->setPhoneNumber('+90 532 345 67 89');
+$address->setText('Kınıklı Mah.');
+$address->setDistrict('Pamukkale');
+$address->setCity('Denizli');
+$address->setCountry('Turkey');
+```
+
+**addAddress** methoduyla siparişinize ekleyin.
+
+```php
+$order->addAddress($address);
+```
+
+İşlem bilgilerini **Transaction** nesnesine atayın.
+
+```php
+$transaction = new Transaction();
+$transaction->setInstallmentCnt("");
+$transaction->setAmount(1000);
+$transaction->setCurrencyCode('TRY');
+$transaction->setCardholderPresentCode('0');
+$transaction->setMotoInd('N');
+$transaction->setDescription('test payment');
+```
+
+Tüm bu nesneleri **RequestModel** nesnesinde toplayın.
+
+```php
+$request = new RequestModel();
+$request->setOptions($options);
+$request->setCard($card);
+$request->setCustomer($customer);
+$request->setOrder($order);
+$request->setTransaction($transaction);
+```
+
+RequestModel'i yapacağınız işleme göre **Request** nesnesine atayın.
+
+### 3D Secure'siz işlem için
+
+```php
+$request = new \Sportakal\Garantipos\Requests\Pay($request);
+```
+
+### İade işlemi için
+
+```php
+$request = new \Sportakal\Garantipos\Requests\Refund($request);
+```
+
+### 3D Secure Pay işlemi için
+
+```php
+$request = new \Sportakal\Garantipos\Requests\ThreeDSecurePay($request);
+```
+
+### İşlemlerin sonucu
+
+İşlemin sonucunu aşağıdaki şekilde kontrol edebilirsiniz.
+
+```php
+$result = $request->getResult();
+
+$status = $result->getStatus(); //boolean
+$message = $result->getStatusMessage(); //string
+$error_message = $result->getErrorMessage()); //string
+```
+
+3D Secure işlemlerde mdStatusCode ve mdErrorMessage değerleri de döner.
+
+3D Secure işlemi sonucunda veriler, **successUrl** veya **errorUrl** olarak belirlediğiniz adrese post edilir. Bu
+adreste aşağıdaki methodla bu verileri yakalayabilirsiniz. Ve mdStatus değerlerini kontrol edebilirsiniz.
+
+```php
+$result = new \Sportakal\Garantipos\Results\ThreeDSecurePayResult($options);
+
+$md_status = $result->getMdStatus();
+$md_response_message = $result->getResponseMessage();
+$md_error_message = $result->getErrorMessage()
+```
+
+***/samples*** klasöründe daha fazla örnek bulabilirsiniz.
+
+## Development
+
+Bağımlılıkları yükleyin:
+
+``` bash
+composer install
+```
+
+## Milestones
+
+* Daha fazla işlem türü eklenecek
+    * İptal İşlemi
+    * Garanti Pay
+    * Bin sorgulama
+    * TCKN sorgulama
+    * Ön Provizyon işlemleri
+
+
+
+
+
+
+
+
+
+
+
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..5272d59
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,27 @@
+{
+    "name": "sportakal/garantipos",
+    "type": "library",
+    "autoload": {
+        "psr-4": {
+            "Sportakal\\Garantipos\\": "src/"
+        }
+    },
+    "authors": [
+        {
+            "name": "sportakal",
+            "email": "portakalsinan@gmail.com"
+        }
+    ],
+    "require": {
+        "mews/pos": "^0.7.0",
+      "ext-curl": "*",
+      "ext-xml": "*",
+      "ext-dom": "*",
+        "ext-simplexml": "*",
+      "ext-json": "*",
+        "vlucas/phpdotenv": "^5.4"
+    },
+    "require-dev": {
+        "php-sage/sage": "^1.2"
+    }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..3c820da
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,1463 @@
+{
+    "_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": "f758a39a7ba6cee427d4990835b842f0",
+    "packages": [
+        {
+            "name": "graham-campbell/result-type",
+            "version": "v1.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/GrahamCampbell/Result-Type.git",
+                "reference": "0690bde05318336c7221785f2a932467f98b64ca"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/0690bde05318336c7221785f2a932467f98b64ca",
+                "reference": "0690bde05318336c7221785f2a932467f98b64ca",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.0 || ^8.0",
+                "phpoption/phpoption": "^1.8"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "GrahamCampbell\\ResultType\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                }
+            ],
+            "description": "An Implementation Of The Result Type",
+            "keywords": [
+                "Graham Campbell",
+                "GrahamCampbell",
+                "Result Type",
+                "Result-Type",
+                "result"
+            ],
+            "support": {
+                "issues": "https://github.com/GrahamCampbell/Result-Type/issues",
+                "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.0.4"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-11-21T21:41:47+00:00"
+        },
+        {
+            "name": "guzzlehttp/guzzle",
+            "version": "6.5.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/guzzle.git",
+                "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e",
+                "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "guzzlehttp/promises": "^1.0",
+                "guzzlehttp/psr7": "^1.6.1",
+                "php": ">=5.5",
+                "symfony/polyfill-intl-idn": "^1.17.0"
+            },
+            "require-dev": {
+                "ext-curl": "*",
+                "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
+                "psr/log": "^1.1"
+            },
+            "suggest": {
+                "psr/log": "Required for using the Log middleware"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "6.5-dev"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/functions_include.php"
+                ],
+                "psr-4": {
+                    "GuzzleHttp\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                }
+            ],
+            "description": "Guzzle is a PHP HTTP client library",
+            "homepage": "http://guzzlephp.org/",
+            "keywords": [
+                "client",
+                "curl",
+                "framework",
+                "http",
+                "http client",
+                "rest",
+                "web service"
+            ],
+            "support": {
+                "issues": "https://github.com/guzzle/guzzle/issues",
+                "source": "https://github.com/guzzle/guzzle/tree/6.5"
+            },
+            "time": "2020-06-16T21:01:06+00:00"
+        },
+        {
+            "name": "guzzlehttp/promises",
+            "version": "1.5.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/promises.git",
+                "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/promises/zipball/fe752aedc9fd8fcca3fe7ad05d419d32998a06da",
+                "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.5"
+            },
+            "require-dev": {
+                "symfony/phpunit-bridge": "^4.4 || ^5.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.5-dev"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/functions_include.php"
+                ],
+                "psr-4": {
+                    "GuzzleHttp\\Promise\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                },
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                },
+                {
+                    "name": "Tobias Nyholm",
+                    "email": "tobias.nyholm@gmail.com",
+                    "homepage": "https://github.com/Nyholm"
+                },
+                {
+                    "name": "Tobias Schultze",
+                    "email": "webmaster@tubo-world.de",
+                    "homepage": "https://github.com/Tobion"
+                }
+            ],
+            "description": "Guzzle promises library",
+            "keywords": [
+                "promise"
+            ],
+            "support": {
+                "issues": "https://github.com/guzzle/promises/issues",
+                "source": "https://github.com/guzzle/promises/tree/1.5.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://github.com/Nyholm",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-10-22T20:56:57+00:00"
+        },
+        {
+            "name": "guzzlehttp/psr7",
+            "version": "1.8.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/guzzle/psr7.git",
+                "reference": "337e3ad8e5716c15f9657bd214d16cc5e69df268"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/guzzle/psr7/zipball/337e3ad8e5716c15f9657bd214d16cc5e69df268",
+                "reference": "337e3ad8e5716c15f9657bd214d16cc5e69df268",
+                "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": {
+                "files": [
+                    "src/functions_include.php"
+                ],
+                "psr-4": {
+                    "GuzzleHttp\\Psr7\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                },
+                {
+                    "name": "Michael Dowling",
+                    "email": "mtdowling@gmail.com",
+                    "homepage": "https://github.com/mtdowling"
+                },
+                {
+                    "name": "George Mponos",
+                    "email": "gmponos@gmail.com",
+                    "homepage": "https://github.com/gmponos"
+                },
+                {
+                    "name": "Tobias Nyholm",
+                    "email": "tobias.nyholm@gmail.com",
+                    "homepage": "https://github.com/Nyholm"
+                },
+                {
+                    "name": "Márk Sági-Kazár",
+                    "email": "mark.sagikazar@gmail.com",
+                    "homepage": "https://github.com/sagikazarmark"
+                },
+                {
+                    "name": "Tobias Schultze",
+                    "email": "webmaster@tubo-world.de",
+                    "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.5"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://github.com/Nyholm",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-03-20T21:51:18+00:00"
+        },
+        {
+            "name": "mews/pos",
+            "version": "0.7.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/mewebstudio/pos.git",
+                "reference": "0ce8e8c96120293f1fa224ca6d43904ff673aac5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/mewebstudio/pos/zipball/0ce8e8c96120293f1fa224ca6d43904ff673aac5",
+                "reference": "0ce8e8c96120293f1fa224ca6d43904ff673aac5",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-json": "*",
+                "ext-openssl": "*",
+                "ext-simplexml": "*",
+                "guzzlehttp/guzzle": "^6.3.3",
+                "php": ">=7.1.3",
+                "symfony/http-foundation": "^5.0",
+                "symfony/serializer": "^5.0"
+            },
+            "require-dev": {
+                "escapestudios/symfony2-coding-standard": "^3.11",
+                "phpunit/phpunit": "^9.0",
+                "squizlabs/php_codesniffer": "^3.5",
+                "symfony/var-dumper": "^5.1"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Mews\\Pos\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Muharrem ERİN",
+                    "email": "me@mewebstudio.com"
+                }
+            ],
+            "description": "Türk bankaları için sanal pos kütüphanesi",
+            "homepage": "https://github.com/mewebstudio/pos",
+            "keywords": [
+                "DenizBank Sanal Pos",
+                "InterVPos",
+                "PayFor",
+                "akbank",
+                "est",
+                "est pos",
+                "kuveytpos",
+                "pos",
+                "posnet",
+                "sanal pos",
+                "vakifbankpos"
+            ],
+            "support": {
+                "issues": "https://github.com/mewebstudio/pos/issues",
+                "source": "https://github.com/mewebstudio/pos/tree/0.7.0"
+            },
+            "time": "2022-05-17T18:33:49+00:00"
+        },
+        {
+            "name": "phpoption/phpoption",
+            "version": "1.8.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/schmittjoh/php-option.git",
+                "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15",
+                "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.0 || ^8.0"
+            },
+            "require-dev": {
+                "bamarni/composer-bin-plugin": "^1.4.1",
+                "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.8-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "PhpOption\\": "src/PhpOption/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "Apache-2.0"
+            ],
+            "authors": [
+                {
+                    "name": "Johannes M. Schmitt",
+                    "email": "schmittjoh@gmail.com",
+                    "homepage": "https://github.com/schmittjoh"
+                },
+                {
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                }
+            ],
+            "description": "Option Type for PHP",
+            "keywords": [
+                "language",
+                "option",
+                "php",
+                "type"
+            ],
+            "support": {
+                "issues": "https://github.com/schmittjoh/php-option/issues",
+                "source": "https://github.com/schmittjoh/php-option/tree/1.8.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-12-04T23:24:31+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": "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"
+        },
+        {
+            "name": "symfony/deprecation-contracts",
+            "version": "v2.5.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/deprecation-contracts.git",
+                "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
+                "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "2.5-dev"
+                },
+                "thanks": {
+                    "name": "symfony/contracts",
+                    "url": "https://github.com/symfony/contracts"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "function.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "A generic function and convention to trigger deprecation notices",
+            "homepage": "https://symfony.com",
+            "support": {
+                "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.1"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-01-02T09:53:40+00:00"
+        },
+        {
+            "name": "symfony/http-foundation",
+            "version": "v5.4.8",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/http-foundation.git",
+                "reference": "ff2818d1c3d49860bcae1f2cbb5eb00fcd3bf9e2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ff2818d1c3d49860bcae1f2cbb5eb00fcd3bf9e2",
+                "reference": "ff2818d1c3d49860bcae1f2cbb5eb00fcd3bf9e2",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/deprecation-contracts": "^2.1|^3",
+                "symfony/polyfill-mbstring": "~1.1",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "require-dev": {
+                "predis/predis": "~1.0",
+                "symfony/cache": "^4.4|^5.0|^6.0",
+                "symfony/expression-language": "^4.4|^5.0|^6.0",
+                "symfony/mime": "^4.4|^5.0|^6.0"
+            },
+            "suggest": {
+                "symfony/mime": "To use the file extension guesser"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\HttpFoundation\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Defines an object-oriented layer for the HTTP specification",
+            "homepage": "https://symfony.com",
+            "support": {
+                "source": "https://github.com/symfony/http-foundation/tree/v5.4.8"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-04-22T08:14:12+00:00"
+        },
+        {
+            "name": "symfony/polyfill-ctype",
+            "version": "v1.25.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-ctype.git",
+                "reference": "30885182c981ab175d4d034db0f6f469898070ab"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab",
+                "reference": "30885182c981ab175d4d034db0f6f469898070ab",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "provide": {
+                "ext-ctype": "*"
+            },
+            "suggest": {
+                "ext-ctype": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Ctype\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Gert de Pagter",
+                    "email": "BackEndTea@gmail.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for ctype functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "ctype",
+                "polyfill",
+                "portable"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-10-20T20:35:02+00:00"
+        },
+        {
+            "name": "symfony/polyfill-intl-idn",
+            "version": "v1.25.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-intl-idn.git",
+                "reference": "749045c69efb97c70d25d7463abba812e91f3a44"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/749045c69efb97c70d25d7463abba812e91f3a44",
+                "reference": "749045c69efb97c70d25d7463abba812e91f3a44",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1",
+                "symfony/polyfill-intl-normalizer": "^1.10",
+                "symfony/polyfill-php72": "^1.10"
+            },
+            "suggest": {
+                "ext-intl": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Intl\\Idn\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Laurent Bassin",
+                    "email": "laurent@bassin.info"
+                },
+                {
+                    "name": "Trevor Rowbotham",
+                    "email": "trevor.rowbotham@pm.me"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "idn",
+                "intl",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.25.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-09-14T14:02:44+00:00"
+        },
+        {
+            "name": "symfony/polyfill-intl-normalizer",
+            "version": "v1.25.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+                "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8",
+                "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "suggest": {
+                "ext-intl": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+                },
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for intl's Normalizer class and related functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "intl",
+                "normalizer",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-02-19T12:13:01+00:00"
+        },
+        {
+            "name": "symfony/polyfill-mbstring",
+            "version": "v1.25.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-mbstring.git",
+                "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825",
+                "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "provide": {
+                "ext-mbstring": "*"
+            },
+            "suggest": {
+                "ext-mbstring": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Mbstring\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for the Mbstring extension",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "mbstring",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-11-30T18:21:41+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php72",
+            "version": "v1.25.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php72.git",
+                "reference": "9a142215a36a3888e30d0a9eeea9766764e96976"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976",
+                "reference": "9a142215a36a3888e30d0a9eeea9766764e96976",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php72\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-php72/tree/v1.25.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-05-27T09:17:38+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php80",
+            "version": "v1.25.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php80.git",
+                "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c",
+                "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.23-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php80\\": ""
+                },
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ion Bazan",
+                    "email": "ion.bazan@gmail.com"
+                },
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-03-04T08:16:47+00:00"
+        },
+        {
+            "name": "symfony/serializer",
+            "version": "v5.4.8",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/serializer.git",
+                "reference": "a806b1031c45bf2ee583beee6df734ecf34d5cfc"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/serializer/zipball/a806b1031c45bf2ee583beee6df734ecf34d5cfc",
+                "reference": "a806b1031c45bf2ee583beee6df734ecf34d5cfc",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/deprecation-contracts": "^2.1|^3",
+                "symfony/polyfill-ctype": "~1.8",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "conflict": {
+                "doctrine/annotations": "<1.12",
+                "phpdocumentor/reflection-docblock": "<3.2.2",
+                "phpdocumentor/type-resolver": "<1.4.0",
+                "symfony/dependency-injection": "<4.4",
+                "symfony/property-access": "<5.4",
+                "symfony/property-info": "<5.3.13",
+                "symfony/uid": "<5.3",
+                "symfony/yaml": "<4.4"
+            },
+            "require-dev": {
+                "doctrine/annotations": "^1.12",
+                "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0",
+                "symfony/cache": "^4.4|^5.0|^6.0",
+                "symfony/config": "^4.4|^5.0|^6.0",
+                "symfony/dependency-injection": "^4.4|^5.0|^6.0",
+                "symfony/error-handler": "^4.4|^5.0|^6.0",
+                "symfony/filesystem": "^4.4|^5.0|^6.0",
+                "symfony/form": "^4.4|^5.0|^6.0",
+                "symfony/http-foundation": "^4.4|^5.0|^6.0",
+                "symfony/http-kernel": "^4.4|^5.0|^6.0",
+                "symfony/mime": "^4.4|^5.0|^6.0",
+                "symfony/property-access": "^5.4|^6.0",
+                "symfony/property-info": "^5.3.13|^6.0",
+                "symfony/uid": "^5.3|^6.0",
+                "symfony/validator": "^4.4|^5.0|^6.0",
+                "symfony/var-dumper": "^4.4|^5.0|^6.0",
+                "symfony/var-exporter": "^4.4|^5.0|^6.0",
+                "symfony/yaml": "^4.4|^5.0|^6.0"
+            },
+            "suggest": {
+                "psr/cache-implementation": "For using the metadata cache.",
+                "symfony/config": "For using the XML mapping loader.",
+                "symfony/mime": "For using a MIME type guesser within the DataUriNormalizer.",
+                "symfony/property-access": "For using the ObjectNormalizer.",
+                "symfony/property-info": "To deserialize relations.",
+                "symfony/var-exporter": "For using the metadata compiler.",
+                "symfony/yaml": "For using the default YAML mapping loader."
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Serializer\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.",
+            "homepage": "https://symfony.com",
+            "support": {
+                "source": "https://github.com/symfony/serializer/tree/v5.4.8"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-04-12T16:02:29+00:00"
+        },
+        {
+            "name": "vlucas/phpdotenv",
+            "version": "v5.4.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/vlucas/phpdotenv.git",
+                "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/264dce589e7ce37a7ba99cb901eed8249fbec92f",
+                "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f",
+                "shasum": ""
+            },
+            "require": {
+                "ext-pcre": "*",
+                "graham-campbell/result-type": "^1.0.2",
+                "php": "^7.1.3 || ^8.0",
+                "phpoption/phpoption": "^1.8",
+                "symfony/polyfill-ctype": "^1.23",
+                "symfony/polyfill-mbstring": "^1.23.1",
+                "symfony/polyfill-php80": "^1.23.1"
+            },
+            "require-dev": {
+                "bamarni/composer-bin-plugin": "^1.4.1",
+                "ext-filter": "*",
+                "phpunit/phpunit": "^7.5.20 || ^8.5.21 || ^9.5.10"
+            },
+            "suggest": {
+                "ext-filter": "Required to use the boolean validator."
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.4-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Dotenv\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Graham Campbell",
+                    "email": "hello@gjcampbell.co.uk",
+                    "homepage": "https://github.com/GrahamCampbell"
+                },
+                {
+                    "name": "Vance Lucas",
+                    "email": "vance@vancelucas.com",
+                    "homepage": "https://github.com/vlucas"
+                }
+            ],
+            "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.",
+            "keywords": [
+                "dotenv",
+                "env",
+                "environment"
+            ],
+            "support": {
+                "issues": "https://github.com/vlucas/phpdotenv/issues",
+                "source": "https://github.com/vlucas/phpdotenv/tree/v5.4.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/GrahamCampbell",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2021-12-12T23:22:04+00:00"
+        }
+    ],
+    "packages-dev": [
+        {
+            "name": "php-sage/sage",
+            "version": "v1.2.25",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-sage/sage.git",
+                "reference": "1cdb12bd791f608d3fbfbbb9b8fdcd2d4104186c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-sage/sage/zipball/1cdb12bd791f608d3fbfbbb9b8fdcd2d4104186c",
+                "reference": "1cdb12bd791f608d3fbfbbb9b8fdcd2d4104186c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.1.0"
+            },
+            "require-dev": {
+                "seld/phar-utils": "^1.2",
+                "symfony/finder": "^3.0 || ^4.0 || ^5.0"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "Sage.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Rokas Šleinius",
+                    "homepage": "https://github.com/raveren"
+                },
+                {
+                    "name": "Contributors",
+                    "homepage": "https://github.com/phpsage/sage/contributors"
+                }
+            ],
+            "description": "☯ Insightful PHP debugging assistant.",
+            "homepage": "https://github.com/phpsage/sage",
+            "keywords": [
+                "debug",
+                "debug_backtrace",
+                "json_decode",
+                "php",
+                "sage",
+                "var_dup"
+            ],
+            "support": {
+                "issues": "https://github.com/php-sage/sage/issues",
+                "source": "https://github.com/php-sage/sage/tree/v1.2.25"
+            },
+            "time": "2022-05-04T11:14:34+00:00"
+        }
+    ],
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": [],
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": {
+        "ext-curl": "*",
+        "ext-xml": "*",
+        "ext-dom": "*",
+        "ext-simplexml": "*",
+        "ext-json": "*"
+    },
+    "platform-dev": [],
+    "plugin-api-version": "2.1.0"
+}
diff --git a/samples/env.php b/samples/env.php
new file mode 100644
index 0000000..08c5e8b
--- /dev/null
+++ b/samples/env.php
@@ -0,0 +1,4 @@
+<?php
+
+require_once __DIR__ . '/../vendor/autoload.php';
+$dotenv = (Dotenv\Dotenv::createImmutable(__DIR__ . '/../'))->load();
diff --git a/samples/pay.php b/samples/pay.php
new file mode 100644
index 0000000..325fafa
--- /dev/null
+++ b/samples/pay.php
@@ -0,0 +1,73 @@
+<?php
+
+
+use Sportakal\Garantipos\Models\Address;
+use Sportakal\Garantipos\Models\Card;
+use Sportakal\Garantipos\Models\Customer;
+use Sportakal\Garantipos\Models\RequestModel;
+use Sportakal\Garantipos\Models\Options;
+use Sportakal\Garantipos\Models\Order;
+use Sportakal\Garantipos\Models\Terminal;
+use Sportakal\Garantipos\Models\Transaction;
+
+require './env.php';
+
+$options = new Options();
+$options->setMode($_ENV['MODE']);
+$options->setApiVersion($_ENV['API_VERSION']);
+$options->setTerminalId($_ENV['TERMINAL_ID']);
+$options->setTerminalProvUserId($_ENV['TERMINAL_PROV_USER_ID_PAY']);
+$options->setTerminalProvUserPassword($_ENV['TERMINAL_PROV_USER_PASSWORD']);
+$options->setTerminalUserId($_ENV['TERMINAL_USER_ID']);
+$options->setTerminalMerchantId($_ENV['TERMINAL_MERCHANT_ID']);
+
+$card = new Card();
+$card->setNumber('5549608789641500');
+$card->setExpireDate('0323');
+$card->setCVV2('712');
+
+$customer = new Customer();
+$customer->setIpAddress('159.146.45.34');
+$customer->setEmailAddress('portakalsinan@gmail.com');
+
+
+$address= new Address();
+$address->setType('B'); // B for 'billing' or S for 'shipping'
+$address->setName('Sinan');
+$address->setLastName('Portakal');
+$address->setPhoneNumber('+90(532)876-23-23');
+$address->setText('Kınıklı Mah.');
+$address->setDistrict('Pamukkale');
+$address->setCity('Denizli');
+$address->setCountry('Turkey');
+
+$order = new Order();
+$order->setOrderID('sportakal_garantipos_' . time());
+$order->addAddress($address);
+
+$transaction = new Transaction();
+$transaction->setInstallmentCnt("");
+$transaction->setAmount(1000);
+$transaction->setCurrencyCode('TRY');
+$transaction->setCardholderPresentCode('0');
+$transaction->setMotoInd('N');
+$transaction->setDescription('test payment');
+
+$request = new RequestModel();
+$request->setOptions($options);
+$request->setCard($card);
+$request->setCustomer($customer);
+$request->setOrder($order);
+$request->setTransaction($transaction);
+
+$request = new \Sportakal\Garantipos\Requests\Pay($request);
+
+try {
+    $result = $request->getResult();
+    ddd($result->getStatus(), $result->getStatusMessage(), $result->getErrorMessage());
+} catch (Exception $e) {
+    ddd($e->getMessage());
+}
+
+
+
diff --git a/samples/refund.php b/samples/refund.php
new file mode 100644
index 0000000..6087fab
--- /dev/null
+++ b/samples/refund.php
@@ -0,0 +1,50 @@
+<?php
+
+
+use Sportakal\Garantipos\Models\Address;
+use Sportakal\Garantipos\Models\Card;
+use Sportakal\Garantipos\Models\Customer;
+use Sportakal\Garantipos\Models\RequestModel;
+use Sportakal\Garantipos\Models\Options;
+use Sportakal\Garantipos\Models\Order;
+use Sportakal\Garantipos\Models\Terminal;
+use Sportakal\Garantipos\Models\Transaction;
+
+
+require './env.php';
+
+$options = new Options();
+$options->setMode($_ENV['MODE']);
+$options->setApiVersion($_ENV['API_VERSION']);
+$options->setTerminalId($_ENV['TERMINAL_ID']);
+$options->setTerminalProvUserId($_ENV['TERMINAL_PROV_USER_ID_REFUND']);
+$options->setTerminalProvUserPassword($_ENV['TERMINAL_PROV_USER_PASSWORD']);
+$options->setTerminalUserId($_ENV['TERMINAL_USER_ID']);
+$options->setTerminalMerchantId($_ENV['TERMINAL_MERCHANT_ID']);
+
+$customer = new Customer();
+$customer->setIpAddress('159.146.45.34');
+
+
+$order = new Order();
+$order->setOrderID('sportakal_garantipos_' . time());
+
+$transaction = new Transaction();
+$transaction->setAmount(80);
+$transaction->setCurrencyCode('TRY');
+$transaction->setOriginalRetrefNum('214707386684');
+
+$request = new RequestModel();
+$request->setOptions($options);
+$request->setCustomer($customer);
+$request->setOrder($order);
+$request->setTransaction($transaction);
+
+$request = new \Sportakal\Garantipos\Requests\Refund($request);
+
+try {
+    $result = $request->getResult();
+    ddd($result->getStatus(), $result->getStatusMessage(), $result->getErrorMessage());
+} catch (Exception $e) {
+    ddd($e->getMessage());
+}
diff --git a/samples/threeDModelPay.php b/samples/threeDModelPay.php
new file mode 100644
index 0000000..d8e4fab
--- /dev/null
+++ b/samples/threeDModelPay.php
@@ -0,0 +1,67 @@
+<?php
+
+
+use Sportakal\Garantipos\Models\Address;
+use Sportakal\Garantipos\Models\Card;
+use Sportakal\Garantipos\Models\Customer;
+use Sportakal\Garantipos\Models\RequestModel;
+use Sportakal\Garantipos\Models\Options;
+use Sportakal\Garantipos\Models\Order;
+use Sportakal\Garantipos\Models\Terminal;
+use Sportakal\Garantipos\Models\Transaction;
+use Sportakal\Garantipos\Requests\InitializeThreeDSecure;
+use Sportakal\Garantipos\Requests\ThreeDSecurePay;
+
+require './env.php';
+
+$options = new Options();
+$options->setMode($_ENV['MODE']);
+$options->setApiVersion($_ENV['API_VERSION']);
+$options->setTerminalId($_ENV['TERMINAL_ID']);
+$options->setTerminalProvUserId($_ENV['TERMINAL_PROV_USER_ID_PAY']);
+$options->setTerminalProvUserPassword($_ENV['TERMINAL_PROV_USER_PASSWORD']);
+$options->setTerminalUserId($_ENV['TERMINAL_USER_ID']);
+$options->setTerminalMerchantId($_ENV['TERMINAL_MERCHANT_ID']);
+$options->setStoreKey($_ENV['THREED_STORE_KEY']);
+
+$card = new Card();
+$card->setNumber('5549608789641500'); //5406697543211173 //5549608789641500
+$card->setExpireDate('0323'); //0323 //0323
+$card->setCVV2('712'); //465 //712
+
+$customer = new Customer();
+$customer->setIpAddress('127.0.0.1');
+$customer->setEmailAddress('portakalsinan@gmail.com');
+
+
+$order = new Order();
+$order->setOrderID('sportakal_garantipos_' . time());
+$order->addAddress(new Address());
+
+$transaction = new Transaction();
+$transaction->setType('sales');
+$transaction->setInstallmentCnt("");
+$transaction->setAmount(80);
+$transaction->setCurrencyCode('TRY');
+$transaction->setCardholderPresentCode('0');
+$transaction->setMotoInd('N');
+$transaction->setDescription('test payment');
+
+$request = new RequestModel();
+$request->setOptions($options);
+$request->setCard($card);
+$request->setCustomer($customer);
+$request->setOrder($order);
+$request->setTransaction($transaction);
+$request->setSuccessURL((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]/garantipos/samples/threeDModelResult.php");
+$request->setErrorURL((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]/garantipos/samples/threeDModelResult.php");
+
+$response = new InitializeThreeDSecure($request);
+$response = $response->getResult();
+
+echo $response->getHtml();
+
+//echo '<pre>';
+//dd($response->getRawBody());
+//echo '</pre>';
+
diff --git a/samples/threeDModelResult.php b/samples/threeDModelResult.php
new file mode 100644
index 0000000..32e09d2
--- /dev/null
+++ b/samples/threeDModelResult.php
@@ -0,0 +1,36 @@
+<?php
+
+
+use Sportakal\Garantipos\Models\Options;
+
+require './env.php';
+
+
+$options = new Options();
+$options->setMode($_ENV['MODE']);
+$options->setApiVersion($_ENV['API_VERSION']);
+$options->setTerminalId($_ENV['TERMINAL_ID']);
+$options->setTerminalProvUserId($_ENV['TERMINAL_PROV_USER_ID_PAY']);
+$options->setTerminalProvUserPassword($_ENV['TERMINAL_PROV_USER_PASSWORD']);
+$options->setTerminalUserId($_ENV['TERMINAL_USER_ID']);
+$options->setTerminalMerchantId($_ENV['TERMINAL_MERCHANT_ID']);
+$options->setStoreKey($_ENV['THREED_STORE_KEY']);
+
+
+try {
+    $md_result = new \Sportakal\Garantipos\Results\ThreeDSecureModelResult($options);
+} catch (Exception $e) {
+    ddd($e->getMessage());
+}
+
+if (!$md_result->getMdStatus()) {
+    ddd($md_result->getMdStatus(), $md_result->getResponseMessage(), $md_result->getMdErrorMessage());
+}
+
+$response = new \Sportakal\Garantipos\Requests\CompleteThreeDSecure($_ENV['TERMINAL_PROV_USER_PASSWORD']);
+try {
+    $result = $response->getResult();
+    ddd($result->getStatus(), $result->getStatusMessage(), $result->getErrorMessage());
+} catch (Exception $e) {
+    ddd($e->getMessage());
+}
diff --git a/samples/threeDPay.php b/samples/threeDPay.php
new file mode 100644
index 0000000..38714c9
--- /dev/null
+++ b/samples/threeDPay.php
@@ -0,0 +1,74 @@
+<?php
+
+
+use Sportakal\Garantipos\Models\Address;
+use Sportakal\Garantipos\Models\Card;
+use Sportakal\Garantipos\Models\Customer;
+use Sportakal\Garantipos\Models\RequestModel;
+use Sportakal\Garantipos\Models\Options;
+use Sportakal\Garantipos\Models\Order;
+use Sportakal\Garantipos\Models\Transaction;
+use Sportakal\Garantipos\Requests\ThreeDSecurePay;
+
+require './env.php';
+
+$options = new Options();
+$options->setMode($_ENV['MODE']);
+$options->setApiVersion($_ENV['API_VERSION']);
+$options->setTerminalId($_ENV['TERMINAL_ID']);
+$options->setTerminalProvUserId($_ENV['TERMINAL_PROV_USER_ID_PAY']);
+$options->setTerminalProvUserPassword($_ENV['TERMINAL_PROV_USER_PASSWORD']);
+$options->setTerminalUserId($_ENV['TERMINAL_USER_ID']);
+$options->setTerminalMerchantId($_ENV['TERMINAL_MERCHANT_ID']);
+$options->setStoreKey($_ENV['THREED_STORE_KEY']);
+
+if ($_POST) {
+    try {
+        $result = new \Sportakal\Garantipos\Results\ThreeDSecurePayResult($options);
+        ddd($result->getMdStatus(), $result->getResponseMessage(), $result->getErrorMessage());
+    } catch (Exception $e) {
+        ddd($e->getMessage());
+    }
+}
+
+
+$card = new Card();
+$card->setNumber('5549608789641500'); //5406697543211173 //5549608789641500
+$card->setExpireDate('0323'); //0323 //0323
+$card->setCVV2('712'); //465 //712
+
+$customer = new Customer();
+$customer->setIpAddress('127.0.0.1');
+$customer->setEmailAddress('eticaret@garanti.com.tr');
+
+
+$order = new Order();
+$order->setOrderID(time() . "DENEME" . date("ymd"));
+$order->addAddress(new Address());
+
+$transaction = new Transaction();
+$transaction->setType('sales');
+$transaction->setInstallmentCnt("");
+$transaction->setAmount(80);
+$transaction->setCurrencyCode('TRY');
+$transaction->setCardholderPresentCode('0');
+$transaction->setMotoInd('N');
+$transaction->setDescription('test payment');
+
+$request = new RequestModel();
+$request->setOptions($options);
+$request->setCard($card);
+$request->setCustomer($customer);
+$request->setOrder($order);
+$request->setTransaction($transaction);
+$request->setSuccessURL((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");
+$request->setErrorURL((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]");
+
+$response = new ThreeDSecurePay($request);
+$response = $response->getResult();
+
+echo $response->getHtml();
+//echo '<pre>';
+//dd($response->getRawBody());
+//echo '</pre>';
+
diff --git a/src/Exceptions/ExpiredCardException.php b/src/Exceptions/ExpiredCardException.php
new file mode 100644
index 0000000..bdc9fa3
--- /dev/null
+++ b/src/Exceptions/ExpiredCardException.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace Sportakal\Garantipos\Exceptions;
+
+class ExpiredCardException extends \Exception
+{
+    public function __construct($message = "Card Expired", $code = 0, \Throwable $previous = null)
+    {
+        parent::__construct($message, $code, $previous);
+    }
+}
diff --git a/src/Exceptions/HashCheckFailedException.php b/src/Exceptions/HashCheckFailedException.php
new file mode 100644
index 0000000..670a1bb
--- /dev/null
+++ b/src/Exceptions/HashCheckFailedException.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace Sportakal\Garantipos\Exceptions;
+
+class HashCheckFailedException extends \Exception
+{
+    public function __construct($message = "Hash Check Failed", $code = 0, \Throwable $previous = null)
+    {
+        parent::__construct($message, $code, $previous);
+    }
+}
diff --git a/src/Handler.php b/src/Handler.php
new file mode 100644
index 0000000..6d9f10a
--- /dev/null
+++ b/src/Handler.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Sportakal\Garantipos;
+
+use Sportakal\Garantipos\Methods\BaseMethod;
+use Sportakal\Garantipos\Models\Options;
+use Sportakal\Garantipos\Utils\CreateHashData;
+use Sportakal\Garantipos\Utils\CreateSecurityData;
+
+class Handler
+{
+
+}
diff --git a/src/Models/Address.php b/src/Models/Address.php
new file mode 100644
index 0000000..bbd76af
--- /dev/null
+++ b/src/Models/Address.php
@@ -0,0 +1,214 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class Address extends BaseModel
+{
+    protected string $_parent_key = 'Address';
+    protected string $Type = 'B'; // B for 'billing' or S for 'shipping'
+    protected string $Name='';
+    protected string $LastName='';
+    protected string $Company='';
+    protected string $Text='';
+    protected string $District='';
+    protected string $City='';
+    protected string $Country='';
+    protected string $PostalCode='';
+    protected string $PhoneNumber='';
+    protected string $GsmNumber='';
+    protected string $FaxNumber='';
+
+    /**
+     * @return string
+     */
+    public function getType(): string
+    {
+        return $this->Type;
+    }
+
+    /**
+     * @param string $Type
+     */
+    public function setType(string $Type): void
+    {
+        $this->Type = $Type;
+    }
+
+    /**
+     * @return string
+     */
+    public function getName(): string
+    {
+        return $this->Name;
+    }
+
+    /**
+     * @param string $Name
+     */
+    public function setName(string $Name): void
+    {
+        $this->Name = $Name;
+    }
+
+    /**
+     * @return string
+     */
+    public function getLastName(): string
+    {
+        return $this->LastName;
+    }
+
+    /**
+     * @param string $LastName
+     */
+    public function setLastName(string $LastName): void
+    {
+        $this->LastName = $LastName;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCompany(): string
+    {
+        return $this->Company;
+    }
+
+    /**
+     * @param string $Company
+     */
+    public function setCompany(string $Company): void
+    {
+        $this->Company = $Company;
+    }
+
+    /**
+     * @return string
+     */
+    public function getText(): string
+    {
+        return $this->Text;
+    }
+
+    /**
+     * @param string $Text
+     */
+    public function setText(string $Text): void
+    {
+        $this->Text = $Text;
+    }
+
+    /**
+     * @return string
+     */
+    public function getDistrict(): string
+    {
+        return $this->District;
+    }
+
+    /**
+     * @param string $District
+     */
+    public function setDistrict(string $District): void
+    {
+        $this->District = $District;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCity(): string
+    {
+        return $this->City;
+    }
+
+    /**
+     * @param string $City
+     */
+    public function setCity(string $City): void
+    {
+        $this->City = $City;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCountry(): string
+    {
+        return $this->Country;
+    }
+
+    /**
+     * @param string $Country
+     */
+    public function setCountry(string $Country): void
+    {
+        $this->Country = $Country;
+    }
+
+    /**
+     * @return string
+     */
+    public function getPostalCode(): string
+    {
+        return $this->PostalCode;
+    }
+
+    /**
+     * @param string $PostalCode
+     */
+    public function setPostalCode(string $PostalCode): void
+    {
+        $this->PostalCode = $PostalCode;
+    }
+
+    /**
+     * @return string
+     */
+    public function getPhoneNumber(): string
+    {
+        return $this->PhoneNumber;
+    }
+
+    /**
+     * @param string $PhoneNumber
+     */
+    public function setPhoneNumber(string $PhoneNumber): void
+    {
+        $this->PhoneNumber = $PhoneNumber;
+    }
+
+    /**
+     * @return string
+     */
+    public function getGsmNumber(): string
+    {
+        return $this->GsmNumber;
+    }
+
+    /**
+     * @param string $GsmNumber
+     */
+    public function setGsmNumber(string $GsmNumber): void
+    {
+        $this->GsmNumber = $GsmNumber;
+    }
+
+    /**
+     * @return string
+     */
+    public function getFaxNumber(): string
+    {
+        return $this->FaxNumber;
+    }
+
+    /**
+     * @param string $FaxNumber
+     */
+    public function setFaxNumber(string $FaxNumber): void
+    {
+        $this->FaxNumber = $FaxNumber;
+    }
+
+
+}
diff --git a/src/Models/BaseModel.php b/src/Models/BaseModel.php
new file mode 100644
index 0000000..c9b1dc2
--- /dev/null
+++ b/src/Models/BaseModel.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+use Spatie\DataTransferObject\DataTransferObject;
+use Spatie\DataTransferObject\DataTransferObjectCollection;
+use Sportakal\Garantipos\Utils\Arrayable;
+
+class BaseModel extends Arrayable
+{
+
+
+}
diff --git a/src/Models/Card.php b/src/Models/Card.php
new file mode 100644
index 0000000..5eda624
--- /dev/null
+++ b/src/Models/Card.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+
+class Card extends BaseModel
+{
+    protected string $Number;
+    protected string $ExpireDate;
+    protected string $CVV2;
+
+    /**
+     * @return string
+     */
+    public function getNumber(): string
+    {
+        return $this->Number;
+    }
+
+    /**
+     * @param string $Number
+     */
+    public function setNumber(string $Number): void
+    {
+        $this->Number = $Number;
+    }
+
+    /**
+     * @return string
+     */
+    public function getExpireDate(): string
+    {
+        return $this->ExpireDate;
+    }
+
+    /**
+     * @param string $ExpireDate
+     */
+    public function setExpireDate(string $ExpireDate): void
+    {
+        $this->ExpireDate = $ExpireDate;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCVV2(): string
+    {
+        return $this->CVV2;
+    }
+
+    /**
+     * @param string $CVV2
+     */
+    public function setCVV2(string $CVV2): void
+    {
+        $this->CVV2 = $CVV2;
+    }
+}
diff --git a/src/Models/CepBank.php b/src/Models/CepBank.php
new file mode 100644
index 0000000..7bf8407
--- /dev/null
+++ b/src/Models/CepBank.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class CepBank extends BaseModel
+{
+    protected string $GSMNumber;
+    protected string $PaymentType; //K for credit, D for Debit, V for Account
+    protected string $HashDate;
+    protected string $HashValue;
+
+    /**
+     * @return string
+     */
+    public function getGSMNumber(): string
+    {
+        return $this->GSMNumber;
+    }
+
+    /**
+     * @param string $GSMNumber
+     */
+    public function setGSMNumber(string $GSMNumber): void
+    {
+        $this->GSMNumber = $GSMNumber;
+    }
+
+    /**
+     * @return string
+     */
+    public function getPaymentType(): string
+    {
+        return $this->PaymentType;
+    }
+
+    /**
+     * @param string $PaymentType
+     */
+    public function setPaymentType(string $PaymentType): void
+    {
+        $this->PaymentType = $PaymentType;
+    }
+
+    /**
+     * @return string
+     */
+    public function getHashDate(): string
+    {
+        return $this->HashDate;
+    }
+
+    /**
+     * @param string $HashDate
+     */
+    public function setHashDate(string $HashDate): void
+    {
+        $this->HashDate = $HashDate;
+    }
+
+    /**
+     * @return string
+     */
+    public function getHashValue(): string
+    {
+        return $this->HashValue;
+    }
+
+    /**
+     * @param string $HashValue
+     */
+    public function setHashValue(string $HashValue): void
+    {
+        $this->HashValue = $HashValue;
+    }
+
+
+
+
+}
diff --git a/src/Models/Cheque.php b/src/Models/Cheque.php
new file mode 100644
index 0000000..e40dd28
--- /dev/null
+++ b/src/Models/Cheque.php
@@ -0,0 +1,78 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class Cheque extends BaseModel
+{
+    protected string $_parent_key = 'Cheque';
+    protected string $Type; //P for Player, S for Sozunuze urun
+    protected string $Amount;
+    protected string $ID;
+    protected string $Bitmap;
+
+    /**
+     * @return string
+     */
+    public function getType(): string
+    {
+        return $this->Type;
+    }
+
+    /**
+     * @param string $Type
+     */
+    public function setType(string $Type): void
+    {
+        $this->Type = $Type;
+    }
+
+    /**
+     * @return string
+     */
+    public function getAmount(): string
+    {
+        return $this->Amount;
+    }
+
+    /**
+     * @param string $Amount
+     */
+    public function setAmount(string $Amount): void
+    {
+        $this->Amount = $Amount;
+    }
+
+    /**
+     * @return string
+     */
+    public function getID(): string
+    {
+        return $this->ID;
+    }
+
+    /**
+     * @param string $ID
+     */
+    public function setID(string $ID): void
+    {
+        $this->ID = $ID;
+    }
+
+    /**
+     * @return string
+     */
+    public function getBitmap(): string
+    {
+        return $this->Bitmap;
+    }
+
+    /**
+     * @param string $Bitmap
+     */
+    public function setBitmap(string $Bitmap): void
+    {
+        $this->Bitmap = $Bitmap;
+    }
+
+
+}
diff --git a/src/Models/Comment.php b/src/Models/Comment.php
new file mode 100644
index 0000000..7c3141c
--- /dev/null
+++ b/src/Models/Comment.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class Comment extends BaseModel
+{
+    protected string $_parent_key = 'Comment';
+    protected string $Number;
+    protected string $Text;
+
+    /**
+     * @return string
+     */
+    public function getNumber(): string
+    {
+        return $this->Number;
+    }
+
+    /**
+     * @param string $Number
+     */
+    public function setNumber(string $Number): void
+    {
+        $this->Number = $Number;
+    }
+
+    /**
+     * @return string
+     */
+    public function getText(): string
+    {
+        return $this->Text;
+    }
+
+    /**
+     * @param string $Text
+     */
+    public function setText(string $Text): void
+    {
+        $this->Text = $Text;
+    }
+
+
+
+}
diff --git a/src/Models/CommercialCardExtendedCredit.php b/src/Models/CommercialCardExtendedCredit.php
new file mode 100644
index 0000000..e0a1549
--- /dev/null
+++ b/src/Models/CommercialCardExtendedCredit.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class CommercialCardExtendedCredit extends BaseModel
+{
+    protected array $PaymentList;
+
+    /**
+     * @return array
+     */
+    public function getPaymentList(): array
+    {
+        return $this->PaymentList;
+    }
+
+    /**
+     * @param array $PaymentList
+     */
+    public function setPaymentList(array $PaymentList): void
+    {
+        $this->PaymentList = $PaymentList;
+    }
+
+    /**
+     * @param Payment $Payment
+     */
+    public function addPayment(Payment $Payment):void
+    {
+        $this->PaymentList[] = $Payment;
+    }
+
+}
diff --git a/src/Models/Customer.php b/src/Models/Customer.php
new file mode 100644
index 0000000..6ddf138
--- /dev/null
+++ b/src/Models/Customer.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+
+class Customer extends BaseModel
+{
+    protected string $IPAddress;
+    protected string $EmailAddress;
+
+    /**
+     * @return string
+     */
+    public function getIPAddress(): string
+    {
+        return $this->IPAddress;
+    }
+
+    /**
+     * @param string $IPAddress
+     */
+    public function setIPAddress(string $IPAddress): void
+    {
+        $this->IPAddress = $IPAddress;
+    }
+
+    /**
+     * @return string
+     */
+    public function getEmailAddress(): string
+    {
+        return $this->EmailAddress;
+    }
+
+    /**
+     * @param string $EmailAddress
+     */
+    public function setEmailAddress(string $EmailAddress): void
+    {
+        $this->EmailAddress = $EmailAddress;
+    }
+
+
+
+
+}
diff --git a/src/Models/DCC.php b/src/Models/DCC.php
new file mode 100644
index 0000000..f1a3439
--- /dev/null
+++ b/src/Models/DCC.php
@@ -0,0 +1,30 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class DCC extends BaseModel
+{
+    protected string $Currency;
+
+    /**
+     * @return string
+     */
+    public function getCurrency(): string
+    {
+        return $this->Currency;
+    }
+
+    /**
+     * @param string $Currency
+     */
+    public function setCurrency(string $Currency): void
+    {
+        $this->Currency = $Currency;
+    }
+
+
+
+
+
+
+}
diff --git a/src/Models/GSMUnitSales.php b/src/Models/GSMUnitSales.php
new file mode 100644
index 0000000..0cead3c
--- /dev/null
+++ b/src/Models/GSMUnitSales.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class GSMUnitSales extends BaseModel
+{
+    protected string $UnitID;
+    protected string $Quantity;
+    protected string $Amount;
+
+    /**
+     * @return string
+     */
+    public function getUnitID(): string
+    {
+        return $this->UnitID;
+    }
+
+    /**
+     * @param string $UnitID
+     */
+    public function setUnitID(string $UnitID): void
+    {
+        $this->UnitID = $UnitID;
+    }
+
+    /**
+     * @return string
+     */
+    public function getQuantity(): string
+    {
+        return $this->Quantity;
+    }
+
+    /**
+     * @param string $Quantity
+     */
+    public function setQuantity(string $Quantity): void
+    {
+        $this->Quantity = $Quantity;
+    }
+
+    /**
+     * @return string
+     */
+    public function getAmount(): string
+    {
+        return $this->Amount;
+    }
+
+    /**
+     * @param string $Amount
+     */
+    public function setAmount(string $Amount): void
+    {
+        $this->Amount = $Amount;
+    }
+}
diff --git a/src/Models/Item.php b/src/Models/Item.php
new file mode 100644
index 0000000..3d75dc9
--- /dev/null
+++ b/src/Models/Item.php
@@ -0,0 +1,113 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class Item extends BaseModel
+{
+    protected string $_parent_key = 'Item';
+    protected string $Number;
+    protected string $ProductID;
+    protected string $ProductCode;
+    protected string $Quantity;
+    protected string $Price;
+    protected string $TotalAmount;
+
+    /**
+     * @return string
+     */
+    public function getNumber(): string
+    {
+        return $this->Number;
+    }
+
+    /**
+     * @param string $Number
+     */
+    public function setNumber(string $Number): void
+    {
+        $this->Number = $Number;
+    }
+
+    /**
+     * @return string
+     */
+    public function getProductID(): string
+    {
+        return $this->ProductID;
+    }
+
+    /**
+     * @param string $ProductID
+     */
+    public function setProductID(string $ProductID): void
+    {
+        $this->ProductID = $ProductID;
+    }
+
+    /**
+     * @return string
+     */
+    public function getProductCode(): string
+    {
+        return $this->ProductCode;
+    }
+
+    /**
+     * @param string $ProductCode
+     */
+    public function setProductCode(string $ProductCode): void
+    {
+        $this->ProductCode = $ProductCode;
+    }
+
+    /**
+     * @return string
+     */
+    public function getQuantity(): string
+    {
+        return $this->Quantity;
+    }
+
+    /**
+     * @param string $Quantity
+     */
+    public function setQuantity(string $Quantity): void
+    {
+        $this->Quantity = $Quantity;
+    }
+
+    /**
+     * @return string
+     */
+    public function getPrice(): string
+    {
+        return $this->Price;
+    }
+
+    /**
+     * @param string $Price
+     */
+    public function setPrice(string $Price): void
+    {
+        $this->Price = $Price;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTotalAmount(): string
+    {
+        return $this->TotalAmount;
+    }
+
+    /**
+     * @param string $TotalAmount
+     */
+    public function setTotalAmount(string $TotalAmount): void
+    {
+        $this->TotalAmount = $TotalAmount;
+    }
+
+
+
+}
diff --git a/src/Models/MoneyCard.php b/src/Models/MoneyCard.php
new file mode 100644
index 0000000..1906024
--- /dev/null
+++ b/src/Models/MoneyCard.php
@@ -0,0 +1,95 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class MoneyCard extends BaseModel
+{
+    protected string $InvoiceAmount;
+    protected string $MigrosCCDiscountAmount;
+    protected string $PaymentAmount;
+    protected string $ExtraDiscountAmount;
+    protected string $ProductBasedDiscountAmount;
+
+    /**
+     * @return string
+     */
+    public function getInvoiceAmount(): string
+    {
+        return $this->InvoiceAmount;
+    }
+
+    /**
+     * @param string $InvoiceAmount
+     */
+    public function setInvoiceAmount(string $InvoiceAmount): void
+    {
+        $this->InvoiceAmount = $InvoiceAmount;
+    }
+
+    /**
+     * @return string
+     */
+    public function getMigrosCCDiscountAmount(): string
+    {
+        return $this->MigrosCCDiscountAmount;
+    }
+
+    /**
+     * @param string $MigrosCCDiscountAmount
+     */
+    public function setMigrosCCDiscountAmount(string $MigrosCCDiscountAmount): void
+    {
+        $this->MigrosCCDiscountAmount = $MigrosCCDiscountAmount;
+    }
+
+    /**
+     * @return string
+     */
+    public function getPaymentAmount(): string
+    {
+        return $this->PaymentAmount;
+    }
+
+    /**
+     * @param string $PaymentAmount
+     */
+    public function setPaymentAmount(string $PaymentAmount): void
+    {
+        $this->PaymentAmount = $PaymentAmount;
+    }
+
+    /**
+     * @return string
+     */
+    public function getExtraDiscountAmount(): string
+    {
+        return $this->ExtraDiscountAmount;
+    }
+
+    /**
+     * @param string $ExtraDiscountAmount
+     */
+    public function setExtraDiscountAmount(string $ExtraDiscountAmount): void
+    {
+        $this->ExtraDiscountAmount = $ExtraDiscountAmount;
+    }
+
+    /**
+     * @return string
+     */
+    public function getProductBasedDiscountAmount(): string
+    {
+        return $this->ProductBasedDiscountAmount;
+    }
+
+    /**
+     * @param string $ProductBasedDiscountAmount
+     */
+    public function setProductBasedDiscountAmount(string $ProductBasedDiscountAmount): void
+    {
+        $this->ProductBasedDiscountAmount = $ProductBasedDiscountAmount;
+    }
+
+
+
+}
diff --git a/src/Models/Options.php b/src/Models/Options.php
new file mode 100644
index 0000000..75c7738
--- /dev/null
+++ b/src/Models/Options.php
@@ -0,0 +1,173 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+
+class Options extends BaseModel
+{
+    protected bool $_pass_in_xml = true;
+    protected Terminal $terminal;
+    protected string $mode;
+    protected string $api_version;
+    protected string $terminal_id;
+    protected string $terminal_prov_user_id;
+    protected string $terminal_prov_user_password;
+    protected string $terminal_user_id;
+    protected string $terminal_merchant_id;
+    protected string $store_key;
+
+
+    /**
+     * @return string
+     */
+    public function getMode(): string
+    {
+        return $this->mode;
+    }
+
+    /**
+     * @param string $mode
+     */
+    public function setMode(string $mode): void
+    {
+        $this->mode = $mode;
+    }
+
+
+    /**
+     * @return string
+     */
+    public function getApiVersion(): string
+    {
+        return $this->api_version;
+    }
+
+    /**
+     * @param string $api_version
+     */
+    public function setApiVersion(string $api_version): void
+    {
+        $this->api_version = $api_version;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTerminalId(): string
+    {
+        return $this->terminal_id;
+    }
+
+    /**
+     * @param string $terminal_id
+     */
+    public function setTerminalId(string $terminal_id): void
+    {
+        $this->terminal_id = $terminal_id;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTerminalProvUserId(): string
+    {
+        return $this->terminal_prov_user_id;
+    }
+
+    /**
+     * @param string $terminal_prov_user_id
+     */
+    public function setTerminalProvUserId(string $terminal_prov_user_id): void
+    {
+        $this->terminal_prov_user_id = $terminal_prov_user_id;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTerminalProvUserPassword(): string
+    {
+        return $this->terminal_prov_user_password;
+    }
+
+    /**
+     * @param string $terminal_prov_user_password
+     */
+    public function setTerminalProvUserPassword(string $terminal_prov_user_password): void
+    {
+        $this->terminal_prov_user_password = $terminal_prov_user_password;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTerminalUserId(): string
+    {
+        return $this->terminal_user_id;
+    }
+
+    /**
+     * @param string $terminal_user_id
+     */
+    public function setTerminalUserId(string $terminal_user_id): void
+    {
+        $this->terminal_user_id = $terminal_user_id;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTerminalMerchantId(): string
+    {
+        return $this->terminal_merchant_id;
+    }
+
+    /**
+     * @param string $terminal_merchant_id
+     */
+    public function setTerminalMerchantId(string $terminal_merchant_id): void
+    {
+        $this->terminal_merchant_id = $terminal_merchant_id;
+    }
+
+    /**
+     * @return string
+     */
+    public function getStoreKey(): string
+    {
+        return $this->store_key;
+    }
+
+    /**
+     * @param string $store_key
+     */
+    public function setStoreKey(string $store_key): void
+    {
+        $this->store_key = $store_key;
+    }
+
+
+    /**
+     */
+    public function setTerminal(): void
+    {
+        $this->terminal = new Terminal();
+        $this->terminal->setID($this->terminal_id);
+        $this->terminal->setProvUserID($this->terminal_prov_user_id);
+        $this->terminal->setProvUserPassword($this->terminal_prov_user_password);
+        $this->terminal->setUserID($this->terminal_user_id);
+        $this->terminal->setMerchantID($this->terminal_merchant_id);
+    }
+
+    /**
+     * @return Terminal
+     */
+    public function getTerminal(): Terminal
+    {
+        if (empty($this->terminal)) {
+            $this->setTerminal();
+        }
+        return $this->terminal;
+    }
+
+}
diff --git a/src/Models/Order.php b/src/Models/Order.php
new file mode 100644
index 0000000..0bb0f61
--- /dev/null
+++ b/src/Models/Order.php
@@ -0,0 +1,168 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class Order extends BaseModel
+{
+    protected string $OrderID;
+    protected string $GroupID;
+    protected array $AddressList;
+    protected string $StartDate;
+    protected string $EndDate;
+    protected array $ItemList;
+    protected Recurring $Recurring;
+    protected array $CommentList;
+
+    /**
+     * @return string
+     */
+    public function getOrderID(): string
+    {
+        return $this->OrderID;
+    }
+
+    /**
+     * @param string $OrderID
+     */
+    public function setOrderID(string $OrderID): void
+    {
+        $this->OrderID = $OrderID;
+    }
+
+    /**
+     * @return string
+     */
+    public function getGroupID(): string
+    {
+        return $this->GroupID;
+    }
+
+    /**
+     * @param string $GroupID
+     */
+    public function setGroupID(string $GroupID): void
+    {
+        $this->GroupID = $GroupID;
+    }
+
+    /**
+     * @return string
+     */
+    public function getStartDate(): string
+    {
+        return $this->StartDate;
+    }
+
+    /**
+     * @param string $StartDate
+     */
+    public function setStartDate(string $StartDate): void
+    {
+        $this->StartDate = $StartDate;
+    }
+
+    /**
+     * @return string
+     */
+    public function getEndDate(): string
+    {
+        return $this->EndDate;
+    }
+
+    /**
+     * @param string $EndDate
+     */
+    public function setEndDate(string $EndDate): void
+    {
+        $this->EndDate = $EndDate;
+    }
+
+    /**
+     * @return array
+     */
+    public function getItemList(): array
+    {
+        return $this->ItemList;
+    }
+
+    /**
+     * @param array $ItemList
+     */
+    public function setItemList(array $ItemList): void
+    {
+        $this->ItemList = $ItemList;
+    }
+
+    /**
+     * @return array
+     */
+    public function getAddressList(): array
+    {
+        return $this->AddressList;
+    }
+
+    /**
+     * @param array $AddressList
+     */
+    public function setAddressList(array $AddressList): void
+    {
+        $this->AddressList = $AddressList;
+    }
+
+    /**
+     * @return Recurring
+     */
+    public function getRecurring(): Recurring
+    {
+        return $this->Recurring;
+    }
+
+    /**
+     * @param Recurring $Recurring
+     */
+    public function setRecurring(Recurring $Recurring): void
+    {
+        $this->Recurring = $Recurring;
+    }
+
+    /**
+     * @return array
+     */
+    public function getCommentList(): array
+    {
+        return $this->CommentList;
+    }
+
+    /**
+     * @param array $CommentList
+     */
+    public function setCommentList(array $CommentList): void
+    {
+        $this->CommentList = $CommentList;
+    }
+
+    /**
+     * @param Item $item
+     */
+    public function addItem(Item $item): void
+    {
+        $this->ItemList[] = $item;
+    }
+
+
+    /**
+     * @param Comment $Comment
+     */
+    public function addComment(Comment $Comment): void
+    {
+        $this->CommentList[] = $Comment;
+    }
+
+    /**
+     * @param Address $Address
+     */
+    public function addAddress(Address $Address): void
+    {
+        $this->AddressList[] = $Address;
+    }
+}
diff --git a/src/Models/Payment.php b/src/Models/Payment.php
new file mode 100644
index 0000000..d3519da
--- /dev/null
+++ b/src/Models/Payment.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class Payment extends BaseModel
+{
+    protected string $_parent_key = 'Payment';
+    protected string $PaymentNum;
+    protected string $Number;
+    protected int $Amount;
+    protected string $DueDate;//YYYYMMDD
+
+
+    /**
+     * @return string
+     */
+    public function getPaymentNum(): string
+    {
+        return $this->PaymentNum;
+    }
+
+    /**
+     * @param string $PaymentNum
+     */
+    public function setPaymentNum(string $PaymentNum): void
+    {
+        $this->PaymentNum = $PaymentNum;
+    }
+
+    /**
+     * @return string
+     */
+    public function getNumber(): string
+    {
+        return $this->Number;
+    }
+
+    /**
+     * @param string $Number
+     */
+    public function setNumber(string $Number): void
+    {
+        $this->Number = $Number;
+    }
+
+    /**
+     * @return int
+     */
+    public function getAmount(): int
+    {
+        return $this->Amount;
+    }
+
+    /**
+     * @param int $Amount
+     */
+    public function setAmount(int $Amount): void
+    {
+        $this->Amount = $Amount;
+    }
+
+    /**
+     * @return string
+     */
+    public function getDueDate(): string
+    {
+        return $this->DueDate;
+    }
+
+    /**
+     * @param string $DueDate
+     */
+    public function setDueDate(string $DueDate): void
+    {
+        $this->DueDate = $DueDate;
+    }
+}
diff --git a/src/Models/Recurring.php b/src/Models/Recurring.php
new file mode 100644
index 0000000..5937286
--- /dev/null
+++ b/src/Models/Recurring.php
@@ -0,0 +1,117 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class Recurring extends BaseModel
+{
+    protected string $Type; // R:Sabit Tutarli   G:Degisken Tutarli
+    protected string $TotalPaymentNum;
+    protected string $FrequencyType; //M for Monthly, W for weekly, D for daily
+    protected string $FrequencyInterval;
+    protected string $StartDate;
+    protected array $PaymentList;
+
+    /**
+     * @return string
+     */
+    public function getType(): string
+    {
+        return $this->Type;
+    }
+
+    /**
+     * @param string $Type
+     */
+    public function setType(string $Type): void
+    {
+        $this->Type = $Type;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTotalPaymentNum(): string
+    {
+        return $this->TotalPaymentNum;
+    }
+
+    /**
+     * @param string $TotalPaymentNum
+     */
+    public function setTotalPaymentNum(string $TotalPaymentNum): void
+    {
+        $this->TotalPaymentNum = $TotalPaymentNum;
+    }
+
+    /**
+     * @return string
+     */
+    public function getFrequencyType(): string
+    {
+        return $this->FrequencyType;
+    }
+
+    /**
+     * @param string $FrequencyType
+     */
+    public function setFrequencyType(string $FrequencyType): void
+    {
+        $this->FrequencyType = $FrequencyType;
+    }
+
+    /**
+     * @return string
+     */
+    public function getFrequencyInterval(): string
+    {
+        return $this->FrequencyInterval;
+    }
+
+    /**
+     * @param string $FrequencyInterval
+     */
+    public function setFrequencyInterval(string $FrequencyInterval): void
+    {
+        $this->FrequencyInterval = $FrequencyInterval;
+    }
+
+    /**
+     * @return string
+     */
+    public function getStartDate(): string
+    {
+        return $this->StartDate;
+    }
+
+    /**
+     * @param string $StartDate
+     */
+    public function setStartDate(string $StartDate): void
+    {
+        $this->StartDate = $StartDate;
+    }
+
+    /**
+     * @return array
+     */
+    public function getPaymentList(): array
+    {
+        return $this->PaymentList;
+    }
+
+    /**
+     * @param array $PaymentList
+     */
+    public function setPaymentList(array $PaymentList): void
+    {
+        $this->PaymentList = $PaymentList;
+    }
+
+    /**
+     * @param Payment $Payment
+     */
+    public function addPayment(Payment $Payment): void
+    {
+        $this->PaymentList[] = $Payment;
+    }
+}
diff --git a/src/Models/RequestModel.php b/src/Models/RequestModel.php
new file mode 100644
index 0000000..4c1a0be
--- /dev/null
+++ b/src/Models/RequestModel.php
@@ -0,0 +1,183 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class RequestModel extends BaseModel
+{
+    protected string $_parent_key = 'GVPSRequest';
+    protected string $Mode = 'TEST';
+    protected string $Version = 'v0.01';
+    protected string $ChannelCode = '';
+    protected Options $options;
+    protected Terminal $Terminal;
+    protected Customer $Customer;
+    protected Card $Card;
+    protected Order $Order;
+    protected Transaction $Transaction;
+
+    protected string $SuccessURL;
+    protected string $ErrorURL;
+
+    /**
+     * @return string
+     */
+    public function getMode(): string
+    {
+        return $this->Mode;
+    }
+
+    /**
+     * @return string
+     */
+    public function getVersion(): string
+    {
+        return $this->Version;
+    }
+
+    /**
+     * @param string $Version
+     */
+    public function setVersion(string $Version): void
+    {
+        $this->Version = $Version;
+    }
+
+    /**
+     * @return string
+     */
+    public function getChannelCode(): string
+    {
+        return $this->ChannelCode;
+    }
+
+    /**
+     * @param string $ChannelCode
+     */
+    public function setChannelCode(string $ChannelCode): void
+    {
+        $this->ChannelCode = $ChannelCode;
+    }
+
+    /**
+     * @return Options
+     */
+    public function getOptions(): Options
+    {
+        return $this->options;
+    }
+
+    /**
+     * @param Options $options
+     */
+    public function setOptions(Options $options): void
+    {
+        $this->options = $options;
+        $this->Terminal = $options->getTerminal();
+        $this->Mode = $options->getMode();
+    }
+
+    /**
+     * @return Terminal
+     */
+    public function getTerminal(): Terminal
+    {
+        return $this->Terminal;
+    }
+
+
+    /**
+     * @return Customer
+     */
+    public function getCustomer(): Customer
+    {
+        return $this->Customer;
+    }
+
+    /**
+     * @param Customer $Customer
+     */
+    public function setCustomer(Customer $Customer): void
+    {
+        $this->Customer = $Customer;
+    }
+
+    /**
+     * @return Card
+     */
+    public function getCard(): Card
+    {
+        return $this->Card;
+    }
+
+    /**
+     * @param Card $Card
+     */
+    public function setCard(Card $Card): void
+    {
+        $this->Card = $Card;
+    }
+
+    /**
+     * @return Order
+     */
+    public function getOrder(): Order
+    {
+        return $this->Order;
+    }
+
+    /**
+     * @param Order $Order
+     */
+    public function setOrder(Order $Order): void
+    {
+        $this->Order = $Order;
+    }
+
+    /**
+     * @return Transaction
+     */
+    public function getTransaction(): Transaction
+    {
+        return $this->Transaction;
+    }
+
+    /**
+     * @param Transaction $Transaction
+     */
+    public function setTransaction(Transaction $Transaction): void
+    {
+        $this->Transaction = $Transaction;
+    }
+
+    /**
+     * @return string
+     */
+    public function getSuccessURL(): string
+    {
+        return $this->SuccessURL;
+    }
+
+    /**
+     * @param string $SuccessURL
+     */
+    public function setSuccessURL(string $SuccessURL): void
+    {
+        $this->SuccessURL = $SuccessURL;
+    }
+
+    /**
+     * @return string
+     */
+    public function getErrorURL(): string
+    {
+        return $this->ErrorURL;
+    }
+
+    /**
+     * @param string $ErrorURL
+     */
+    public function setErrorURL(string $ErrorURL): void
+    {
+        $this->ErrorURL = $ErrorURL;
+    }
+}
diff --git a/src/Models/ResultModels/PostResultModel.php b/src/Models/ResultModels/PostResultModel.php
new file mode 100644
index 0000000..5dc0fa8
--- /dev/null
+++ b/src/Models/ResultModels/PostResultModel.php
@@ -0,0 +1,72 @@
+<?php
+
+namespace Sportakal\Garantipos\Models\ResultModels;
+
+use Sportakal\Garantipos\Utils\Arrayable;
+
+class PostResultModel extends Arrayable implements ResultModelInterface
+{
+    public array $fields;
+    public string $secure3dsecuritylevel;
+    public string $mode;
+    public string $apiversion;
+    public string $clientid;
+    public string $terminalprovuserid;
+    public string $terminaluserid;
+    public string $terminalmerchantid;
+    public string $customeripaddress;
+    public string $customeremailaddress;
+    public string $orderid;
+    public string $txntype;
+    public string $txninstallmentcount;
+    public string $txnamount;
+    public string $txncurrencycode;
+    public string $cavv;
+    public string $eci;
+    public string $xid;
+    public string $md;
+    public string $mdstatus;
+    public string $mderrormessage;
+    public string $response;
+    public string $errmsg;
+    public string $hostmsg;
+    public string $successurl;
+    public string $errorurl;
+    public string $hash;
+    public string $hostrefnum;
+
+    public function __construct(array $post_fields = [])
+    {
+        if (count($post_fields) === 0) {
+            $post_fields = $_POST;
+        }
+        $this->fields = $post_fields;
+        $this->secure3dsecuritylevel = $post_fields['secure3dsecuritylevel'] ?? '';
+        $this->mode = $post_fields['mode'] ?? '';
+        $this->apiversion = $post_fields['apiversion'] ?? '';
+        $this->clientid = $post_fields['clientid'] ?? '';
+        $this->terminalprovuserid = $post_fields['terminalprovuserid'] ?? '';
+        $this->terminaluserid = $post_fields['terminaluserid'] ?? '';
+        $this->terminalmerchantid = $post_fields['terminalmerchantid'] ?? '';
+        $this->customeripaddress = $post_fields['customeripaddress'] ?? '';
+        $this->customeremailaddress = $post_fields['customeremailaddress'] ?? '';
+        $this->orderid = $post_fields['orderid'] ?? '';
+        $this->txntype = $post_fields['txntype'] ?? '';
+        $this->txninstallmentcount = $post_fields['txninstallmentcount'] ?? '';
+        $this->txnamount = $post_fields['txnamount'] ?? '';
+        $this->txncurrencycode = $post_fields['txncurrencycode'] ?? '';
+        $this->cavv = $post_fields['cavv'] ?? '';
+        $this->eci = $post_fields['eci'] ?? '';
+        $this->xid = $post_fields['xid'] ?? '';
+        $this->md = $post_fields['md'] ?? '';
+        $this->mdstatus = $post_fields['mdstatus'] ?? '';
+        $this->mderrormessage = $post_fields['mderrormessage'] ?? '';
+        $this->response = $post_fields['response'] ?? '';
+        $this->errmsg = $post_fields['errmsg'] ?? '';
+        $this->hostmsg = $post_fields['hostmsg'] ?? '';
+        $this->successurl = $post_fields['successurl'] ?? '';
+        $this->errorurl = $post_fields['errorurl'] ?? '';
+        $this->hash = $_POST['secure3dhash'] ?? '';
+        $this->hostrefnum = $_POST['hostrefnum'] ?? '';
+    }
+}
diff --git a/src/Models/ResultModels/ResultModelInterface.php b/src/Models/ResultModels/ResultModelInterface.php
new file mode 100644
index 0000000..1838e98
--- /dev/null
+++ b/src/Models/ResultModels/ResultModelInterface.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace Sportakal\Garantipos\Models\ResultModels;
+
+interface ResultModelInterface
+{
+
+}
diff --git a/src/Models/ResultModels/XmlResultModel.php b/src/Models/ResultModels/XmlResultModel.php
new file mode 100644
index 0000000..f83ac0e
--- /dev/null
+++ b/src/Models/ResultModels/XmlResultModel.php
@@ -0,0 +1,40 @@
+<?php
+
+namespace Sportakal\Garantipos\Models\ResultModels;
+
+use Sportakal\Garantipos\Utils\Arrayable;
+
+class XmlResultModel extends Arrayable implements ResultModelInterface
+{
+    public array $fields;
+    public string $source;
+    public string $code;
+    public string $reason_code;
+    public string $message;
+    public string $error_message;
+    public string $system_error_message;
+    public string $ret_ref_num;
+    public string $provision_date;
+    public string $card_type;
+    public string $hash_data;
+    public array $host_messages;
+
+    public function __construct(array $post_fields = [])
+    {
+        if (count($post_fields) < 0) {
+            $post_fields = $_POST;
+        }
+        $this->fields = $post_fields;
+        $this->source = $post_fields['Transaction']['Response']['Source'] ?? '';
+        $this->code = $post_fields['Transaction']['Response']['Code'];
+        $this->reason_code = $post_fields['Transaction']['Response']['ReasonCode'] ?? '';
+        $this->message = $post_fields['Transaction']['Response']['Message'] ?? '';
+        $this->error_message = $post_fields['Transaction']['Response']['ErrorMsg'] ?? '';
+        $this->system_error_message = $post_fields['Transaction']['Response']['SysErrMsg'] ?? '';
+        $this->ret_ref_num = $post_fields['Transaction']['RetrefNum'] ?? '';
+        $this->provision_date = $post_fields['Transaction']['ProvDate'] ?? '';
+        $this->card_type = $post_fields['Transaction']['CardType'] ?? '';
+        $this->hash_data = $post_fields['Transaction']['HashData'] ?? '';
+        $this->host_messages = $post_fields['Transaction']['HostMsgList']['HostMsg'] ?? [];
+    }
+}
diff --git a/src/Models/Reward.php b/src/Models/Reward.php
new file mode 100644
index 0000000..f590c5e
--- /dev/null
+++ b/src/Models/Reward.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class Reward extends BaseModel
+{
+    protected string $_parent_key = 'Reward';
+    protected string $Type; //MR, BNS, Mil, FirmBasedBns, FirmBasedCheque
+    protected string $UsedAmount;
+    protected string $GainedAmount;
+
+    /**
+     * @return string
+     */
+    public function getType(): string
+    {
+        return $this->Type;
+    }
+
+    /**
+     * @param string $Type
+     */
+    public function setType(string $Type): void
+    {
+        $this->Type = $Type;
+    }
+
+    /**
+     * @return string
+     */
+    public function getUsedAmount(): string
+    {
+        return $this->UsedAmount;
+    }
+
+    /**
+     * @param string $UsedAmount
+     */
+    public function setUsedAmount(string $UsedAmount): void
+    {
+        $this->UsedAmount = $UsedAmount;
+    }
+
+    /**
+     * @return string
+     */
+    public function getGainedAmount(): string
+    {
+        return $this->GainedAmount;
+    }
+
+    /**
+     * @param string $GainedAmount
+     */
+    public function setGainedAmount(string $GainedAmount): void
+    {
+        $this->GainedAmount = $GainedAmount;
+    }
+
+
+}
diff --git a/src/Models/Secure3D.php b/src/Models/Secure3D.php
new file mode 100644
index 0000000..f184640
--- /dev/null
+++ b/src/Models/Secure3D.php
@@ -0,0 +1,77 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class Secure3D extends BaseModel
+{
+    protected string $AuthenticationCode;
+    protected string $SecurityLevel;
+    protected string $TxnID;
+    protected string $Md;
+
+    /**
+     * @return string
+     */
+    public function getAuthenticationCode(): string
+    {
+        return $this->AuthenticationCode;
+    }
+
+    /**
+     * @param string $AuthenticationCode
+     */
+    public function setAuthenticationCode(string $AuthenticationCode): void
+    {
+        $this->AuthenticationCode = $AuthenticationCode;
+    }
+
+    /**
+     * @return string
+     */
+    public function getSecurityLevel(): string
+    {
+        return $this->SecurityLevel;
+    }
+
+    /**
+     * @param string $SecurityLevel
+     */
+    public function setSecurityLevel(string $SecurityLevel): void
+    {
+        $this->SecurityLevel = $SecurityLevel;
+    }
+
+    /**
+     * @return string
+     */
+    public function getTxnID(): string
+    {
+        return $this->TxnID;
+    }
+
+    /**
+     * @param string $TxnID
+     */
+    public function setTxnID(string $TxnID): void
+    {
+        $this->TxnID = $TxnID;
+    }
+
+    /**
+     * @return string
+     */
+    public function getMd(): string
+    {
+        return $this->Md;
+    }
+
+    /**
+     * @param string $Md
+     */
+    public function setMd(string $Md): void
+    {
+        $this->Md = $Md;
+    }
+
+
+}
diff --git a/src/Models/Terminal.php b/src/Models/Terminal.php
new file mode 100644
index 0000000..1e7fd5e
--- /dev/null
+++ b/src/Models/Terminal.php
@@ -0,0 +1,122 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class Terminal extends BaseModel
+{
+    protected string $ProvUserID;
+    protected string $ProvUserPassword;
+    protected string $HashData;
+    protected string $UserID;
+    protected string $ID;
+    protected string $ID_;
+    protected string $MerchantID;
+
+    /**
+     * @return string
+     */
+    public function getProvUserID(): string
+    {
+        return $this->ProvUserID;
+    }
+
+    /**
+     * @param string $ProvUserID
+     */
+    public function setProvUserID(string $ProvUserID): void
+    {
+        $this->ProvUserID = $ProvUserID;
+    }
+
+    /**
+     * @return string
+     */
+    public function getProvUserPassword(): string
+    {
+        return $this->ProvUserPassword;
+    }
+
+    /**
+     * @param string $ProvUserPassword
+     */
+    public function setProvUserPassword(string $ProvUserPassword): void
+    {
+        $this->ProvUserPassword = $ProvUserPassword;
+    }
+
+
+    /**
+     * @return string
+     */
+    public function getHashData(): string
+    {
+        return $this->HashData;
+    }
+
+    /**
+     * @param string $HashData
+     */
+    public function setHashData(string $HashData): void
+    {
+        $this->HashData = $HashData;
+    }
+
+    /**
+     * @return string
+     */
+    public function getUserID(): string
+    {
+        return $this->UserID;
+    }
+
+    /**
+     * @param string $UserID
+     */
+    public function setUserID(string $UserID): void
+    {
+        $this->UserID = $UserID;
+    }
+
+    /**
+     * @return string
+     */
+    public function getID(): string
+    {
+        return $this->ID;
+    }
+
+    /**
+     * @param string $ID
+     */
+    public function setID(string $ID): void
+    {
+        $this->ID = $ID;
+        $this->ID_ = "0" . $ID;
+    }
+
+    /**
+     * @return string
+     */
+    public function getID_(): string
+    {
+        return $this->ID_;
+    }
+
+    /**
+     * @return string
+     */
+    public function getMerchantID(): string
+    {
+        return $this->MerchantID;
+    }
+
+    /**
+     * @param string $MerchantID
+     */
+    public function setMerchantID(string $MerchantID): void
+    {
+        $this->MerchantID = $MerchantID;
+    }
+
+
+}
diff --git a/src/Models/Transaction.php b/src/Models/Transaction.php
new file mode 100644
index 0000000..1159a9d
--- /dev/null
+++ b/src/Models/Transaction.php
@@ -0,0 +1,419 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class Transaction extends BaseModel
+{
+    protected string $Type;
+    protected string $SubType;
+    protected string $FirmCardNo;
+    protected string $InstallmentCnt;
+    protected int $Amount;
+    protected string $CurrencyCode;
+    protected string $OriginalRetrefNum;
+    protected string $DelayDayCount;
+    protected string $DownPaymentRate;
+    protected string $CardholderPresentCode;
+    protected string $MotoInd;
+    protected string $Description;
+    protected CommercialCardExtendedCredit $CommercialCardExtendedCredit;
+    protected Verification $Verification;
+    protected DCC $DCC;
+    protected UtilityPayment $UtilityPayment;
+    protected GSMUnitSales $GSMUnitSales;
+    protected CepBank $CepBank;
+    protected Secure3D $Secure3D;
+    protected array $RewardList;
+    protected array $ChequeList;
+    protected MoneyCard $MoneyCard;
+
+    /**
+     * @return string
+     */
+    public function getType(): string
+    {
+        return $this->Type;
+    }
+
+    /**
+     * @param string $Type
+     */
+    public function setType(string $Type): void
+    {
+        $this->Type = $Type;
+    }
+
+    /**
+     * @return string
+     */
+    public function getSubType(): string
+    {
+        return $this->SubType;
+    }
+
+    /**
+     * @param string $SubType
+     */
+    public function setSubType(string $SubType): void
+    {
+        $this->SubType = $SubType;
+    }
+
+    /**
+     * @return string
+     */
+    public function getFirmCardNo(): string
+    {
+        return $this->FirmCardNo;
+    }
+
+    /**
+     * @param string $FirmCardNo
+     */
+    public function setFirmCardNo(string $FirmCardNo): void
+    {
+        $this->FirmCardNo = $FirmCardNo;
+    }
+
+    /**
+     * @return string
+     */
+    public function getInstallmentCnt(): string
+    {
+        return $this->InstallmentCnt;
+    }
+
+    /**
+     * @param string $InstallmentCnt
+     */
+    public function setInstallmentCnt(string $InstallmentCnt): void
+    {
+        $this->InstallmentCnt = $InstallmentCnt;
+    }
+
+    /**
+     * @return int
+     */
+    public function getAmount(): int
+    {
+        return $this->Amount;
+    }
+
+    /**
+     * @param int $Amount
+     */
+    public function setAmount(int $Amount): void
+    {
+        $this->Amount = $Amount;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCurrencyCode(): string
+    {
+        return $this->CurrencyCode;
+    }
+
+    /**
+     * @param $currency
+     */
+    public function setCurrencyCode($currency): void
+    {
+        $this->CurrencyCode = $currency;
+        if (is_string($currency)) {
+            switch ($currency) {
+                case "USD":
+                    $this->CurrencyCode = 840;
+                    break;
+                case "EUR":
+                    $this->CurrencyCode = 978;
+                    break;
+                case "GBP":
+                    $this->CurrencyCode = 826;
+                    break;
+                case "JPY":
+                    $this->CurrencyCode = 392;
+                    break;
+                case "TRY":
+                case "TRL":
+                default:
+                    $this->CurrencyCode = 949;
+                    break;
+            }
+        }
+
+    }
+
+    /**
+     * @return string
+     */
+    public function getOriginalRetrefNum(): string
+    {
+        return $this->OriginalRetrefNum;
+    }
+
+    /**
+     * @param string $OriginalRetrefNum
+     */
+    public function setOriginalRetrefNum(string $OriginalRetrefNum): void
+    {
+        $this->OriginalRetrefNum = $OriginalRetrefNum;
+    }
+
+    /**
+     * @return string
+     */
+    public function getDelayDayCount(): string
+    {
+        return $this->DelayDayCount;
+    }
+
+    /**
+     * @param string $DelayDayCount
+     */
+    public function setDelayDayCount(string $DelayDayCount): void
+    {
+        $this->DelayDayCount = $DelayDayCount;
+    }
+
+    /**
+     * @return string
+     */
+    public function getDownPaymentRate(): string
+    {
+        return $this->DownPaymentRate;
+    }
+
+    /**
+     * @param string $DownPaymentRate
+     */
+    public function setDownPaymentRate(string $DownPaymentRate): void
+    {
+        $this->DownPaymentRate = $DownPaymentRate;
+    }
+
+    /**
+     * @return string
+     */
+    public function getCardholderPresentCode(): string
+    {
+        return $this->CardholderPresentCode;
+    }
+
+    /**
+     * @param string $CardholderPresentCode
+     */
+    public function setCardholderPresentCode(string $CardholderPresentCode): void
+    {
+        $this->CardholderPresentCode = $CardholderPresentCode;
+    }
+
+    /**
+     * @return string
+     */
+    public function getMotoInd(): string
+    {
+        return $this->MotoInd;
+    }
+
+    /**
+     * @param string $MotoInd
+     */
+    public function setMotoInd(string $MotoInd): void
+    {
+        $this->MotoInd = $MotoInd;
+    }
+
+    /**
+     * @return string
+     */
+    public function getDescription(): string
+    {
+        return $this->Description;
+    }
+
+    /**
+     * @param string $Description
+     */
+    public function setDescription(string $Description): void
+    {
+        $this->Description = $Description;
+    }
+
+    /**
+     * @return CommercialCardExtendedCredit
+     */
+    public function getCommercialCardExtendedCredit(): CommercialCardExtendedCredit
+    {
+        return $this->CommercialCardExtendedCredit;
+    }
+
+    /**
+     * @param CommercialCardExtendedCredit $CommercialCardExtendedCredit
+     */
+    public function setCommercialCardExtendedCredit(CommercialCardExtendedCredit $CommercialCardExtendedCredit): void
+    {
+        $this->CommercialCardExtendedCredit = $CommercialCardExtendedCredit;
+    }
+
+    /**
+     * @return Verification
+     */
+    public function getVerification(): Verification
+    {
+        return $this->Verification;
+    }
+
+    /**
+     * @param Verification $Verification
+     */
+    public function setVerification(Verification $Verification): void
+    {
+        $this->Verification = $Verification;
+    }
+
+    /**
+     * @return DCC
+     */
+    public function getDCC(): DCC
+    {
+        return $this->DCC;
+    }
+
+    /**
+     * @param DCC $DCC
+     */
+    public function setDCC(DCC $DCC): void
+    {
+        $this->DCC = $DCC;
+    }
+
+    /**
+     * @return UtilityPayment
+     */
+    public function getUtilityPayment(): UtilityPayment
+    {
+        return $this->UtilityPayment;
+    }
+
+    /**
+     * @param UtilityPayment $UtilityPayment
+     */
+    public function setUtilityPayment(UtilityPayment $UtilityPayment): void
+    {
+        $this->UtilityPayment = $UtilityPayment;
+    }
+
+    /**
+     * @return GSMUnitSales
+     */
+    public function getGSMUnitSales(): GSMUnitSales
+    {
+        return $this->GSMUnitSales;
+    }
+
+    /**
+     * @param GSMUnitSales $GSMUnitSales
+     */
+    public function setGSMUnitSales(GSMUnitSales $GSMUnitSales): void
+    {
+        $this->GSMUnitSales = $GSMUnitSales;
+    }
+
+    /**
+     * @return CepBank
+     */
+    public function getCepBank(): CepBank
+    {
+        return $this->CepBank;
+    }
+
+    /**
+     * @param CepBank $CepBank
+     */
+    public function setCepBank(CepBank $CepBank): void
+    {
+        $this->CepBank = $CepBank;
+    }
+
+    /**
+     * @return Secure3D
+     */
+    public function getSecure3D(): Secure3D
+    {
+        return $this->Secure3D;
+    }
+
+    /**
+     * @param Secure3D $Secure3D
+     */
+    public function setSecure3D(Secure3D $Secure3D): void
+    {
+        $this->Secure3D = $Secure3D;
+    }
+
+    /**
+     * @return array
+     */
+    public function getRewardList(): array
+    {
+        return $this->RewardList;
+    }
+
+    /**
+     * @param array $RewardList
+     */
+    public function setRewardList(array $RewardList): void
+    {
+        $this->RewardList = $RewardList;
+    }
+
+    /**
+     * @return array
+     */
+    public function getChequeList(): array
+    {
+        return $this->ChequeList;
+    }
+
+    /**
+     * @param array $ChequeList
+     */
+    public function setChequeList(array $ChequeList): void
+    {
+        $this->ChequeList = $ChequeList;
+    }
+
+    /**
+     * @return MoneyCard
+     */
+    public function getMoneyCard(): MoneyCard
+    {
+        return $this->MoneyCard;
+    }
+
+    /**
+     * @param MoneyCard $MoneyCard
+     */
+    public function setMoneyCard(MoneyCard $MoneyCard): void
+    {
+        $this->MoneyCard = $MoneyCard;
+    }
+
+    /**
+     * @param Reward $Reward
+     */
+    public function addReward(Reward $Reward): void
+    {
+        $this->RewardList[] = $Reward;
+    }
+
+    /**
+     * @param Cheque $Cheque
+     */
+    public function addCheque(Cheque $Cheque): void
+    {
+        $this->ChequeList[] = $Cheque;
+    }
+}
diff --git a/src/Models/UtilityPayment.php b/src/Models/UtilityPayment.php
new file mode 100644
index 0000000..aa3126b
--- /dev/null
+++ b/src/Models/UtilityPayment.php
@@ -0,0 +1,61 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class UtilityPayment extends BaseModel
+{
+    protected string $type;
+    protected string $subscriber_code;
+    protected string $invoice_id;
+
+    /**
+     * @return string
+     */
+    public function getType(): string
+    {
+        return $this->type;
+    }
+
+    /**
+     * @param string $type
+     */
+    public function setType(string $type): void
+    {
+        $this->type = $type;
+    }
+
+    /**
+     * @return string
+     */
+    public function getSubscriberCode(): string
+    {
+        return $this->subscriber_code;
+    }
+
+    /**
+     * @param string $subscriber_code
+     */
+    public function setSubscriberCode(string $subscriber_code): void
+    {
+        $this->subscriber_code = $subscriber_code;
+    }
+
+    /**
+     * @return string
+     */
+    public function getInvoiceId(): string
+    {
+        return $this->invoice_id;
+    }
+
+    /**
+     * @param string $invoice_id
+     */
+    public function setInvoiceId(string $invoice_id): void
+    {
+        $this->invoice_id = $invoice_id;
+    }
+
+
+
+}
diff --git a/src/Models/Verification.php b/src/Models/Verification.php
new file mode 100644
index 0000000..2fe8d54
--- /dev/null
+++ b/src/Models/Verification.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Sportakal\Garantipos\Models;
+
+class Verification extends BaseModel
+{
+    protected string $identity;
+    protected string $extre_info;
+    protected string $SMS_password;
+
+    /**
+     * @return string
+     */
+    public function getIdentity(): string
+    {
+        return $this->identity;
+    }
+
+    /**
+     * @param string $identity
+     */
+    public function setIdentity(string $identity): void
+    {
+        $this->identity = $identity;
+    }
+
+    /**
+     * @return string
+     */
+    public function getExtreInfo(): string
+    {
+        return $this->extre_info;
+    }
+
+    /**
+     * @param string $extre_info
+     */
+    public function setExtreInfo(string $extre_info): void
+    {
+        $this->extre_info = $extre_info;
+    }
+
+    /**
+     * @return string
+     */
+    public function getSMSPassword(): string
+    {
+        return $this->SMS_password;
+    }
+
+    /**
+     * @param string $SMS_password
+     */
+    public function setSMSPassword(string $SMS_password): void
+    {
+        $this->SMS_password = $SMS_password;
+    }
+
+
+}
diff --git a/src/Requests/CompleteThreeDSecure.php b/src/Requests/CompleteThreeDSecure.php
new file mode 100644
index 0000000..b88399d
--- /dev/null
+++ b/src/Requests/CompleteThreeDSecure.php
@@ -0,0 +1,97 @@
+<?php
+
+namespace Sportakal\Garantipos\Requests;
+
+use Sportakal\Garantipos\Models\Card;
+use Sportakal\Garantipos\Models\Customer;
+use Sportakal\Garantipos\Models\RequestModel;
+use Sportakal\Garantipos\Models\Options;
+use Sportakal\Garantipos\Models\Order;
+use Sportakal\Garantipos\Models\Secure3D;
+use Sportakal\Garantipos\Models\Transaction;
+use Sportakal\Garantipos\Requests\Constructors\XmlRequest;
+use Sportakal\Garantipos\Results\Interfaces\PaymentResultInterface;
+use Sportakal\Garantipos\Results\PayResult;
+use Sportakal\Garantipos\Results\RefundResult;
+use Sportakal\Garantipos\Results\CompleteThreeDSecureResult;
+use Sportakal\Garantipos\Results\ThreeDSecureModelResult;
+use Sportakal\Garantipos\Utils\CreateHashData;
+
+class CompleteThreeDSecure extends XmlRequest
+{
+    public function __construct($TerminalProvUserPassword)
+    {
+        $options = new Options();
+        $options->setMode($_POST['mode']); //TEST
+        $options->setApiVersion($_POST['apiversion']);
+        $options->setTerminalId($_POST['clientid']);
+        $options->setTerminalProvUserId($_POST['terminalprovuserid']);
+        $options->setTerminalProvUserPassword($TerminalProvUserPassword);
+        $options->setTerminalUserId($_POST['terminaluserid']);
+        $options->setTerminalMerchantId($_POST['terminalmerchantid']);
+
+        $card = new Card();
+        $card->setNumber('');
+        $card->setExpireDate('');
+        $card->setCVV2('');
+
+        $customer = new Customer();
+        $customer->setIpAddress($_POST['customeripaddress']);
+        $customer->setEmailAddress($_POST['customeremailaddress']);
+
+
+        $order = new Order();
+        $order->setOrderID($_POST['orderid']);
+//        $order->addAddress(new Address());
+
+        $transaction = new Transaction();
+        $transaction->setType($_POST['txntype']);
+        $transaction->setInstallmentCnt($_POST['txninstallmentcount']);
+        $transaction->setAmount($_POST['txnamount']);
+        $transaction->setCurrencyCode($_POST['txncurrencycode']);
+        $transaction->setCardholderPresentCode('13');
+        $Secure3D = new Secure3D();
+        $Secure3D->setAuthenticationCode($_POST['cavv']);
+        $Secure3D->setSecurityLevel($_POST['eci']);
+        $Secure3D->setTxnID($_POST['xid']);
+        $Secure3D->setMd($_POST['md']);
+        $transaction->setSecure3D($Secure3D);
+        $transaction->setMotoInd('N');
+
+        $request = new RequestModel();
+        $request->setOptions($options);
+        $request->setCard($card);
+        $request->setCustomer($customer);
+        $request->setOrder($order);
+        $request->setTransaction($transaction);
+
+        parent::__construct($request);
+    }
+
+    public function setHashData(): void
+    {
+        $this->setSecurityData();
+        $string = '';
+        $string .= $this->GVPSRequest->getOrder()->getOrderID();
+        $string .= $this->GVPSRequest->getTerminal()->getID();
+        $string .= $this->GVPSRequest->getCard()->getNumber();
+        $string .= $this->GVPSRequest->getTransaction()->getAmount();
+        $string .= $this->security_data;
+        $this->hash_data = CreateHashData::get($string);
+
+        $this->GVPSRequest->getTerminal()->setHashData($this->hash_data);
+    }
+
+    /**
+     * @throws \DOMException
+     * @throws \JsonException
+     */
+    public function getResult(): CompleteThreeDSecureResult
+    {
+        if (empty($this->response)) {
+            $this->exec();
+        }
+        return (new CompleteThreeDSecureResult($this->response->getArray()));
+    }
+
+}
diff --git a/src/Requests/Constructors/PostRequest.php b/src/Requests/Constructors/PostRequest.php
new file mode 100644
index 0000000..f312d49
--- /dev/null
+++ b/src/Requests/Constructors/PostRequest.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Sportakal\Garantipos\Requests\Constructors;
+
+use Sportakal\Garantipos\Models\RequestModel;
+use Sportakal\Garantipos\Utils\CreateHashData;
+use Sportakal\Garantipos\Utils\Curl;
+use Sportakal\Garantipos\Utils\GetHost;
+
+abstract class PostRequest extends RequestBase
+{
+
+    public function __construct(RequestModel $GVPSRequest)
+    {
+        parent::__construct($GVPSRequest);
+    }
+
+    protected function exec(): void
+    {
+        $headers = ["Content-Type: application/x-www-form-urlencoded",];
+        $data = [
+            'secure3dsecuritylevel' => $this->secure3dsecuritylevel,
+            'mode' => $this->GVPSRequest->getMode(),
+            'apiversion' => $this->GVPSRequest->getVersion(),
+            'terminalprovuserid' => $this->GVPSRequest->getTerminal()->getProvUserID(),
+            'terminaluserid' => $this->GVPSRequest->getTerminal()->getUserID(),
+            'terminalmerchantid' => $this->GVPSRequest->getTerminal()->getMerchantID(),
+            'txntype' => $this->GVPSRequest->getTransaction()->getType(),
+            'txnamount' => $this->GVPSRequest->getTransaction()->getAmount(),
+            'txncurrencycode' => $this->GVPSRequest->getTransaction()->getCurrencyCode(),
+            'txninstallmentcount' => $this->GVPSRequest->getTransaction()->getInstallmentCnt(),
+            'orderid' => $this->GVPSRequest->getOrder()->getOrderID(),
+            'terminalid' => $this->GVPSRequest->getTerminal()->getID(),
+            'successurl' => $this->GVPSRequest->getSuccessUrl(),
+            'errorurl' => $this->GVPSRequest->getErrorUrl(),
+            'customeripaddress' => $this->GVPSRequest->getCustomer()->getIPAddress(),
+            'customeremailaddress' => $this->GVPSRequest->getCustomer()->getEmailAddress(),
+            'secure3dhash' => $this->hash_data,
+            'cardnumber' => $this->GVPSRequest->getCard()->getNumber(),
+            'cardexpiredatemonth' => substr($this->GVPSRequest->getCard()->getExpireDate(), 0, 2),
+            'cardexpiredateyear' => substr($this->GVPSRequest->getCard()->getExpireDate(), -2, 2),
+            'cardcvv2' => $this->GVPSRequest->getCard()->getCVV2(),
+        ];
+
+        $data = http_build_query($data);
+        $curl = new Curl(GetHost::get($this->GVPSRequest->getMode(), false), $data, $headers);
+        $this->response = $curl->getResponse();
+    }
+}
diff --git a/src/Requests/Constructors/RequestBase.php b/src/Requests/Constructors/RequestBase.php
new file mode 100644
index 0000000..02726b7
--- /dev/null
+++ b/src/Requests/Constructors/RequestBase.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Sportakal\Garantipos\Requests\Constructors;
+
+use Sportakal\Garantipos\Models\RequestModel;
+use Sportakal\Garantipos\Models\ResultModels\ResultModelInterface;
+use Sportakal\Garantipos\Requests\Interfaces\RequestInterface;
+use Sportakal\Garantipos\Utils\CreateHashData;
+use Sportakal\Garantipos\Utils\CreateSecurityData;
+use Sportakal\Garantipos\Utils\Response;
+
+abstract class RequestBase implements RequestInterface
+{
+    protected string $hash_data;
+    protected string $security_data;
+    protected RequestModel $GVPSRequest;
+    protected Response $response;
+
+    public function __construct(RequestModel $GVPSRequest)
+    {
+        $this->GVPSRequest = $GVPSRequest;
+        $this->setHashData();
+    }
+
+    protected function setSecurityData(): void
+    {
+        $this->security_data = CreateSecurityData::get($this->GVPSRequest->getTerminal());
+    }
+
+    public function getHashData(): string
+    {
+        if (empty($this->hash_data)) {
+            $this->setHashData();
+        }
+        return $this->hash_data;
+    }
+
+}
diff --git a/src/Requests/Constructors/XmlRequest.php b/src/Requests/Constructors/XmlRequest.php
new file mode 100644
index 0000000..14fa688
--- /dev/null
+++ b/src/Requests/Constructors/XmlRequest.php
@@ -0,0 +1,23 @@
+<?php
+
+namespace Sportakal\Garantipos\Requests\Constructors;
+
+use Sportakal\Garantipos\Results\PayResult;
+use Sportakal\Garantipos\Utils\Curl;
+use Sportakal\Garantipos\Utils\GetHost;
+use Sportakal\Garantipos\Utils\Response;
+use Sportakal\Garantipos\Utils\XmlCreator;
+
+abstract class XmlRequest extends RequestBase
+{
+    /**
+     * @throws \DOMException
+     */
+    protected function exec():void
+    {
+        $array = [$this->GVPSRequest->toArray()];
+        $xml = (new XmlCreator($array, false))->getXml();
+        $body = "data=" . $xml;
+        $this->response = (new Curl(GetHost::get($this->GVPSRequest->getMode(), true), $body))->getResponse();
+    }
+}
diff --git a/src/Requests/InitializeThreeDSecure.php b/src/Requests/InitializeThreeDSecure.php
new file mode 100644
index 0000000..73f8b43
--- /dev/null
+++ b/src/Requests/InitializeThreeDSecure.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Sportakal\Garantipos\Requests;
+
+use Sportakal\Garantipos\Models\RequestModel;
+use Sportakal\Garantipos\Requests\Constructors\PostRequest;
+use Sportakal\Garantipos\Results\Interfaces\PaymentResultInterface;
+use Sportakal\Garantipos\Results\InitializeThreeDSecureResult;
+use Sportakal\Garantipos\Utils\CreateHashData;
+use Sportakal\Garantipos\Utils\Curl;
+use Sportakal\Garantipos\Utils\GetHost;
+
+class InitializeThreeDSecure extends PostRequest
+{
+    protected string $secure3dsecuritylevel = '3D';
+
+    public function setHashData(): void
+    {
+        $this->setSecurityData();
+        $string = '';
+        $string .= $this->GVPSRequest->getTerminal()->getID();
+        $string .= $this->GVPSRequest->getOrder()->getOrderID();
+        $string .= $this->GVPSRequest->getTransaction()->getAmount();
+        $string .= $this->GVPSRequest->getSuccessURL();
+        $string .= $this->GVPSRequest->getErrorURL();
+        $string .= $this->GVPSRequest->getTransaction()->getType();
+        $string .= $this->GVPSRequest->getTransaction()->getInstallmentCnt();
+        $string .= $this->GVPSRequest->getOptions()->getStoreKey();
+        $string .= $this->security_data;
+        $this->hash_data = CreateHashData::get($string);
+
+        $this->GVPSRequest->getTerminal()->setHashData($this->hash_data);
+    }
+
+    public function getResult(): InitializeThreeDSecureResult
+    {
+        if (empty($this->response)) {
+            $this->exec();
+        }
+
+        return (new InitializeThreeDSecureResult($this->response));
+    }
+}
diff --git a/src/Requests/Interfaces/RequestInterface.php b/src/Requests/Interfaces/RequestInterface.php
new file mode 100644
index 0000000..f678f71
--- /dev/null
+++ b/src/Requests/Interfaces/RequestInterface.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace Sportakal\Garantipos\Requests\Interfaces;
+
+use Sportakal\Garantipos\Models\ResultModels\ResultModelInterface;
+use Sportakal\Garantipos\Results\Interfaces\PaymentResultInterface;
+
+interface RequestInterface
+{
+    public function setHashData(): void;
+
+    public function getHashData(): string;
+
+    public function getResult(): PaymentResultInterface;
+
+}
diff --git a/src/Requests/Pay.php b/src/Requests/Pay.php
new file mode 100644
index 0000000..dca9427
--- /dev/null
+++ b/src/Requests/Pay.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Sportakal\Garantipos\Requests;
+
+use Sportakal\Garantipos\Models\RequestModel;
+use Sportakal\Garantipos\Models\ResultModels\ResultModelInterface;
+use Sportakal\Garantipos\Requests\Constructors\XmlRequest;
+use Sportakal\Garantipos\Results\Interfaces\PaymentResultInterface;
+use Sportakal\Garantipos\Results\PayResult;
+use Sportakal\Garantipos\Utils\CreateHashData;
+
+class Pay extends XmlRequest
+{
+    public function __construct(RequestModel $GVPSRequest)
+    {
+        parent::__construct($GVPSRequest);
+        $this->GVPSRequest->getTransaction()->setType('sales');
+    }
+
+    public function setHashData(): void
+    {
+        $this->setSecurityData();
+        $string = '';
+        $string .= $this->GVPSRequest->getOrder()->getOrderID();
+        $string .= $this->GVPSRequest->getTerminal()->getID();
+        $string .= $this->GVPSRequest->getCard()->getNumber();
+        $string .= $this->GVPSRequest->getTransaction()->getAmount();
+        $string .= $this->security_data;
+        $this->hash_data = CreateHashData::get($string);
+
+        $this->GVPSRequest->getTerminal()->setHashData($this->hash_data);
+    }
+
+    /**
+     * @throws \DOMException
+     * @throws \JsonException
+     */
+    public function getResult(): PayResult
+    {
+        if (empty($this->response)) {
+            $this->exec();
+        }
+        return (new PayResult($this->response->getArray()));
+    }
+}
diff --git a/src/Requests/Refund.php b/src/Requests/Refund.php
new file mode 100644
index 0000000..682c851
--- /dev/null
+++ b/src/Requests/Refund.php
@@ -0,0 +1,45 @@
+<?php
+
+namespace Sportakal\Garantipos\Requests;
+
+use Sportakal\Garantipos\Models\RequestModel;
+use Sportakal\Garantipos\Requests\Constructors\XmlRequest;
+use Sportakal\Garantipos\Results\Interfaces\PaymentResultInterface;
+use Sportakal\Garantipos\Results\PayResult;
+use Sportakal\Garantipos\Results\RefundResult;
+use Sportakal\Garantipos\Utils\CreateHashData;
+
+class Refund extends XmlRequest
+{
+    public function __construct(RequestModel $GVPSRequest)
+    {
+        parent::__construct($GVPSRequest);
+        $this->GVPSRequest->getTransaction()->setType('refund');
+    }
+
+    public function setHashData(): void
+    {
+        $this->setSecurityData();
+        $string = '';
+        $string .= $this->GVPSRequest->getOrder()->getOrderID();
+        $string .= $this->GVPSRequest->getTerminal()->getID();
+        $string .= $this->GVPSRequest->getTransaction()->getAmount();
+        $string .= $this->security_data;
+        $this->hash_data = CreateHashData::get($string);
+
+        $this->GVPSRequest->getTerminal()->setHashData($this->hash_data);
+    }
+
+    /**
+     * @throws \DOMException
+     * @throws \JsonException
+     */
+    public function getResult(): RefundResult
+    {
+        if (empty($this->response)) {
+            $this->exec();
+        }
+        return (new RefundResult($this->response->getArray()));
+    }
+
+}
diff --git a/src/Requests/ThreeDSecurePay.php b/src/Requests/ThreeDSecurePay.php
new file mode 100644
index 0000000..31e4b17
--- /dev/null
+++ b/src/Requests/ThreeDSecurePay.php
@@ -0,0 +1,48 @@
+<?php
+
+namespace Sportakal\Garantipos\Requests;
+
+use Sportakal\Garantipos\Models\RequestModel;
+use Sportakal\Garantipos\Requests\Constructors\PostRequest;
+use Sportakal\Garantipos\Results\Interfaces\PaymentResultInterface;
+use Sportakal\Garantipos\Results\ThreeDSecurePayResult;
+use Sportakal\Garantipos\Results\InitializeThreeDSecureResult;
+use Sportakal\Garantipos\Utils\CreateHashData;
+
+class ThreeDSecurePay extends PostRequest
+{
+    protected string $secure3dsecuritylevel;
+
+    public function setHashData(): void
+    {
+        $this->setSecurityData();
+        $string = '';
+        $string .= $this->GVPSRequest->getTerminal()->getID();
+        $string .= $this->GVPSRequest->getOrder()->getOrderID();
+        $string .= $this->GVPSRequest->getTransaction()->getAmount();
+        $string .= $this->GVPSRequest->getSuccessURL();
+        $string .= $this->GVPSRequest->getErrorURL();
+        $string .= $this->GVPSRequest->getTransaction()->getType();
+        $string .= $this->GVPSRequest->getTransaction()->getInstallmentCnt();
+        $string .= $this->GVPSRequest->getOptions()->getStoreKey();
+        $string .= $this->security_data;
+        $this->hash_data = CreateHashData::get($string);
+
+        $this->GVPSRequest->getTerminal()->setHashData($this->hash_data);
+    }
+
+    public function __construct(RequestModel $GVPSRequest, string $secure3dsecuritylevel = '3D_PAY')
+    {
+        parent::__construct($GVPSRequest);
+        $this->secure3dsecuritylevel = $secure3dsecuritylevel;
+    }
+
+    public function getResult(): InitializeThreeDSecureResult
+    {
+        if (empty($this->response)) {
+            $this->exec();
+        }
+
+        return (new InitializeThreeDSecureResult($this->response));
+    }
+}
diff --git a/src/Results/CompleteThreeDSecureResult.php b/src/Results/CompleteThreeDSecureResult.php
new file mode 100644
index 0000000..2765d6b
--- /dev/null
+++ b/src/Results/CompleteThreeDSecureResult.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Sportakal\Garantipos\Results;
+
+use Sportakal\Garantipos\Results\Constructors\XmlResult;
+
+class CompleteThreeDSecureResult extends XmlResult
+{
+    public function setHashData(): void
+    {
+        $this->hash_data = "";
+    }
+}
diff --git a/src/Results/Constructors/PostResult.php b/src/Results/Constructors/PostResult.php
new file mode 100644
index 0000000..10bd801
--- /dev/null
+++ b/src/Results/Constructors/PostResult.php
@@ -0,0 +1,195 @@
+<?php
+
+namespace Sportakal\Garantipos\Results\Constructors;
+
+use Sportakal\Garantipos\Exceptions\HashCheckFailedException;
+use Sportakal\Garantipos\Models\Options;
+use Sportakal\Garantipos\Models\Order;
+use Sportakal\Garantipos\Models\ResultModels\PostResultModel;
+use Sportakal\Garantipos\Models\Transaction;
+use Sportakal\Garantipos\Results\Interfaces\PaymentResultInterface;
+use Sportakal\Garantipos\Utils\Arrayable;
+
+abstract class PostResult extends Arrayable implements PaymentResultInterface
+{
+    protected PostResultModel $postResultModel;
+    protected Options $options;
+    protected string $hash_data;
+    protected bool $md_status;
+    protected int $md_status_code;
+    protected string $md_error_message;
+    protected string $response_message;
+    protected string $error_message;
+    protected string $host_message;
+    protected string $reference_number;
+
+
+    /**
+     * @param array $postFields
+     * @throws HashCheckFailedException
+     */
+    public function __construct(Options $options, array $postFields = [])
+    {
+        $this->postResultModel = new PostResultModel($postFields);
+        $this->options = $options;
+
+        $this->setMdStatus(in_array((int)$this->postResultModel->mdstatus, [1, 2, 3, 4], true));
+        $this->setMdStatusCode((int)$this->postResultModel->mdstatus);
+        $this->setMdErrorMessage($this->postResultModel->mderrormessage);
+        $this->setResponseMessage($this->postResultModel->response);
+        $this->setErrorMessage($this->postResultModel->errmsg);
+        $this->setHostMessage($this->postResultModel->hostmsg);
+        $this->setReferenceNumber($this->postResultModel->hostrefnum);
+
+        if ($this->getHashData() !== $this->postResultModel->hash) {
+            throw new HashCheckFailedException();
+        }
+    }
+
+    /**
+     * @return string
+     */
+    public function getReferenceNumber(): string
+    {
+        return $this->reference_number;
+    }
+
+    /**
+     * @param string $reference_number
+     */
+    protected function setReferenceNumber(string $reference_number): void
+    {
+        $this->reference_number = $reference_number;
+    }
+
+
+    /**
+     * @return string
+     */
+    public function getHashData(): string
+    {
+        if (empty($this->hash_data)) {
+            $this->setHashData();
+        }
+        return $this->hash_data; //1B493654D0089F8D202E8EC3B54EB590EDE84C42
+    }
+
+    /**
+     * @param bool $md_status
+     * @return void
+     */
+    protected function setMdStatus(bool $md_status): void
+    {
+        $this->md_status = $md_status;
+    }
+
+    /**
+     * @param $md_status_code
+     * @return void
+     */
+    protected function setMdStatusCode($md_status_code): void
+    {
+        $this->md_status_code = $md_status_code;
+    }
+
+    /**
+     * @param $md_error_message
+     * @return void
+     */
+    protected function setMdErrorMessage($md_error_message): void
+    {
+        if ($this->md_status_code === 1) {
+            $this->md_error_message = "Tam Doğrulama";
+        } else if ($this->md_status_code === 2) {
+            $this->md_error_message = "Kart Sahibi veya bankası sisteme kayıtlı değil";
+        } else if ($this->md_status_code === 3) {
+            $this->md_error_message = "Kartın bankası sisteme kayıtlı değil";
+        } elseif ($this->md_status_code === 4) {
+            $this->md_error_message = "Doğrulama denemesi, kart sahibi sisteme daha sonra kayıt olmayı seçmiş";
+        } else if ($this->md_status_code === 5) {
+            $this->md_error_message = "Doğrulama yapılamıyor";
+        } else if ($this->md_status_code === 7) {
+            $this->md_error_message = "Sistem Hatası";
+        } else if ($this->md_status_code === 8) {
+            $this->md_error_message = "Bilinmeyen Kart No";
+        } else if ($this->md_status_code === 0) {
+            $this->md_error_message = "Doğrulama Başarısız, 3-D Secure imzası geçersiz.";
+        } else if ($md_error_message !== '') {
+            $this->md_error_message = $md_error_message;
+        }
+    }
+
+    /**
+     * @param string $response_message
+     */
+    protected function setResponseMessage(string $response_message): void
+    {
+        $this->response_message = $response_message;
+    }
+
+    /**
+     * @param string $error_message
+     */
+    protected function setErrorMessage(string $error_message): void
+    {
+        $this->error_message = $error_message;
+    }
+
+    /**
+     * @param string $host_message
+     */
+    protected function setHostMessage(string $host_message): void
+    {
+        $this->host_message = $host_message;
+    }
+
+
+    /**
+     * @return bool
+     */
+    public function getMdStatus(): bool
+    {
+        return $this->md_status;
+    }
+
+    /**
+     * @return int
+     */
+    public function getMdStatusCode(): int
+    {
+        return $this->md_status_code;
+    }
+
+    /**
+     * @return string
+     */
+    public function getMdErrorMessage(): string
+    {
+        return $this->md_error_message;
+    }
+
+    /**
+     * @return string
+     */
+    public function getResponseMessage(): string
+    {
+        return $this->response_message;
+    }
+
+    /**
+     * @return string
+     */
+    public function getErrorMessage(): string
+    {
+        return $this->error_message;
+    }
+
+    /**
+     * @return string
+     */
+    public function getHostMessage(): string
+    {
+        return $this->host_message;
+    }
+
+}
diff --git a/src/Results/Constructors/XmlResult.php b/src/Results/Constructors/XmlResult.php
new file mode 100644
index 0000000..f7ef50a
--- /dev/null
+++ b/src/Results/Constructors/XmlResult.php
@@ -0,0 +1,165 @@
+<?php
+
+namespace Sportakal\Garantipos\Results\Constructors;
+
+use Sportakal\Garantipos\Models\ResultModels\XmlResultModel;
+use Sportakal\Garantipos\Results\Interfaces\PaymentResultInterface;
+
+abstract class XmlResult implements PaymentResultInterface
+{
+    protected XmlResultModel $xmlResultModel;
+    protected string $hash_data;
+    protected bool $status;
+    protected string $status_code;
+    protected string $status_message;
+    protected string $reason_code;
+    protected string $error_message;
+    protected string $host_message;
+    protected string $reference_number;
+
+    /**
+     * @param array $postFields
+     */
+    public function __construct(array $postFields)
+    {
+        $this->xmlResultModel = new XmlResultModel($postFields);
+
+        $this->setStatus($this->xmlResultModel->code === "00");
+        $this->setStatusCode($this->xmlResultModel->code);
+        $this->setStatusMessage($this->xmlResultModel->message);
+        $this->setReasonCode($this->xmlResultModel->reason_code);
+        $this->setErrorMessage($this->xmlResultModel->error_message . " " . $this->xmlResultModel->system_error_message);
+        $this->setHostMessage($this->xmlResultModel->host_message[0] ?? '');
+        $this->setReferenceNumber($this->xmlResultModel->ret_ref_num);
+    }
+
+
+    /**
+     * @return string
+     */
+    public function getHashData(): string
+    {
+        if (empty($this->hash_data)) {
+            $this->setHashData();
+        }
+        return $this->hash_data; //1B493654D0089F8D202E8EC3B54EB590EDE84C42
+    }
+
+    /**
+     * @return string
+     */
+    public function getReferenceNumber(): string
+    {
+        return $this->reference_number;
+    }
+
+    /**
+     * @param string $reference_number
+     */
+    protected function setReferenceNumber(string $reference_number): void
+    {
+        $this->reference_number = $reference_number;
+    }
+
+
+    /**
+     * @return bool
+     */
+    public function getStatus(): bool
+    {
+        return $this->status;
+    }
+
+    /**
+     * @param bool $status
+     */
+    protected function setStatus(bool $status): void
+    {
+        $this->status = $status;
+    }
+
+    /**
+     * @return string
+     */
+    public function getStatusCode(): string
+    {
+        return $this->status_code;
+    }
+
+    /**
+     * @return string
+     */
+    public function getStatusMessage(): string
+    {
+        return $this->status_message;
+    }
+
+
+    /**
+     * @param string $status_code
+     */
+    protected function setStatusCode(string $status_code): void
+    {
+        $this->status_code = $status_code;
+    }
+
+
+    /**
+     * @param string $status_message
+     */
+    protected function setStatusMessage(string $status_message): void
+    {
+        $this->status_message = $status_message;
+    }
+
+
+    /**
+     * @return string
+     */
+    public function getReasonCode(): string
+    {
+        return $this->reason_code;
+    }
+
+    /**
+     * @param string $reason_code
+     */
+    public function setReasonCode(string $reason_code): void
+    {
+        $this->reason_code = $reason_code;
+    }
+
+    /**
+     * @return string
+     */
+    public function getErrorMessage(): string
+    {
+        return $this->error_message;
+    }
+
+    /**
+     * @param string $error_message
+     */
+    protected function setErrorMessage(string $error_message): void
+    {
+        $this->error_message = $error_message;
+    }
+
+    /**
+     * @return string
+     */
+    public function getHostMessage(): string
+    {
+        return $this->host_message;
+    }
+
+    /**
+     * @param string $host_message
+     */
+    protected function setHostMessage(string $host_message): void
+    {
+        $this->host_message = $host_message;
+    }
+
+
+}
diff --git a/src/Results/InitializeThreeDSecureResult.php b/src/Results/InitializeThreeDSecureResult.php
new file mode 100644
index 0000000..4c832c5
--- /dev/null
+++ b/src/Results/InitializeThreeDSecureResult.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Sportakal\Garantipos\Results;
+
+use Sportakal\Garantipos\Results\Interfaces\PaymentResultInterface;
+use Sportakal\Garantipos\Utils\Response;
+
+class InitializeThreeDSecureResult implements PaymentResultInterface
+{
+    protected Response $response;
+
+    public function __construct(Response $response)
+    {
+        $this->response = $response;
+    }
+
+    public function setHashData(): void
+    {
+
+    }
+
+    public function getResponse(): Response
+    {
+        return $this->response;
+    }
+
+    public function getHtml(): string
+    {
+        return $this->response->getRawBody();
+    }
+}
diff --git a/src/Results/Interfaces/PaymentResultInterface.php b/src/Results/Interfaces/PaymentResultInterface.php
new file mode 100644
index 0000000..922e944
--- /dev/null
+++ b/src/Results/Interfaces/PaymentResultInterface.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace Sportakal\Garantipos\Results\Interfaces;
+
+interface PaymentResultInterface
+{
+    public function setHashData(): void;
+}
diff --git a/src/Results/PayResult.php b/src/Results/PayResult.php
new file mode 100644
index 0000000..e828f00
--- /dev/null
+++ b/src/Results/PayResult.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Sportakal\Garantipos\Results;
+
+use Sportakal\Garantipos\Results\Constructors\XmlResult;
+
+class PayResult extends XmlResult
+{
+    public function setHashData(): void
+    {
+        $this->hash_data = "";
+    }
+}
diff --git a/src/Results/RefundResult.php b/src/Results/RefundResult.php
new file mode 100644
index 0000000..10684ef
--- /dev/null
+++ b/src/Results/RefundResult.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Sportakal\Garantipos\Results;
+
+use Sportakal\Garantipos\Results\Constructors\XmlResult;
+
+class RefundResult extends XmlResult
+{
+    public function setHashData(): void
+    {
+        $this->hash_data = "";
+    }
+}
diff --git a/src/Results/ThreeDSecureModelResult.php b/src/Results/ThreeDSecureModelResult.php
new file mode 100644
index 0000000..0ce0b44
--- /dev/null
+++ b/src/Results/ThreeDSecureModelResult.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Sportakal\Garantipos\Results;
+
+use Sportakal\Garantipos\Models\RequestModel;
+use Sportakal\Garantipos\Models\Order;
+use Sportakal\Garantipos\Models\Transaction;
+use Sportakal\Garantipos\Requests\ThreeDSecurePay;
+use Sportakal\Garantipos\Results\Constructors\PostResult;
+
+class ThreeDSecureModelResult extends PostResult
+{
+    public function setHashData(): void
+    {
+        $order = new Order();
+        $order->setOrderID($this->postResultModel->orderid);
+
+        $transaction = new Transaction();
+        $transaction->setType($this->postResultModel->txntype);
+        $transaction->setInstallmentCnt($this->postResultModel->txninstallmentcount);
+        $transaction->setAmount($this->postResultModel->txnamount);
+
+        $request = new RequestModel();
+        $request->setOptions($this->options);
+        $request->setOrder($order);
+        $request->setTransaction($transaction);
+        $request->setSuccessURL($this->postResultModel->successurl);
+        $request->setErrorURL($this->postResultModel->errorurl);
+
+        $pay = new ThreeDSecurePay($request);
+        $this->hash_data = $pay->getHashData();;
+    }
+}
diff --git a/src/Results/ThreeDSecurePayResult.php b/src/Results/ThreeDSecurePayResult.php
new file mode 100644
index 0000000..3a6ca72
--- /dev/null
+++ b/src/Results/ThreeDSecurePayResult.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Sportakal\Garantipos\Results;
+
+use Sportakal\Garantipos\Models\RequestModel;
+use Sportakal\Garantipos\Models\Order;
+use Sportakal\Garantipos\Models\Transaction;
+use Sportakal\Garantipos\Requests\ThreeDSecurePay;
+use Sportakal\Garantipos\Results\Constructors\PostResult;
+
+class ThreeDSecurePayResult extends PostResult
+{
+    public function setHashData(): void
+    {
+        $order = new Order();
+        $order->setOrderID($this->postResultModel->orderid);
+
+        $transaction = new Transaction();
+        $transaction->setType($this->postResultModel->txntype);
+        $transaction->setInstallmentCnt($this->postResultModel->txninstallmentcount);
+        $transaction->setAmount($this->postResultModel->txnamount);
+
+        $request = new RequestModel();
+        $request->setOptions($this->options);
+        $request->setOrder($order);
+        $request->setTransaction($transaction);
+        $request->setSuccessURL($this->postResultModel->successurl);
+        $request->setErrorURL($this->postResultModel->errorurl);
+
+        $pay = new ThreeDSecurePay($request);
+        $this->hash_data = $pay->getHashData();;
+    }
+}
diff --git a/src/Utils/Arrayable.php b/src/Utils/Arrayable.php
new file mode 100644
index 0000000..0144c6c
--- /dev/null
+++ b/src/Utils/Arrayable.php
@@ -0,0 +1,34 @@
+<?php
+
+namespace Sportakal\Garantipos\Utils;
+
+use Sportakal\Garantipos\Models\BaseModel;
+
+class Arrayable
+{
+    public function toArray(): array
+    {
+        $array = get_object_vars($this);
+        $array = $this->parseArray($array);
+
+        return $array;
+    }
+
+    protected function parseArray(array $array): array
+    {
+        foreach ($array as $key => $value) {
+            if ($value instanceof self) {
+                $array[$key] = $value->toArray();
+                continue;
+            }
+
+            if (!is_array($value)) {
+                continue;
+            }
+
+            $array[$key] = $this->parseArray($value);
+        }
+
+        return $array;
+    }
+}
diff --git a/src/Utils/CreateHashData.php b/src/Utils/CreateHashData.php
new file mode 100644
index 0000000..2e609fa
--- /dev/null
+++ b/src/Utils/CreateHashData.php
@@ -0,0 +1,13 @@
+<?php
+
+namespace Sportakal\Garantipos\Utils;
+
+use Sportakal\Garantipos\Models\Options;
+
+class CreateHashData
+{
+    public static function get(string $string): string
+    {
+        return strtoupper(sha1($string));
+    }
+}
diff --git a/src/Utils/CreateSecurityData.php b/src/Utils/CreateSecurityData.php
new file mode 100644
index 0000000..059f3df
--- /dev/null
+++ b/src/Utils/CreateSecurityData.php
@@ -0,0 +1,14 @@
+<?php
+
+namespace Sportakal\Garantipos\Utils;
+
+use Sportakal\Garantipos\Models\Options;
+use Sportakal\Garantipos\Models\Terminal;
+
+class CreateSecurityData
+{
+    public static function get(Terminal $terminal)
+    {
+        return strtoupper(sha1($terminal->getProvUserPassword() . $terminal->getID_()));
+    }
+}
diff --git a/src/Utils/Curl.php b/src/Utils/Curl.php
new file mode 100644
index 0000000..abf1fa2
--- /dev/null
+++ b/src/Utils/Curl.php
@@ -0,0 +1,55 @@
+<?php
+
+namespace Sportakal\Garantipos\Utils;
+
+class Curl
+{
+    protected string $url;
+    protected string $body;
+    protected array $headers;
+    protected string $requestMethod;
+    protected Response $response;
+
+    /**
+     * @param string $url
+     * @param string $body
+     * @param array $headers
+     * @param string $requestMethod
+     */
+    public function __construct(string $url, string $body, array $headers = [], string $requestMethod = '')
+    {
+        $this->url = $url;
+        $this->body = $body;
+        $this->headers = $headers;
+        $this->requestMethod = $requestMethod;
+        $this->make();
+    }
+
+    protected function make(): void
+    {
+        $curl = curl_init();
+
+        curl_setopt_array($curl, array(
+            CURLOPT_URL => $this->url,
+            CURLOPT_RETURNTRANSFER => true,
+            CURLOPT_MAXREDIRS => 10,
+            CURLOPT_FOLLOWLOCATION => true,
+            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
+            CURLOPT_CUSTOMREQUEST => 'POST',
+            CURLOPT_POSTFIELDS => $this->body,
+            CURLOPT_HTTPHEADER => $this->headers, //['Content-Type: text/xml; charset=utf-8', 'SOAPAction: "http://tempuri.org/GetFormsAuthenticationTicket"']
+        ));
+
+        $result = curl_exec($curl);
+        $this->response = new Response($curl, $result, $this->requestMethod);
+        curl_close($curl);
+
+    }
+
+    public function getResponse(): Response
+    {
+        return $this->response;
+    }
+
+
+}
diff --git a/src/Utils/GetHost.php b/src/Utils/GetHost.php
new file mode 100644
index 0000000..27cca16
--- /dev/null
+++ b/src/Utils/GetHost.php
@@ -0,0 +1,27 @@
+<?php
+
+namespace Sportakal\Garantipos\Utils;
+
+use Sportakal\Garantipos\Models\Options;
+
+class GetHost
+{
+    /**
+     * @param string $mode
+     * @return string
+     */
+    public static function get(string $mode = 'TEST', $xml = false): string
+    {
+        if ($mode === 'TEST') {
+            if ($xml) {
+                return 'https://sanalposprovtest.garanti.com.tr/VPServlet';
+            }
+            return 'https://sanalposprovtest.garanti.com.tr/servlet/gt3dengine';
+        }
+
+        if ($xml) {
+            return 'https://sanalposprov.garanti.com.tr/VPServlet';
+        }
+        return 'https://sanalposprov.garanti.com.tr/servlet/gt3dengine';
+    }
+}
diff --git a/src/Utils/Response.php b/src/Utils/Response.php
new file mode 100644
index 0000000..3f8060b
--- /dev/null
+++ b/src/Utils/Response.php
@@ -0,0 +1,97 @@
+<?php
+
+namespace Sportakal\Garantipos\Utils;
+
+
+class Response
+{
+    protected $curl;
+    protected string $result;
+    protected string $requestMethod;
+
+    public function __construct($curl, string $result, string $requestMethod)
+    {
+        $this->curl = $curl;
+        $this->result = $result;
+        $this->requestMethod = $requestMethod;
+    }
+
+    /**
+     * @return string
+     */
+    public function getRawBody(): string
+    {
+        return $this->result;
+    }
+
+    /**
+     * @return array
+     */
+    public function getInfo(): array
+    {
+        return curl_getinfo($this->curl);
+    }
+
+    /**
+     * @return array
+     * @throws \JsonException
+     */
+    public function getArray(): array
+    {
+        return (new XmlParser($this->getRawBody()))->getArray();
+    }
+
+    /**
+     * @param $key
+     * @return array|string|null
+     * @throws \JsonException
+     */
+    public function getValue($key)
+    {
+        return (new XmlParser($this->getRawBody()))->getValue($key);
+    }
+
+    /**
+     * @return array|string
+     * @throws \JsonException
+     */
+    public function getResult()
+    {
+        return $this->getValue($this->requestMethod . 'Result');
+    }
+
+    /**
+     * @return bool
+     */
+    public function isSuccessful(): bool
+    {
+        return $this->getResult()['ServiceResult'] === 'Successful';
+    }
+
+    /**
+     * @return string
+     * @throws \JsonException
+     */
+    public function getStatus(): string
+    {
+        return $this->getResult()['ServiceResult'];
+    }
+
+    /**
+     * @return string
+     * @throws \JsonException
+     */
+    public function getStatusDesc(): string
+    {
+        return $this->getResult()['ServiceResultDescription'];
+    }
+
+    /**
+     * @return string
+     * @throws \JsonException
+     */
+    public function getErrorCode(): string
+    {
+        return $this->getResult()['ErrorCode'];
+    }
+}
diff --git a/src/Utils/Secure3DSecurityLevels.php b/src/Utils/Secure3DSecurityLevels.php
new file mode 100644
index 0000000..dd0a5b3
--- /dev/null
+++ b/src/Utils/Secure3DSecurityLevels.php
@@ -0,0 +1,11 @@
+<?php
+
+namespace Sportakal\Garantipos\Utils;
+
+class Secure3DSecurityLevels
+{
+    public const Three3D_MODEL = '3D';
+    public const Three3D_PAY = '3D_PAY';
+    public const ThreeD_FULL = '3D_FULL';
+    public const ThreeD_HALF = '3D_HALF';
+}
diff --git a/src/Utils/XmlCreator.php b/src/Utils/XmlCreator.php
new file mode 100644
index 0000000..88599e6
--- /dev/null
+++ b/src/Utils/XmlCreator.php
@@ -0,0 +1,113 @@
+<?php
+
+namespace Sportakal\Garantipos\Utils;
+
+use DOMDocument;
+use DOMElement;
+
+class XmlCreator
+{
+    protected array $data;
+    protected bool $soap = true;
+    private DOMDocument $dom;
+
+    /**
+     * @throws \DOMException
+     */
+    public function __construct(array $data, $soap = true)
+    {
+        $this->data = $data;
+        $this->soap = $soap;
+
+        $this->createDOMDocument();
+
+        $body = $this->dom;
+        if ($this->soap) {
+            $body = $this->addSoapElements();
+        }
+        $this->createNode($this->dom, $body, $this->data);
+    }
+
+    private function createDOMDocument(): void
+    {
+        $dom = new DOMDocument('1.0', 'UTF-8');
+        $dom->encoding = 'UTF-8';
+        $dom->preserveWhiteSpace = false;
+        $dom->formatOutput = true;
+        $this->dom = $dom;
+    }
+
+    /**
+     * @return DOMElement|bool
+     * @throws \DOMException
+     */
+    protected function addSoapElements()
+    {
+        $dom = $this->dom;
+
+        $soap_envelope = $dom->createElement('soap:Envelope');
+        $soap_envelope->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
+        $soap_envelope->setAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema');
+        $soap_envelope->setAttribute('xmlns:soap', 'http://schemas.xmlsoap.org/soap/envelope/');
+
+        $soap_body = $dom->createElement('soap:Body');;
+        $soap_envelope->appendChild($soap_body);
+        $dom->appendChild($soap_envelope);
+
+        return $soap_body;
+    }
+
+    /**
+     * @param DOMDocument $dom
+     * @param DOMElement|DOMDocument $parent
+     * @param array $data
+     * @throws \DOMException
+     */
+    private function createNode(DOMDocument $dom, $parent, array $data): void
+    {
+        foreach ($data as $key => $value) {
+            if (strpos($key, '_') === 0) {
+                continue;
+            }
+
+            if (isset($value['_pass_in_xml']) && $value['_pass_in_xml'] === true) {
+                continue;
+            }
+
+            if (!$key || is_int($key)) {
+                $key = $data['_key'] ?? null;
+            }
+
+            if (isset($value['_parent_key'])) {
+                $key = $value['_parent_key'];
+            }
+
+            if (!$key) {
+                $parent->nodeValue = htmlspecialchars($value);
+                continue;
+            }
+
+            $parentNode = $dom->createElement($key);
+            foreach ($value['_attributes'] ?? [] as $attribute => $attributeValue) {
+                $parentNode->setAttribute($attribute, $attributeValue);
+            }
+            $parent->appendChild($parentNode);
+            if (!is_array($value)) {
+                $parentNode->nodeValue = htmlspecialchars($value);
+                continue;
+            }
+
+            $this->createNode($dom, $parentNode, $value);
+        }
+    }
+
+    public function getXml(): string
+    {
+        return $this->dom->saveXML();
+    }
+
+    public function getHtml(): string
+    {
+        return $this->dom->saveHTML($this->dom->documentElement);
+    }
+}
diff --git a/src/Utils/XmlParser.php b/src/Utils/XmlParser.php
new file mode 100644
index 0000000..c5c3a0f
--- /dev/null
+++ b/src/Utils/XmlParser.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Sportakal\Garantipos\Utils;
+
+class XmlParser
+{
+    protected string $xml;
+    protected array $array;
+
+    /**
+     * @throws \JsonException
+     */
+    public function __construct(string $xml)
+    {
+        $this->xml = $xml;
+        $this->parse();
+    }
+
+    /**
+     * @throws \JsonException
+     */
+    protected function parse()
+    {
+        $body = $this->xml;
+        $body = strtr($body, ['<soap:' => '<soap', '</soap:' => '</soap']);
+        $simplexml_object = simplexml_load_string($body);
+        $json = json_encode($simplexml_object, JSON_THROW_ON_ERROR);
+        $json = str_replace('{}', '""', $json);
+        $this->array = json_decode($json, TRUE, 512, JSON_THROW_ON_ERROR);
+    }
+
+    /**
+     * @return array
+     */
+    public function getArray(): array
+    {
+        return $this->array;
+    }
+
+    /**
+     * @return string|array|null
+     */
+    public function getValue(string $key, $arr = null)
+    {
+        $foundValue = null;
+        if (!$arr) {
+            $arr = $this->array;
+        }
+        foreach ($arr as $k => $v) {
+            if ($k === $key) {
+                $foundValue = $v;
+            } elseif (is_array($v) && count($v) > 0) {
+                $foundValue = $this->getValue($key, $v);
+            }
+        }
+        return $foundValue;
+    }
+
+}