├── .directory ├── .github └── workflows │ └── php.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── bin └── jenkins.sh ├── composer.bak ├── composer.json ├── composer.lock ├── examples ├── create-payment.php ├── eet-payments.php ├── js-initialization.md ├── status.php └── symfony.md ├── factory.php ├── gopay-php-api.iml ├── phpunit.xml.dist ├── src ├── Auth.php ├── Config.php ├── Definition │ ├── Account │ │ └── StatementGeneratingFormat.php │ ├── Language.php │ ├── Payment │ │ ├── BankSwiftCode.php │ │ ├── BnplType.php │ │ ├── Currency.php │ │ ├── PaymentInstrument.php │ │ ├── PaymentItemType.php │ │ └── Recurrence.php │ ├── RequestMethods.php │ ├── Response │ │ ├── PaymentStatus.php │ │ ├── PaymentSubStatus.php │ │ ├── PreAuthState.php │ │ ├── RecurrenceState.php │ │ └── Result.php │ └── TokenScope.php ├── GoPay.php ├── Http │ ├── JsonBrowser.php │ ├── Log │ │ ├── Logger.php │ │ ├── NullLogger.php │ │ └── PrintHttpRequest.php │ ├── Request.php │ └── Response.php ├── OAuth2.php ├── Payments.php └── Token │ ├── AccessToken.php │ ├── CachedOAuth.php │ ├── InMemoryTokenCache.php │ └── TokenCache.php └── tests └── integration ├── CardTokenTest.php ├── CommonMethodTest.php ├── CreatePaymentTest.php ├── EETTest.php ├── GivenGoPay.php ├── OnDemandPaymentTest.php ├── PreAuthorizationTest.php ├── RecurrentPaymentTest.php ├── RefundTest.php └── TestUtils.php /.directory: -------------------------------------------------------------------------------- 1 | [Dolphin] 2 | Timestamp=2017,3,13,11,15,50 3 | Version=3 4 | 5 | [Settings] 6 | HiddenFilesShown=true 7 | -------------------------------------------------------------------------------- /.github/workflows/php.yml: -------------------------------------------------------------------------------- 1 | name: PHP Composer 2 | 3 | on: 4 | - push 5 | - pull_request 6 | 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | strategy: 11 | matrix: 12 | operating-system: [ubuntu-latest, windows-latest, macOS-latest] 13 | php-versions: ["8.1", "8.2"] 14 | 15 | name: PHP ${{ matrix.php-versions }} Test on ${{ matrix.operating-system }} 16 | 17 | steps: 18 | - uses: actions/checkout@v3 19 | 20 | - name: Validate composer.json and composer.lock 21 | run: composer validate --strict 22 | 23 | - name: Install PHP 24 | uses: shivammathur/setup-php@v2 25 | with: 26 | php-version: ${{ matrix.php-versions }} 27 | 28 | - name: Check PHP Version 29 | run: php -v 30 | 31 | - name: Install dependencies 32 | run: composer install --prefer-dist --no-progress 33 | 34 | # Add a test script to composer.json, for instance: "test": "vendor/bin/phpunit" 35 | # Docs: https://getcomposer.org/doc/articles/scripts.md 36 | 37 | - name: Run test suite 38 | run: vendor/phpunit/phpunit/phpunit --no-configuration tests/integration 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # IDE 2 | /nbproject/ 3 | .idea 4 | /gopay-php-api.iml 5 | 6 | # APP 7 | /vendor/ 8 | /bin/ 9 | !/bin/jenkins.sh 10 | /var/ 11 | /phpunit.xml 12 | .phpunit.result.cache 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | # Changelog 3 | 4 | ## v1.4.6 5 | - Added `_5048` substate 6 | 7 | ## v1.4.5 8 | - `isProductionMode` is now deprecated and will be removed 9 | - `gatewayUrl` parameter is preferred way to set gateway url 10 | - `Supercash` payment method is no longer supported by the payment gateways, relevant code marked as deprecated 11 | 12 | ## v1.4.4 13 | 14 | - Dropped support for Guzzle 5 depedency 15 | - Added Guzzle 7 support 16 | 17 | 18 | ## v1.4.3 19 | 20 | - `isProductionMode` may now take anything that can be resolved as a boolean via filter_var ("yes", "true", true ...) 21 | 22 | ## v1.2.0 23 | 24 | * Added [EET](https://help.gopay.com/cs/tema/propojeni-do-eet/jak-bude-fungovat-napojeni-gopay-do-eet) Support 25 | 26 | ## v1.1.1 27 | 28 | * Fix `GoPay\Definition\Payment\BankSwiftCode::KOMERCNI_BANKA` 29 | * Composer `autoload-dev` 30 | * Update badges in readme (#2) 31 | 32 | ## v1.1.0 33 | 34 | * Add travis-ci 35 | * Simplified token caching, based on [python-sdk](https://github.com/gopaycommunity/gopay-python-api/) 36 | * `TokenCache` handles only set/get token, no `isExpired` method 37 | * `$client` is passed as first argument instead of `setClient` method 38 | * `getAccessToken` can return null if token does not exist 39 | 40 | #### Before 41 | 42 | ```php 43 | file = __DIR__ . "/{$client}"; 55 | } 56 | 57 | public function setAccessToken(AccessToken $t) 58 | { 59 | file_put_contents($this->file, serialize($t); 60 | } 61 | 62 | public function getAccessToken() 63 | { 64 | if (file_exists($this->file)) { 65 | return unserialize(file_get_contents($this->file)); 66 | } 67 | return $this->getExpiredToken(); 68 | } 69 | } 70 | ``` 71 | 72 | #### After 73 | 74 | ```php 75 | file = __DIR__ . "/{$client}"; 87 | } 88 | 89 | public function setAccessToken($client, AccessToken $t) 90 | { 91 | $this->setClient($client); 92 | file_put_contents($this->file, serialize($t); 93 | } 94 | 95 | public function getAccessToken($client) 96 | { 97 | $this->setClient($client); 98 | if (file_exists($this->file)) { 99 | return unserialize(file_get_contents($this->file)); 100 | } 101 | return null; 102 | } 103 | } 104 | ``` 105 | 106 | ## v1.0.1 107 | 108 | * Add phpunit's bootstrap (#1) 109 | 110 | ## v1.0.0 111 | 112 | * Call every API method without validation 113 | * Cache access token 114 | * Log HTTP communication 115 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 GoPay.com 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # GoPay's PHP SDK for Payments REST API 3 | 4 | [![License](https://poser.pugx.org/gopay/payments-sdk-php/license)](https://packagist.org/packages/gopay/payments-sdk-php) 5 | [![Latest Stable Version](https://poser.pugx.org/gopay/payments-sdk-php/v/stable)](https://packagist.org/packages/gopay/payments-sdk-php) 6 | [![Total Downloads](https://poser.pugx.org/gopay/payments-sdk-php/downloads)](https://packagist.org/packages/gopay/payments-sdk-php) 7 | [![Monthly Downloads](https://poser.pugx.org/gopay/payments-sdk-php/d/monthly)](https://packagist.org/packages/gopay/payments-sdk-php) 8 | [![Dependency Status](https://www.versioneye.com/user/projects/570b383e2aca6b000e0dea95/badge.svg)](https://www.versioneye.com/user/projects/570b383e2aca6b000e0dea95) 9 | 10 | ## Requirements 11 | 12 | - PHP >= 8.1 13 | - enabled extension `curl`, `json` 14 | 15 | ## Installation 16 | 17 | The simplest way to install SDK is to use [Composer](https://getcomposer.org/doc/00-intro.md): 18 | 19 | ```bash 20 | composer require gopay/payments-sdk-php 21 | ``` 22 | 23 | ## Basic usage 24 | 25 | ```php 26 | // minimal configuration 27 | $gopay = GoPay\Api::payments([ 28 | 'goid' => 'my goid', 29 | 'clientId' => 'my id', 30 | 'clientSecret' => 'my secret', 31 | 'gatewayUrl' => 'gateway url' 32 | ]); 33 | 34 | // full configuration 35 | $gopay = GoPay\Api::payments([ 36 | 'goid' => 'my goid', 37 | 'clientId' => 'my id', 38 | 'clientSecret' => 'my secret', 39 | 'gatewayUrl' => 'gateway url', 40 | 'scope' => GoPay\Definition\TokenScope::ALL, 41 | 'language' => GoPay\Definition\Language::CZECH, 42 | 'timeout' => 30 43 | ]); 44 | ``` 45 | 46 | ### Configuration 47 | 48 | #### Required fields 49 | 50 | Required field | Data type | Documentation | 51 | -------------- | --------- | ----------- | 52 | `goid` | string | default GoPay account used in `createPayment` if `target` is not specified 53 | `clientId` | string | | 54 | `clientSecret` | string | | 55 | `gatewayUrl` | string | [test or production environment?](https://help.gopay.com/en/s/uY) | 56 | 57 | #### Optional fields 58 | 59 | Optional field | Data type | Default value | Documentation | 60 | -------------- | --------- | ------------- | ------------- | 61 | `scope` | string | [`GoPay\Definition\TokenScope::ALL`](src/Definition/TokenScope.php) | | 62 | `language` | string | [`GoPay\Definition\Language::ENGLISH`](src/Definition/Language.php) | language used in `createPayment` if `lang` is not specified + used for [localization of errors](https://doc.gopay.com/#errors) 63 | `timeout` | int | 30 | Browser timeout in seconds | 64 | 65 | ### Available methods 66 | 67 | API | SDK method | 68 | --- | ---------- | 69 | [Create a payment](https://doc.gopay.com#payment-creation) | `$gopay->createPayment(array $payment)` | 70 | [Get status of a payment](https://doc.gopay.com#payment-inquiry) | `$gopay->getStatus($id)` | 71 | [Refund a payment](https://doc.gopay.com#payment-refund) | `$gopay->refundPayment($id, $amount)` | 72 | [Create a recurring payment](https://doc.gopay.com#creating-a-recurrence) | `$gopay->createRecurrence($id, array $payment)` | 73 | [Cancel a recurring payment](https://doc.gopay.com#void-a-recurring-payment) | `$gopay->voidRecurrence($id)` | 74 | [Capture a preauthorized payment](https://doc.gopay.com#capturing-a-preauthorized-payment) | `$gopay->captureAuthorization($id)` | 75 | [Capture a preauthorized payment partially](https://doc.gopay.com#partially-capturing-a-preauthorized-payment) | `$gopay->captureAuthorizationPartial($id, array $capturePayment)` | 76 | [Void a preauthorized payment](https://doc.gopay.com#voiding-a-preauthorized-payment) | `$gopay->voidAuthorization($id)` | 77 | [Get payment card details](https://doc.gopay.com#payment-card-inquiry) | `$gopay->getCardDetails($cardId)` | 78 | [Delete a saved card](https://doc.gopay.com#payment-card-deletion) | `$gopay->deleteCard($cardId)` | 79 | [Get allowed payment methods for a currency](https://doc.gopay.com#available-payment-methods-for-a-currency) | `$gopay->getPaymentInstruments($goid, $currency)` | 80 | [Get all allowed payment methods](https://doc.gopay.com#all-available-payment-methods) | `$gopay->getPaymentInstrumentsAll($goid)` | 81 | [Generate an account statement](https://doc.gopay.com#account-statement) | `$gopay->getAccountStatement(array $accountStatement)` 82 | 83 | ### SDK response? Has my call succeed? 84 | 85 | SDK returns wrapped API response. Every method returns 86 | [`GoPay\Http\Response` object](src/Http/Response.php). Structure of `json/__toString` 87 | should be same as in [documentation](https://doc.gopay.com/en). 88 | SDK throws no exception. Please create an issue if you catch one. 89 | 90 | ```php 91 | $response = $gopay->createPayment([/* define your payment */]); 92 | if ($response->hasSucceed()) { 93 | echo "hooray, API returned {$response}"; 94 | return $response->json['gw_url']; // url for initiation of gateway 95 | } else { 96 | // errors format: https://doc.gopay.com/en/?shell#http-result-codes 97 | echo "oops, API returned {$response->statusCode}: {$response}"; 98 | } 99 | 100 | ``` 101 | 102 | Method | Description | 103 | ------ | ---------- | 104 | `$response->hasSucceed()` | checks if API returns status code _200_ | 105 | `$response->json` | decoded response, returned objects are converted into associative arrays | 106 | `$response->statusCode` | HTTP status code | 107 | `$response->rawBody` | raw body from HTTP response | 108 | 109 | ### Are required fields and allowed values validated? 110 | 111 | **No.** API [validates fields](https://doc.gopay.com/#error) pretty extensively 112 | so there is no need to duplicate validation in SDK. It would only introduce new type of error. 113 | Or we would have to perfectly simulate API error messages. That's why SDK just calls API which 114 | behavior is well documented in [doc.gopay.com](https://doc.gopay.com). 115 | 116 | ***** 117 | 118 | ## Advanced usage 119 | 120 | ### Initiation of the payment gateway 121 | 122 | ```php 123 | // create payment and pass url to template 124 | $response = $gopay->createPayment([/* define your payment */]); 125 | if ($response->hasSucceed()) { 126 | 127 | $gatewayUrl => $response->json['gw_url'], 128 | $embedJs => $gopay->urlToEmbedJs() 129 | // render template 130 | } 131 | ``` 132 | 133 | #### [Inline gateway](https://doc.gopay.com/#inline) 134 | 135 | ```php 136 |
137 | 138 | 139 |
140 | ``` 141 | 142 | #### [Redirect gateway](https://doc.gopay.com/#redirect) 143 | 144 | ```php 145 |
146 | 147 |
148 | ``` 149 | 150 | #### [Asynchronous initialization using JavaScript](/examples/js-initialization.md) 151 | 152 | ### Enums ([Code lists](https://doc.gopay.com/#ciselniky)) 153 | 154 | Instead of hardcoding bank codes string you can use predefined enums. 155 | Check using enums in [create-payment example](/examples/create-payment.php) 156 | 157 | Type | Description | 158 | ---- | ----------- | 159 | [Language](/src/Definition/Language.php) | Payment language, localization of error messages | 160 | [Token scope](/src/Definition/TokenScope.php) | Authorization scope for [OAuth2](https://doc.gopay.com/#access-token) | 161 | [Payment enums](/src/Definition/Payment) | Enums for creating payment | 162 | [Response enums](/src/Definition/Response) | Result of creating payment, executing payment operations | 163 | [ItemType enums](/src/Definition/Payment/PaymentItemType.php) | Type of an item | 164 | [VatRate enums](/src/Definition/Payment/VatRate.php) | VatRate of an item | 165 | 166 | ### Framework integration 167 | 168 | - [Symfony2](/examples/symfony.md) 169 | 170 | ### Cache access token 171 | 172 | Access token expires after 30 minutes so it's expensive to use new token for every request. 173 | Unfortunately it's default behavior of [`GoPay\Token\InMemoryTokenCache`](src/Token/InMemoryTokenCache.php). 174 | But you can implement your cache and store tokens in Memcache, Redis, files, ... It's up to you. 175 | 176 | Your cache must implement [`GoPay\Token\TokenCache` interface](src/Token/TokenCache.php). 177 | Be aware that there are two [scopes](https://doc.gopay.com/#scope) (`TokenScope`) and 178 | SDK can be used for different clients (`clientId`, `gatewayUrl`). So `client` passed to 179 | methods is unique identifier (`string`) that is built for current environment. 180 | Below you can see example implementation of caching tokens in file: 181 | 182 | ```php 183 | // register cache in optional service configuration 184 | $gopay = GoPay\payments( 185 | [/* your config */], 186 | ['cache' => new PrimitiveFileCache()] 187 | ); 188 | ``` 189 | 190 | ```php 191 | new GoPay\Http\Log\PrintHttpRequest()] 226 | ); 227 | ``` 228 | 229 | Available logger | Description | 230 | ---------------- | ----------- | 231 | [NullLogger](/src/Http/Log/NullLogger.php) | Default logger which does nothing | 232 | [PrintHttpRequest](/src/Http/Log/PrintHttpRequest.php) | Prints basic information about request and response, used in [remote tests](tests/integration/GivenGoPay.php#GivenGoPay.php-26) | 233 | 234 | ## Contributing 235 | 236 | Contributions from others would be very much appreciated! Send 237 | [pull request](https://github.com/gopaycommunity/gopay-php-api/pulls)/ 238 | [issue](https://github.com/gopaycommunity/gopay-php-api/issues). Thanks! 239 | 240 | ## License 241 | 242 | Copyright (c) 2015 GoPay.com. MIT Licensed, 243 | see [LICENSE](/LICENSE) for details. 244 | -------------------------------------------------------------------------------- /bin/jenkins.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | composer install 4 | phpqa --verbose --analyzedDir ./ --buildDir ./var/CI --ignoredDirs=bin,vendor 5 | bin/phpunit --log-junit ./var/CI/junit.xml --testdox-text ./var/CI/testdox.txt --testdox-html ./var/CI/testdox.html -------------------------------------------------------------------------------- /composer.bak: -------------------------------------------------------------------------------- 1 | { 2 | "_readme": [ 3 | "This file locks the dependencies of your project to a known state", 4 | "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", 5 | "This file is @generated automatically" 6 | ], 7 | "content-hash": "bba0818c6d6b76a59ba353271fcbd6d3", 8 | "packages": [ 9 | { 10 | "name": "guzzlehttp/guzzle", 11 | "version": "6.3.3", 12 | "source": { 13 | "type": "git", 14 | "url": "https://github.com/guzzle/guzzle.git", 15 | "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba" 16 | }, 17 | "dist": { 18 | "type": "zip", 19 | "url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba", 20 | "reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba", 21 | "shasum": "" 22 | }, 23 | "require": { 24 | "guzzlehttp/promises": "^1.0", 25 | "guzzlehttp/psr7": "^1.4", 26 | "php": ">=5.5" 27 | }, 28 | "require-dev": { 29 | "ext-curl": "*", 30 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", 31 | "psr/log": "^1.0" 32 | }, 33 | "suggest": { 34 | "psr/log": "Required for using the Log middleware" 35 | }, 36 | "type": "library", 37 | "extra": { 38 | "branch-alias": { 39 | "dev-master": "6.3-dev" 40 | } 41 | }, 42 | "autoload": { 43 | "files": [ 44 | "src/functions_include.php" 45 | ], 46 | "psr-4": { 47 | "GuzzleHttp\\": "src/" 48 | } 49 | }, 50 | "notification-url": "https://packagist.org/downloads/", 51 | "license": [ 52 | "MIT" 53 | ], 54 | "authors": [ 55 | { 56 | "name": "Michael Dowling", 57 | "email": "mtdowling@gmail.com", 58 | "homepage": "https://github.com/mtdowling" 59 | } 60 | ], 61 | "description": "Guzzle is a PHP HTTP client library", 62 | "homepage": "http://guzzlephp.org/", 63 | "keywords": [ 64 | "client", 65 | "curl", 66 | "framework", 67 | "http", 68 | "http client", 69 | "rest", 70 | "web service" 71 | ], 72 | "time": "2018-04-22T15:46:56+00:00" 73 | }, 74 | { 75 | "name": "guzzlehttp/promises", 76 | "version": "v1.3.1", 77 | "source": { 78 | "type": "git", 79 | "url": "https://github.com/guzzle/promises.git", 80 | "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646" 81 | }, 82 | "dist": { 83 | "type": "zip", 84 | "url": "https://api.github.com/repos/guzzle/promises/zipball/a59da6cf61d80060647ff4d3eb2c03a2bc694646", 85 | "reference": "a59da6cf61d80060647ff4d3eb2c03a2bc694646", 86 | "shasum": "" 87 | }, 88 | "require": { 89 | "php": ">=5.5.0" 90 | }, 91 | "require-dev": { 92 | "phpunit/phpunit": "^4.0" 93 | }, 94 | "type": "library", 95 | "extra": { 96 | "branch-alias": { 97 | "dev-master": "1.4-dev" 98 | } 99 | }, 100 | "autoload": { 101 | "psr-4": { 102 | "GuzzleHttp\\Promise\\": "src/" 103 | }, 104 | "files": [ 105 | "src/functions_include.php" 106 | ] 107 | }, 108 | "notification-url": "https://packagist.org/downloads/", 109 | "license": [ 110 | "MIT" 111 | ], 112 | "authors": [ 113 | { 114 | "name": "Michael Dowling", 115 | "email": "mtdowling@gmail.com", 116 | "homepage": "https://github.com/mtdowling" 117 | } 118 | ], 119 | "description": "Guzzle promises library", 120 | "keywords": [ 121 | "promise" 122 | ], 123 | "time": "2016-12-20T10:07:11+00:00" 124 | }, 125 | { 126 | "name": "guzzlehttp/psr7", 127 | "version": "1.5.2", 128 | "source": { 129 | "type": "git", 130 | "url": "https://github.com/guzzle/psr7.git", 131 | "reference": "9f83dded91781a01c63574e387eaa769be769115" 132 | }, 133 | "dist": { 134 | "type": "zip", 135 | "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115", 136 | "reference": "9f83dded91781a01c63574e387eaa769be769115", 137 | "shasum": "" 138 | }, 139 | "require": { 140 | "php": ">=5.4.0", 141 | "psr/http-message": "~1.0", 142 | "ralouphie/getallheaders": "^2.0.5" 143 | }, 144 | "provide": { 145 | "psr/http-message-implementation": "1.0" 146 | }, 147 | "require-dev": { 148 | "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" 149 | }, 150 | "type": "library", 151 | "extra": { 152 | "branch-alias": { 153 | "dev-master": "1.5-dev" 154 | } 155 | }, 156 | "autoload": { 157 | "psr-4": { 158 | "GuzzleHttp\\Psr7\\": "src/" 159 | }, 160 | "files": [ 161 | "src/functions_include.php" 162 | ] 163 | }, 164 | "notification-url": "https://packagist.org/downloads/", 165 | "license": [ 166 | "MIT" 167 | ], 168 | "authors": [ 169 | { 170 | "name": "Michael Dowling", 171 | "email": "mtdowling@gmail.com", 172 | "homepage": "https://github.com/mtdowling" 173 | }, 174 | { 175 | "name": "Tobias Schultze", 176 | "homepage": "https://github.com/Tobion" 177 | } 178 | ], 179 | "description": "PSR-7 message implementation that also provides common utility methods", 180 | "keywords": [ 181 | "http", 182 | "message", 183 | "psr-7", 184 | "request", 185 | "response", 186 | "stream", 187 | "uri", 188 | "url" 189 | ], 190 | "time": "2018-12-04T20:46:45+00:00" 191 | }, 192 | { 193 | "name": "psr/http-message", 194 | "version": "1.0.1", 195 | "source": { 196 | "type": "git", 197 | "url": "https://github.com/php-fig/http-message.git", 198 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" 199 | }, 200 | "dist": { 201 | "type": "zip", 202 | "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", 203 | "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", 204 | "shasum": "" 205 | }, 206 | "require": { 207 | "php": ">=5.3.0" 208 | }, 209 | "type": "library", 210 | "extra": { 211 | "branch-alias": { 212 | "dev-master": "1.0.x-dev" 213 | } 214 | }, 215 | "autoload": { 216 | "psr-4": { 217 | "Psr\\Http\\Message\\": "src/" 218 | } 219 | }, 220 | "notification-url": "https://packagist.org/downloads/", 221 | "license": [ 222 | "MIT" 223 | ], 224 | "authors": [ 225 | { 226 | "name": "PHP-FIG", 227 | "homepage": "http://www.php-fig.org/" 228 | } 229 | ], 230 | "description": "Common interface for HTTP messages", 231 | "homepage": "https://github.com/php-fig/http-message", 232 | "keywords": [ 233 | "http", 234 | "http-message", 235 | "psr", 236 | "psr-7", 237 | "request", 238 | "response" 239 | ], 240 | "time": "2016-08-06T14:39:51+00:00" 241 | }, 242 | { 243 | "name": "ralouphie/getallheaders", 244 | "version": "2.0.5", 245 | "source": { 246 | "type": "git", 247 | "url": "https://github.com/ralouphie/getallheaders.git", 248 | "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa" 249 | }, 250 | "dist": { 251 | "type": "zip", 252 | "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa", 253 | "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa", 254 | "shasum": "" 255 | }, 256 | "require": { 257 | "php": ">=5.3" 258 | }, 259 | "require-dev": { 260 | "phpunit/phpunit": "~3.7.0", 261 | "satooshi/php-coveralls": ">=1.0" 262 | }, 263 | "type": "library", 264 | "autoload": { 265 | "files": [ 266 | "src/getallheaders.php" 267 | ] 268 | }, 269 | "notification-url": "https://packagist.org/downloads/", 270 | "license": [ 271 | "MIT" 272 | ], 273 | "authors": [ 274 | { 275 | "name": "Ralph Khattar", 276 | "email": "ralph.khattar@gmail.com" 277 | } 278 | ], 279 | "description": "A polyfill for getallheaders.", 280 | "time": "2016-02-11T07:05:27+00:00" 281 | } 282 | ], 283 | "packages-dev": [ 284 | { 285 | "name": "doctrine/instantiator", 286 | "version": "1.1.0", 287 | "source": { 288 | "type": "git", 289 | "url": "https://github.com/doctrine/instantiator.git", 290 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" 291 | }, 292 | "dist": { 293 | "type": "zip", 294 | "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", 295 | "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", 296 | "shasum": "" 297 | }, 298 | "require": { 299 | "php": "^7.1" 300 | }, 301 | "require-dev": { 302 | "athletic/athletic": "~0.1.8", 303 | "ext-pdo": "*", 304 | "ext-phar": "*", 305 | "phpunit/phpunit": "^6.2.3", 306 | "squizlabs/php_codesniffer": "^3.0.2" 307 | }, 308 | "type": "library", 309 | "extra": { 310 | "branch-alias": { 311 | "dev-master": "1.2.x-dev" 312 | } 313 | }, 314 | "autoload": { 315 | "psr-4": { 316 | "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" 317 | } 318 | }, 319 | "notification-url": "https://packagist.org/downloads/", 320 | "license": [ 321 | "MIT" 322 | ], 323 | "authors": [ 324 | { 325 | "name": "Marco Pivetta", 326 | "email": "ocramius@gmail.com", 327 | "homepage": "http://ocramius.github.com/" 328 | } 329 | ], 330 | "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", 331 | "homepage": "https://github.com/doctrine/instantiator", 332 | "keywords": [ 333 | "constructor", 334 | "instantiate" 335 | ], 336 | "time": "2017-07-22T11:58:36+00:00" 337 | }, 338 | { 339 | "name": "hamcrest/hamcrest-php", 340 | "version": "v2.0.0", 341 | "source": { 342 | "type": "git", 343 | "url": "https://github.com/hamcrest/hamcrest-php.git", 344 | "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad" 345 | }, 346 | "dist": { 347 | "type": "zip", 348 | "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/776503d3a8e85d4f9a1148614f95b7a608b046ad", 349 | "reference": "776503d3a8e85d4f9a1148614f95b7a608b046ad", 350 | "shasum": "" 351 | }, 352 | "require": { 353 | "php": "^5.3|^7.0" 354 | }, 355 | "replace": { 356 | "cordoval/hamcrest-php": "*", 357 | "davedevelopment/hamcrest-php": "*", 358 | "kodova/hamcrest-php": "*" 359 | }, 360 | "require-dev": { 361 | "phpunit/php-file-iterator": "1.3.3", 362 | "phpunit/phpunit": "~4.0", 363 | "satooshi/php-coveralls": "^1.0" 364 | }, 365 | "type": "library", 366 | "extra": { 367 | "branch-alias": { 368 | "dev-master": "2.0-dev" 369 | } 370 | }, 371 | "autoload": { 372 | "classmap": [ 373 | "hamcrest" 374 | ] 375 | }, 376 | "notification-url": "https://packagist.org/downloads/", 377 | "license": [ 378 | "BSD" 379 | ], 380 | "description": "This is the PHP port of Hamcrest Matchers", 381 | "keywords": [ 382 | "test" 383 | ], 384 | "time": "2016-01-20T08:20:44+00:00" 385 | }, 386 | { 387 | "name": "myclabs/deep-copy", 388 | "version": "1.8.1", 389 | "source": { 390 | "type": "git", 391 | "url": "https://github.com/myclabs/DeepCopy.git", 392 | "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" 393 | }, 394 | "dist": { 395 | "type": "zip", 396 | "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", 397 | "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", 398 | "shasum": "" 399 | }, 400 | "require": { 401 | "php": "^7.1" 402 | }, 403 | "replace": { 404 | "myclabs/deep-copy": "self.version" 405 | }, 406 | "require-dev": { 407 | "doctrine/collections": "^1.0", 408 | "doctrine/common": "^2.6", 409 | "phpunit/phpunit": "^7.1" 410 | }, 411 | "type": "library", 412 | "autoload": { 413 | "psr-4": { 414 | "DeepCopy\\": "src/DeepCopy/" 415 | }, 416 | "files": [ 417 | "src/DeepCopy/deep_copy.php" 418 | ] 419 | }, 420 | "notification-url": "https://packagist.org/downloads/", 421 | "license": [ 422 | "MIT" 423 | ], 424 | "description": "Create deep copies (clones) of your objects", 425 | "keywords": [ 426 | "clone", 427 | "copy", 428 | "duplicate", 429 | "object", 430 | "object graph" 431 | ], 432 | "time": "2018-06-11T23:09:50+00:00" 433 | }, 434 | { 435 | "name": "phpdocumentor/reflection-common", 436 | "version": "1.0.1", 437 | "source": { 438 | "type": "git", 439 | "url": "https://github.com/phpDocumentor/ReflectionCommon.git", 440 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" 441 | }, 442 | "dist": { 443 | "type": "zip", 444 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 445 | "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", 446 | "shasum": "" 447 | }, 448 | "require": { 449 | "php": ">=5.5" 450 | }, 451 | "require-dev": { 452 | "phpunit/phpunit": "^4.6" 453 | }, 454 | "type": "library", 455 | "extra": { 456 | "branch-alias": { 457 | "dev-master": "1.0.x-dev" 458 | } 459 | }, 460 | "autoload": { 461 | "psr-4": { 462 | "phpDocumentor\\Reflection\\": [ 463 | "src" 464 | ] 465 | } 466 | }, 467 | "notification-url": "https://packagist.org/downloads/", 468 | "license": [ 469 | "MIT" 470 | ], 471 | "authors": [ 472 | { 473 | "name": "Jaap van Otterdijk", 474 | "email": "opensource@ijaap.nl" 475 | } 476 | ], 477 | "description": "Common reflection classes used by phpdocumentor to reflect the code structure", 478 | "homepage": "http://www.phpdoc.org", 479 | "keywords": [ 480 | "FQSEN", 481 | "phpDocumentor", 482 | "phpdoc", 483 | "reflection", 484 | "static analysis" 485 | ], 486 | "time": "2017-09-11T18:02:19+00:00" 487 | }, 488 | { 489 | "name": "phpdocumentor/reflection-docblock", 490 | "version": "4.3.0", 491 | "source": { 492 | "type": "git", 493 | "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", 494 | "reference": "94fd0001232e47129dd3504189fa1c7225010d08" 495 | }, 496 | "dist": { 497 | "type": "zip", 498 | "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", 499 | "reference": "94fd0001232e47129dd3504189fa1c7225010d08", 500 | "shasum": "" 501 | }, 502 | "require": { 503 | "php": "^7.0", 504 | "phpdocumentor/reflection-common": "^1.0.0", 505 | "phpdocumentor/type-resolver": "^0.4.0", 506 | "webmozart/assert": "^1.0" 507 | }, 508 | "require-dev": { 509 | "doctrine/instantiator": "~1.0.5", 510 | "mockery/mockery": "^1.0", 511 | "phpunit/phpunit": "^6.4" 512 | }, 513 | "type": "library", 514 | "extra": { 515 | "branch-alias": { 516 | "dev-master": "4.x-dev" 517 | } 518 | }, 519 | "autoload": { 520 | "psr-4": { 521 | "phpDocumentor\\Reflection\\": [ 522 | "src/" 523 | ] 524 | } 525 | }, 526 | "notification-url": "https://packagist.org/downloads/", 527 | "license": [ 528 | "MIT" 529 | ], 530 | "authors": [ 531 | { 532 | "name": "Mike van Riel", 533 | "email": "me@mikevanriel.com" 534 | } 535 | ], 536 | "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", 537 | "time": "2017-11-30T07:14:17+00:00" 538 | }, 539 | { 540 | "name": "phpdocumentor/type-resolver", 541 | "version": "0.4.0", 542 | "source": { 543 | "type": "git", 544 | "url": "https://github.com/phpDocumentor/TypeResolver.git", 545 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" 546 | }, 547 | "dist": { 548 | "type": "zip", 549 | "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", 550 | "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", 551 | "shasum": "" 552 | }, 553 | "require": { 554 | "php": "^5.5 || ^7.0", 555 | "phpdocumentor/reflection-common": "^1.0" 556 | }, 557 | "require-dev": { 558 | "mockery/mockery": "^0.9.4", 559 | "phpunit/phpunit": "^5.2||^4.8.24" 560 | }, 561 | "type": "library", 562 | "extra": { 563 | "branch-alias": { 564 | "dev-master": "1.0.x-dev" 565 | } 566 | }, 567 | "autoload": { 568 | "psr-4": { 569 | "phpDocumentor\\Reflection\\": [ 570 | "src/" 571 | ] 572 | } 573 | }, 574 | "notification-url": "https://packagist.org/downloads/", 575 | "license": [ 576 | "MIT" 577 | ], 578 | "authors": [ 579 | { 580 | "name": "Mike van Riel", 581 | "email": "me@mikevanriel.com" 582 | } 583 | ], 584 | "time": "2017-07-14T14:27:02+00:00" 585 | }, 586 | { 587 | "name": "phpspec/prophecy", 588 | "version": "1.8.0", 589 | "source": { 590 | "type": "git", 591 | "url": "https://github.com/phpspec/prophecy.git", 592 | "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" 593 | }, 594 | "dist": { 595 | "type": "zip", 596 | "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", 597 | "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", 598 | "shasum": "" 599 | }, 600 | "require": { 601 | "doctrine/instantiator": "^1.0.2", 602 | "php": "^5.3|^7.0", 603 | "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", 604 | "sebastian/comparator": "^1.1|^2.0|^3.0", 605 | "sebastian/recursion-context": "^1.0|^2.0|^3.0" 606 | }, 607 | "require-dev": { 608 | "phpspec/phpspec": "^2.5|^3.2", 609 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" 610 | }, 611 | "type": "library", 612 | "extra": { 613 | "branch-alias": { 614 | "dev-master": "1.8.x-dev" 615 | } 616 | }, 617 | "autoload": { 618 | "psr-0": { 619 | "Prophecy\\": "src/" 620 | } 621 | }, 622 | "notification-url": "https://packagist.org/downloads/", 623 | "license": [ 624 | "MIT" 625 | ], 626 | "authors": [ 627 | { 628 | "name": "Konstantin Kudryashov", 629 | "email": "ever.zet@gmail.com", 630 | "homepage": "http://everzet.com" 631 | }, 632 | { 633 | "name": "Marcello Duarte", 634 | "email": "marcello.duarte@gmail.com" 635 | } 636 | ], 637 | "description": "Highly opinionated mocking framework for PHP 5.3+", 638 | "homepage": "https://github.com/phpspec/prophecy", 639 | "keywords": [ 640 | "Double", 641 | "Dummy", 642 | "fake", 643 | "mock", 644 | "spy", 645 | "stub" 646 | ], 647 | "time": "2018-08-05T17:53:17+00:00" 648 | }, 649 | { 650 | "name": "phpunit/php-code-coverage", 651 | "version": "4.0.8", 652 | "source": { 653 | "type": "git", 654 | "url": "https://github.com/sebastianbergmann/php-code-coverage.git", 655 | "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" 656 | }, 657 | "dist": { 658 | "type": "zip", 659 | "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", 660 | "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", 661 | "shasum": "" 662 | }, 663 | "require": { 664 | "ext-dom": "*", 665 | "ext-xmlwriter": "*", 666 | "php": "^5.6 || ^7.0", 667 | "phpunit/php-file-iterator": "^1.3", 668 | "phpunit/php-text-template": "^1.2", 669 | "phpunit/php-token-stream": "^1.4.2 || ^2.0", 670 | "sebastian/code-unit-reverse-lookup": "^1.0", 671 | "sebastian/environment": "^1.3.2 || ^2.0", 672 | "sebastian/version": "^1.0 || ^2.0 || ^3.0" 673 | }, 674 | "require-dev": { 675 | "ext-xdebug": "^2.1.4", 676 | "phpunit/phpunit": "^5.7" 677 | }, 678 | "suggest": { 679 | "ext-xdebug": "^2.5.1" 680 | }, 681 | "type": "library", 682 | "extra": { 683 | "branch-alias": { 684 | "dev-master": "4.0.x-dev" 685 | } 686 | }, 687 | "autoload": { 688 | "classmap": [ 689 | "src/" 690 | ] 691 | }, 692 | "notification-url": "https://packagist.org/downloads/", 693 | "license": [ 694 | "BSD-3-Clause" 695 | ], 696 | "authors": [ 697 | { 698 | "name": "Sebastian Bergmann", 699 | "email": "sb@sebastian-bergmann.de", 700 | "role": "lead" 701 | } 702 | ], 703 | "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", 704 | "homepage": "https://github.com/sebastianbergmann/php-code-coverage", 705 | "keywords": [ 706 | "coverage", 707 | "testing", 708 | "xunit" 709 | ], 710 | "time": "2017-04-02T07:44:40+00:00" 711 | }, 712 | { 713 | "name": "phpunit/php-file-iterator", 714 | "version": "1.4.5", 715 | "source": { 716 | "type": "git", 717 | "url": "https://github.com/sebastianbergmann/php-file-iterator.git", 718 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" 719 | }, 720 | "dist": { 721 | "type": "zip", 722 | "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", 723 | "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", 724 | "shasum": "" 725 | }, 726 | "require": { 727 | "php": ">=5.3.3" 728 | }, 729 | "type": "library", 730 | "extra": { 731 | "branch-alias": { 732 | "dev-master": "1.4.x-dev" 733 | } 734 | }, 735 | "autoload": { 736 | "classmap": [ 737 | "src/" 738 | ] 739 | }, 740 | "notification-url": "https://packagist.org/downloads/", 741 | "license": [ 742 | "BSD-3-Clause" 743 | ], 744 | "authors": [ 745 | { 746 | "name": "Sebastian Bergmann", 747 | "email": "sb@sebastian-bergmann.de", 748 | "role": "lead" 749 | } 750 | ], 751 | "description": "FilterIterator implementation that filters files based on a list of suffixes.", 752 | "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", 753 | "keywords": [ 754 | "filesystem", 755 | "iterator" 756 | ], 757 | "time": "2017-11-27T13:52:08+00:00" 758 | }, 759 | { 760 | "name": "phpunit/php-text-template", 761 | "version": "1.2.1", 762 | "source": { 763 | "type": "git", 764 | "url": "https://github.com/sebastianbergmann/php-text-template.git", 765 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" 766 | }, 767 | "dist": { 768 | "type": "zip", 769 | "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 770 | "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", 771 | "shasum": "" 772 | }, 773 | "require": { 774 | "php": ">=5.3.3" 775 | }, 776 | "type": "library", 777 | "autoload": { 778 | "classmap": [ 779 | "src/" 780 | ] 781 | }, 782 | "notification-url": "https://packagist.org/downloads/", 783 | "license": [ 784 | "BSD-3-Clause" 785 | ], 786 | "authors": [ 787 | { 788 | "name": "Sebastian Bergmann", 789 | "email": "sebastian@phpunit.de", 790 | "role": "lead" 791 | } 792 | ], 793 | "description": "Simple template engine.", 794 | "homepage": "https://github.com/sebastianbergmann/php-text-template/", 795 | "keywords": [ 796 | "template" 797 | ], 798 | "time": "2015-06-21T13:50:34+00:00" 799 | }, 800 | { 801 | "name": "phpunit/php-timer", 802 | "version": "1.0.9", 803 | "source": { 804 | "type": "git", 805 | "url": "https://github.com/sebastianbergmann/php-timer.git", 806 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" 807 | }, 808 | "dist": { 809 | "type": "zip", 810 | "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 811 | "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", 812 | "shasum": "" 813 | }, 814 | "require": { 815 | "php": "^5.3.3 || ^7.0" 816 | }, 817 | "require-dev": { 818 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 819 | }, 820 | "type": "library", 821 | "extra": { 822 | "branch-alias": { 823 | "dev-master": "1.0-dev" 824 | } 825 | }, 826 | "autoload": { 827 | "classmap": [ 828 | "src/" 829 | ] 830 | }, 831 | "notification-url": "https://packagist.org/downloads/", 832 | "license": [ 833 | "BSD-3-Clause" 834 | ], 835 | "authors": [ 836 | { 837 | "name": "Sebastian Bergmann", 838 | "email": "sb@sebastian-bergmann.de", 839 | "role": "lead" 840 | } 841 | ], 842 | "description": "Utility class for timing", 843 | "homepage": "https://github.com/sebastianbergmann/php-timer/", 844 | "keywords": [ 845 | "timer" 846 | ], 847 | "time": "2017-02-26T11:10:40+00:00" 848 | }, 849 | { 850 | "name": "phpunit/php-token-stream", 851 | "version": "2.0.2", 852 | "source": { 853 | "type": "git", 854 | "url": "https://github.com/sebastianbergmann/php-token-stream.git", 855 | "reference": "791198a2c6254db10131eecfe8c06670700904db" 856 | }, 857 | "dist": { 858 | "type": "zip", 859 | "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", 860 | "reference": "791198a2c6254db10131eecfe8c06670700904db", 861 | "shasum": "" 862 | }, 863 | "require": { 864 | "ext-tokenizer": "*", 865 | "php": "^7.0" 866 | }, 867 | "require-dev": { 868 | "phpunit/phpunit": "^6.2.4" 869 | }, 870 | "type": "library", 871 | "extra": { 872 | "branch-alias": { 873 | "dev-master": "2.0-dev" 874 | } 875 | }, 876 | "autoload": { 877 | "classmap": [ 878 | "src/" 879 | ] 880 | }, 881 | "notification-url": "https://packagist.org/downloads/", 882 | "license": [ 883 | "BSD-3-Clause" 884 | ], 885 | "authors": [ 886 | { 887 | "name": "Sebastian Bergmann", 888 | "email": "sebastian@phpunit.de" 889 | } 890 | ], 891 | "description": "Wrapper around PHP's tokenizer extension.", 892 | "homepage": "https://github.com/sebastianbergmann/php-token-stream/", 893 | "keywords": [ 894 | "tokenizer" 895 | ], 896 | "time": "2017-11-27T05:48:46+00:00" 897 | }, 898 | { 899 | "name": "phpunit/phpunit", 900 | "version": "5.5.4", 901 | "source": { 902 | "type": "git", 903 | "url": "https://github.com/sebastianbergmann/phpunit.git", 904 | "reference": "3e6e88e56c912133de6e99b87728cca7ed70c5f5" 905 | }, 906 | "dist": { 907 | "type": "zip", 908 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/3e6e88e56c912133de6e99b87728cca7ed70c5f5", 909 | "reference": "3e6e88e56c912133de6e99b87728cca7ed70c5f5", 910 | "shasum": "" 911 | }, 912 | "require": { 913 | "ext-dom": "*", 914 | "ext-json": "*", 915 | "ext-pcre": "*", 916 | "ext-reflection": "*", 917 | "ext-spl": "*", 918 | "myclabs/deep-copy": "~1.3", 919 | "php": "^5.6 || ^7.0", 920 | "phpspec/prophecy": "^1.3.1", 921 | "phpunit/php-code-coverage": "^4.0.1", 922 | "phpunit/php-file-iterator": "~1.4", 923 | "phpunit/php-text-template": "~1.2", 924 | "phpunit/php-timer": "^1.0.6", 925 | "phpunit/phpunit-mock-objects": "^3.2", 926 | "sebastian/comparator": "~1.1", 927 | "sebastian/diff": "~1.2", 928 | "sebastian/environment": "^1.3 || ^2.0", 929 | "sebastian/exporter": "~1.2", 930 | "sebastian/global-state": "~1.0", 931 | "sebastian/object-enumerator": "~1.0", 932 | "sebastian/resource-operations": "~1.0", 933 | "sebastian/version": "~1.0|~2.0", 934 | "symfony/yaml": "~2.1|~3.0" 935 | }, 936 | "conflict": { 937 | "phpdocumentor/reflection-docblock": "3.0.2" 938 | }, 939 | "suggest": { 940 | "phpunit/php-invoker": "~1.1" 941 | }, 942 | "bin": [ 943 | "phpunit" 944 | ], 945 | "type": "library", 946 | "extra": { 947 | "branch-alias": { 948 | "dev-master": "5.5.x-dev" 949 | } 950 | }, 951 | "autoload": { 952 | "classmap": [ 953 | "src/" 954 | ] 955 | }, 956 | "notification-url": "https://packagist.org/downloads/", 957 | "license": [ 958 | "BSD-3-Clause" 959 | ], 960 | "authors": [ 961 | { 962 | "name": "Sebastian Bergmann", 963 | "email": "sebastian@phpunit.de", 964 | "role": "lead" 965 | } 966 | ], 967 | "description": "The PHP Unit Testing framework.", 968 | "homepage": "https://phpunit.de/", 969 | "keywords": [ 970 | "phpunit", 971 | "testing", 972 | "xunit" 973 | ], 974 | "time": "2016-08-26T07:11:44+00:00" 975 | }, 976 | { 977 | "name": "phpunit/phpunit-mock-objects", 978 | "version": "3.4.4", 979 | "source": { 980 | "type": "git", 981 | "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", 982 | "reference": "a23b761686d50a560cc56233b9ecf49597cc9118" 983 | }, 984 | "dist": { 985 | "type": "zip", 986 | "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118", 987 | "reference": "a23b761686d50a560cc56233b9ecf49597cc9118", 988 | "shasum": "" 989 | }, 990 | "require": { 991 | "doctrine/instantiator": "^1.0.2", 992 | "php": "^5.6 || ^7.0", 993 | "phpunit/php-text-template": "^1.2", 994 | "sebastian/exporter": "^1.2 || ^2.0" 995 | }, 996 | "conflict": { 997 | "phpunit/phpunit": "<5.4.0" 998 | }, 999 | "require-dev": { 1000 | "phpunit/phpunit": "^5.4" 1001 | }, 1002 | "suggest": { 1003 | "ext-soap": "*" 1004 | }, 1005 | "type": "library", 1006 | "extra": { 1007 | "branch-alias": { 1008 | "dev-master": "3.2.x-dev" 1009 | } 1010 | }, 1011 | "autoload": { 1012 | "classmap": [ 1013 | "src/" 1014 | ] 1015 | }, 1016 | "notification-url": "https://packagist.org/downloads/", 1017 | "license": [ 1018 | "BSD-3-Clause" 1019 | ], 1020 | "authors": [ 1021 | { 1022 | "name": "Sebastian Bergmann", 1023 | "email": "sb@sebastian-bergmann.de", 1024 | "role": "lead" 1025 | } 1026 | ], 1027 | "description": "Mock Object library for PHPUnit", 1028 | "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", 1029 | "keywords": [ 1030 | "mock", 1031 | "xunit" 1032 | ], 1033 | "time": "2017-06-30T09:13:00+00:00" 1034 | }, 1035 | { 1036 | "name": "sebastian/code-unit-reverse-lookup", 1037 | "version": "1.0.1", 1038 | "source": { 1039 | "type": "git", 1040 | "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", 1041 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" 1042 | }, 1043 | "dist": { 1044 | "type": "zip", 1045 | "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 1046 | "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", 1047 | "shasum": "" 1048 | }, 1049 | "require": { 1050 | "php": "^5.6 || ^7.0" 1051 | }, 1052 | "require-dev": { 1053 | "phpunit/phpunit": "^5.7 || ^6.0" 1054 | }, 1055 | "type": "library", 1056 | "extra": { 1057 | "branch-alias": { 1058 | "dev-master": "1.0.x-dev" 1059 | } 1060 | }, 1061 | "autoload": { 1062 | "classmap": [ 1063 | "src/" 1064 | ] 1065 | }, 1066 | "notification-url": "https://packagist.org/downloads/", 1067 | "license": [ 1068 | "BSD-3-Clause" 1069 | ], 1070 | "authors": [ 1071 | { 1072 | "name": "Sebastian Bergmann", 1073 | "email": "sebastian@phpunit.de" 1074 | } 1075 | ], 1076 | "description": "Looks up which function or method a line of code belongs to", 1077 | "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", 1078 | "time": "2017-03-04T06:30:41+00:00" 1079 | }, 1080 | { 1081 | "name": "sebastian/comparator", 1082 | "version": "1.2.4", 1083 | "source": { 1084 | "type": "git", 1085 | "url": "https://github.com/sebastianbergmann/comparator.git", 1086 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" 1087 | }, 1088 | "dist": { 1089 | "type": "zip", 1090 | "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 1091 | "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", 1092 | "shasum": "" 1093 | }, 1094 | "require": { 1095 | "php": ">=5.3.3", 1096 | "sebastian/diff": "~1.2", 1097 | "sebastian/exporter": "~1.2 || ~2.0" 1098 | }, 1099 | "require-dev": { 1100 | "phpunit/phpunit": "~4.4" 1101 | }, 1102 | "type": "library", 1103 | "extra": { 1104 | "branch-alias": { 1105 | "dev-master": "1.2.x-dev" 1106 | } 1107 | }, 1108 | "autoload": { 1109 | "classmap": [ 1110 | "src/" 1111 | ] 1112 | }, 1113 | "notification-url": "https://packagist.org/downloads/", 1114 | "license": [ 1115 | "BSD-3-Clause" 1116 | ], 1117 | "authors": [ 1118 | { 1119 | "name": "Jeff Welch", 1120 | "email": "whatthejeff@gmail.com" 1121 | }, 1122 | { 1123 | "name": "Volker Dusch", 1124 | "email": "github@wallbash.com" 1125 | }, 1126 | { 1127 | "name": "Bernhard Schussek", 1128 | "email": "bschussek@2bepublished.at" 1129 | }, 1130 | { 1131 | "name": "Sebastian Bergmann", 1132 | "email": "sebastian@phpunit.de" 1133 | } 1134 | ], 1135 | "description": "Provides the functionality to compare PHP values for equality", 1136 | "homepage": "http://www.github.com/sebastianbergmann/comparator", 1137 | "keywords": [ 1138 | "comparator", 1139 | "compare", 1140 | "equality" 1141 | ], 1142 | "time": "2017-01-29T09:50:25+00:00" 1143 | }, 1144 | { 1145 | "name": "sebastian/diff", 1146 | "version": "1.4.3", 1147 | "source": { 1148 | "type": "git", 1149 | "url": "https://github.com/sebastianbergmann/diff.git", 1150 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" 1151 | }, 1152 | "dist": { 1153 | "type": "zip", 1154 | "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", 1155 | "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", 1156 | "shasum": "" 1157 | }, 1158 | "require": { 1159 | "php": "^5.3.3 || ^7.0" 1160 | }, 1161 | "require-dev": { 1162 | "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" 1163 | }, 1164 | "type": "library", 1165 | "extra": { 1166 | "branch-alias": { 1167 | "dev-master": "1.4-dev" 1168 | } 1169 | }, 1170 | "autoload": { 1171 | "classmap": [ 1172 | "src/" 1173 | ] 1174 | }, 1175 | "notification-url": "https://packagist.org/downloads/", 1176 | "license": [ 1177 | "BSD-3-Clause" 1178 | ], 1179 | "authors": [ 1180 | { 1181 | "name": "Kore Nordmann", 1182 | "email": "mail@kore-nordmann.de" 1183 | }, 1184 | { 1185 | "name": "Sebastian Bergmann", 1186 | "email": "sebastian@phpunit.de" 1187 | } 1188 | ], 1189 | "description": "Diff implementation", 1190 | "homepage": "https://github.com/sebastianbergmann/diff", 1191 | "keywords": [ 1192 | "diff" 1193 | ], 1194 | "time": "2017-05-22T07:24:03+00:00" 1195 | }, 1196 | { 1197 | "name": "sebastian/environment", 1198 | "version": "2.0.0", 1199 | "source": { 1200 | "type": "git", 1201 | "url": "https://github.com/sebastianbergmann/environment.git", 1202 | "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" 1203 | }, 1204 | "dist": { 1205 | "type": "zip", 1206 | "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", 1207 | "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", 1208 | "shasum": "" 1209 | }, 1210 | "require": { 1211 | "php": "^5.6 || ^7.0" 1212 | }, 1213 | "require-dev": { 1214 | "phpunit/phpunit": "^5.0" 1215 | }, 1216 | "type": "library", 1217 | "extra": { 1218 | "branch-alias": { 1219 | "dev-master": "2.0.x-dev" 1220 | } 1221 | }, 1222 | "autoload": { 1223 | "classmap": [ 1224 | "src/" 1225 | ] 1226 | }, 1227 | "notification-url": "https://packagist.org/downloads/", 1228 | "license": [ 1229 | "BSD-3-Clause" 1230 | ], 1231 | "authors": [ 1232 | { 1233 | "name": "Sebastian Bergmann", 1234 | "email": "sebastian@phpunit.de" 1235 | } 1236 | ], 1237 | "description": "Provides functionality to handle HHVM/PHP environments", 1238 | "homepage": "http://www.github.com/sebastianbergmann/environment", 1239 | "keywords": [ 1240 | "Xdebug", 1241 | "environment", 1242 | "hhvm" 1243 | ], 1244 | "time": "2016-11-26T07:53:53+00:00" 1245 | }, 1246 | { 1247 | "name": "sebastian/exporter", 1248 | "version": "1.2.2", 1249 | "source": { 1250 | "type": "git", 1251 | "url": "https://github.com/sebastianbergmann/exporter.git", 1252 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4" 1253 | }, 1254 | "dist": { 1255 | "type": "zip", 1256 | "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4", 1257 | "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4", 1258 | "shasum": "" 1259 | }, 1260 | "require": { 1261 | "php": ">=5.3.3", 1262 | "sebastian/recursion-context": "~1.0" 1263 | }, 1264 | "require-dev": { 1265 | "ext-mbstring": "*", 1266 | "phpunit/phpunit": "~4.4" 1267 | }, 1268 | "type": "library", 1269 | "extra": { 1270 | "branch-alias": { 1271 | "dev-master": "1.3.x-dev" 1272 | } 1273 | }, 1274 | "autoload": { 1275 | "classmap": [ 1276 | "src/" 1277 | ] 1278 | }, 1279 | "notification-url": "https://packagist.org/downloads/", 1280 | "license": [ 1281 | "BSD-3-Clause" 1282 | ], 1283 | "authors": [ 1284 | { 1285 | "name": "Jeff Welch", 1286 | "email": "whatthejeff@gmail.com" 1287 | }, 1288 | { 1289 | "name": "Volker Dusch", 1290 | "email": "github@wallbash.com" 1291 | }, 1292 | { 1293 | "name": "Bernhard Schussek", 1294 | "email": "bschussek@2bepublished.at" 1295 | }, 1296 | { 1297 | "name": "Sebastian Bergmann", 1298 | "email": "sebastian@phpunit.de" 1299 | }, 1300 | { 1301 | "name": "Adam Harvey", 1302 | "email": "aharvey@php.net" 1303 | } 1304 | ], 1305 | "description": "Provides the functionality to export PHP variables for visualization", 1306 | "homepage": "http://www.github.com/sebastianbergmann/exporter", 1307 | "keywords": [ 1308 | "export", 1309 | "exporter" 1310 | ], 1311 | "time": "2016-06-17T09:04:28+00:00" 1312 | }, 1313 | { 1314 | "name": "sebastian/global-state", 1315 | "version": "1.1.1", 1316 | "source": { 1317 | "type": "git", 1318 | "url": "https://github.com/sebastianbergmann/global-state.git", 1319 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" 1320 | }, 1321 | "dist": { 1322 | "type": "zip", 1323 | "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", 1324 | "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", 1325 | "shasum": "" 1326 | }, 1327 | "require": { 1328 | "php": ">=5.3.3" 1329 | }, 1330 | "require-dev": { 1331 | "phpunit/phpunit": "~4.2" 1332 | }, 1333 | "suggest": { 1334 | "ext-uopz": "*" 1335 | }, 1336 | "type": "library", 1337 | "extra": { 1338 | "branch-alias": { 1339 | "dev-master": "1.0-dev" 1340 | } 1341 | }, 1342 | "autoload": { 1343 | "classmap": [ 1344 | "src/" 1345 | ] 1346 | }, 1347 | "notification-url": "https://packagist.org/downloads/", 1348 | "license": [ 1349 | "BSD-3-Clause" 1350 | ], 1351 | "authors": [ 1352 | { 1353 | "name": "Sebastian Bergmann", 1354 | "email": "sebastian@phpunit.de" 1355 | } 1356 | ], 1357 | "description": "Snapshotting of global state", 1358 | "homepage": "http://www.github.com/sebastianbergmann/global-state", 1359 | "keywords": [ 1360 | "global state" 1361 | ], 1362 | "time": "2015-10-12T03:26:01+00:00" 1363 | }, 1364 | { 1365 | "name": "sebastian/object-enumerator", 1366 | "version": "1.0.0", 1367 | "source": { 1368 | "type": "git", 1369 | "url": "https://github.com/sebastianbergmann/object-enumerator.git", 1370 | "reference": "d4ca2fb70344987502567bc50081c03e6192fb26" 1371 | }, 1372 | "dist": { 1373 | "type": "zip", 1374 | "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/d4ca2fb70344987502567bc50081c03e6192fb26", 1375 | "reference": "d4ca2fb70344987502567bc50081c03e6192fb26", 1376 | "shasum": "" 1377 | }, 1378 | "require": { 1379 | "php": ">=5.6", 1380 | "sebastian/recursion-context": "~1.0" 1381 | }, 1382 | "require-dev": { 1383 | "phpunit/phpunit": "~5" 1384 | }, 1385 | "type": "library", 1386 | "extra": { 1387 | "branch-alias": { 1388 | "dev-master": "1.0.x-dev" 1389 | } 1390 | }, 1391 | "autoload": { 1392 | "classmap": [ 1393 | "src/" 1394 | ] 1395 | }, 1396 | "notification-url": "https://packagist.org/downloads/", 1397 | "license": [ 1398 | "BSD-3-Clause" 1399 | ], 1400 | "authors": [ 1401 | { 1402 | "name": "Sebastian Bergmann", 1403 | "email": "sebastian@phpunit.de" 1404 | } 1405 | ], 1406 | "description": "Traverses array structures and object graphs to enumerate all referenced objects", 1407 | "homepage": "https://github.com/sebastianbergmann/object-enumerator/", 1408 | "time": "2016-01-28T13:25:10+00:00" 1409 | }, 1410 | { 1411 | "name": "sebastian/recursion-context", 1412 | "version": "1.0.5", 1413 | "source": { 1414 | "type": "git", 1415 | "url": "https://github.com/sebastianbergmann/recursion-context.git", 1416 | "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" 1417 | }, 1418 | "dist": { 1419 | "type": "zip", 1420 | "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", 1421 | "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", 1422 | "shasum": "" 1423 | }, 1424 | "require": { 1425 | "php": ">=5.3.3" 1426 | }, 1427 | "require-dev": { 1428 | "phpunit/phpunit": "~4.4" 1429 | }, 1430 | "type": "library", 1431 | "extra": { 1432 | "branch-alias": { 1433 | "dev-master": "1.0.x-dev" 1434 | } 1435 | }, 1436 | "autoload": { 1437 | "classmap": [ 1438 | "src/" 1439 | ] 1440 | }, 1441 | "notification-url": "https://packagist.org/downloads/", 1442 | "license": [ 1443 | "BSD-3-Clause" 1444 | ], 1445 | "authors": [ 1446 | { 1447 | "name": "Jeff Welch", 1448 | "email": "whatthejeff@gmail.com" 1449 | }, 1450 | { 1451 | "name": "Sebastian Bergmann", 1452 | "email": "sebastian@phpunit.de" 1453 | }, 1454 | { 1455 | "name": "Adam Harvey", 1456 | "email": "aharvey@php.net" 1457 | } 1458 | ], 1459 | "description": "Provides functionality to recursively process PHP variables", 1460 | "homepage": "http://www.github.com/sebastianbergmann/recursion-context", 1461 | "time": "2016-10-03T07:41:43+00:00" 1462 | }, 1463 | { 1464 | "name": "sebastian/resource-operations", 1465 | "version": "1.0.0", 1466 | "source": { 1467 | "type": "git", 1468 | "url": "https://github.com/sebastianbergmann/resource-operations.git", 1469 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" 1470 | }, 1471 | "dist": { 1472 | "type": "zip", 1473 | "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1474 | "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", 1475 | "shasum": "" 1476 | }, 1477 | "require": { 1478 | "php": ">=5.6.0" 1479 | }, 1480 | "type": "library", 1481 | "extra": { 1482 | "branch-alias": { 1483 | "dev-master": "1.0.x-dev" 1484 | } 1485 | }, 1486 | "autoload": { 1487 | "classmap": [ 1488 | "src/" 1489 | ] 1490 | }, 1491 | "notification-url": "https://packagist.org/downloads/", 1492 | "license": [ 1493 | "BSD-3-Clause" 1494 | ], 1495 | "authors": [ 1496 | { 1497 | "name": "Sebastian Bergmann", 1498 | "email": "sebastian@phpunit.de" 1499 | } 1500 | ], 1501 | "description": "Provides a list of PHP built-in functions that operate on resources", 1502 | "homepage": "https://www.github.com/sebastianbergmann/resource-operations", 1503 | "time": "2015-07-28T20:34:47+00:00" 1504 | }, 1505 | { 1506 | "name": "sebastian/version", 1507 | "version": "2.0.1", 1508 | "source": { 1509 | "type": "git", 1510 | "url": "https://github.com/sebastianbergmann/version.git", 1511 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" 1512 | }, 1513 | "dist": { 1514 | "type": "zip", 1515 | "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", 1516 | "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", 1517 | "shasum": "" 1518 | }, 1519 | "require": { 1520 | "php": ">=5.6" 1521 | }, 1522 | "type": "library", 1523 | "extra": { 1524 | "branch-alias": { 1525 | "dev-master": "2.0.x-dev" 1526 | } 1527 | }, 1528 | "autoload": { 1529 | "classmap": [ 1530 | "src/" 1531 | ] 1532 | }, 1533 | "notification-url": "https://packagist.org/downloads/", 1534 | "license": [ 1535 | "BSD-3-Clause" 1536 | ], 1537 | "authors": [ 1538 | { 1539 | "name": "Sebastian Bergmann", 1540 | "email": "sebastian@phpunit.de", 1541 | "role": "lead" 1542 | } 1543 | ], 1544 | "description": "Library that helps with managing the version number of Git-hosted PHP projects", 1545 | "homepage": "https://github.com/sebastianbergmann/version", 1546 | "time": "2016-10-03T07:35:21+00:00" 1547 | }, 1548 | { 1549 | "name": "symfony/polyfill-ctype", 1550 | "version": "v1.10.0", 1551 | "source": { 1552 | "type": "git", 1553 | "url": "https://github.com/symfony/polyfill-ctype.git", 1554 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19" 1555 | }, 1556 | "dist": { 1557 | "type": "zip", 1558 | "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e3d826245268269cd66f8326bd8bc066687b4a19", 1559 | "reference": "e3d826245268269cd66f8326bd8bc066687b4a19", 1560 | "shasum": "" 1561 | }, 1562 | "require": { 1563 | "php": ">=5.3.3" 1564 | }, 1565 | "suggest": { 1566 | "ext-ctype": "For best performance" 1567 | }, 1568 | "type": "library", 1569 | "extra": { 1570 | "branch-alias": { 1571 | "dev-master": "1.9-dev" 1572 | } 1573 | }, 1574 | "autoload": { 1575 | "psr-4": { 1576 | "Symfony\\Polyfill\\Ctype\\": "" 1577 | }, 1578 | "files": [ 1579 | "bootstrap.php" 1580 | ] 1581 | }, 1582 | "notification-url": "https://packagist.org/downloads/", 1583 | "license": [ 1584 | "MIT" 1585 | ], 1586 | "authors": [ 1587 | { 1588 | "name": "Symfony Community", 1589 | "homepage": "https://symfony.com/contributors" 1590 | }, 1591 | { 1592 | "name": "Gert de Pagter", 1593 | "email": "BackEndTea@gmail.com" 1594 | } 1595 | ], 1596 | "description": "Symfony polyfill for ctype functions", 1597 | "homepage": "https://symfony.com", 1598 | "keywords": [ 1599 | "compatibility", 1600 | "ctype", 1601 | "polyfill", 1602 | "portable" 1603 | ], 1604 | "time": "2018-08-06T14:22:27+00:00" 1605 | }, 1606 | { 1607 | "name": "symfony/yaml", 1608 | "version": "v3.4.20", 1609 | "source": { 1610 | "type": "git", 1611 | "url": "https://github.com/symfony/yaml.git", 1612 | "reference": "291e13d808bec481eab83f301f7bff3e699ef603" 1613 | }, 1614 | "dist": { 1615 | "type": "zip", 1616 | "url": "https://api.github.com/repos/symfony/yaml/zipball/291e13d808bec481eab83f301f7bff3e699ef603", 1617 | "reference": "291e13d808bec481eab83f301f7bff3e699ef603", 1618 | "shasum": "" 1619 | }, 1620 | "require": { 1621 | "php": "^5.5.9|>=7.0.8", 1622 | "symfony/polyfill-ctype": "~1.8" 1623 | }, 1624 | "conflict": { 1625 | "symfony/console": "<3.4" 1626 | }, 1627 | "require-dev": { 1628 | "symfony/console": "~3.4|~4.0" 1629 | }, 1630 | "suggest": { 1631 | "symfony/console": "For validating YAML files using the lint command" 1632 | }, 1633 | "type": "library", 1634 | "extra": { 1635 | "branch-alias": { 1636 | "dev-master": "3.4-dev" 1637 | } 1638 | }, 1639 | "autoload": { 1640 | "psr-4": { 1641 | "Symfony\\Component\\Yaml\\": "" 1642 | }, 1643 | "exclude-from-classmap": [ 1644 | "/Tests/" 1645 | ] 1646 | }, 1647 | "notification-url": "https://packagist.org/downloads/", 1648 | "license": [ 1649 | "MIT" 1650 | ], 1651 | "authors": [ 1652 | { 1653 | "name": "Fabien Potencier", 1654 | "email": "fabien@symfony.com" 1655 | }, 1656 | { 1657 | "name": "Symfony Community", 1658 | "homepage": "https://symfony.com/contributors" 1659 | } 1660 | ], 1661 | "description": "Symfony Yaml Component", 1662 | "homepage": "https://symfony.com", 1663 | "time": "2018-11-11T19:48:54+00:00" 1664 | }, 1665 | { 1666 | "name": "webmozart/assert", 1667 | "version": "1.3.0", 1668 | "source": { 1669 | "type": "git", 1670 | "url": "https://github.com/webmozart/assert.git", 1671 | "reference": "0df1908962e7a3071564e857d86874dad1ef204a" 1672 | }, 1673 | "dist": { 1674 | "type": "zip", 1675 | "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", 1676 | "reference": "0df1908962e7a3071564e857d86874dad1ef204a", 1677 | "shasum": "" 1678 | }, 1679 | "require": { 1680 | "php": "^5.3.3 || ^7.0" 1681 | }, 1682 | "require-dev": { 1683 | "phpunit/phpunit": "^4.6", 1684 | "sebastian/version": "^1.0.1" 1685 | }, 1686 | "type": "library", 1687 | "extra": { 1688 | "branch-alias": { 1689 | "dev-master": "1.3-dev" 1690 | } 1691 | }, 1692 | "autoload": { 1693 | "psr-4": { 1694 | "Webmozart\\Assert\\": "src/" 1695 | } 1696 | }, 1697 | "notification-url": "https://packagist.org/downloads/", 1698 | "license": [ 1699 | "MIT" 1700 | ], 1701 | "authors": [ 1702 | { 1703 | "name": "Bernhard Schussek", 1704 | "email": "bschussek@gmail.com" 1705 | } 1706 | ], 1707 | "description": "Assertions to validate method input/output with nice error messages.", 1708 | "keywords": [ 1709 | "assert", 1710 | "check", 1711 | "validate" 1712 | ], 1713 | "time": "2018-01-29T19:49:41+00:00" 1714 | } 1715 | ], 1716 | "aliases": [], 1717 | "minimum-stability": "stable", 1718 | "stability-flags": [], 1719 | "prefer-stable": false, 1720 | "prefer-lowest": false, 1721 | "platform": { 1722 | "php": ">=5.4.0" 1723 | }, 1724 | "platform-dev": [] 1725 | } 1726 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gopay/payments-sdk-php", 3 | "description": "GoPay's PHP SDK for Payments REST API", 4 | "keywords": [ 5 | "gopay", 6 | "payments", 7 | "sdk", 8 | "rest", 9 | "api" 10 | ], 11 | "type": "library", 12 | "license": "MIT", 13 | "authors": [ 14 | { 15 | "name": "GoPay", 16 | "homepage": "https://github.com/gopaycommunity/gopay-php-api/contributors" 17 | } 18 | ], 19 | "config": { 20 | "bin-dir": "bin", 21 | "optimize-autoloader": true 22 | }, 23 | "autoload": { 24 | "psr-4": { 25 | "GoPay\\": "src/" 26 | }, 27 | "files": [ 28 | "factory.php" 29 | ], 30 | "classmap": [ 31 | "src/" 32 | ] 33 | }, 34 | "autoload-dev": { 35 | "files": [ 36 | "tests/integration/GivenGoPay.php", 37 | "vendor/hamcrest/hamcrest-php/hamcrest/Hamcrest.php" 38 | ] 39 | }, 40 | "require": { 41 | "php": ">=8.1", 42 | "guzzlehttp/guzzle": "^7.7.0", 43 | "symfony/deprecation-contracts": "^3.3.0" 44 | }, 45 | "require-dev": { 46 | "phpunit/phpunit": "9.3.7", 47 | "hamcrest/hamcrest-php": "*", 48 | "phpspec/prophecy": "~1.0", 49 | "phpspec/prophecy-phpunit": "^2.0" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /examples/create-payment.php: -------------------------------------------------------------------------------- 1 | 'my goid', 13 | 'clientId' => 'my id', 14 | 'clientSecret' => 'my secret', 15 | 'gatewayUrl' => 'https://gw.sandbox.gopay.com/api', 16 | 'language' => Language::CZECH 17 | ]); 18 | 19 | // recurrent payment must have field '' 20 | $recurrentPayment = [ 21 | 'recurrence' => [ 22 | 'recurrence_cycle' => Recurrence::DAILY, 23 | 'recurrence_period' => "7", 24 | 'recurrence_date_to' => '2015-12-31' 25 | ] 26 | ]; 27 | 28 | // pre-authorized payment must have field 'preauthorization' 29 | $preauthorizedPayment = [ 30 | 'preauthorization' => true 31 | ]; 32 | 33 | $response = $gopay->createPayment([ 34 | 'payer' => [ 35 | 'default_payment_instrument' => PaymentInstrument::BANK_ACCOUNT, 36 | 'allowed_payment_instruments' => [PaymentInstrument::BANK_ACCOUNT], 37 | 'default_swift' => BankSwiftCode::FIO_BANKA, 38 | 'allowed_swifts' => [BankSwiftCode::FIO_BANKA, BankSwiftCode::MBANK], 39 | 'contact' => [ 40 | 'first_name' => 'Zbynek', 41 | 'last_name' => 'Zak', 42 | 'email' => 'zbynek.zak@gopay.cz', 43 | 'phone_number' => '+420777456123', 44 | 'city' => 'C.Budejovice', 45 | 'street' => 'Plana 67', 46 | 'postal_code' => '373 01', 47 | 'country_code' => 'CZE', 48 | ], 49 | ], 50 | 'amount' => 150, 51 | 'currency' => Currency::CZECH_CROWNS, 52 | 'order_number' => '001', 53 | 'order_description' => 'pojisteni01', 54 | 'items' => [ 55 | ['name' => 'item01', 'amount' => 50], 56 | ['name' => 'item02', 'amount' => 100], 57 | ], 58 | 'additional_params' => [ 59 | array('name' => 'invoicenumber', 'value' => '2015001003') 60 | ], 61 | 'callback' => [ 62 | 'return_url' => 'http://www.your-url.tld/return', 63 | 'notification_url' => 'http://www.your-url.tld/notify' 64 | ], 65 | 'lang' => Language::CZECH, // if lang is not specified, then default lang is used 66 | ]); 67 | 68 | if ($response->hasSucceed()) { 69 | // response format: https://doc.gopay.com/en/?shell#standard-payment 70 | echo "hooray, API returned {$response}
\n"; 71 | echo "Gateway url: {$response->json['gw_url']}"; 72 | } else { 73 | // errors format: https://doc.gopay.com/en/?shell#http-result-codes 74 | echo "oops, API returned {$response->statusCode}: {$response}"; 75 | } 76 | -------------------------------------------------------------------------------- /examples/eet-payments.php: -------------------------------------------------------------------------------- 1 | 'my goid', 14 | 'clientId' => 'my clientId', 15 | 'clientSecret' => 'my clientSecret', 16 | 'gatewayUrl' => 'https://gw.sandbox.gopay.com/api', 17 | 'language' => Language::CZECH 18 | ]); 19 | 20 | // Create standard payment with eet 21 | $response = $gopay->createPayment([ 22 | 'payer' => [ 23 | 'default_payment_instrument' => PaymentInstrument::BANK_ACCOUNT, 24 | 'allowed_payment_instruments' => [PaymentInstrument::BANK_ACCOUNT], 25 | 'default_swift' => BankSwiftCode::FIO_BANKA, 26 | 'allowed_swifts' => [BankSwiftCode::FIO_BANKA, BankSwiftCode::MBANK], 27 | 'contact' => [ 28 | 'first_name' => 'Zbynek', 29 | 'last_name' => 'Zak', 30 | 'email' => 'test@test.cz', 31 | 'phone_number' => '+420777456123', 32 | 'city' => 'C.Budejovice', 33 | 'street' => 'Plana 67', 34 | 'postal_code' => '373 01', 35 | 'country_code' => 'CZE' 36 | ] 37 | ], 38 | 'amount' => 139951, 39 | 'currency' => Currency::CZECH_CROWNS, 40 | 'order_number' => '001', 41 | 'order_description' => 'obuv', 42 | 'items' => [ 43 | [ 44 | 'type' => 'ITEM', 45 | 'name' => 'obuv', 46 | 'product_url' => 'https://www.eshop.cz/boty/lodicky', 47 | 'ean' => 1234567890123, 48 | 'amount' => 119990, 49 | 'count' => 1, 50 | 'vat_rate' => VatRate::RATE_4 51 | ], 52 | [ 53 | 'type' => PaymentItemType::ITEM, 54 | 'name' => 'oprava podpatku', 55 | 'product_url' => 'https://www.eshop.cz/boty/opravy', 56 | 'ean' => 1234567890189, 57 | 'amount' => 19961, 58 | 'count' => 1, 59 | 'vat_rate' => VatRate::RATE_3 60 | ] 61 | ], 62 | 'eet' => [ 63 | 'celk_trzba' => 139951, 64 | 'zakl_dan1' => 99160, 65 | 'dan1' => 20830, 66 | 'zakl_dan2' => 17358, 67 | 'dan2' => 2603, 68 | 'mena' => Currency::CZECH_CROWNS 69 | ], 70 | 'additional_params' => [[ 71 | 'name' => 'invoicenumber', 72 | 'value' => '2015001003' 73 | ]], 74 | 'callback' => [ 75 | 'return_url' => 'https://www.eshop.cz/return', 76 | 'notification_url' => 'https://www.eshop.cz/notify' 77 | ], 78 | 'lang' => Language::CZECH 79 | ]); 80 | 81 | if ($response->hasSucceed()) { 82 | // response format: https://doc.gopay.com/en/?shell#standard-payment 83 | echo "hooray, API returned {$response}
\n"; 84 | echo "Gateway url: {$response->json['gw_url']}"; 85 | } else { 86 | // errors format: https://doc.gopay.com/en/?shell#http-result-codes 87 | echo "oops, API returned {$response->statusCode}: {$response}"; 88 | } 89 | -------------------------------------------------------------------------------- /examples/js-initialization.md: -------------------------------------------------------------------------------- 1 | # [Initialization using JavaScript](https://help.gopay.com/en/s/ey) 2 | 3 | ## Server-side 4 | 5 | ```php 6 | # /create-payment 7 | $response = $gopay->createPayment([/* define your payment */]); 8 | if ($response->hasSucceed()) { 9 | echo json_encode($response->json); 10 | } else { 11 | http_response_code(400); 12 | } 13 | ``` 14 | 15 | ```php 16 | # /payment-status 17 | $response = $gopay->getStatus($_GET['id']); 18 | if ($response->hasSucceed()) { 19 | echo json_encode($response->json); 20 | } else { 21 | http_response_code(404); 22 | } 23 | ``` 24 | 25 | ##  Client-side 26 | 27 | ```html 28 | urlToEmbedJs() ?> 30 | 31 |
32 | 33 | 34 | 35 |
36 | 37 | 121 | ``` 122 | -------------------------------------------------------------------------------- /examples/status.php: -------------------------------------------------------------------------------- 1 | 'my goid', 10 | 'clientId' => 'my id', 11 | 'clientSecret' => 'my secret', 12 | 'gatewayUrl' => 'https://gw.sandbox.gopay.com/api', 13 | 'scope' => TokenScope::ALL, 14 | 'language' => Language::CZECH 15 | ]); 16 | $response = $gopay->getStatus('payment id'); 17 | 18 | if ($response->hasSucceed()) { 19 | // response format: https://doc.gopay.com/en/?shell#status-of-the-payment 20 | echo "hooray, API returned {$response}
\n"; 21 | } else { 22 | // errors format: https://doc.gopay.com/en/?shell#http-result-codes 23 | echo "oops, API returned {$response->statusCode}: {$response}"; 24 | } 25 | -------------------------------------------------------------------------------- /examples/symfony.md: -------------------------------------------------------------------------------- 1 | 2 | # Symfony integration 3 | 4 | Example integration with basic configuration and 5 | [controller defined as service](http://symfony.com/doc/current/cookbook/controller/service.html). 6 | 7 | ## Step 1: Define parameters, service 8 | 9 | ```yml 10 | parameters: 11 | gopay.config: 12 | goid: my_goid 13 | clientId: my_id 14 | clientSecret: my_secret 15 | gatewayUrl: 'https://gw.sandbox.gopay.com/api' 16 | # optional config 17 | scope: payment-all 18 | language: CS 19 | timeout: 30 20 | 21 | services: 22 | gopay.payments: 23 | class: GoPay\Payments 24 | factory: ["GoPay\Api", payments] 25 | arguments: 26 | - %gopay.config% 27 | ``` 28 | 29 | ## Step 2: Call API in controller 30 | 31 | ``` 32 | services: 33 | appbundle.controller.gopay: 34 | class: AppBundle\Controller\GoPayController 35 | arguments: 36 | - @gopay.payments 37 | ``` 38 | 39 | ```php 40 | 41 | namespace AppBundle\Controller; 42 | 43 | use GoPay\Payments; 44 | use Sensio\Bundle\FrameworkExtraBundle\Configuration as SFW; 45 | use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; 46 | 47 | /** @SFW\Route("/gopay", service="appbundle.controller.gopay") */ 48 | class GoPayController 49 | { 50 | private $payments; 51 | 52 | public function __construct(Payments $p) 53 | { 54 | $this->payments = $p; 55 | } 56 | 57 | /** 58 | * @SFW\Route("/payment") 59 | * @SFW\Template() 60 | */ 61 | public function payAction() 62 | { 63 | $response = $this->payments->createPayment([/* define your payment */]); 64 | if ($response->hasSucceed()) { 65 | return [ 66 | 'gatewayUrl' => $response->json['gw_url'], 67 | 'embedJs' => $this->payments->urlToEmbedJs() 68 | ]; 69 | } else { 70 | throw new NotFoundHttpException((string) $response); 71 | } 72 | } 73 | 74 | /** 75 | * @SFW\Route("/payment/{id}") 76 | * @SFW\Template() 77 | */ 78 | public function statusAction($id) 79 | { 80 | $response = $this->payments->getStatus($id); 81 | if ($response->hasSucceed()) { 82 | return ['payment' => $response->json]; 83 | } else { 84 | throw new NotFoundHttpException((string) $response); 85 | } 86 | } 87 | } 88 | ``` 89 | 90 | ```twig 91 | // src/AppBundle/Resources/views/GoPay/pay.html.twig 92 | 93 | 94 | 95 | Pay 96 | 97 | 98 |
99 | 100 | 101 |
102 | 103 | 104 | ``` 105 | 106 | ## Optional: Register custom cache and logger 107 | 108 | ```yml 109 | services: 110 | gopay.payments: 111 | class: GoPay\Payments 112 | factory: ["GoPay\Api", payments] 113 | arguments: 114 | - %gopay.config% 115 | - cache: @gopay.cache 116 | logger: @gopay.logger 117 | 118 | gopay.cache: 119 | class: GoPay\Token\InMemoryTokenCache 120 | 121 | gopay.logger: 122 | class: GoPay\Http\Log\PrintHttpRequest 123 | ``` 124 | -------------------------------------------------------------------------------- /factory.php: -------------------------------------------------------------------------------- 1 | new Token\InMemoryTokenCache, 10 | 'logger' => new Http\Log\NullLogger 11 | ]; 12 | $browser = new Http\JsonBrowser($services['logger'], $config['timeout']); 13 | $gopay = new GoPay($config, $browser); 14 | $auth = new Token\CachedOAuth(new OAuth2($gopay), $services['cache']); 15 | return new Payments($gopay, $auth); 16 | } 17 | 18 | /** 19 | * @deprecated Supercash payments are no longer supported 20 | * @param array|Config $userConfig 21 | * @param array $userServices 22 | * @return PaymentsSupercash 23 | */ 24 | function paymentsSupercash(array|Config $userConfig, array $userServices = []) 25 | { 26 | $config = Config::parseUserConfig($userConfig); 27 | $services = $userServices + [ 28 | 'cache' => new Token\InMemoryTokenCache, 29 | 'logger' => new Http\Log\NullLogger 30 | ]; 31 | $browser = new Http\JsonBrowser($services['logger'], $config['timeout']); 32 | $gopay = new GoPay($config, $browser); 33 | $auth = new Token\CachedOAuth(new OAuth2($gopay), $services['cache']); 34 | return new PaymentsSupercash($gopay, $auth); 35 | } 36 | 37 | /** Symfony container needs class for factory :( */ 38 | class Api 39 | { 40 | public static function payments(array|Config $config, array $services = []) 41 | { 42 | return payments($config, $services); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /gopay-php-api.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 14 | 15 | 16 | 17 | ./tests/unit/ 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/Auth.php: -------------------------------------------------------------------------------- 1 | TokenScope::ALL, 58 | 'language' => Language::ENGLISH, 59 | 'timeout' => 30 60 | ]; 61 | } 62 | 63 | return $userConfig; 64 | } else { 65 | return $userConfig->toArray(); 66 | } 67 | } 68 | 69 | /** 70 | * @param array $arr 71 | * @return Config 72 | */ 73 | public static function fromArray(array $arr): Config 74 | { 75 | $config = new Config(); 76 | 77 | $config->goid = $arr['goid'] ?? null; 78 | $config->clientId = $arr['clientId'] ?? null; 79 | $config->clientSecret = $arr['clientSecret'] ?? null; 80 | $config->gatewayUrl = $arr['gatewayUrl'] ?? null; 81 | 82 | // Properties with default values are set only if their value is provided 83 | if (isset($arr['scope'])) { 84 | $config->scope = $arr['scope']; 85 | } 86 | if (isset($arr['language'])) { 87 | $config->language = $arr['language']; 88 | } 89 | if (isset($arr['timeout'])) { 90 | $config->timeout = $arr['timeout']; 91 | } 92 | 93 | return $config; 94 | } 95 | 96 | /** 97 | * @return array 98 | */ 99 | public function toArray(): array 100 | { 101 | return [ 102 | 'goid' => $this->goid, 103 | 'clientId' => $this->clientId, 104 | 'clientSecret' => $this->clientSecret, 105 | 'gatewayUrl' => $this->gatewayUrl, 106 | 'scope' => $this->scope, 107 | 'language' => $this->language, 108 | 'timeout' => $this->timeout, 109 | ]; 110 | } 111 | } -------------------------------------------------------------------------------- /src/Definition/Account/StatementGeneratingFormat.php: -------------------------------------------------------------------------------- 1 | config = Config::parseUserConfig($config, false); 26 | $this->browser = $b; 27 | } 28 | 29 | public function getConfig($key) 30 | { 31 | return $this->config[$key]; 32 | } 33 | 34 | public function call($urlPath, $authorization, $method, $contentType = null, $data = null) 35 | { 36 | $r = new Request($this->buildUrl($urlPath)); 37 | $r->method = $method; 38 | $r->headers = $this->buildHeaders($contentType, $authorization); 39 | $r->body = $this->encodeData($contentType, $data); 40 | return $this->browser->send($r); 41 | } 42 | 43 | public function buildUrl($urlPath) 44 | { 45 | $urlBase = rtrim($this->config['gatewayUrl'], '/'); 46 | if (substr($urlBase, -4) !== '/api') { 47 | $urlBase .= '/api'; 48 | } 49 | 50 | return $urlBase . $urlPath; 51 | } 52 | 53 | public function buildEmbedUrl() 54 | { 55 | $urlBase = rtrim($this->config['gatewayUrl'], '/'); 56 | if (substr($urlBase, -4) === '/api') { 57 | $urlBase = substr($urlBase, 0, -4); 58 | } 59 | 60 | return $urlBase . '/gp-gw/js/embed.js'; 61 | } 62 | 63 | 64 | private function encodeData($contentType, $data) 65 | { 66 | if ($data) { 67 | if ($contentType === GoPay::FORM) { 68 | return http_build_query($data, "", '&'); 69 | } 70 | return json_encode($data); 71 | } 72 | return ''; 73 | } 74 | 75 | private function buildHeaders($contentType, $authorization) 76 | { 77 | $customUserAgent = array_key_exists('customUserAgent', $this->config) ? $this->config['customUserAgent'] : null; 78 | if (is_null($contentType)) { 79 | return [ 80 | 'Accept' => 'application/json', 81 | 'Accept-Language' => $this->getAcceptedLanguage(), 82 | 'Authorization' => $authorization, 83 | 'User-Agent' => is_null($customUserAgent) ? self::DEFAULT_USER_AGENT : $customUserAgent 84 | ]; 85 | } else { 86 | return [ 87 | 'Accept' => 'application/json', 88 | 'Accept-Language' => $this->getAcceptedLanguage(), 89 | 'Content-Type' => $contentType, 90 | 'Authorization' => $authorization, 91 | 'User-Agent' => is_null($customUserAgent) ? self::DEFAULT_USER_AGENT : $customUserAgent 92 | ]; 93 | } 94 | } 95 | 96 | private function getAcceptedLanguage() 97 | { 98 | static $czechLike = [Language::CZECH, Language::SLOVAK]; 99 | return in_array($this->getConfig('language'), $czechLike) ? self::LOCALE_CZECH : self::LOCALE_ENGLISH; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/Http/JsonBrowser.php: -------------------------------------------------------------------------------- 1 | logger = $l; 18 | $this->timeout = $timeoutInSeconds; 19 | } 20 | 21 | public function send(Request $r) 22 | { 23 | try { 24 | if (class_exists('\GuzzleHttp\Message\Request')) { 25 | $client = new GuzzleClient(); 26 | $guzzRequest = $client->createRequest($r->method, $r->url); 27 | $guzzRequest->setHeaders($r->headers); 28 | $guzzRequest->setBody(\GuzzleHttp\Stream\Stream::factory($r->body)); 29 | } else { 30 | $client = new GuzzleClient(['timeout' => $this->timeout]); 31 | $guzzRequest = new \GuzzleHttp\Psr7\Request($r->method, $r->url, $r->headers, $r->body); 32 | } 33 | $guzzResponse = $client->send($guzzRequest); 34 | $response = new Response((string)$guzzResponse->getBody()); 35 | $response->statusCode = (string)$guzzResponse->getStatusCode(); 36 | $response->json = json_decode((string)$response, true); 37 | $this->logger->logHttpCommunication($r, $response); 38 | return $response; 39 | } catch (ClientException $e) { 40 | if ($e->hasResponse()) { 41 | $response = new Response($e->getResponse()->getBody()); 42 | $response->json = json_decode($e->getResponse()->getBody(), true); 43 | $response->statusCode = $e->getCode(); 44 | $this->logger->logHttpCommunication($r, $response); 45 | return $response; 46 | } 47 | } catch (\Exception $ex) { 48 | $response = new Response($ex->getMessage()); 49 | $response->statusCode = 500; 50 | $response->json = json_decode("{}", true); 51 | $this->logger->logHttpCommunication($r, $response); 52 | return $response; 53 | } 54 | } 55 | 56 | /** 57 | * @return Logger 58 | */ 59 | public function getLogger(): Logger 60 | { 61 | return $this->logger; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/Http/Log/Logger.php: -------------------------------------------------------------------------------- 1 | method} {$request->url} -> {$response->statusCode}"; 13 | $this->log($msg); 14 | } 15 | 16 | public function log(string $message) 17 | { 18 | echo "$message\n"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Http/Request.php: -------------------------------------------------------------------------------- 1 | url = $url; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Http/Response.php: -------------------------------------------------------------------------------- 1 | rawBody = (string) $rawBody; 17 | } 18 | 19 | public function hasSucceed() 20 | { 21 | return $this->statusCode < 400; 22 | } 23 | 24 | public function __toString() 25 | { 26 | return $this->rawBody; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/OAuth2.php: -------------------------------------------------------------------------------- 1 | gopay = $g; 15 | } 16 | 17 | public function authorize() 18 | { 19 | $credentials = "{$this->gopay->getConfig('clientId')}:{$this->gopay->getConfig('clientSecret')}"; 20 | $response = $this->gopay->call( 21 | '/oauth2/token', 22 | 'Basic ' . base64_encode($credentials), 23 | RequestMethods::POST, 24 | GoPay::FORM, 25 | ['grant_type' => 'client_credentials', 'scope' => $this->gopay->getConfig('scope')] 26 | ); 27 | $t = new AccessToken; 28 | $t->response = $response; 29 | if ($response->hasSucceed()) { 30 | $t->token = $response->json['access_token']; 31 | $expSuffix = ""; 32 | if ($response->json['expires_in'] > 0) { 33 | $expSuffix .= " + {$response->json['expires_in']} seconds"; 34 | } 35 | $t->expirationDate = new \DateTime("now {$expSuffix}"); 36 | } 37 | return $t; 38 | } 39 | 40 | public function getClient() 41 | { 42 | $ids = [ 43 | $this->gopay->getConfig('clientId'), 44 | $this->gopay->getConfig('gatewayUrl'), 45 | $this->gopay->getConfig('scope'), 46 | ]; 47 | return implode('-', $ids); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Payments.php: -------------------------------------------------------------------------------- 1 | gopay = $g; 15 | $this->auth = $a; 16 | } 17 | 18 | public function createPayment(array $rawPayment) 19 | { 20 | $payment = $rawPayment + [ 21 | 'target' => [ 22 | 'type' => 'ACCOUNT', 23 | 'goid' => $this->gopay->getConfig('goid') 24 | ], 25 | 'lang' => $this->gopay->getConfig('language') 26 | ]; 27 | return $this->post('/payments/payment', GoPay::JSON, $payment); 28 | } 29 | 30 | public function getStatus($id) 31 | { 32 | return $this->get("/payments/payment/{$id}"); 33 | } 34 | 35 | /** @see refundPaymentEET */ 36 | public function refundPayment($id, $data) 37 | { 38 | if (is_array($data)) { 39 | return $this->refundPaymentEET($id, $data); 40 | } 41 | return $this->post("/payments/payment/{$id}/refund", GoPay::FORM, ['amount' => $data]); 42 | } 43 | 44 | 45 | public function createRecurrence($id, array $payment) 46 | { 47 | return $this->post("/payments/payment/{$id}/create-recurrence", GoPay::JSON, $payment); 48 | } 49 | 50 | public function voidRecurrence($id) 51 | { 52 | return $this->post("/payments/payment/{$id}/void-recurrence", GoPay::FORM, array()); 53 | } 54 | 55 | public function captureAuthorization($id) 56 | { 57 | return $this->post("/payments/payment/{$id}/capture", GoPay::FORM, array()); 58 | } 59 | 60 | public function captureAuthorizationPartial($id, array $capturePayment) 61 | { 62 | return $this->post("/payments/payment/{$id}/capture", GoPay::JSON, $capturePayment); 63 | } 64 | 65 | public function voidAuthorization($id) 66 | { 67 | return $this->post("/payments/payment/{$id}/void-authorization", GoPay::FORM, array()); 68 | } 69 | 70 | public function getCardDetails($cardId) 71 | { 72 | return $this->get("/payments/cards/{$cardId}"); 73 | } 74 | 75 | public function deleteCard($cardId) 76 | { 77 | return $this->delete("/payments/cards/{$cardId}"); 78 | } 79 | 80 | public function getHistoryRefunds($id) 81 | { 82 | return $this->get("/payments/payment/{$id}/refunds"); 83 | } 84 | 85 | public function getPaymentInstruments($goid, $currency) 86 | { 87 | return $this->get("/eshops/eshop/{$goid}/payment-instruments/{$currency}"); 88 | } 89 | public function getPaymentInstrumentsAll($goid) 90 | { 91 | return $this->get("/eshops/eshop/{$goid}/payment-instruments"); 92 | } 93 | 94 | public function getAccountStatement(array $accountStatement) 95 | { 96 | return $this->post("/accounts/account-statement", GoPay::JSON, $accountStatement); 97 | } 98 | 99 | public function refundPaymentEET($id, array $paymentData) 100 | { 101 | return $this->post("/payments/payment/{$id}/refund", GoPay::JSON, $paymentData); 102 | } 103 | public function getEETReceiptByPaymentId($paymentId) 104 | { 105 | return $this->get("/payments/payment/{$paymentId}/eet-receipts"); 106 | } 107 | 108 | public function findEETReceiptsByFilter(array $filter) 109 | { 110 | return $this->post("/eet-receipts", GoPay::JSON, $filter); 111 | } 112 | 113 | 114 | // prepsat metodu api na metody GET a POST, a metode call se bude predavat parametr METHOD 115 | 116 | /** @return \GoPay\Http\Response */ 117 | public function get($urlPath) 118 | { 119 | $token = $this->auth->authorize(); 120 | if ($token->token) { 121 | return $this->gopay->call( 122 | $urlPath, 123 | "Bearer {$token->token}", 124 | RequestMethods::GET 125 | ); 126 | } 127 | return $token->response; 128 | } 129 | 130 | /** @return \GoPay\Http\Response */ 131 | public function post($urlPath, $contentType, $data = null) 132 | { 133 | $token = $this->auth->authorize(); 134 | if ($token->token) { 135 | return $this->gopay->call( 136 | $urlPath, 137 | "Bearer {$token->token}", 138 | RequestMethods::POST, 139 | $contentType, 140 | $data 141 | ); 142 | } 143 | return $token->response; 144 | } 145 | 146 | /** @return \GoPay\Http\Response */ 147 | public function delete($urlPath) 148 | { 149 | $token = $this->auth->authorize(); 150 | if ($token->token) { 151 | return $this->gopay->call( 152 | $urlPath, 153 | "Bearer {$token->token}", 154 | RequestMethods::DELETE 155 | ); 156 | } 157 | return $token->response; 158 | } 159 | 160 | public function urlToEmbedJs() 161 | { 162 | return $this->gopay->buildEmbedUrl(); 163 | } 164 | 165 | public function getGopay() 166 | { 167 | return $this->gopay; 168 | } 169 | 170 | public function getAuth() 171 | { 172 | return $this->auth; 173 | } 174 | } 175 | -------------------------------------------------------------------------------- /src/Token/AccessToken.php: -------------------------------------------------------------------------------- 1 | token == '' || $this->expirationDate < (new \DateTime); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Token/CachedOAuth.php: -------------------------------------------------------------------------------- 1 | oauth = $auth; 16 | $this->cache = $cache; 17 | } 18 | 19 | public function authorize() 20 | { 21 | $client = $this->oauth->getClient(); 22 | $token = $this->cache->getAccessToken($client); 23 | if (!($token instanceof AccessToken) || $token->isExpired()) { 24 | $token = $this->oauth->authorize(); 25 | $this->cache->setAccessToken($client, $token); 26 | } 27 | return $token; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Token/InMemoryTokenCache.php: -------------------------------------------------------------------------------- 1 | tokens[$client] = $t; 13 | } 14 | 15 | public function getAccessToken($client) 16 | { 17 | return array_key_exists($client, $this->tokens) ? $this->tokens[$client] : null; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Token/TokenCache.php: -------------------------------------------------------------------------------- 1 | gopay = TestUtils::setup(); 32 | } 33 | 34 | public static function createBaseCardTokenPayment() 35 | { 36 | $basePayment = [ 37 | 'payer' => [ 38 | 'allowed_payment_instruments' => [PaymentInstrument::PAYMENT_CARD], 39 | 'default_payment_instrument' => PaymentInstrument::PAYMENT_CARD, 40 | 'contact' => [ 41 | 'first_name' => 'Jarda', 42 | 'last_name' => 'Sokol', 43 | 'email' => 'test-sokol25@test.cz', 44 | ], 45 | ], 46 | 'order_number' => '9876', 47 | 'amount' => 2000, 48 | 'currency' => Currency::CZECH_CROWNS, 49 | 'order_description' => '9876Description', 50 | 'lang' => Language::CZECH, 51 | 'additional_params' => [ 52 | array('name' => 'invoicenumber', 'value' => '2015001003') 53 | ], 54 | 'items' => [ 55 | ['name' => 'item01', 'amount' => 2000, 'count' => 1], 56 | ], 57 | 'callback' => [ 58 | 'return_url' => 'https://eshop123.cz/return', 59 | 'notification_url' => 'https://eshop123.cz/notify' 60 | ], 61 | ]; 62 | 63 | return $basePayment; 64 | } 65 | 66 | public function testPaymentWithCardTokenRequest() 67 | { 68 | $basePayment = self::createBaseCardTokenPayment(); 69 | $basePayment['payer']['request_card_token'] = true; 70 | 71 | $response = $this->gopay->createPayment($basePayment); 72 | $responseBody = $response->json; 73 | 74 | assertNotEmpty($responseBody); 75 | assertArrayNotHasKey('errors', $responseBody); 76 | assertNotNull($responseBody['id']); 77 | 78 | 79 | echo print_r($responseBody, true); 80 | 81 | if ($response->hasSucceed()) { 82 | print_r("Payment ID: " . $responseBody['id'] . "\n"); 83 | print_r("Payment gwUrl: " . $responseBody['gw_url'] . "\n"); 84 | print_r("Payment state: " . $responseBody['state'] . "\n"); 85 | } 86 | } 87 | 88 | 89 | public function testPaymentWithCardToken() 90 | { 91 | $basePayment = self::createBaseCardTokenPayment(); 92 | $basePayment['payer']['allowed_card_token'] = 'X5GMEJIPGhRuIBm/Q5G+D6m0WYnjN70YoLFZhN61UeSu9U0TRrrx0T1Xxvqp2dUEwqBjy62stJFLzkMoRxfeoOfetEnJqotVYntw9BFEp3mbYwkTN7XsAU36MbMkYplwsPmXBeQD9XCYUfjXmn16WQ=='; 93 | 94 | $response = $this->gopay->createPayment($basePayment); 95 | $responseBody = $response->json; 96 | 97 | assertNotEmpty($responseBody); 98 | assertArrayNotHasKey('errors', $responseBody); 99 | assertNotNull($responseBody['id']); 100 | 101 | 102 | echo print_r($responseBody, true); 103 | 104 | if ($response->hasSucceed()) { 105 | print_r("Payment ID: " . $responseBody['id'] . "\n"); 106 | print_r("Payment gwUrl: " . $responseBody['gw_url'] . "\n"); 107 | print_r("Payment state: " . $responseBody['state'] . "\n"); 108 | } 109 | } 110 | 111 | public function testActiveCardDetails() 112 | { 113 | $cardId = 3011475940; 114 | 115 | $response = $this->gopay->getCardDetails($cardId); 116 | $responseBody = $response->json; 117 | 118 | assertNotEmpty($responseBody); 119 | assertArrayNotHasKey('errors', $responseBody); 120 | 121 | assertEquals($responseBody['status'], "ACTIVE"); 122 | 123 | echo print_r($responseBody, true); 124 | 125 | if ($response->hasSucceed()) { 126 | print_r("Card ID: " . $responseBody['card_id'] . "\n"); 127 | print_r("Card status: " . $responseBody['status'] . "\n"); 128 | print_r("Card token: " . $responseBody['card_token'] . "\n"); 129 | print_r("Card fingerprint: " . $responseBody['card_fingerprint'] . "\n"); 130 | } 131 | } 132 | 133 | public function testDeletedCardDetails() 134 | { 135 | $cardId = 3011480505; 136 | 137 | $response = $this->gopay->getCardDetails($cardId); 138 | $responseBody = $response->json; 139 | 140 | assertNotEmpty($responseBody); 141 | assertArrayNotHasKey('errors', $responseBody); 142 | 143 | assertEquals($responseBody['status'], "DELETED"); 144 | 145 | echo print_r($responseBody, true); 146 | 147 | if ($response->hasSucceed()) { 148 | print_r("Card ID: " . $responseBody['card_id'] . "\n"); 149 | print_r("Card status: " . $responseBody['status'] . "\n"); 150 | } 151 | } 152 | 153 | public function testDeleteCardToken() 154 | { 155 | $cardId = 3011480505; 156 | 157 | $response = $this->gopay->deleteCard($cardId); 158 | assertTrue($response->hasSucceed()); 159 | assertEquals($response->statusCode, 204); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /tests/integration/CommonMethodTest.php: -------------------------------------------------------------------------------- 1 | gopay = TestUtils::setup(); 31 | } 32 | 33 | public function testPaymentStatus() 34 | { 35 | $paymentId = 3178283550; 36 | 37 | $response = $this->gopay->getStatus($paymentId); 38 | $responseBody = $response->json; 39 | 40 | assertNotEmpty($responseBody); 41 | assertArrayNotHasKey('errors', $responseBody); 42 | 43 | assertNotNull($responseBody['id']); 44 | echo print_r($responseBody, true); 45 | 46 | if ($response->hasSucceed()) { 47 | print_r("Payment ID: " . $responseBody['id'] . "\n"); 48 | print_r("Payment gwUrl: " . $responseBody['gw_url'] . "\n"); 49 | print_r("Payment state: " . $responseBody['state'] . "\n"); 50 | } 51 | } 52 | 53 | public function testGetPaymentInstruments() 54 | { 55 | $response = $this->gopay->getPaymentInstruments(TestUtils::GO_ID, Currency::CZECH_CROWNS); 56 | $responseBody = $response->json; 57 | 58 | assertNotEmpty($responseBody); 59 | assertArrayNotHasKey('errors', $responseBody); 60 | assertArrayHasKey('enabledPaymentInstruments', $responseBody); 61 | 62 | echo print_r($responseBody, true); 63 | } 64 | 65 | public function testGetAccountStatement() 66 | { 67 | $accountStatement = [ 68 | 'date_from' => '2023-01-01', 69 | 'date_to' => '2023-02-27', 70 | 'goid' => TestUtils::GO_ID, 71 | 'currency' => Currency::CZECH_CROWNS, 72 | 'format' => StatementGeneratingFormat::CSV_A, 73 | ]; 74 | 75 | $response = $this->gopay->getAccountStatement($accountStatement); 76 | 77 | assertTrue($response->hasSucceed()); 78 | assertNotEmpty($response); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /tests/integration/CreatePaymentTest.php: -------------------------------------------------------------------------------- 1 | gopay = TestUtils::setup(); 33 | } 34 | 35 | public static function createBasePayment() 36 | { 37 | $basePayment = [ 38 | 'payer' => [ 39 | 'allowed_payment_instruments' => [ 40 | PaymentInstrument::BANK_ACCOUNT, 41 | PaymentInstrument::PAYMENT_CARD, 42 | # PaymentInstrument::TWISTO, 43 | # PaymentInstrument::SKIPPAY 44 | ], 45 | # 'allowed_bnpl_types' => [ 46 | # BnplType::DEFERRED_PAYMENT, 47 | # BnplType::PAY_IN_THREE 48 | # ], 49 | # 'default_bnpl_type' => BnplType::DEFERRED_PAYMENT, 50 | # 'default_payment_instrument' => PaymentInstrument::TWISTO 51 | 'allowed_swifts' => [BankSwiftCode::RAIFFEISENBANK, BankSwiftCode::CESKA_SPORITELNA], 52 | # 'default_swift' => BankSwiftCode::FIO_BANKA, 53 | # 'default_payment_instrument' => PaymentInstrument::BANK_ACCOUNT, 54 | 'contact' => [ 55 | 'email' => 'test.test@gopay.cz', 56 | ], 57 | ], 58 | 'order_number' => '9876', 59 | 'amount' => 2300, 60 | 'currency' => Currency::CZECH_CROWNS, 61 | 'order_description' => '9876Description', 62 | 'lang' => Language::CZECH, 63 | 'additional_params' => [ 64 | array('name' => 'invoicenumber', 'value' => '2015001003') 65 | ], 66 | 'items' => [ 67 | ['name' => 'item01', 'amount' => 2300, 'count' => 1], 68 | ], 69 | 'callback' => [ 70 | 'return_url' => 'https://eshop123.cz/return', 71 | 'notification_url' => 'https://eshop123.cz/notify' 72 | ], 73 | ]; 74 | 75 | return $basePayment; 76 | } 77 | 78 | public function testCreatePayment() 79 | { 80 | $basePayment = self::createBasePayment(); 81 | 82 | $response = $this->gopay->createPayment($basePayment); 83 | $responseBody = $response->json; 84 | 85 | assertNotEmpty($responseBody); 86 | assertArrayNotHasKey('errors', $responseBody); 87 | assertNotNull($responseBody['id']); 88 | 89 | echo print_r($responseBody, true); 90 | 91 | if ($response->hasSucceed()) { 92 | print_r("Payment ID: " . $responseBody['id'] . "\n"); 93 | print_r("Payment gwUrl: " . $responseBody['gw_url'] . "\n"); 94 | print_r("Payment state: " . $responseBody['state'] . "\n"); 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /tests/integration/EETTest.php: -------------------------------------------------------------------------------- 1 | gopay = TestUtils::setupEET(); 32 | } 33 | 34 | private function createBaseEETPayment() 35 | { 36 | $baseEETPayment = [ 37 | 'payer' => [ 38 | 'allowed_payment_instruments' => [ 39 | PaymentInstrument::BANK_ACCOUNT, 40 | PaymentInstrument::PAYMENT_CARD 41 | ], 42 | 'allowed_swifts' => [BankSwiftCode::RAIFFEISENBANK, BankSwiftCode::CESKA_SPORITELNA], 43 | //'default_swift' => BankSwiftCode::FIO_BANKA, 44 | //'default_payment_instrument' => PaymentInstrument::BANK_ACCOUNT, 45 | 'contact' => [ 46 | 'email' => 'test.test@gopay.cz', 47 | ], 48 | ], 49 | 'order_number' => 'EET9876', 50 | 'amount' => 139950, 51 | 'currency' => Currency::CZECH_CROWNS, 52 | 'order_description' => 'EET9876Description', 53 | 'lang' => Language::CZECH, 54 | 'additional_params' => [ 55 | array('name' => 'invoicenumber', 'value' => '2015001003') 56 | ], 57 | 'items' => [ 58 | [ 59 | 'name' => 'Pocitac Item1', 'amount' => '119990', 'count' => '1', 'vat_rate' => 21, 60 | 'type' => PaymentItemType::ITEM, 'ean' => '1234567890123', 61 | 'product_url' => 'https://www.eshop123.cz/pocitac' 62 | ], 63 | [ 64 | 'name' => 'Oprava Item2', 'amount' => '19960', 'count' => '1', 'vat_rate' => 15, 65 | 'type' => PaymentItemType::ITEM, 'ean' => '1234567890189', 66 | 'product_url' => 'https://www.eshop123.cz/pocitac/oprava' 67 | ], 68 | ], 69 | 'callback' => [ 70 | 'return_url' => 'https://eshop123.cz/return', 71 | 'notification_url' => 'https://eshop123.cz/notify' 72 | ], 73 | 'eet' => [ 74 | 'celk_trzba' => 139950, 75 | 'zakl_dan1' => 99165, 76 | 'dan1' => 20825, 77 | 'zakl_dan2' => 17357, 78 | 'dan2' => 2603, 79 | 'mena' => Currency::CZECH_CROWNS 80 | ] 81 | ]; 82 | 83 | return $baseEETPayment; 84 | } 85 | 86 | private function createEETPaymentObject($baseEETPayment) 87 | { 88 | $payment = $this->gopay->createPayment($baseEETPayment); 89 | 90 | assertNotEmpty($payment->json); 91 | assertNotNull($payment->json['id']); 92 | 93 | echo print_r($payment->json, true); 94 | $st = json_encode($payment->json); 95 | 96 | if (strpos($st, 'error_code') === false) { 97 | print_r("Payment ID: " . $payment->json['id'] . "\n"); 98 | print_r("Payment gwUrl: " . $payment->json['gw_url'] . "\n"); 99 | print_r("Payment state: " . $payment->json['state'] . "\n"); 100 | } 101 | 102 | return $payment; 103 | } 104 | 105 | public function testCreateEETPayment() 106 | { 107 | $baseEETPayment = $this->createBaseEETPayment(); 108 | $payment = $this->createEETPaymentObject($baseEETPayment); 109 | assertNotEmpty($payment->json); 110 | assertNotNull($payment->json['id']); 111 | } 112 | 113 | public function testCreateRecurrentEETPayment() 114 | { 115 | $baseEETPayment = $this->createBaseEETPayment(); 116 | 117 | $baseEETPayment['recurrence'] = [ 118 | 'recurrence_cycle' => Recurrence::WEEKLY, 119 | 'recurrence_period' => "1", 120 | 'recurrence_date_to' => '2100-04-01' 121 | ]; 122 | 123 | // $baseEETPayment['recurrence'] = [ 124 | // 'recurrence_cycle' => Recurrence::ON_DEMAND, 125 | // 'recurrence_date_to' => '2018-04-01' 126 | // ]; 127 | 128 | $payment = $this->createEETPaymentObject($baseEETPayment); 129 | assertNotEmpty($payment->json); 130 | assertNotNull($payment->json['id']); 131 | $st = json_encode($payment->json); 132 | if (strpos($st, 'error_code') === false) { 133 | print_r("Recurrence: "); 134 | echo print_r($payment->json['recurrence'], true); 135 | } 136 | } 137 | 138 | public function testNextOnDemandEET() 139 | { 140 | $nextEETPayment = [ 141 | 'amount' => 2000, 142 | 'currency' => Currency::CZECH_CROWNS, 143 | 'order_number' => 'EETOnDemand9876', 144 | 'order_description' => 'EETOnDemand9876Description', 145 | 'items' => [ 146 | [ 147 | 'name' => 'OnDemand Prodlouzena zaruka', 'amount' => '2000', 'count' => '1', 148 | 'vat_rate' => 21, 'type' => PaymentItemType::ITEM, 149 | 'ean' => '1234567890123', 150 | 'product_url' => 'https://www.eshop123.cz/pocitac/prodlouzena_zaruka' 151 | ], 152 | ], 153 | 'eet' => [ 154 | 'celk_trzba' => 2000, 155 | 'zakl_dan1' => 1580, 156 | 'dan1' => 420, 157 | 'mena' => Currency::CZECH_CROWNS 158 | ] 159 | ]; 160 | 161 | $EETOnDemandPayment = $this->gopay->createRecurrence(3049604610, $nextEETPayment); 162 | assertNotEmpty($EETOnDemandPayment->json); 163 | echo print_r($EETOnDemandPayment->json, true); 164 | $st = json_encode($EETOnDemandPayment->json); 165 | 166 | if (strpos($st, 'error_code') === false) { 167 | print_r("Payment ID: " . $EETOnDemandPayment->json['id'] . "\n"); 168 | print_r("Payment gwUrl: " . $EETOnDemandPayment->json['gw_url'] . "\n"); 169 | print_r("Payment state: " . $EETOnDemandPayment->json['state'] . "\n"); 170 | } 171 | } 172 | 173 | public function testEETPaymentStatus() 174 | { 175 | $EETPaymentId = 3049604714; 176 | $response = $this->gopay->getStatus($EETPaymentId); 177 | assertNotEmpty($response->json); 178 | assertNotNull($response->json['id']); 179 | echo print_r($response->json, true); 180 | $st = json_encode($response->json); 181 | 182 | if (strpos($st, 'error_code') === false) { 183 | print_r("Payment ID: " . $response->json['id'] . "\n"); 184 | print_r("Payment gwUrl: " . $response->json['gw_url'] . "\n"); 185 | print_r("Payment state: " . $response->json['state'] . "\n"); 186 | } 187 | } 188 | 189 | public function tEETPaymentRefund() 190 | { 191 | $refundObject = [ 192 | 'amount' => 139950, 193 | 'items' => [ 194 | [ 195 | 'name' => 'Pocitac Item1', 'amount' => '119990', 'count' => '1', 'vat_rate' => 21, 196 | 'type' => PaymentItemType::ITEM, 'ean' => '1234567890123', 197 | 'product_url' => 'https://www.eshop123.cz/pocitac' 198 | ], 199 | [ 200 | 'name' => 'Oprava Item2', 'amount' => '19960', 'count' => '1', 'vat_rate' => 15, 201 | 'type' => PaymentItemType::ITEM, 'ean' => '1234567890189', 202 | 'product_url' => 'https://www.eshop123.cz/pocitac/oprava' 203 | ], 204 | ], 205 | 'eet' => [ 206 | 'celk_trzba' => 139950, 207 | 'zakl_dan1' => 99165, 208 | 'dan1' => 20825, 209 | 'zakl_dan2' => 17357, 210 | 'dan2' => 2603, 211 | 'mena' => Currency::CZECH_CROWNS 212 | ] 213 | ]; 214 | 215 | $response = $this->gopay->refundPayment(3049604714, $refundObject); 216 | 217 | echo print_r($response->json, true); 218 | } 219 | 220 | public function testEETReceiptFindByFilter() 221 | { 222 | $receiptFilter = [ 223 | 'date_from' => '2017-03-02', 224 | 'date_to' => '2017-04-02', 225 | 'id_provozovny' => 11 226 | ]; 227 | 228 | $receipts = $this->gopay->findEETReceiptsByFilter($receiptFilter); 229 | assertNotEmpty($receipts->json); 230 | echo print_r($receipts->json, true); 231 | } 232 | 233 | public function testEETReceiptFindByPaymentId() 234 | { 235 | $receipt = $this->gopay->getEETReceiptByPaymentId(3048429735); 236 | assertNotEmpty($receipt->json); 237 | echo print_r($receipt->json, true); 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /tests/integration/GivenGoPay.php: -------------------------------------------------------------------------------- 1 | getenv('goid'), 20 | 'clientId' => getenv('clientId'), 21 | 'clientSecret' => getenv('clientSecret'), 22 | 'gatewayUrl' => 'https://gw.sandbox.gopay.com/api', 23 | 'scope' => TokenScope::ALL, 24 | 'language' => Language::CZECH 25 | ]; 26 | $services = [ 27 | 'logger' => new Http\Log\PrintHttpRequest 28 | ]; 29 | $this->gopay = payments($config, $services); 30 | } 31 | 32 | protected function whenCustomerCalls() 33 | { 34 | $params = func_get_args(); 35 | $method = array_shift($params); 36 | $this->response = call_user_func_array([$this->gopay, $method], $params); 37 | } 38 | 39 | protected function apiShouldReturn($field, $assert) 40 | { 41 | assertThat($this->response->hasSucceed(), is(true)); 42 | assertThat($this->response->statusCode, is(200)); 43 | assertThat($this->response->json[$field], $assert); 44 | } 45 | 46 | protected function apiShouldReturnError($statusCode, $error) 47 | { 48 | assertThat($this->response->hasSucceed(), is(false)); 49 | assertThat($this->response->statusCode, is($statusCode)); 50 | assertThat($this->response->json['errors'][0], identicalTo($error)); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tests/integration/OnDemandPaymentTest.php: -------------------------------------------------------------------------------- 1 | gopay = TestUtils::setup(); 32 | } 33 | 34 | public function testCreateOnDemandPayment() 35 | { 36 | $basePayment = CreatePaymentTest::createBasePayment(); 37 | 38 | $basePayment['recurrence'] = [ 39 | 'recurrence_cycle' => Recurrence::ON_DEMAND, 40 | 'recurrence_date_to' => '2100-04-01' 41 | ]; 42 | 43 | $response = $this->gopay->createPayment($basePayment); 44 | $responseBody = $response->json; 45 | 46 | assertNotEmpty($responseBody); 47 | assertArrayNotHasKey('errors', $responseBody); 48 | 49 | assertNotNull($responseBody['id']); 50 | echo print_r($responseBody, true); 51 | 52 | if ($response->hasSucceed()) { 53 | print_r("OnDemand Payment ID: " . $responseBody['id'] . "\n"); 54 | print_r("OnDemand Payment gwUrl: " . $responseBody['gw_url'] . "\n"); 55 | print_r("OnDemand Payment state: " . $responseBody['state'] . "\n"); 56 | print_r("Recurrence: "); 57 | echo print_r($responseBody['recurrence'], true); 58 | } 59 | } 60 | 61 | 62 | public function testCreateNextOnDemandPayment() 63 | { 64 | $nextPayment = [ 65 | 'amount' => 4000, 66 | 'currency' => Currency::CZECH_CROWNS, 67 | 'order_number' => 'OnDemand9876', 68 | 'order_description' => 'OnDemand9876Description', 69 | 'items' => [ 70 | ['name' => 'item01', 'amount' => 2000, 'count' => 1], 71 | ], 72 | ]; 73 | 74 | $response = $this->gopay->createRecurrence(3252157272, $nextPayment); 75 | $responseBody = $response->json; 76 | 77 | assertNotEmpty($responseBody); 78 | 79 | assertArrayHasKey("errors", $responseBody); 80 | $message = $responseBody['errors'][0]['error_name']; 81 | assertEquals($message, 'PAYMENT_RECURRENCE_STOPPED'); 82 | 83 | echo print_r($responseBody, true); 84 | 85 | if ($response->hasSucceed()) { 86 | print_r("OnDemand Payment ID: " . $responseBody['id'] . "\n"); 87 | print_r("OnDemand Payment gwUrl: " . $responseBody['gw_url'] . "\n"); 88 | print_r("OnDemand Payment state: " . $responseBody['state'] . "\n"); 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /tests/integration/PreAuthorizationTest.php: -------------------------------------------------------------------------------- 1 | gopay = TestUtils::setup(); 30 | } 31 | 32 | public function testCreatePreAuthorizedPayment() 33 | { 34 | $basePayment = CreatePaymentTest::createBasePayment(); 35 | 36 | $basePayment['preauthorization'] = true; 37 | 38 | $response = $this->gopay->createPayment($basePayment); 39 | $responseBody = $response->json; 40 | 41 | assertNotEmpty($responseBody); 42 | assertArrayNotHasKey('errors', $responseBody); 43 | 44 | assertNotNull($responseBody['id']); 45 | echo print_r($responseBody, true); 46 | $st = json_encode($responseBody); 47 | 48 | if ($response->hasSucceed()) { 49 | print_r("Payment ID: " . $responseBody['id'] . "\n"); 50 | print_r("Payment gwUrl: " . $responseBody['gw_url'] . "\n"); 51 | print_r("Payment state: " . $responseBody['state'] . "\n"); 52 | print_r("PreAuthorization: "); 53 | echo print_r($responseBody['preauthorization'], true); 54 | } 55 | } 56 | 57 | /** 58 | * returns an error, the preauthorized payment id '3049602803' has been already processed or cancelled 59 | */ 60 | public function testVoidAuthorization() 61 | { 62 | $authorizedPaymentId = 3192064499; 63 | 64 | $response = $this->gopay->voidAuthorization($authorizedPaymentId); 65 | $responseBody = $response->json; 66 | 67 | assertNotEmpty($responseBody); 68 | 69 | assertArrayHasKey("errors", $responseBody); 70 | $message = $responseBody['errors'][0]['error_name']; 71 | assertEquals($message, 'PAYMENT_AUTH_VOID_FAILED'); 72 | 73 | echo print_r($responseBody, true); 74 | } 75 | 76 | /** 77 | * returns an error, the preauthorized payment id '3049602803' has been already processed or cancelled 78 | */ 79 | public function testCapturePayment() 80 | { 81 | $authorizedPaymentId = 3192064499; 82 | 83 | $response = $this->gopay->captureAuthorization($authorizedPaymentId); 84 | $responseBody = $response->json; 85 | 86 | assertNotEmpty($responseBody); 87 | 88 | assertArrayHasKey("errors", $responseBody); 89 | $message = $responseBody['errors'][0]['error_name']; 90 | assertEquals($message, 'PAYMENT_CAPTURE_DONE'); 91 | 92 | echo print_r($responseBody, true); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /tests/integration/RecurrentPaymentTest.php: -------------------------------------------------------------------------------- 1 | gopay = TestUtils::setup(); 31 | } 32 | 33 | public function testCreateRecurrentPayment() 34 | { 35 | $basePayment = CreatePaymentTest::createBasePayment(); 36 | 37 | $basePayment['recurrence'] = [ 38 | 'recurrence_cycle' => Recurrence::WEEKLY, 39 | 'recurrence_period' => "1", 40 | 'recurrence_date_to' => '2100-04-01' 41 | ]; 42 | 43 | $response = $this->gopay->createPayment($basePayment); 44 | $responseBody = $response->json; 45 | 46 | assertNotEmpty($responseBody); 47 | assertArrayNotHasKey('errors', $responseBody); 48 | 49 | assertNotNull($responseBody['id']); 50 | echo print_r($response->json, true); 51 | 52 | if ($response->hasSucceed()) { 53 | print_r("Payment ID: " . $responseBody['id'] . "\n"); 54 | print_r("Payment gwUrl: " . $responseBody['gw_url'] . "\n"); 55 | print_r("Payment state: " . $responseBody['state'] . "\n"); 56 | print_r("Recurrence: "); 57 | echo print_r($responseBody['recurrence'], true); 58 | } 59 | } 60 | 61 | /* Returns an error, as the recurrence for the payment id '3049603544' has been already stopped. */ 62 | public function testVoidRecurrence() 63 | { 64 | $authorizedPaymentId = 3252157272; 65 | 66 | $response = $this->gopay->voidRecurrence($authorizedPaymentId); 67 | $responseBody = $response->json; 68 | 69 | assertNotEmpty($responseBody); 70 | 71 | assertArrayHasKey("errors", $responseBody); 72 | $message = $responseBody['errors'][0]['error_name']; 73 | assertEquals($message, 'PAYMENT_RECURRENCE_STOPPED'); 74 | 75 | echo print_r($responseBody, true); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/integration/RefundTest.php: -------------------------------------------------------------------------------- 1 | gopay = TestUtils::setup(); 27 | } 28 | 29 | /** This test will always return an error, as the payment with id '3049604064' has been already refunded */ 30 | public function testRefundPayment() 31 | { 32 | $paymentId = 3178283550; 33 | 34 | $response = $this->gopay->refundPayment($paymentId, 2300); 35 | $responseBody = $response->json; 36 | 37 | assertNotEmpty($responseBody); 38 | 39 | assertArrayHasKey('errors', $responseBody); 40 | $message = $responseBody['errors'][0]['error_name']; 41 | assertEquals($message, 'PAYMENT_REFUND_NOT_SUPPORTED'); 42 | 43 | echo print_r($response->json, true); 44 | } 45 | 46 | public function testHistoryOfRefunds() 47 | { 48 | { 49 | $cardId = 3178283550; 50 | 51 | $response = $this->gopay->getHistoryRefunds($cardId); 52 | $responseBody = $response->json; 53 | 54 | echo print_r($responseBody, true); 55 | 56 | assertNotEmpty($responseBody); 57 | assertArrayNotHasKey('errors', $responseBody); 58 | 59 | echo print_r($responseBody, true); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /tests/integration/TestUtils.php: -------------------------------------------------------------------------------- 1 | self::GO_ID, 23 | 'clientId' => self::CLIENT_ID, 24 | 'clientSecret' => self::CLIENT_SECRET, 25 | 'gatewayUrl' => 'https://gw.sandbox.gopay.com/api', 26 | 'language' => Language::CZECH 27 | ]); 28 | return $gopay; 29 | } 30 | 31 | public static function setupEET() 32 | { 33 | $gopay = payments([ 34 | 'goid' => self::GO_ID_EET, 35 | 'clientId' => self::CLIENT_ID_EET, 36 | 'clientSecret' => self::CLIENT_SECRET_EET, 37 | 'gatewayUrl' => 'https://gw.sandbox.gopay.com/api', 38 | 'language' => Language::CZECH 39 | ]); 40 | return $gopay; 41 | } 42 | } 43 | --------------------------------------------------------------------------------