diff --git a/.gitignore b/.gitignore
index 5657f6e..4bf6bca 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
-vendor
\ No newline at end of file
+vendor
+build/artifacts
+phpunit.xml
\ No newline at end of file
diff --git a/.php_cs b/.php_cs
new file mode 100644
index 0000000..e071a31
--- /dev/null
+++ b/.php_cs
@@ -0,0 +1,12 @@
+in(__DIR__)
+ ->exclude('build/artifacts')
+ ->exclude('vendor')
+;
+
+return Symfony\CS\Config\Config::create()
+ ->fixers(array('-psr0', 'symfony', 'long_array_syntax', '-phpdoc_separation'))
+ ->finder($finder)
+ ;
\ No newline at end of file
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
deleted file mode 100644
index 1468b15..0000000
--- a/.scrutinizer.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-tools:
- external_code_coverage: true
- php_mess_detector: true
- php_cs_fixer:
- config:
- level: psr2
- php_analyzer:
- config:
- parameter_reference_check: { enabled: false }
- checkstyle: { enabled: false, no_trailing_whitespace: true, naming: { enabled: true, local_variable: '^[a-z][a-zA-Z0-9]*$', abstract_class_name: ^Abstract|Factory$, utility_class_name: 'Utils?$', constant_name: '^[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*$', property_name: '^[a-z][a-zA-Z0-9]*$', method_name: '^(?:[a-z]|__)[a-zA-Z0-9]*$', parameter_name: '^[a-z][a-zA-Z0-9]*$', interface_name: '^[A-Z][a-zA-Z0-9]*Interface$', type_name: '^[A-Z][a-zA-Z0-9]*$', exception_name: '^[A-Z][a-zA-Z0-9]*Exception$', isser_method_name: '^(?:is|has|should|may|supports)' } }
- unreachable_code: { enabled: false }
- check_access_control: { enabled: false }
- typo_checks: { enabled: false }
- check_variables: { enabled: false }
- check_calls: { enabled: true, too_many_arguments: true, missing_argument: true, argument_type_checks: lenient }
- suspicious_code: { enabled: false, overriding_parameter: false, overriding_closure_use: false, parameter_closure_use_conflict: false, parameter_multiple_times: false, non_existent_class_in_instanceof_check: false, non_existent_class_in_catch_clause: false, assignment_of_null_return: false, non_commented_switch_fallthrough: false, non_commented_empty_catch_block: false, overriding_private_members: false, use_statement_alias_conflict: false, precedence_in_condition_assignment: false }
- dead_assignments: { enabled: false }
- verify_php_doc_comments: { enabled: false, parameters: false, return: false, suggest_more_specific_types: false, ask_for_return_if_not_inferrable: false, ask_for_param_type_annotation: false }
- loops_must_use_braces: { enabled: false }
- check_usage_context: { enabled: true, method_call_on_non_object: null, foreach: { value_as_reference: true, traversable: true }, missing_argument: null, argument_type_checks: null }
- simplify_boolean_return: { enabled: false }
- phpunit_checks: { enabled: false }
- reflection_checks: { enabled: false }
- precedence_checks: { enabled: true, assignment_in_condition: true, comparison_of_bit_result: true }
- basic_semantic_checks: { enabled: false }
- unused_code: { enabled: false }
- deprecation_checks: { enabled: false }
- useless_function_calls: { enabled: false }
- metrics_lack_of_cohesion_methods: { enabled: false }
- metrics_coupling: { enabled: true, stable_code: { namespace_prefixes: { }, classes: { } } }
- doctrine_parameter_binding: { enabled: false }
- doctrine_entity_manager_injection: { enabled: false }
- symfony_request_injection: { enabled: false }
- doc_comment_fixes: { enabled: false }
- reflection_fixes: { enabled: false }
- use_statement_fixes: { enabled: true, remove_unused: true, preserve_multiple: false, order_alphabetically: false }
- php_code_sniffer: true
- sensiolabs_security_checker: true
- php_cpd: true
- php_loc: true
- php_pdepend: true
- php_hhvm: true
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index d02c2f2..5c0af31 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,20 +1,31 @@
language: php
php:
- - 5.3.3
- 5.3
- 5.4
- 5.5
- 5.6
+ - 7.0
+ - nightly
- hhvm
-before_script:
- - COMPOSER_ROOT_VERSION=dev-master composer --prefer-source --dev install
+sudo: false
+
+env:
+ - COMPOSER_OPTS=""
+ - COMPOSER_OPTS="--prefer-lowest"
+
+matrix:
+ allow_failures:
+ - php: nightly
+ - php: 7
+
+install:
+ - travis_retry composer update $COMPOSER_OPTS --no-interaction --prefer-source
script:
- - phpunit --colors --coverage-clover=coverage.clover
- - if [ "`phpenv version-name`" = "5.5" ]; then wget https://scrutinizer-ci.com/ocular.phar; fi
- - if [ "`phpenv version-name`" = "5.5" ]; then php ocular.phar code-coverage:upload --format=php-clover coverage.clover; fi
+ - phpunit --colors --verbose --exclude-group webhook
+ - if [[ "`phpenv version-name`" != "5.3" && "`phpenv version-name`" != "hhvm" ]]; then phpunit --colors --verbose --group Webhook; fi
notifications:
- slack: xsolla:btcuaeuOi3LBjHaV2Xrrb39U
\ No newline at end of file
+ slack: xsolla:V74WgCQlV6kas6X9SNQKl5R1
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d683aa4..f83be4e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,22 +1,35 @@
-# CHANGELOG
+# Change Log
+All notable changes to this project will be documented in this file.
+This project adheres to [Semantic Versioning](http://semver.org/).
-## 1.1.1 (2014-08-05)
+## [Unreleased](https://github.com/xsolla/xsolla-sdk-php/compare/v2.0.0-BETA1...master)
+
+## [v2.0.0-BETA1](https://github.com/xsolla/xsolla-sdk-php/compare/v1.1.1...v2.0.0-BETA1)
+### Added
+* Simplified `XsollaClient` and `TokenRequest` methods for obtaining [Payment UI token](http://developers.xsolla.com/api.html#payment-ui)
+* `WebhookServer` for receiving [notifications from Xsolla](http://developers.xsolla.com/api.html#notifications)
+* [All API methods](http://developers.xsolla.com/api.html) available through `XsollaClient`
+
+### Removed
+* Removed all deprecated functionality from [previous API version](http://xsolla.github.io/en/)
+
+## [v1.1.1](https://github.com/xsolla/xsolla-sdk-php/compare/v1.1.0...v1.1.1) - 2014-08-05
* add payment_amount, payment_currency to default locked parameters list for generation of paystation2 payment page url
-## 1.1.0 (2014-07-24)
+## [v1.1.0](https://github.com/xsolla/xsolla-sdk-php/compare/v1.0.4...v1.1.0) - 2014-07-24
* add Shopping Cart Protocol 3.0 http://xsolla.github.io/en/shopingcart3.html
-## 1.0.4 (2014-06-04)
+## [v1.0.4](https://github.com/xsolla/xsolla-sdk-php/compare/v1.0.3...v1.0.4) - 2014-06-04
* fix incorrect sign code for Shopping Cart Protocol 2.0
* add `$reasonCode` and `$reasonDescription` optional arguments to `PaymentStorageInterface::cancel`
-## 1.0.3 (2014-04-22)
+## [v1.0.3](https://github.com/xsolla/xsolla-sdk-php/compare/v1.0.2...v1.0.3) - 2014-04-22
* added missed sandbox key to UrlBuilder for sandbox-secure.xsolla.com
* fixed wrong error code for IPN requests with zero valued parameters
-## 1.0.2 (2014-02-27)
+## [v1.0.2](https://github.com/xsolla/xsolla-sdk-php/compare/v1.0.1...v1.0.2) - 2014-02-27
* add `$baseUrl` optional argument to `UrlBuilder::getUrl()` and `UrlBuilder::SANDBOX_URL` constant
-## 1.0.1 (2014-02-25)
+## [v1.0.1](https://github.com/xsolla/xsolla-sdk-php/compare/v1.0.0...v1.0.1) - 2014-02-25
* fix `description` response field name for UnprocessableRequestException handling in Shopping Cart protocol
* fix repeated notifications handling in Shopping Cart protocol
\ No newline at end of file
diff --git a/README.md b/README.md
index a98a7dc..0bb7d35 100644
--- a/README.md
+++ b/README.md
@@ -1,127 +1,125 @@
-# [DEPRECATED] Xsolla SDK for PHP
+# Xsolla SDK for PHP
[](https://packagist.org/packages/xsolla/xsolla-sdk-php)
[](https://travis-ci.org/xsolla/xsolla-sdk-php)
-[](https://scrutinizer-ci.com/g/xsolla/xsolla-sdk-php/)
-[](https://scrutinizer-ci.com/g/xsolla/xsolla-sdk-php/)
-[](https://insight.sensiolabs.com/projects/44ae8284-c5c3-40f8-b1e3-de4093995db5)
+[](https://scrutinizer-ci.com/g/xsolla/xsolla-sdk-php)
+[](https://gitter.im/xsolla/xsolla-sdk-php?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+[](https://raw.githubusercontent.com/xsolla/xsolla-sdk-php/master/LICENSE)
-An official PHP SDK for interacting with [Xsolla API](http://developers.xsolla.com/api.html)
+An official PHP SDK for interacting with [Xsolla API](http://developers.xsolla.com)
+
+
+
+## Features
+
+* Full customisation of Payment UI with the help of different methods of getting token.
+* Client for all API methods, making your integration easy and convenient. You can use it for setting up and updating virtual currency, items and subscription plans, for managing the users balance, for checking the finance information with the help of Report API and so on.
+* Convenient webhook server:
+ * To start you need only one callback function.
+ * All security checking already implemented: signature authentication and IP whitelisting.
+ * Full customisation of notification processing logic, if standard server class doesn’t suit you.
+* SDK is built on Guzzle v3, and utilizes many of its features, including persistent connections, parallel requests, events and plugins (via Symfony2 EventDispatcher), service descriptions, over-the-wire logging, caching, flexible batching, and request retrying with truncated exponential back off.
## Requirements
-* PHP 5.3.3+
+* PHP 5.3.9+
* Your php.ini needs to have the date.timezone setting
+* The following PHP extensions are required:
+ * curl
+ * json
## Installation
+### Installing via Composer
+
The recommended way to install Xsolla SDK for PHP is through [Composer](http://getcomposer.org).
``` bash
$ cd /path/to/your/project
-$ composer require xsolla/xsolla-sdk-php:~1.0
+$ composer require xsolla/xsolla-sdk-php
```
-## Usage
+### Installing via Phar
-### Generate URL to [Payment Page](http://xsolla.github.io/en/plugindemonstration.html)
+You can [download the packaged phar](https://github.com/xsolla/xsolla-sdk-php/releases) and include it in your scripts to get started:
``` php
-setEmail('example@example.com')
- ->setPhone('79090000000');
+### Integrate Payment UI
-$invoice = new Invoice;
-$invoice->setVirtualCurrencyAmount(5);
+Generate Payment UI token:
-$url = $urlBuilderFactory->getPayStation()
- ->setInvoice($invoice)
- ->setUser($user)
- ->unlockParameterForUser('email')
- ->setCountry('US')
- ->setLocale('en')
- ->setParameter('theme', 115)
- ->setParameter('description', 'Purchase description')
- ->getUrl();
+``` php
+
+$client = XsollaClient::factory(array(
+ 'merchant_id' => MERCHANT_ID,
+ 'api_key' => 'API_KEY'
+));
+$paymentUIToken = $client->createCommonPaymentUIToken(PROJECT_ID, USER_ID);
```
-### Receive [Instant Payment Notification](http://xsolla.github.io/en/currency.html)
-For receiving IPN requests you should implement [\Xsolla\SDK\Protocol\Storage](https://github.com/xsolla/xsolla-sdk-php/tree/master/src/Protocol/Storage) interfaces.
-Also you can setup sql tables for your [protocol](http://xsolla.github.io/en/currency.html) from [resources/mysql](https://github.com/xsolla/xsolla-sdk-php/tree/master/resources/mysql) and use [\Xsolla\SDK\Protocol\Storage\Pdo](https://github.com/xsolla/xsolla-sdk-php/tree/master/src/Protocol/Storage/Pdo) classes directly or extend it.
+Render Payment UI script in your page:
``` php
-getStandardProtocol($usersStorage, $paymentsStorage);
-
-$request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
-$response = $protocol->run($request);
-$response->send();
+
+
+
+
+
+
+
+
+
+
```
-[IpChecker](https://github.com/xsolla/xsolla-sdk-php/blob/master/src/Validator/IpChecker.php) - additional security level for situations when your secret key is compromised.
-It's a optional parameter for ProtocolFactory and you can skip it for development and testing environment.
-If you use reverse proxy, you should set a list of trusted proxies via [Request::setTrustedProxies()](http://symfony.com/doc/current/components/http_foundation/trusting_proxies.html)
-#### IPN demo
-You can run IPN demo with the following commands(required php 5.4+ with built-in server):
+### Receive webhooks
-``` bash
-$ cd /path/to/xsolla/xsolla-sdk-php
-$ composer install
-$ php -S localhost:9000 -t example example/ipn_standard.php > /dev/null 2>&1 &
-$ # no command
-$ curl 'localhost:9000'
-$ # user found
-$ curl 'http://localhost:9000/?command=check&v1=demo&v2=&v3=&md5=a3561b90df78828133eb285e36965419'
-$ # user not found or disabled
-$ curl 'http://localhost:9000/?command=check&v1=not_exist&v2=&v3=&md5=5f67cabd3cf27cac2944e7f9f762a42a'
-$ # success IPN handling. Response contain payment ID
-$ curl 'http://localhost:9000/?command=pay&id=1&v1=demo&v2=&v3=&date=2014-02-19+13%3A03%3A52&sum=1&md5=eae3e95e93ff64f72aeb9fadfd8f0d66'
-$ # failed IPN handling. Unprocessable request error
-$ curl 'http://localhost:9000/?command=pay&id=2&v1=demo&v2=&v3=&date=2014-02-19+13%3A04%3A30&sum=5&md5=3067aeb81faa883f36d27acc9d808abb'
-$ # success payment cancel
-$ curl 'http://localhost:9000/?command=cancel&id=3&md5=9ac4f238314b0a0dae5be98151d19f33'
-```
-### Examples
-More examples you can find in [example](https://github.com/xsolla/xsolla-sdk-php/tree/master/example) folder.
-All examples are executable and you can run them with the following commands.
+``` php
+getNotificationType()) {
+ case Message::USER_VALIDATION:
+ //check user existence
+ break;
+ case Message::PAYMENT:
+ //handle payment
+ break;
+ case Message::REFUND:
+ //handle refund
+ break;
+ default:
+ throw new XsollaWebhookException('Notification type not implemented');
+ }
+};
+
+$webhookServer = WebhookServer::create($callback, PROJECT_KEY); // https://merchant.xsolla.com/MERCHANT_ID/projects/PROJECT_ID/settings/connection
+$webhookServer->start();
```
+
## Additional resources
* [Website](http://xsolla.com)
-* [Documentation](http://xsolla.github.io)
+* [Documentation](http://developers.xsolla.com)
* [Status](http://status.xsolla.com)
+* [Support and Feedback](mailto:api.developers@xsolla.com)
\ No newline at end of file
diff --git a/build/artifacts/.gitkeep b/build/artifacts/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/build/packager.php b/build/packager.php
new file mode 100644
index 0000000..ff82d52
--- /dev/null
+++ b/build/packager.php
@@ -0,0 +1,20 @@
+exec('rm -rf '.__DIR__.'/artifacts/xsolla.*');
+
+$packager->recursiveCopy('src', 'Xsolla/SDK');
+$packager->recursiveCopy('vendor/guzzle/guzzle/src/Guzzle', 'Guzzle', array('php', 'pem'));
+$packager->recursiveCopy('vendor/symfony/event-dispatcher', 'Symfony/Component/EventDispatcher');
+$packager->recursiveCopy('vendor/symfony/http-foundation', 'Symfony/Component/HttpFoundation');
+
+$packager->createAutoloader(array(), 'xsolla-autoloader.php');
+$packager->createPhar(__DIR__.'/artifacts/xsolla.phar', null, 'xsolla-autoloader.php');
+$packager->createZip(__DIR__.'/artifacts/xsolla.zip');
+
+$packager->startSection('test-phar');
+$packager->exec('php '.__DIR__.'/test-phar.php');
+$packager->endSection();
diff --git a/build/test-phar.php b/build/test-phar.php
new file mode 100644
index 0000000..cfbaa5c
--- /dev/null
+++ b/build/test-phar.php
@@ -0,0 +1,13 @@
+ 'MERCHANT_ID',
+ 'api_key' => 'API_KEY',
+));
+
+$webhookServer = WebhookServer::create(function () {}, 'PROJECT_SECRET_KEY');
diff --git a/composer.json b/composer.json
index baa49f6..7b9b7b2 100644
--- a/composer.json
+++ b/composer.json
@@ -3,31 +3,33 @@
"type": "library",
"description":"Xsolla SDK for PHP. Xsolla is the authorized reseller and merchant providing e-commerce services for online games.",
"keywords": ["sdk", "xsolla", "api", "payment", "games"],
- "homepage": "http://xsolla.github.io",
+ "homepage": "http://xsolla.com",
"license": "MIT",
- "authors": [
- {
- "name": "Xsolla Developers",
- "email": "api.developers@xsolla.com"
- }
- ],
+ "support": {
+ "email": "api.developers@xsolla.com",
+ "issues": "https://github.com/xsolla/xsolla-sdk-php/issues",
+ "docs": "http://developers.xsolla.com",
+ "source": "https://github.com/xsolla/xsolla-sdk-php/releases"
+ },
"require": {
- "php": ">=5.3.3",
- "ext-simplexml": "*",
- "symfony/http-foundation": "~2.4"
-
+ "php": ">=5.3.9",
+ "ext-json": "*",
+ "guzzle/guzzle": "~3.8",
+ "symfony/http-foundation": "~2.3"
},
"require-dev": {
- "guzzle/http": "~3.7"
- },
- "suggest": {
- "guzzle/http": "Required for advanced API commands",
- "ext-pdo": "Required for Protocol/Storage/Pdo classes usage"
+ "phpunit/phpunit": "4.*",
+ "symfony/process": "~2.3",
+ "mtdowling/burgomaster": "^0.0.2"
},
"autoload": {
"psr-4": {
- "Xsolla\\SDK\\": "src",
- "Xsolla\\SDK\\Tests\\": "tests"
+ "Xsolla\\SDK\\": "src"
}
+ },
+ "autoload-dev": {
+ "psr-4": {
+ "Xsolla\\SDK\\Tests\\": "tests"
+ }
}
}
diff --git a/composer.lock b/composer.lock
index 8ad3cd0..7294eb4 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1,40 +1,197 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
- "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file"
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
+ "This file is @generated automatically"
],
- "hash": "cb31b34ed4e66efe0e48549c188c71ea",
+ "hash": "b9848ce7e74d46fd7f938ebda701d763",
"packages": [
+ {
+ "name": "guzzle/guzzle",
+ "version": "v3.9.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/guzzle/guzzle3.git",
+ "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/0645b70d953bc1c067bbc8d5bc53194706b628d9",
+ "reference": "0645b70d953bc1c067bbc8d5bc53194706b628d9",
+ "shasum": ""
+ },
+ "require": {
+ "ext-curl": "*",
+ "php": ">=5.3.3",
+ "symfony/event-dispatcher": "~2.1"
+ },
+ "replace": {
+ "guzzle/batch": "self.version",
+ "guzzle/cache": "self.version",
+ "guzzle/common": "self.version",
+ "guzzle/http": "self.version",
+ "guzzle/inflection": "self.version",
+ "guzzle/iterator": "self.version",
+ "guzzle/log": "self.version",
+ "guzzle/parser": "self.version",
+ "guzzle/plugin": "self.version",
+ "guzzle/plugin-async": "self.version",
+ "guzzle/plugin-backoff": "self.version",
+ "guzzle/plugin-cache": "self.version",
+ "guzzle/plugin-cookie": "self.version",
+ "guzzle/plugin-curlauth": "self.version",
+ "guzzle/plugin-error-response": "self.version",
+ "guzzle/plugin-history": "self.version",
+ "guzzle/plugin-log": "self.version",
+ "guzzle/plugin-md5": "self.version",
+ "guzzle/plugin-mock": "self.version",
+ "guzzle/plugin-oauth": "self.version",
+ "guzzle/service": "self.version",
+ "guzzle/stream": "self.version"
+ },
+ "require-dev": {
+ "doctrine/cache": "~1.3",
+ "monolog/monolog": "~1.0",
+ "phpunit/phpunit": "3.7.*",
+ "psr/log": "~1.0",
+ "symfony/class-loader": "~2.1",
+ "zendframework/zend-cache": "2.*,<2.3",
+ "zendframework/zend-log": "2.*,<2.3"
+ },
+ "suggest": {
+ "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated."
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-0": {
+ "Guzzle": "src/",
+ "Guzzle\\Tests": "tests/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Michael Dowling",
+ "email": "mtdowling@gmail.com",
+ "homepage": "https://github.com/mtdowling"
+ },
+ {
+ "name": "Guzzle Community",
+ "homepage": "https://github.com/guzzle/guzzle/contributors"
+ }
+ ],
+ "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle",
+ "homepage": "http://guzzlephp.org/",
+ "keywords": [
+ "client",
+ "curl",
+ "framework",
+ "http",
+ "http client",
+ "rest",
+ "web service"
+ ],
+ "time": "2015-03-18 18:23:50"
+ },
+ {
+ "name": "symfony/event-dispatcher",
+ "version": "v2.7.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/EventDispatcher.git",
+ "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/9310b5f9a87ec2ea75d20fec0b0017c77c66dac3",
+ "reference": "9310b5f9a87ec2ea75d20fec0b0017c77c66dac3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "psr/log": "~1.0",
+ "symfony/config": "~2.0,>=2.0.5",
+ "symfony/dependency-injection": "~2.6",
+ "symfony/expression-language": "~2.6",
+ "symfony/phpunit-bridge": "~2.7",
+ "symfony/stopwatch": "~2.3"
+ },
+ "suggest": {
+ "symfony/dependency-injection": "",
+ "symfony/http-kernel": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.7-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\EventDispatcher\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony EventDispatcher Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-06-18 19:21:56"
+ },
{
"name": "symfony/http-foundation",
- "version": "v2.4.2",
- "target-dir": "Symfony/Component/HttpFoundation",
+ "version": "v2.7.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/HttpFoundation.git",
- "reference": "cdee7c84ba8b2a8aafa1c055f5cb4f640d81c129"
+ "reference": "88903c0531b90d4ecd90282b18f08c0c77bde0b2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/cdee7c84ba8b2a8aafa1c055f5cb4f640d81c129",
- "reference": "cdee7c84ba8b2a8aafa1c055f5cb4f640d81c129",
+ "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/88903c0531b90d4ecd90282b18f08c0c77bde0b2",
+ "reference": "88903c0531b90d4ecd90282b18f08c0c77bde0b2",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "symfony/expression-language": "~2.4",
+ "symfony/phpunit-bridge": "~2.7"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.4-dev"
+ "dev-master": "2.7-dev"
}
},
"autoload": {
- "psr-0": {
+ "psr-4": {
"Symfony\\Component\\HttpFoundation\\": ""
},
"classmap": [
- "Symfony/Component/HttpFoundation/Resources/stubs"
+ "Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -44,99 +201,95 @@
"authors": [
{
"name": "Fabien Potencier",
- "email": "fabien@symfony.com",
- "homepage": "http://fabien.potencier.org",
- "role": "Lead Developer"
+ "email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
+ "homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony HttpFoundation Component",
- "homepage": "http://symfony.com",
- "time": "2014-02-11 15:39:28"
+ "homepage": "https://symfony.com",
+ "time": "2015-07-09 16:07:40"
}
],
"packages-dev": [
{
- "name": "guzzle/common",
- "version": "v3.8.1",
- "target-dir": "Guzzle/Common",
+ "name": "doctrine/instantiator",
+ "version": "1.0.5",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/common.git",
- "reference": "67f6c3fd04bae387d47c2a673fa623ed8f4189bb"
+ "url": "https://github.com/doctrine/instantiator.git",
+ "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/common/zipball/67f6c3fd04bae387d47c2a673fa623ed8f4189bb",
- "reference": "67f6c3fd04bae387d47c2a673fa623ed8f4189bb",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d",
+ "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d",
"shasum": ""
},
"require": {
- "php": ">=5.3.2",
- "symfony/event-dispatcher": ">=2.1"
+ "php": ">=5.3,<8.0-DEV"
+ },
+ "require-dev": {
+ "athletic/athletic": "~0.1.8",
+ "ext-pdo": "*",
+ "ext-phar": "*",
+ "phpunit/phpunit": "~4.0",
+ "squizlabs/php_codesniffer": "~2.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.7-dev"
+ "dev-master": "1.0.x-dev"
}
},
"autoload": {
- "psr-0": {
- "Guzzle\\Common": ""
+ "psr-4": {
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "description": "Common libraries used by Guzzle",
- "homepage": "http://guzzlephp.org/",
+ "authors": [
+ {
+ "name": "Marco Pivetta",
+ "email": "ocramius@gmail.com",
+ "homepage": "http://ocramius.github.com/"
+ }
+ ],
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+ "homepage": "https://github.com/doctrine/instantiator",
"keywords": [
- "collection",
- "common",
- "event",
- "exception"
+ "constructor",
+ "instantiate"
],
- "time": "2014-01-28 22:29:15"
+ "time": "2015-06-14 21:17:01"
},
{
- "name": "guzzle/http",
- "version": "v3.8.1",
- "target-dir": "Guzzle/Http",
+ "name": "mtdowling/burgomaster",
+ "version": "0.0.2",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/http.git",
- "reference": "565fd64be16d91c840f497c5de76f86d54a822d8"
+ "url": "https://github.com/mtdowling/Burgomaster.git",
+ "reference": "31624f429cf53d6f9715533ded5ea6ac7ac584b3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/http/zipball/565fd64be16d91c840f497c5de76f86d54a822d8",
- "reference": "565fd64be16d91c840f497c5de76f86d54a822d8",
+ "url": "https://api.github.com/repos/mtdowling/Burgomaster/zipball/31624f429cf53d6f9715533ded5ea6ac7ac584b3",
+ "reference": "31624f429cf53d6f9715533ded5ea6ac7ac584b3",
"shasum": ""
},
"require": {
- "guzzle/common": "self.version",
- "guzzle/parser": "self.version",
- "guzzle/stream": "self.version",
- "php": ">=5.3.2"
- },
- "suggest": {
- "ext-curl": "*"
+ "php": ">=5.3.3"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "3.7-dev"
- }
- },
"autoload": {
- "psr-0": {
- "Guzzle\\Http": ""
- }
+ "files": [
+ "src/Burgomaster.php"
+ ]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -149,92 +302,93 @@
"homepage": "https://github.com/mtdowling"
}
],
- "description": "HTTP libraries used by Guzzle",
- "homepage": "http://guzzlephp.org/",
+ "description": "Packages up PHP packages into zips and phars",
"keywords": [
- "Guzzle",
- "client",
- "curl",
- "http",
- "http client"
+ "phar",
+ "zip"
],
- "time": "2014-01-23 18:23:29"
+ "time": "2014-09-12 20:50:51"
},
{
- "name": "guzzle/parser",
- "version": "v3.8.1",
- "target-dir": "Guzzle/Parser",
+ "name": "phpdocumentor/reflection-docblock",
+ "version": "2.0.4",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/parser.git",
- "reference": "3f52387052f2e4ef083145a0f73c3654aa14e086"
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/parser/zipball/3f52387052f2e4ef083145a0f73c3654aa14e086",
- "reference": "3f52387052f2e4ef083145a0f73c3654aa14e086",
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
"shasum": ""
},
"require": {
- "php": ">=5.3.2"
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.0"
+ },
+ "suggest": {
+ "dflydev/markdown": "~1.0",
+ "erusev/parsedown": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.7-dev"
+ "dev-master": "2.0.x-dev"
}
},
"autoload": {
"psr-0": {
- "Guzzle\\Parser": ""
+ "phpDocumentor": [
+ "src/"
+ ]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
- "description": "Interchangeable parsers used by Guzzle",
- "homepage": "http://guzzlephp.org/",
- "keywords": [
- "URI Template",
- "cookie",
- "http",
- "message",
- "url"
+ "authors": [
+ {
+ "name": "Mike van Riel",
+ "email": "mike.vanriel@naenius.com"
+ }
],
- "time": "2013-10-24 00:04:09"
+ "time": "2015-02-03 12:10:50"
},
{
- "name": "guzzle/stream",
- "version": "v3.8.1",
- "target-dir": "Guzzle/Stream",
+ "name": "phpspec/prophecy",
+ "version": "v1.4.1",
"source": {
"type": "git",
- "url": "https://github.com/guzzle/stream.git",
- "reference": "fa8af730ca714861c0001cfba64aaecc5f21bb96"
+ "url": "https://github.com/phpspec/prophecy.git",
+ "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/guzzle/stream/zipball/fa8af730ca714861c0001cfba64aaecc5f21bb96",
- "reference": "fa8af730ca714861c0001cfba64aaecc5f21bb96",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373",
+ "reference": "3132b1f44c7bf2ec4c7eb2d3cb78fdeca760d373",
"shasum": ""
},
"require": {
- "guzzle/common": "self.version",
- "php": ">=5.3.2"
+ "doctrine/instantiator": "^1.0.2",
+ "phpdocumentor/reflection-docblock": "~2.0",
+ "sebastian/comparator": "~1.1"
},
- "suggest": {
- "guzzle/http": "To convert Guzzle request objects to PHP streams"
+ "require-dev": {
+ "phpspec/phpspec": "~2.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "3.7-dev"
+ "dev-master": "1.4.x-dev"
}
},
"autoload": {
"psr-0": {
- "Guzzle\\Stream": ""
+ "Prophecy\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -243,89 +397,873 @@
],
"authors": [
{
- "name": "Michael Dowling",
- "email": "mtdowling@gmail.com",
- "homepage": "https://github.com/mtdowling"
+ "name": "Konstantin Kudryashov",
+ "email": "ever.zet@gmail.com",
+ "homepage": "http://everzet.com"
+ },
+ {
+ "name": "Marcello Duarte",
+ "email": "marcello.duarte@gmail.com"
}
],
- "description": "Guzzle stream wrapper component",
- "homepage": "http://guzzlephp.org/",
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
+ "homepage": "https://github.com/phpspec/prophecy",
"keywords": [
- "Guzzle",
- "component",
- "stream"
+ "Double",
+ "Dummy",
+ "fake",
+ "mock",
+ "spy",
+ "stub"
],
- "time": "2014-01-28 22:14:17"
+ "time": "2015-04-27 22:15:08"
},
{
- "name": "symfony/event-dispatcher",
- "version": "v2.4.2",
- "target-dir": "Symfony/Component/EventDispatcher",
+ "name": "phpunit/php-code-coverage",
+ "version": "2.1.9",
"source": {
"type": "git",
- "url": "https://github.com/symfony/EventDispatcher.git",
- "reference": "4708b8cd41984a5ba29fe7dd40716f7f761ac501"
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "5bd48b86cd282da411bb80baac1398ce3fefac41"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/4708b8cd41984a5ba29fe7dd40716f7f761ac501",
- "reference": "4708b8cd41984a5ba29fe7dd40716f7f761ac501",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/5bd48b86cd282da411bb80baac1398ce3fefac41",
+ "reference": "5bd48b86cd282da411bb80baac1398ce3fefac41",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=5.3.3",
+ "phpunit/php-file-iterator": "~1.3",
+ "phpunit/php-text-template": "~1.2",
+ "phpunit/php-token-stream": "~1.3",
+ "sebastian/environment": "~1.0",
+ "sebastian/version": "~1.0"
},
"require-dev": {
- "symfony/dependency-injection": "~2.0"
+ "ext-xdebug": ">=2.1.4",
+ "phpunit/phpunit": "~4"
},
"suggest": {
- "symfony/dependency-injection": "",
- "symfony/http-kernel": ""
+ "ext-dom": "*",
+ "ext-xdebug": ">=2.2.1",
+ "ext-xmlwriter": "*"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "2.4-dev"
+ "dev-master": "2.1.x-dev"
}
},
"autoload": {
- "psr-0": {
- "Symfony\\Component\\EventDispatcher\\": ""
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+ "keywords": [
+ "coverage",
+ "testing",
+ "xunit"
+ ],
+ "time": "2015-07-26 12:54:47"
+ },
+ {
+ "name": "phpunit/php-file-iterator",
+ "version": "1.4.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+ "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
+ "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4.x-dev"
}
},
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
"notification-url": "https://packagist.org/downloads/",
"license": [
- "MIT"
+ "BSD-3-Clause"
],
"authors": [
{
- "name": "Fabien Potencier",
- "email": "fabien@symfony.com",
- "homepage": "http://fabien.potencier.org",
- "role": "Lead Developer"
- },
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+ "keywords": [
+ "filesystem",
+ "iterator"
+ ],
+ "time": "2015-06-21 13:08:43"
+ },
+ {
+ "name": "phpunit/php-text-template",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
{
- "name": "Symfony Community",
- "homepage": "http://symfony.com/contributors"
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
}
],
- "description": "Symfony EventDispatcher Component",
- "homepage": "http://symfony.com",
- "time": "2014-02-11 13:52:09"
- }
- ],
- "aliases": [
-
- ],
- "minimum-stability": "stable",
- "stability-flags": [
-
- ],
+ "description": "Simple template engine.",
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+ "keywords": [
+ "template"
+ ],
+ "time": "2015-06-21 13:50:34"
+ },
+ {
+ "name": "phpunit/php-timer",
+ "version": "1.0.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
+ "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
+ "reference": "3e82f4e9fc92665fafd9157568e4dcb01d014e5b",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Utility class for timing",
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
+ "keywords": [
+ "timer"
+ ],
+ "time": "2015-06-21 08:01:12"
+ },
+ {
+ "name": "phpunit/php-token-stream",
+ "version": "1.4.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
+ "reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/7a9b0969488c3c54fd62b4d504b3ec758fd005d9",
+ "reference": "7a9b0969488c3c54fd62b4d504b3ec758fd005d9",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.4-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Wrapper around PHP's tokenizer extension.",
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
+ "keywords": [
+ "tokenizer"
+ ],
+ "time": "2015-06-19 03:43:16"
+ },
+ {
+ "name": "phpunit/phpunit",
+ "version": "4.7.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
+ "reference": "9b97f9d807b862c2de2a36e86690000801c85724"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9b97f9d807b862c2de2a36e86690000801c85724",
+ "reference": "9b97f9d807b862c2de2a36e86690000801c85724",
+ "shasum": ""
+ },
+ "require": {
+ "ext-dom": "*",
+ "ext-json": "*",
+ "ext-pcre": "*",
+ "ext-reflection": "*",
+ "ext-spl": "*",
+ "php": ">=5.3.3",
+ "phpspec/prophecy": "~1.3,>=1.3.1",
+ "phpunit/php-code-coverage": "~2.1",
+ "phpunit/php-file-iterator": "~1.4",
+ "phpunit/php-text-template": "~1.2",
+ "phpunit/php-timer": ">=1.0.6",
+ "phpunit/phpunit-mock-objects": "~2.3",
+ "sebastian/comparator": "~1.1",
+ "sebastian/diff": "~1.2",
+ "sebastian/environment": "~1.2",
+ "sebastian/exporter": "~1.2",
+ "sebastian/global-state": "~1.0",
+ "sebastian/version": "~1.0",
+ "symfony/yaml": "~2.1|~3.0"
+ },
+ "suggest": {
+ "phpunit/php-invoker": "~1.1"
+ },
+ "bin": [
+ "phpunit"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.7.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "The PHP Unit Testing framework.",
+ "homepage": "https://phpunit.de/",
+ "keywords": [
+ "phpunit",
+ "testing",
+ "xunit"
+ ],
+ "time": "2015-07-13 11:28:34"
+ },
+ {
+ "name": "phpunit/phpunit-mock-objects",
+ "version": "2.3.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
+ "reference": "18dfbcb81d05e2296c0bcddd4db96cade75e6f42"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/18dfbcb81d05e2296c0bcddd4db96cade75e6f42",
+ "reference": "18dfbcb81d05e2296c0bcddd4db96cade75e6f42",
+ "shasum": ""
+ },
+ "require": {
+ "doctrine/instantiator": "~1.0,>=1.0.2",
+ "php": ">=5.3.3",
+ "phpunit/php-text-template": "~1.2",
+ "sebastian/exporter": "~1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "suggest": {
+ "ext-soap": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.3.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sb@sebastian-bergmann.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Mock Object library for PHPUnit",
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
+ "keywords": [
+ "mock",
+ "xunit"
+ ],
+ "time": "2015-07-10 06:54:24"
+ },
+ {
+ "name": "sebastian/comparator",
+ "version": "1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/comparator.git",
+ "reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
+ "reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/diff": "~1.2",
+ "sebastian/exporter": "~1.2"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides the functionality to compare PHP values for equality",
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
+ "keywords": [
+ "comparator",
+ "compare",
+ "equality"
+ ],
+ "time": "2015-07-26 15:48:44"
+ },
+ {
+ "name": "sebastian/diff",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/diff.git",
+ "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3",
+ "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Diff implementation",
+ "homepage": "http://www.github.com/sebastianbergmann/diff",
+ "keywords": [
+ "diff"
+ ],
+ "time": "2015-02-22 15:13:53"
+ },
+ {
+ "name": "sebastian/environment",
+ "version": "1.3.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/environment.git",
+ "reference": "4fe0a44cddd8cc19583a024bdc7374eb2fef0b87"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4fe0a44cddd8cc19583a024bdc7374eb2fef0b87",
+ "reference": "4fe0a44cddd8cc19583a024bdc7374eb2fef0b87",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.3.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Provides functionality to handle HHVM/PHP environments",
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
+ "keywords": [
+ "Xdebug",
+ "environment",
+ "hhvm"
+ ],
+ "time": "2015-07-26 06:42:57"
+ },
+ {
+ "name": "sebastian/exporter",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/exporter.git",
+ "reference": "7ae5513327cb536431847bcc0c10edba2701064e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7ae5513327cb536431847bcc0c10edba2701064e",
+ "reference": "7ae5513327cb536431847bcc0c10edba2701064e",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3",
+ "sebastian/recursion-context": "~1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.2.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Volker Dusch",
+ "email": "github@wallbash.com"
+ },
+ {
+ "name": "Bernhard Schussek",
+ "email": "bschussek@2bepublished.at"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides the functionality to export PHP variables for visualization",
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
+ "keywords": [
+ "export",
+ "exporter"
+ ],
+ "time": "2015-06-21 07:55:53"
+ },
+ {
+ "name": "sebastian/global-state",
+ "version": "1.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/global-state.git",
+ "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c7428acdb62ece0a45e6306f1ae85e1c05b09c01",
+ "reference": "c7428acdb62ece0a45e6306f1ae85e1c05b09c01",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.2"
+ },
+ "suggest": {
+ "ext-uopz": "*"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ }
+ ],
+ "description": "Snapshotting of global state",
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
+ "keywords": [
+ "global state"
+ ],
+ "time": "2014-10-06 09:23:50"
+ },
+ {
+ "name": "sebastian/recursion-context",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
+ "reference": "994d4a811bafe801fb06dccbee797863ba2792ba"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/994d4a811bafe801fb06dccbee797863ba2792ba",
+ "reference": "994d4a811bafe801fb06dccbee797863ba2792ba",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "~4.4"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Adam Harvey",
+ "email": "aharvey@php.net"
+ }
+ ],
+ "description": "Provides functionality to recursively process PHP variables",
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+ "time": "2015-06-21 08:04:50"
+ },
+ {
+ "name": "sebastian/version",
+ "version": "1.0.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/version.git",
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
+ "shasum": ""
+ },
+ "type": "library",
+ "autoload": {
+ "classmap": [
+ "src/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de",
+ "role": "lead"
+ }
+ ],
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+ "homepage": "https://github.com/sebastianbergmann/version",
+ "time": "2015-06-21 13:59:46"
+ },
+ {
+ "name": "symfony/process",
+ "version": "v2.7.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Process.git",
+ "reference": "48aeb0e48600321c272955132d7606ab0a49adb3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Process/zipball/48aeb0e48600321c272955132d7606ab0a49adb3",
+ "reference": "48aeb0e48600321c272955132d7606ab0a49adb3",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.7-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Process\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Process Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-07-01 11:25:50"
+ },
+ {
+ "name": "symfony/yaml",
+ "version": "v2.7.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/Yaml.git",
+ "reference": "4bfbe0ed3909bfddd75b70c094391ec1f142f860"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/Yaml/zipball/4bfbe0ed3909bfddd75b70c094391ec1f142f860",
+ "reference": "4bfbe0ed3909bfddd75b70c094391ec1f142f860",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.9"
+ },
+ "require-dev": {
+ "symfony/phpunit-bridge": "~2.7"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.7-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Yaml\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony Yaml Component",
+ "homepage": "https://symfony.com",
+ "time": "2015-07-01 11:25:50"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
"platform": {
- "php": ">=5.3.3",
- "ext-simplexml": "*"
+ "php": ">=5.3.9",
+ "ext-json": "*"
},
- "platform-dev": [
-
- ]
+ "platform-dev": []
}
diff --git a/example/calculator.php b/example/calculator.php
deleted file mode 100644
index c0259dc..0000000
--- a/example/calculator.php
+++ /dev/null
@@ -1,22 +0,0 @@
-getCalculatorApi();
-
-$virtualCurrencyAmount = $calculatorApi->calculateVirtualCurrencyAmount($paypalId, 100);
-echo 'Calculation of the amount of the game currency on the basis of the amount of payment 100 via Paypal: ' . $virtualCurrencyAmount . PHP_EOL;
-
-$amount = $calculatorApi->calculateAmount($paypalId, 100);
-echo 'Calculation of the amount of payment via Paypal on the basis of the amount of game currency 100: ' . $amount . PHP_EOL;
diff --git a/example/ipn_shopping_cart.php b/example/ipn_shopping_cart.php
deleted file mode 100644
index 0606cde..0000000
--- a/example/ipn_shopping_cart.php
+++ /dev/null
@@ -1,22 +0,0 @@
-getShoppingCartProtocol($paymentStorage);
-
-$request = Request::createFromGlobals();
-$response = $protocol->run($request);
-$response->send();
diff --git a/example/ipn_shopping_cart_3.php b/example/ipn_shopping_cart_3.php
deleted file mode 100644
index 9f040a8..0000000
--- a/example/ipn_shopping_cart_3.php
+++ /dev/null
@@ -1,57 +0,0 @@
-getV1();
- }
-
- public function getAdditionalUserFields(User $user)
- {
- return array();
- }
-}
-
-$userStorage = new UsersDemoStorage;
-$paymentStorage = new PaymentShoppingCart3DemoStorage;
-
-$demoProject = new Project(
- '4783',//demo project id
- 'key'//demo project secret key
-);
-$protocolBuilder = new ProtocolFactory($demoProject);
-$protocol = $protocolBuilder->getShoppingCart3Protocol($userStorage, $paymentStorage);
-
-$request = Request::createFromGlobals();
-$response = $protocol->run($request);
-$response->send();
diff --git a/example/ipn_standard.php b/example/ipn_standard.php
deleted file mode 100644
index 071fe36..0000000
--- a/example/ipn_standard.php
+++ /dev/null
@@ -1,56 +0,0 @@
-getV1();
- }
-
- public function getAdditionalUserFields(User $user)
- {
- return array();
- }
-}
-
-$userStorage = new UsersDemoStorage;
-$paymentStorage = new PaymentStandardDemoStorage;
-
-$demoProject = new Project(
- '4783',//demo project id
- 'key'//demo project secret key
-);
-$protocolBuilder = new ProtocolFactory($demoProject);
-$protocol = $protocolBuilder->getStandardProtocol($userStorage, $paymentStorage);
-
-$request = Request::createFromGlobals();
-$response = $protocol->run($request);
-$response->send();
diff --git a/example/mobile_payment.php b/example/mobile_payment.php
deleted file mode 100644
index 2cbbddb..0000000
--- a/example/mobile_payment.php
+++ /dev/null
@@ -1,29 +0,0 @@
-setPhone('79120000000');
-
-$demoProject = new Project(
- '4783', //demo project id
- 'key' //demo project secret key
-);
-
-$apiFactory = new ApiFactory($demoProject);
-
-$mobilePaymentApi = $apiFactory->getMobilePaymentApi();
-
-$invoice = $mobilePaymentApi->calculateAmount($user, 1000);
-echo 'Cost of 1000 units of virtual currency: ' . $invoice->getAmount() . PHP_EOL;
-
-$invoice = $mobilePaymentApi->calculateVirtualCurrencyAmount($user, 100);
-echo 'Amount of virtual currency that can be bought for 100 rubles: ' . $invoice->getVirtualCurrencyAmount() . PHP_EOL;
-
-$invoice = $mobilePaymentApi->createInvoice($user, new Invoice(null, 100));
-echo 'Issue an invoice for a virtual currency for 100 rubles. Your invoice number: ' . $invoice->getId() . PHP_EOL;
diff --git a/example/payment_page_url_builder.php b/example/payment_page_url_builder.php
deleted file mode 100644
index c787792..0000000
--- a/example/payment_page_url_builder.php
+++ /dev/null
@@ -1,32 +0,0 @@
-setEmail('example@example.com')
- ->setPhone('79000000000');
-
-$demoProject = new Project(
- '4783',//demo project id
- 'key'//demo project secret key
-);
-
-$invoice = new Invoice;
-$invoice->setVirtualCurrencyAmount(10);
-
-$urlBuilderFactory = new UrlBuilderFactory($demoProject);
-
-$url = $urlBuilderFactory->getCreditCards()
- ->setInvoice($invoice)
- ->setUser($user)
- ->unlockParameterForUser('email')
- ->setCountry('US')
- ->setLocale('fr')
- ->setParameter('description', 'Purchase description')
- ->getUrl();
-
-echo 'URL to PayStation payment page: ' . $url . PHP_EOL;
diff --git a/example/qiwi_wallet.php b/example/qiwi_wallet.php
deleted file mode 100644
index 64437a1..0000000
--- a/example/qiwi_wallet.php
+++ /dev/null
@@ -1,28 +0,0 @@
-setPhone('79120000000');
-
-$demoProject = new Project(
- '4783',//demo project id
- 'key'//demo project secret key
-);
-
-$apiFactory = new ApiFactory($demoProject);
-
-$mobilePaymentApi= $apiFactory->getQiwiWalletApi();
-
-$invoice = $mobilePaymentApi->calculateAmount($user, 1000);
-echo 'Cost of 1000 units of virtual currency: ' . $invoice->getAmount() . PHP_EOL;
-
-$invoice = $mobilePaymentApi->calculateVirtualCurrencyAmount($user, 100);
-echo 'Amount of virtual currency that can be bought for 100 rubles: ' . $invoice->getVirtualCurrencyAmount() . PHP_EOL;
-
-$invoice = $mobilePaymentApi->createInvoice($user, new Invoice(null, 100));
-echo 'Issue an invoice for a virtual currency for 100 rubles. Your invoice number: ' . $invoice->getId() . PHP_EOL;
diff --git a/example/subscription.php b/example/subscription.php
deleted file mode 100644
index 924baa0..0000000
--- a/example/subscription.php
+++ /dev/null
@@ -1,30 +0,0 @@
-getSubscriptionsApi();
-
-$user = new User('v1', 'v2');
-$userSubscriptions = $subscriptionApi->search($user, SubscriptionsApi::TYPE_CARD);
-
-if (!isset($userSubscriptions[0])) {
- echo 'Subscriptions not found'.PHP_EOL;
- exit;
-}
-$invoice = new Invoice;
-$invoice->setVirtualCurrencyAmount(100);
-
-$subscriptionApi->pay($userSubscriptions[0], $invoice);
-$subscriptionApi->pay($userSubscriptions[0], $invoice);
-$subscriptionApi->delete($userSubscriptions[0]);
diff --git a/example/xsolla_number.php b/example/xsolla_number.php
deleted file mode 100644
index c9b968c..0000000
--- a/example/xsolla_number.php
+++ /dev/null
@@ -1,20 +0,0 @@
-getNumberApi();
-
-$number = $numberApi->getNumber($user);
-
-echo 'Xsolla number for user "demo_user": '. $number . PHP_EOL;
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 4c0677b..96d08a7 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -14,6 +14,12 @@
bootstrap = "./vendor/autoload.php"
>
+
+
+
+
+
+
./tests
diff --git a/resources/mysql/shopping_cart.sql b/resources/mysql/shopping_cart.sql
deleted file mode 100644
index fdbd1d6..0000000
--- a/resources/mysql/shopping_cart.sql
+++ /dev/null
@@ -1,24 +0,0 @@
-CREATE TABLE `xsolla_shopping_cart_invoice` (
- `v1` INT UNSIGNED NOT NULL AUTO_INCREMENT,
- `v2` VARCHAR(200) NULL DEFAULT NULL,
- `v3` VARCHAR(100) NULL DEFAULT NULL,
- `timestamp_create` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `invoice_amount` DECIMAL(12,2) UNSIGNED NOT NULL,
- `invoice_currency` CHAR(3) NOT NULL,
- `id_xsolla` INT(11) UNSIGNED NULL DEFAULT NULL,
- `timestamp_ipn` TIMESTAMP NULL DEFAULT NULL,
- `timestamp_xsolla_ipn` TIMESTAMP NULL DEFAULT NULL,
- `is_dry_run` TINYINT(1) UNSIGNED NOT NULL,
- `pid` INT NULL DEFAULT NULL,
- `geotype` INT NULL DEFAULT NULL,
- `user_amount` DECIMAL(12,2) UNSIGNED NULL DEFAULT NULL,
- `user_currency` CHAR(3) NULL DEFAULT NULL,
- `transfer_amount` DECIMAL(12,2) UNSIGNED NULL DEFAULT NULL,
- `transfer_currency` CHAR(3) NULL DEFAULT NULL,
- `is_canceled` TINYINT(1) NOT NULL DEFAULT 0,
- `timestamp_canceled` TIMESTAMP NULL DEFAULT NULL,
- PRIMARY KEY (`v1`),
- UNIQUE INDEX `id_xsolla_UNIQUE` (`id_xsolla` ASC))
- ENGINE = InnoDB
- DEFAULT CHARACTER SET = utf8
- COLLATE = utf8_general_ci;
diff --git a/resources/mysql/shopping_cart3.sql b/resources/mysql/shopping_cart3.sql
deleted file mode 100644
index a2d5fd8..0000000
--- a/resources/mysql/shopping_cart3.sql
+++ /dev/null
@@ -1,25 +0,0 @@
-CREATE TABLE `xsolla_standard_user` (
- `v1` VARCHAR(255) NOT NULL,
- `v2` VARCHAR(200) NULL DEFAULT NULL,
- `v3` VARCHAR(100) NULL DEFAULT NULL,
- PRIMARY KEY (`v1`))
- ENGINE = InnoDB
- DEFAULT CHARACTER SET = utf8
- COLLATE = utf8_general_ci;
-
-CREATE TABLE `xsolla_shoppingcart3_invoice` (
- `id` INT NOT NULL AUTO_INCREMENT,
- `v1` VARCHAR(255) NOT NULL,
- `id_xsolla` INT UNSIGNED NOT NULL,
- `timestamp_ipn` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `timestamp_xsolla_ipn` TIMESTAMP NOT NULL,
- `payment_amount` DECIMAL(12,2) UNSIGNED NOT NULL,
- `payment_currency` CHAR(3) NOT NULL,
- `is_dry_run` TINYINT(1) NOT NULL,
- `is_canceled` TINYINT(1) NOT NULL DEFAULT 0,
- `timestamp_canceled` TIMESTAMP NULL DEFAULT NULL,
- PRIMARY KEY (`id`),
- UNIQUE INDEX `id_xsolla_UNIQUE` (`id_xsolla` ASC))
- ENGINE = InnoDB
- DEFAULT CHARACTER SET = utf8
- COLLATE = utf8_general_ci;
diff --git a/resources/mysql/standard.sql b/resources/mysql/standard.sql
deleted file mode 100644
index 88322c0..0000000
--- a/resources/mysql/standard.sql
+++ /dev/null
@@ -1,24 +0,0 @@
-CREATE TABLE `xsolla_standard_user` (
- `v1` VARCHAR(255) NOT NULL,
- `v2` VARCHAR(200) NULL DEFAULT NULL,
- `v3` VARCHAR(100) NULL DEFAULT NULL,
- PRIMARY KEY (`v1`))
- ENGINE = InnoDB
- DEFAULT CHARACTER SET = utf8
- COLLATE = utf8_general_ci;
-
-CREATE TABLE `xsolla_standard_invoice` (
- `id` INT NOT NULL AUTO_INCREMENT,
- `v1` VARCHAR(255) NOT NULL,
- `id_xsolla` INT UNSIGNED NOT NULL,
- `timestamp_ipn` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
- `timestamp_xsolla_ipn` TIMESTAMP NOT NULL,
- `amount_virtual_currency` DECIMAL(12,2) UNSIGNED NOT NULL,
- `is_dry_run` TINYINT(1) NOT NULL,
- `is_canceled` TINYINT(1) NOT NULL DEFAULT 0,
- `timestamp_canceled` TIMESTAMP NULL DEFAULT NULL,
- PRIMARY KEY (`id`),
- UNIQUE INDEX `id_xsolla_UNIQUE` (`id_xsolla` ASC))
- ENGINE = InnoDB
- DEFAULT CHARACTER SET = utf8
- COLLATE = utf8_general_ci;
diff --git a/resources/schema/mobilepayment/calculate.xsd b/resources/schema/mobilepayment/calculate.xsd
deleted file mode 100644
index f2d8aa2..0000000
--- a/resources/schema/mobilepayment/calculate.xsd
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/resources/schema/mobilepayment/invoice.xsd b/resources/schema/mobilepayment/invoice.xsd
deleted file mode 100644
index ef1ff34..0000000
--- a/resources/schema/mobilepayment/invoice.xsd
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/resources/schema/qiwi/calculate.xsd b/resources/schema/qiwi/calculate.xsd
deleted file mode 100644
index f2d8aa2..0000000
--- a/resources/schema/qiwi/calculate.xsd
+++ /dev/null
@@ -1,39 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/resources/schema/qiwi/invoice.xsd b/resources/schema/qiwi/invoice.xsd
deleted file mode 100644
index 901b112..0000000
--- a/resources/schema/qiwi/invoice.xsd
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/API/PaymentUI/PaymentUIScriptRenderer.php b/src/API/PaymentUI/PaymentUIScriptRenderer.php
new file mode 100644
index 0000000..3ee673a
--- /dev/null
+++ b/src/API/PaymentUI/PaymentUIScriptRenderer.php
@@ -0,0 +1,38 @@
+
+ var options = {
+ access_token: '%s',
+ sandbox: %s
+ };
+ var s = document.createElement('script');
+ s.type = "text/javascript";
+ s.async = true;
+ s.src = "//static.xsolla.com/embed/paystation/1.0.2/widget.min.js";
+ s.addEventListener('load', function (e) {
+ XPayStationWidget.init(options);
+ }, false);
+ var head = document.getElementsByTagName('head')[0];
+ head.appendChild(s);
+
+EOF;
+
+ return sprintf($template, $token, $isSandbox ? 'true' : 'false');
+ }
+}
diff --git a/src/API/PaymentUI/TokenRequest.php b/src/API/PaymentUI/TokenRequest.php
new file mode 100644
index 0000000..20f5fff
--- /dev/null
+++ b/src/API/PaymentUI/TokenRequest.php
@@ -0,0 +1,105 @@
+data['user']['id']['value'] = $userId;
+ $this->data['settings']['project_id'] = $projectId;
+ }
+
+ /**
+ * @param string $email
+ *
+ * @return self
+ */
+ public function setUserEmail($email)
+ {
+ $this->data['user']['email']['value'] = $email;
+
+ return $this;
+ }
+
+ /**
+ * @param string $name
+ *
+ * @return self
+ */
+ public function setUserName($name)
+ {
+ $this->data['user']['name']['value'] = $name;
+
+ return $this;
+ }
+
+ /**
+ * @param string $currencyIsoCode
+ *
+ * @return self
+ */
+ public function setCurrency($currencyIsoCode)
+ {
+ $this->data['settings']['currency'] = $currencyIsoCode;
+
+ return $this;
+ }
+
+ /**
+ * @param array $customParameters
+ *
+ * @return self
+ */
+ public function setCustomParameters(array $customParameters)
+ {
+ $this->data['custom_parameters'] = $customParameters;
+
+ return $this;
+ }
+
+ /**
+ * @param string $externalId
+ *
+ * @return self
+ */
+ public function setExternalPaymentId($externalId)
+ {
+ $this->data['settings']['external_id'] = $externalId;
+
+ return $this;
+ }
+
+ /**
+ * @param bool $isSandbox
+ *
+ * @return self
+ */
+ public function setSandboxMode($isSandbox = true)
+ {
+ if (true === $isSandbox) {
+ $this->data['settings']['mode'] = 'sandbox';
+ } else {
+ unset($this->data['settings']['mode']);
+ }
+
+ return $this;
+ }
+
+ /**
+ * @return array
+ */
+ public function toArray()
+ {
+ return $this->data;
+ }
+}
diff --git a/src/API/Resources/xsolla-2015-07-23.php b/src/API/Resources/xsolla-2015-07-23.php
new file mode 100644
index 0000000..a09fe23
--- /dev/null
+++ b/src/API/Resources/xsolla-2015-07-23.php
@@ -0,0 +1,1489 @@
+ 'Xsolla API',
+ 'apiVersion' => '2015-07-23',
+ 'description' => '',
+ 'baseUrl' => 'https://api.xsolla.com',
+ 'operations' => array(
+ // Payment UI
+ 'CreatePaymentUIToken' => array(
+ 'httpMethod' => 'POST',
+ 'uri' => '/merchant/merchants/{merchant_id}/token',
+ 'summary' => 'Create payment UI token',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ // Subscriptions
+ 'CreateSubscriptionPlan' => array(
+ 'httpMethod' => 'POST',
+ 'uri' => '/merchant/projects/{project_id}/subscriptions/plans',
+ 'summary' => 'Create a recurrent plan',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'UpdateSubscriptionPlan' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/projects/{project_id}/subscriptions/plans/{plan_id}',
+ 'summary' => 'Update a recurrent plan',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'plan_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'DeleteSubscriptionPlan' => array(
+ 'httpMethod' => 'DELETE',
+ 'uri' => '/merchant/projects/{project_id}/subscriptions/plans/{plan_id}/delete',
+ 'summary' => 'Delete a recurrent plan',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'plan_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'DisableSubscriptionPlan' => array(
+ 'httpMethod' => 'DELETE',
+ 'uri' => '/merchant/projects/{project_id}/subscriptions/plans/{plan_id}',
+ 'summary' => 'Disable a recurrent plan',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'plan_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'EnableSubscriptionPlan' => array(
+ 'httpMethod' => 'PATCH',
+ 'uri' => '/merchant/projects/{project_id}/subscriptions/plans/{plan_id}',
+ 'summary' => 'Enable a recurrent plan',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'plan_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'ListSubscriptionPlans' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/subscriptions/plans',
+ 'summary' => 'List all recurrent plans',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'CreateSubscriptionProduct' => array(
+ 'httpMethod' => 'POST',
+ 'uri' => '/merchant/projects/{project_id}/subscriptions/products',
+ 'summary' => 'Create a product',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'UpdateSubscriptionProduct' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/projects/{project_id}/subscriptions/products/{product_id}',
+ 'summary' => 'Update a product',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'product_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'DeleteSubscriptionProduct' => array(
+ 'httpMethod' => 'DELETE',
+ 'uri' => '/merchant/projects/{project_id}/subscriptions/products/{product_id}',
+ 'summary' => 'Delete a product',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'product_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'ListSubscriptionProducts' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/subscriptions/products',
+ 'summary' => 'List all recurrent products',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'group_id' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ 'limit' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => false,
+ ),
+ 'offset' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => false,
+ ),
+ ),
+ ),
+ 'UpdateSubscription' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/projects/{project_id}/users/{user_id}/subscriptions/{subscription_id}',
+ 'summary' => 'Update a recurrent subscription. It\'s available to update the status of subscription (active or canceled) and to postpone the date of the next charge for current subscription.',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'user_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'subscription_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'ListSubscriptions' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/users/{user_id}/subscriptions',
+ 'summary' => 'List all recurrent subscriptions',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'user_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'status' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ 'limit' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => false,
+ ),
+ 'offset' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => false,
+ ),
+ 'datetime_from' => array(//TODO DATETIME
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ 'datetime_to' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ ),
+ ),
+ 'ListSubscriptionPayments' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/users/{user_id}/subscriptions/payments',
+ 'summary' => 'List all recurrent payments',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'user_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'status' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ 'limit' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => false,
+ ),
+ 'offset' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => false,
+ ),
+ 'datetime_from' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ 'datetime_to' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ ),
+ ),
+ 'ListSubscriptionCurrencies' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/subscriptions/currencies',
+ 'summary' => 'List all recurrent currencies',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ //User attributes
+ 'ListUserAttributes' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/user_attributes',
+ 'summary' => 'Get list of user attributes',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'GetUserAttribute' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/user_attributes/{user_attribute_id}',
+ 'summary' => 'Show a user attribute',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'user_attribute_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'CreateUserAttribute' => array(
+ 'httpMethod' => 'POST',
+ 'uri' => '/merchant/projects/{project_id}/user_attributes',
+ 'summary' => 'Create user attribute',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'UpdateUserAttribute' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/projects/{project_id}/user_attributes/{user_attribute_id}',
+ 'summary' => 'Update user attribute',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'user_attribute_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'DeleteUserAttribute' => array(
+ 'httpMethod' => 'DELETE',
+ 'uri' => '/merchant/projects/{project_id}/user_attributes/{user_attribute_id}',
+ 'summary' => 'Delete a user attribute',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'user_attribute_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ // Virtual Items
+ 'CreateVirtualItem' => array(
+ 'httpMethod' => 'POST',
+ 'uri' => '/merchant/projects/{project_id}/virtual_items/items',
+ 'summary' => 'Create a virtual item',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'GetVirtualItem' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/virtual_items/items/{item_id}',
+ 'summary' => 'Get a virtual item',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'item_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'UpdateVirtualItem' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/projects/{project_id}/virtual_items/items/{item_id}',
+ 'summary' => 'Update a virtual item',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'item_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'DeleteVirtualItem' => array(
+ 'httpMethod' => 'DELETE',
+ 'uri' => '/merchant/projects/{project_id}/virtual_items/items/{item_id}',
+ 'summary' => 'Delete a virtual item',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'item_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'ListVirtualItems' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/virtual_items/items',
+ 'summary' => 'List a virtual items',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'UpdateVirtualItemImage' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/projects/{project_id}/virtual_items/items/{item_id}/image',
+ 'summary' => 'Upload an image for virtual item',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'item_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'DeleteVirtualItemImage' => array(
+ 'httpMethod' => 'DELETE',
+ 'uri' => '/merchant/projects/{project_id}/virtual_items/items/{item_id}/image',
+ 'summary' => 'Change a virtual item image to default',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'item_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'CreateVirtualItemsGroup' => array(
+ 'httpMethod' => 'POST',
+ 'uri' => '/merchant/projects/{project_id}/virtual_items/groups',
+ 'summary' => 'Create a virtual items group',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'GetVirtualItemsGroup' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/virtual_items/groups/{group_id}',
+ 'summary' => 'Get a virtual items group',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'group_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'UpdateVirtualItemsGroup' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/projects/{project_id}/virtual_items/groups/{group_id}',
+ 'summary' => 'Update a virtual items group',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'group_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'DeleteVirtualItemsGroup' => array(
+ 'httpMethod' => 'DELETE',
+ 'uri' => '/merchant/projects/{project_id}/virtual_items/groups/{group_id}',
+ 'summary' => 'Delete a virtual items group',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'group_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'ListVirtualItemsGroups' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/virtual_items/groups',
+ 'summary' => 'List all virtual items groups',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'UpdateVirtualItemOrderInGroup' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => 'https://api.xsolla.com/merchant/projects/{project_id}/virtual_items/sort',
+ 'summary' => 'Update items order in group',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ // Virtual Currency
+ 'GetProjectVirtualCurrencySettings' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/virtual_currency',
+ 'summary' => 'Get project virtual currency settings',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'UpdateProjectVirtualCurrencySettings' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/projects/{project_id}/virtual_currency',
+ 'summary' => 'Update project virtual currency settings',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ // Wallet
+ 'CreateWalletUser' => array(
+ 'httpMethod' => 'POST',
+ 'uri' => '/merchant/projects/{project_id}/users',
+ 'summary' => 'Create a new user',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'GetWalletUser' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/users/{user_id}',
+ 'summary' => 'Retrieve a user data',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'user_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'UpdateWalletUser' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/projects/{project_id}/users/{user_id}',
+ 'summary' => 'Update user\'s information',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'user_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'ListWalletUsers' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/users',
+ 'summary' => 'List all users',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'email' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ 'phone' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ 'limit' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'offset' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'ListWalletUserOperations' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/users/{user_id}/transactions',
+ 'summary' => 'List all operations',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'user_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'datetime_from' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'datetime_to' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'RechargeWalletUserBalance' => array(
+ 'httpMethod' => 'POST',
+ 'uri' => '/merchant/projects/{project_id}/users/{user_id}/recharge',
+ 'summary' => 'Change a balance',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'user_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'ListWalletUserVirtualItems' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/users/{user_id}/virtual_items',
+ 'summary' => 'Get user\'s virtual items',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'user_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'limit' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'offset' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'AddVirtualItemToWalletUser' => array(
+ 'httpMethod' => 'POST ',
+ 'uri' => 'https://api.xsolla.com/merchant/projects/{project_id}/users/{user_id}/virtual_items/add',
+ 'summary' => 'Add the virtual items to the user\'s account',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'user_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'DeleteVirtualItemFromWalletUser' => array(
+ 'httpMethod' => 'POST ',
+ 'uri' => 'https://api.xsolla.com/merchant/projects/{project_id}/users/{user_id}/virtual_items/remove',
+ 'summary' => 'Delete the virtual items from the user\'s account',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'user_id' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ // Coupons
+ 'GetCoupon' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/projects/{project_id}/coupons/{code}',
+ 'summary' => 'Get information about coupon by code',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'code' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'RedeemCoupon' => array(
+ 'httpMethod' => 'POST ',
+ 'uri' => '/merchant/projects/{project_id}/coupons/{code}/redeem',
+ 'summary' => 'Redeem coupon by code',
+ 'parameters' => array(
+ 'project_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'code' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ // Promotions
+ 'CreatePromotion' => array(
+ 'httpMethod' => 'POST',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions',
+ 'summary' => 'Create a new promotion',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'GetPromotion' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions/{promotion_id}',
+ 'summary' => 'Get a promotion',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'promotion_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'UpdatePromotion' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions/{promotion_id}',
+ 'summary' => 'Update a promotion. If the promotion is read-only (read_only = true), you are not allowed to change "project_id" parameter.',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'promotion_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'ReviewPromotion' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions/{promotion_id}/review',
+ 'summary' => 'Check the promotion, if it is ready for activation. This method returns the list of errors (if they exist).',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'promotion_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'TogglePromotion' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions/{promotion_id}/toggle',
+ 'summary' => 'Toggle the promotion. Change the status of promotion from enabled to disabled and vice versa.',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'promotion_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'DeletePromotion' => array(
+ 'httpMethod' => 'DELETE',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions/{promotion_id}',
+ 'summary' => 'Delete a promotion. Only disabled promotion is allowed to delete (enabled = false).',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'promotion_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'ListPromotions' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions',
+ 'summary' => 'List all promotions',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'GetPromotionSubject' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions/{promotion_id}/subject',
+ 'summary' => 'Get the subject of the promotion',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'promotion_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'SetPromotionSubject' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions/{promotion_id}/subject',
+ 'summary' => 'Set the subject of the promotion. If the promotion is read-only (read_only = true), you are not allowed to update the subject. The subject can take the following values: "purchase", or "items", or "packages".',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'promotion_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'GetPromotionPaymentSystems' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions/{promotion_id}/payment_systems',
+ 'summary' => 'Get the payment systems of the promotion. If the payment systems list is empty, the promotion will be valid for all payment systems.',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'promotion_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'SetPromotionPaymentSystems' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions/{promotion_id}/payment_systems',
+ 'summary' => 'Set the payment systems of the promotion. If the payment systems list is empty, the promotion will be applied for all payment systems. If the promotion is read-only (read_only = true), you are not allowed to call this command.',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'promotion_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'GetPromotionPeriods' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions/{promotion_id}/periods',
+ 'summary' => 'Get the periods of the promotion',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'promotion_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'SetPromotionPeriods' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions/{promotion_id}/periods',
+ 'summary' => 'Set the periods of the promotion. If the promotion is read-only (read_only = true), you are not allowed to edit existing periods, add new periods only.',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'promotion_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ 'GetPromotionRewards' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions/{promotion_id}/rewards',
+ 'summary' => 'Get the rewards of the promotion',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'promotion_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'SetPromotionRewards' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/merchants/{merchant_id}/promotions/{promotion_id}/rewards',
+ 'summary' => 'Set the rewards to the promotion. If the promotion is read-only (read_only = true), you are not allowed to update the rewards.',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'promotion_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ // Events
+ 'ListEvents' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/merchants/{merchant_id}/events/messages',
+ 'summary' => 'List all events from Xsolla Event System',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ ),
+ ),
+ // Reports
+ 'ListPaymentsRegistry' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/merchants/{merchant_id}/reports/transactions/registry.{format}',
+ 'summary' => 'Get information about all transactions for specified data range/transfer/report in different data formats. JSON, CSV or XML will be returned in response from the API.',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'format' => array(
+ 'location' => 'uri',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ 'datetime_from' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ 'datetime_to' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ 'project_id' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => false,
+ ),
+ 'show_dry_run' => array(
+ 'location' => 'query',
+ 'type' => 'boolean',
+ 'required' => false,
+ ),
+ 'transfer_id' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => false,
+ ),
+ 'report_id' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => false,
+ ),
+ 'limit' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => false,
+ ),
+ 'offset' => array(
+ 'location' => 'query',
+ 'type' => 'integer',
+ 'required' => false,
+ ),
+ 'in_transfer_currency' => array(
+ 'location' => 'query',
+ 'type' => 'boolean',
+ 'required' => false,
+ ),
+ 'show_total' => array(
+ 'location' => 'query',
+ 'type' => 'boolean',
+ 'required' => false,
+ ),
+ ),
+ ),
+ 'ListTransfersRegistry' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/merchants/{merchant_id}/reports/transfers',
+ 'summary' => 'List all transfers',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'datetime_from' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ 'datetime_to' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ ),
+ ),
+ 'ListReportsRegistry' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/merchants/{merchant_id}/reports',
+ 'summary' => 'Get a list of finance reports for specified data range',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'datetime_from' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ 'datetime_to' => array(
+ 'location' => 'query',
+ 'type' => 'string',
+ 'required' => false,
+ ),
+ ),
+ ),
+ 'CreateRefundRequest' => array(
+ 'httpMethod' => 'PUT',
+ 'uri' => '/merchant/merchants/{merchant_id}/reports/transactions/{transaction_id}/refund',
+ 'summary' => 'Send a refund request. Money will be returned to user',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'transaction_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ 'request' => array(
+ 'location' => 'body',
+ 'type' => 'array',
+ 'required' => true,
+ 'filters' => array(
+ '\Xsolla\SDK\API\XsollaClient::jsonEncode',
+ ),
+ ),
+ ),
+ ),
+ // Support
+ 'ListSupportTickets' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/merchants/{merchant_id}/support/tickets',
+ 'summary' => 'List all tickets',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ ),
+ ),
+ 'ListSupportTicketComments' => array(
+ 'httpMethod' => 'GET',
+ 'uri' => '/merchant/merchants/{merchant_id}/support/tickets/{ticket_id}/comments',
+ 'summary' => 'List all comments',
+ 'parameters' => array(
+ 'merchant_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'static' => true,
+ 'required' => true,
+ ),
+ 'ticket_id' => array(
+ 'location' => 'uri',
+ 'type' => 'integer',
+ 'required' => true,
+ ),
+ ),
+ ),
+ ),
+);
diff --git a/src/API/XsollaClient.php b/src/API/XsollaClient.php
new file mode 100644
index 0000000..1e3e073
--- /dev/null
+++ b/src/API/XsollaClient.php
@@ -0,0 +1,174 @@
+ 'https://api.xsolla.com');
+ $required = array(
+ 'merchant_id',
+ 'api_key',
+ );
+ $config = Collection::fromConfig($config, $default, $required);
+ $client = new static(isset($config['base_url']) ? $config['base_url'] : null, $config);
+ $client->setDescription(ServiceDescription::factory(__DIR__.'/Resources/xsolla-2015-07-23.php'));
+ $client->setDefaultOption('auth', array($config['merchant_id'], $config['api_key'], 'Basic'));
+ $client->setDefaultOption('headers', array('Accept' => 'application/json', 'Content-Type' => 'application/json'));
+ $client->setDefaultOption('command.params', array('merchant_id' => $config['merchant_id']));
+ $client->setUserAgent(Version::getVersion());
+ $exceptionCb = function (Event $event) {
+ $previous = $event['exception'];
+ if ($previous instanceof BadResponseException) {
+ $e = XsollaAPIException::fromBadResponse($previous);
+ } else {
+ $e = new XsollaAPIException('XsollaClient Exception: '.$previous->getMessage(), 0, $previous);
+ }
+ throw $e;
+ };
+ $client->getEventDispatcher()->addListener('request.exception', $exceptionCb);
+
+ return $client;
+ }
+
+ /**
+ * @param int $projectId
+ * @param string $userId
+ * @return string
+ */
+ public function createCommonPaymentUIToken($projectId, $userId)
+ {
+ $tokenRequest = new TokenRequest($projectId, $userId);
+
+ return $this->createPaymentUITokenFromRequest($tokenRequest);
+ }
+
+ /**
+ * @param TokenRequest $tokenRequest
+ * @return string
+ */
+ public function createPaymentUITokenFromRequest(TokenRequest $tokenRequest)
+ {
+ $parsedResponse = $this->CreatePaymentUIToken(array('request' => $tokenRequest->toArray()));
+
+ return $parsedResponse['token'];
+ }
+}
diff --git a/src/Api/ApiFactory.php b/src/Api/ApiFactory.php
deleted file mode 100644
index fba262a..0000000
--- a/src/Api/ApiFactory.php
+++ /dev/null
@@ -1,59 +0,0 @@
-client = $client ?: $this->setUpClient();
- $this->project = $project;
- }
-
- protected function setUpClient()
- {
- $client = new Client(self::BASE_URL);
- $client->setUserAgent(Version::getVersion());
-
- return $client;
- }
-
- public function getCalculatorApi()
- {
- return new CalculatorApi($this->client, $this->project);
- }
-
- public function getMobilePaymentApi()
- {
- return new MobilePaymentApi($this->client, $this->project);
- }
-
- public function getNumberApi()
- {
- return new NumberApi($this->client, $this->project);
- }
-
- public function getQiwiWalletApi()
- {
- return new QiwiWalletApi($this->client, $this->project);
- }
-
- /**
- * @param bool $isTest
- * @return SubscriptionsApi
- */
- public function getSubscriptionsApi($isTest = false)
- {
- return new SubscriptionsApi($this->client, $this->project, $isTest);
- }
-}
diff --git a/src/Api/CalculatorApi.php b/src/Api/CalculatorApi.php
deleted file mode 100644
index 7cb4e38..0000000
--- a/src/Api/CalculatorApi.php
+++ /dev/null
@@ -1,61 +0,0 @@
-client = $client;
- $this->project = $project;
- }
-
- /**
- * @param int $geotypeId payment system ID
- * @param float $amount
- * @return string
- */
- public function calculateVirtualCurrencyAmount($geotypeId, $amount)
- {
- $request = $this->createRequest('/calc/out.php', $geotypeId, $amount);
-
- return $request->send()->getBody(true);
- }
-
- /**
- * @param int $geotypeId payment system ID
- * @param float $virtualCurrencyAmount
- * @return string
- */
- public function calculateAmount($geotypeId, $virtualCurrencyAmount)
- {
- $request = $this->createRequest('/calc/inn.php', $geotypeId, $virtualCurrencyAmount);
-
- return $request->send()->getBody(true);
- }
-
- protected function createRequest($url, $geotypeId, $amount)
- {
- return $this->client->get(
- $url,
- array(),
- array(
- 'query' => array(
- 'project_id' => $this->project->getProjectId(),
- 'geotype_id' => $geotypeId,
- 'sum' => $amount
- )
- )
- );
- }
-}
diff --git a/src/Api/MobilePaymentApi.php b/src/Api/MobilePaymentApi.php
deleted file mode 100644
index 988b82e..0000000
--- a/src/Api/MobilePaymentApi.php
+++ /dev/null
@@ -1,131 +0,0 @@
-client = $client;
- $this->project = $project;
- }
-
- public function createInvoice(User $user, Invoice $invoice)
- {
- $email = $user->getEmail();
- $queryParams = array(
- 'command' => 'invoice',
- 'project' => $this->project->getProjectId(),
- 'v1' => $user->getV1(),
- 'v2' => $user->getV2(),
- 'v3' => $user->getV3(),
- 'sum' => $invoice->getAmount(),
- 'out' => $invoice->getVirtualCurrencyAmount(),
- 'phone' => $user->getPhone(),
- 'userip' => $user->getUserIP()
- );
-
- if (!empty($email)) {
- $queryParams['email'] = $email;
- }
-
- $result = $this->send($queryParams, __DIR__ . $this->xsd_path_invoice);
-
- $this->checkCodeResult($result);
-
- $resultInvoice = new Invoice();
- $resultInvoice->setId($result->invoice);
-
- return $resultInvoice;
-
- }
-
- protected function calculate(User $user, array $operationParams)
- {
- $queryParams = array(
- 'command' => 'calculate',
- 'project' => $this->project->getProjectId(),
- 'phone' => $user->getPhone()
- );
- $queryParams = array_merge($queryParams, $operationParams);
-
- $result = $this->send(
- $queryParams,
- __DIR__ . $this->xsd_path_calculate
- );
-
- $this->checkCodeResult($result);
-
- return new Invoice($result->out, $result->sum);
- }
-
- public function calculateVirtualCurrencyAmount(User $user, $amount)
- {
- $operationParams = array('sum' => $amount);
- return $this->calculate($user, $operationParams);
- }
-
- public function calculateAmount(User $user, $virtualCurrencyAmount)
- {
- $operationParams = array('out' => $virtualCurrencyAmount);
- return $this->calculate($user, $operationParams);
- }
-
- protected function createSignString(array $params)
- {
- $signString = '';
- foreach ($params as $value) {
- $signString .= $value;
- }
-
- return $signString;
- }
-
- protected function send(array $queryParams, $schemaFilename)
- {
- $signString = $this->createSignString($queryParams);
- $queryParams['md5'] = md5($signString . $this->project->getSecretKey());
- $request = $this->client->get($this->url, array(), array('query' => $queryParams));
-
- $xsollaResponse = $request->send()->getBody();
- $xsd = new Xsd();
- $xsd->check($xsollaResponse, $schemaFilename);
- $result = new \SimpleXMLElement($xsollaResponse);
-
- return $result;
- }
-
- protected function checkCodeResult($result)
- {
- if ($result->result == self::CODE_ERROR_WRONG_SIGN) {
- throw new SecurityException((string) $result->comment, (int) $result->result);
- } elseif ($result->result == self::CODE_ERROR_INTERNAL_SERVER) {
- throw new InternalServerException((string) $result->comment, (int) $result->result);
- } elseif ($result->result != self::CODE_SUCCESS) {
- throw new InvalidArgumentException((string) $result->comment, (int) $result->result);
- }
- }
-}
diff --git a/src/Api/NumberApi.php b/src/Api/NumberApi.php
deleted file mode 100644
index e44d8b3..0000000
--- a/src/Api/NumberApi.php
+++ /dev/null
@@ -1,61 +0,0 @@
-client = $client;
- $this->project = $project;
- }
-
- /**
- * @param User $user
- * @return int
- * @throws \RuntimeException
- */
- public function getNumber(User $user)
- {
- $request = $this->client->get(
- '/xsolla_number.php',
- array(),
- array(
- 'query' => array(
- 'project' => $this->project->getProjectId(),
- 'v1' => $user->getV1(),
- 'v2' => $user->getV2(),
- 'v3' => $user->getV3(),
- 'email' => $user->getEmail(),
- 'format' => 'json'
- )
- )
- );
-
- $response = $request->send()->json();
- if (self::CODE_SUCCESS == $response['result']) {
- return $response['number'];
- } elseif (in_array($response['result'], $this->temporaryErrorCodes)) {
- throw new InternalServerException($response['description'], $response['result']);
- } else {
- throw new InvalidArgumentException($response['description'], $response['result']);
- }
- }
-}
diff --git a/src/Api/QiwiWalletApi.php b/src/Api/QiwiWalletApi.php
deleted file mode 100644
index 4f90809..0000000
--- a/src/Api/QiwiWalletApi.php
+++ /dev/null
@@ -1,21 +0,0 @@
-client = $client;
- $this->project = $project;
- $this->isTest = $isTest;
- }
-
- /**
- * @param User $user
- * @param int $type One of Subscriptions::TYPE_* constants
- * @return Subscription[]
- */
- public function search(User $user, $type = null)
- {
- $parameters = array(
- 'merchant_id' => $this->project->getProjectId(),
- 'v1' => $user->getV1(),
- 'v2' => $user->getV2(),
- 'v3' => $user->getV3(),
- 'type' => $type,
- 'test' => $this->isTest
- );
-
- $request = $this->client->get(
- self::URL,
- array('X-Xsolla-Sign' => $this->generateSign($parameters)),
- array('query' => $parameters)
- );
-
- try {
- $rows = $request->send()->json();
- } catch (ClientErrorResponseException $e) {
- $this->processException($e);
- }
-
- $subscriptions = array();
- foreach ($rows['subscriptions'] as $row) {
- $subscriptions[] = new Subscription($row['id'], $row['name'], $row['type'], $row['currency']);
- }
-
- return $subscriptions;
- }
-
- public function pay(Subscription $subscription, Invoice $invoice, $cardCvv = null)
- {
- $parameters = array(
- 'subscription_id' => $subscription->getId(),
- 'merchant_id' => $this->project->getProjectId(),
- 'amount_virtual' => $invoice->getVirtualCurrencyAmount(),
- 'card_cvv' => $cardCvv
- );
-
- $request = $this->client->post(
- self::URL . '/' . $subscription->getType(),
- array('X-Xsolla-Sign' => $this->generateSign($parameters)),
- null,
- array('query' => $parameters)
- );
-
- try {
- $result = $request->send()->json();
-
- return $result['id'];
- } catch (ClientErrorResponseException $e) {
- $this->processException($e);
- }
- }
-
- public function delete(Subscription $subscription)
- {
- $parameters = array(
- 'merchant_id' => $this->project->getProjectId(),
- 'subscription_id' => $subscription->getId()
- );
- $request = $this->client->delete(
- self::URL . '/' . $subscription->getType(),
- array('X-Xsolla-Sign' => $this->generateSign($parameters)),
- null,
- array('query' => $parameters)
- );
-
- try {
- return Response::HTTP_NO_CONTENT == $request->send()->getStatusCode();
- } catch (ClientErrorResponseException $e) {
- $this->processException($e);
- }
- }
-
- protected function generateSign($parameters)
- {
- $signString = '';
- ksort($parameters);
- foreach ($parameters as $key => $val) {
- $signString .= $key . '=' . $val;
- }
-
- return md5($signString . $this->project->getSecretKey());
- }
-
- public function processException(ClientErrorResponseException $e)
- {
- $response = $e->getResponse()->json();
- if (self::ERROR_CODE_INVALID_SIGN == $response['error']['code']) {
- throw new SecurityException($response['error']['message'], $response['error']['code']);
- }
- throw new InvalidArgumentException($response['error']['message'], $response['error']['code']);
- }
-}
diff --git a/src/Exception/API/AccessDeniedException.php b/src/Exception/API/AccessDeniedException.php
new file mode 100644
index 0000000..d389619
--- /dev/null
+++ b/src/Exception/API/AccessDeniedException.php
@@ -0,0 +1,7 @@
+ '\Xsolla\SDK\Exception\API\UnprocessableEntityException',
+ 403 => '\Xsolla\SDK\Exception\API\AccessDeniedException',
+ );
+
+ protected static $messageTemplate =
+<<getResponse()->getStatusCode();
+ $message = sprintf(
+ static::$messageTemplate,
+ $previous->getMessage(),
+ $previous->getRequest(),
+ $previous->getResponse()
+ );
+ if (array_key_exists($statusCode, static::$exceptions)) {
+ return new static::$exceptions[$statusCode]($message, 0, $previous);
+ }
+
+ return new self($message, 0, $previous);
+ }
+}
diff --git a/src/Exception/Exception.php b/src/Exception/Exception.php
deleted file mode 100644
index 67e1f2d..0000000
--- a/src/Exception/Exception.php
+++ /dev/null
@@ -1,8 +0,0 @@
-amount = $amount;
- $this->virtualCurrencyAmount = $virtualCurrencyAmount;
- $this->currency = $currency;
- $this->id = $id;
- $this->amountShoppingCart3 = $amountShoppingCart3;
- $this->currencyShoppingCart3 = $currencyShoppingCart3;
- }
-
- public function getVirtualCurrencyAmount()
- {
- return $this->virtualCurrencyAmount;
- }
-
- public function getAmount()
- {
- return $this->amount;
- }
-
- public function getCurrency()
- {
- return $this->currency;
- }
-
- public function getId()
- {
- return $this->id;
- }
-
- public function setCurrency($currency)
- {
- $this->currency = $currency;
-
- return $this;
- }
-
- public function setId($id)
- {
- $this->id = $id;
-
- return $this;
- }
-
- public function setVirtualCurrencyAmount($out)
- {
- $this->virtualCurrencyAmount = $out;
-
- return $this;
- }
-
- public function setAmount($sum)
- {
- $this->amount = $sum;
-
- return $this;
- }
-
- public function setAmountShoppingCart3($amountShoppingCart3)
- {
- $this->amountShoppingCart3 = $amountShoppingCart3;
- return $this;
- }
-
- public function getAmountShoppingCart3()
- {
- return $this->amountShoppingCart3;
- }
-
- public function setCurrencyShoppingCart3($currencyShoppingCart3)
- {
- $this->currencyShoppingCart3 = $currencyShoppingCart3;
- return $this;
- }
-
- public function getCurrencyShoppingCart3()
- {
- return $this->currencyShoppingCart3;
- }
-
-}
diff --git a/src/PaymentPage/UrlBuilder.php b/src/PaymentPage/UrlBuilder.php
deleted file mode 100644
index 275932f..0000000
--- a/src/PaymentPage/UrlBuilder.php
+++ /dev/null
@@ -1,226 +0,0 @@
- 'project',
- 'signparams' => 'signparams',
- );
-
- protected $defaultLockedParameters = array(
- 'theme' => 'theme',
- 'project' => 'project',
- 'signparams' => 'signparams',
- 'v0' => 'v0',
- 'v1' => 'v1',
- 'v2' => 'v2',
- 'v3' => 'v3',
- 'out' => 'out',
- 'email' => 'email',
- 'currency' => 'currency',
- 'userip' => 'userip',
- 'allowSubscription' => 'allowSubscription',
- 'fastcheckout' => 'fastcheckout',
- 'id_package' => 'id_package',
- 'payment_amount' => 'payment_amount',
- 'payment_currency' => 'payment_currency',
- );
-
- protected $defaultParameters = array();
-
- public function __construct(Project $project, array $immutableParameters = array())
- {
- $this->project = $project;
- $this->immutableParameters = $immutableParameters;
- $this->clear();
- }
-
- public function setUser(User $user, $lockForUser = true, $hideFromUser = false)
- {
- $this->setParameter('v1', $user->getV1(), $lockForUser, $hideFromUser);
- $this->setParameter('v2', $user->getV2(), $lockForUser, $hideFromUser);
- $this->setParameter('v3', $user->getV3(), $lockForUser, $hideFromUser);
- $this->setParameter('email', $user->getEmail(), $lockForUser, $hideFromUser);
- $this->setParameter('userip', $user->getUserIP(), $lockForUser, $hideFromUser);
- $this->setParameter('phone', $user->getPhone(), $lockForUser, $hideFromUser);
-
- return $this;
- }
-
- public function setInvoice(Invoice $invoice, $lockForUser = true, $hideFromUser = false)
- {
- $this->setParameter('out', $invoice->getVirtualCurrencyAmount(), $lockForUser, $hideFromUser);
- $this->setParameter('currency', $invoice->getCurrency(), $lockForUser, $hideFromUser);
- $this->setParameter('sum', $invoice->getAmount(), $lockForUser, $hideFromUser);
- $this->setParameter('payment_amount', $invoice->getAmountShoppingCart3(), $lockForUser, $hideFromUser);
- $this->setParameter('payment_currency', $invoice->getCurrencyShoppingCart3(), $lockForUser, $hideFromUser);
- return $this;
- }
-
- /**
- * @param string $locale 2-letter definition is used according to ISO 639-1 standard
- * @return $this
- */
- public function setLocale($locale)
- {
- return $this->setParameter('local', $locale, false, false);
- }
-
- /**
- * @param string $country 2-letter definition of the country is used according to ISO 3166-1 alpha-2 standard
- * @return $this
- */
- public function setCountry($country)
- {
- return $this->setParameter('country', $country, false, false);
- }
-
- /**
- * @param string $name Additional parameters are described in documentation http://xsolla.github.io/en/pswidget.html#title4
- * @param string $value
- * @param bool $lockForUser Denies user to change parameter value on payment page. Also parameter will be hidden on payment page
- * @param bool $hideFromUser Hides parameter value on payment page
- * @return $this
- */
- public function setParameter($name, $value, $lockForUser = false, $hideFromUser = false)
- {
- if (!$value) {
- return $this;
- }
- $this->parameters[$name] = $value;
- if ($hideFromUser) {
- $this->hiddenParameters[] = $name;
- }
- if ($lockForUser) {
- $this->lockParameterForUser($name);
- } else {
- $this->unlockParameterForUser($name);
- }
-
- return $this;
- }
-
- /**
- * @param string $name Denies user change parameter value on payment page
- * @return $this
- */
- public function lockParameterForUser($name)
- {
- $this->lockedParameters[$name] = $name;
-
- return $this;
- }
-
- /**
- * @param string $name Allows user to change parameter value on payment page
- * @return $this
- */
- public function unlockParameterForUser($name)
- {
- unset($this->lockedParameters[$name]);
-
- return $this;
- }
-
- public function clear()
- {
- $this->parameters = array();
- $this->hiddenParameters = array();
- $this->lockedParameters = $this->defaultLockedParameters;
-
- return $this;
- }
-
- public function getUrl($baseUrl = self::BASE_URL)
- {
- $parameters = array_merge($this->parameters, $this->immutableParameters);
- $parameters['project'] = $this->project->getProjectId();
-
- $hiddenParametersList = $this->getHiddenParametersList();
- if ($hiddenParametersList) {
- $parameters['hidden'] = $hiddenParametersList;
- }
-
- $lockedParametersList = $this->getLockedParametersList();
- if ($lockedParametersList) {
- $parameters['signparams'] = $lockedParametersList;
- }
- $isSandbox = $baseUrl === self::SANDBOX_URL;
- $parameters['sign'] = $this->generateSign($parameters, $isSandbox);
-
- return $baseUrl.http_build_query($parameters);
- }
-
- protected function getLockedParametersList()
- {
- $lockedParameters = $this->getSignParametersSortedKeys();
- if (!array_diff($lockedParameters, $this->defaultLockedParameters) and
- !array_diff($this->defaultLockedParameters, $lockedParameters)
- ) {
- return;
- }
-
- return $this->implodeParameters($lockedParameters);
- }
-
- protected function getHiddenParametersList()
- {
- return $this->implodeParameters($this->hiddenParameters);
- }
-
- protected function implodeParameters(array $parameters)
- {
- if (!$parameters) {
- return;
- }
- $uniqueParameters = array_unique($parameters);
-
- return implode(',', $uniqueParameters);
- }
-
- protected function generateSign(array $params, $isSandbox = false)
- {
- $keys = $this->getSignParametersSortedKeys();
- $sign = '';
- foreach ($keys as $key) {
- if (isset($params[$key])) {
- $sign .= $key . '=' . $params[$key];
- }
- }
- $key = $this->project->getSecretKey();
- if ($isSandbox) {
- $key = self::SANDBOX_KEY.$key;
- }
-
- return md5($sign . $key);
- }
-
- protected function getSignParametersSortedKeys()
- {
- $parameters = array_merge($this->lockedParameters, $this->immutableLockedParameters);
- $keys = array_unique($parameters);
- sort($keys);
-
- return $keys;
- }
-}
diff --git a/src/PaymentPage/UrlBuilderFactory.php b/src/PaymentPage/UrlBuilderFactory.php
deleted file mode 100644
index bdfdcbf..0000000
--- a/src/PaymentPage/UrlBuilderFactory.php
+++ /dev/null
@@ -1,75 +0,0 @@
-project = $project;
- }
-
- /**
- * @link http://xsolla.github.io/en/paystation.html
- * @return UrlBuilder
- */
- public function getPayStation()
- {
- return new UrlBuilder($this->project, array('marketplace' => 'paystation'));
- }
-
- /**
- * @link http://xsolla.github.io/en/card.html
- * @return UrlBuilder
- */
- public function getCreditCards()
- {
- return new UrlBuilder(
- $this->project,
- array('marketplace' => 'landing', 'pid'=> 1380, 'theme' => 201)
- );
- }
-
- /**
- * @link http://xsolla.github.io/en/pswidget.html
- * @return UrlBuilder
- */
- public function getPayDesk()
- {
- return new UrlBuilder($this->project, array('marketplace' => 'paydesk'));
- }
-
- /**
- * @link http://xsolla.github.io/en/mversion.html
- * @return UrlBuilder
- */
- public function getMobilePayment()
- {
- return new UrlBuilder(
- $this->project,
- array('marketplace' => 'landing', 'theme' => 201, 'pid' => 1738)
- );
- }
-
- /**
- * @link http://xsolla.github.io/en/directpayment.html
- * @param int $pid payment system ID
- * @return UrlBuilder
- */
- public function getDirectPayment($pid)
- {
- return new UrlBuilder($this->project, array('marketplace' => 'landing', 'pid' => $pid));
- }
-
- /**
- * @link http://xsolla.github.io/en/mversion.html
- * @return UrlBuilder
- */
- public function getMobileVersion()
- {
- return new UrlBuilder($this->project, array('marketplace' => 'mobile'));
- }
-}
diff --git a/src/Project.php b/src/Project.php
deleted file mode 100644
index b7bb90c..0000000
--- a/src/Project.php
+++ /dev/null
@@ -1,30 +0,0 @@
-projectId = $projectId;
- $this->secretKey = $secretKey;
- }
-
- /**
- * @return int
- */
- public function getProjectId()
- {
- return $this->projectId;
- }
-
- /**
- * @return string
- */
- public function getSecretKey()
- {
- return $this->secretKey;
- }
-}
diff --git a/src/Protocol/Command/Cancel.php b/src/Protocol/Command/Cancel.php
deleted file mode 100644
index 137e3a1..0000000
--- a/src/Protocol/Command/Cancel.php
+++ /dev/null
@@ -1,51 +0,0 @@
-project = $protocol->getProject();
- $this->paymentStorage = $paymentStorage;
- }
-
- public function process(Request $request)
- {
- try {
- $this->paymentStorage->cancel(
- $request->query->get('id'),
- $request->query->get('reason_code'),
- $request->query->get('reason')
- );
-
- return array(
- 'result' => self::CODE_SUCCESS,
- self::COMMENT_FIELD_NAME => '',
- );
- } catch (InvoiceNotFoundException $e) {
- return array(
- 'result' => self::CODE_INVALID_ORDER_DETAILS,
- self::COMMENT_FIELD_NAME => trim('Invoice not found. ' . $e->getMessage()),
- );
- }
- }
-
- public function checkSign(Request $request)
- {
- return $this->generateSign($request, array('command', 'id')) === $request->query->get('md5');
- }
-
- public function getRequiredParams()
- {
- return array('command', 'md5', 'id');
- }
-
-}
diff --git a/src/Protocol/Command/Check.php b/src/Protocol/Command/Check.php
deleted file mode 100644
index 48a1e9e..0000000
--- a/src/Protocol/Command/Check.php
+++ /dev/null
@@ -1,51 +0,0 @@
-userStorage = $protocol->getUserStorage();
- $this->project = $protocol->getProject();
- }
-
- public function process(Request $request)
- {
- $user = $this->createUser($request);
- $hasUser = $this->userStorage->isUserExists($user);
- if ($hasUser) {
- $response = array('result' => self::CODE_SUCCESS);
- $spec = $this->userStorage->getAdditionalUserFields($user);
- if (count($spec) > 0) {
- $response['specification'] = $spec;
- }
- } else {
- $response = array('result' => self::CODE_USER_NOT_FOUND);
- }
- $response['comment'] = '';
-
- return $response;
- }
-
- public function checkSign(Request $request)
- {
- return $this->generateSign($request, array('command', 'v1')) === $request->query->get('md5');
- }
-
- public function getRequiredParams()
- {
- return array('command', 'v1', 'md5');
- }
-}
diff --git a/src/Protocol/Command/CheckShoppingCart3.php b/src/Protocol/Command/CheckShoppingCart3.php
deleted file mode 100644
index c69ca56..0000000
--- a/src/Protocol/Command/CheckShoppingCart3.php
+++ /dev/null
@@ -1,19 +0,0 @@
-userStorage = $protocol->getUserStorage();
- $this->project = $protocol->getProject();
- }
-
- public function checkSign(Request $request)
- {
- return $this->generateSign($request, array('command', 'v1', 'foreignInvoice')) === $request->query->get('md5');
- }
-}
\ No newline at end of file
diff --git a/src/Protocol/Command/Command.php b/src/Protocol/Command/Command.php
deleted file mode 100644
index 8321901..0000000
--- a/src/Protocol/Command/Command.php
+++ /dev/null
@@ -1,102 +0,0 @@
-checkRequiredParams($request)) {
- $missedParameters = array_diff($this->getRequiredParams(), $request->query->keys());
- $exceptionMessage = 'Invalid request format. Missed parameters: ' . implode(', ', $missedParameters);
- throw new InvalidRequestException($exceptionMessage);
- }
-
- if (!$this->checkSign($request)) {
- throw new InvalidSignException('Invalid md5 signature');
- }
-
- return $this->process($request);
- }
-
- public function checkRequiredParams(Request $request)
- {
- $requiredParameters = $this->getRequiredParams();
-
- foreach ($requiredParameters as $param) {
- $value = $request->query->get($param);
- if (empty($value) and $value !== '0') {
- return false;
- }
- }
-
- return true;
- }
-
- public function generateSign(Request $request, $parameters)
- {
- $signString = '';
- foreach ($parameters as $parameter) {
- $signString .= $request->query->get($parameter);
- }
-
- return md5($signString . $this->project->getSecretKey());
- }
-
- protected function getDateTimeXsolla($format, $datetime)
- {
- $xsollaTimeZone = new \DateTimeZone('Europe/Moscow');
- $datetimeObj = \DateTime::createFromFormat($format, $datetime, $xsollaTimeZone);
- if (!$datetimeObj) {
- throw new InvalidRequestException(sprintf('Datetime string %s could not be converted to DateTime object from format \'%s\'', $datetime, $format));
- }
- $datetimeObj->setTimezone(new \DateTimeZone(date_default_timezone_get()));
-
- return $datetimeObj;
- }
-
- protected function emptyStringToNull($string)
- {
- $trimmedString = trim($string);
-
- return $trimmedString == '' ? null : $trimmedString;
- }
-
- // @codeCoverageIgnoreStart
- abstract public function checkSign(Request $request);
-
- abstract public function process(Request $request);
-
- abstract public function getRequiredParams();
-
- abstract public function getInvalidSignResponseCode();
-
- abstract public function getInvalidRequestResponseCode();
-
- abstract public function getCommentFieldName();
-
- abstract public function getUnprocessableRequestResponseCode();
-
- abstract public function getTemporaryServerErrorResponseCode();
- // @codeCoverageIgnoreEnd
-}
diff --git a/src/Protocol/Command/PayShoppingCart.php b/src/Protocol/Command/PayShoppingCart.php
deleted file mode 100644
index 5ceb88a..0000000
--- a/src/Protocol/Command/PayShoppingCart.php
+++ /dev/null
@@ -1,87 +0,0 @@
-project = $protocol->getProject();
- $this->paymentStorage = $protocol->getPaymentShoppingCartStorage();
- }
-
- public function getRequiredParams()
- {
- return array('command', 'sign', 'id', 'v1', 'amount', 'currency', 'datetime');
- }
-
- public function process(Request $request)
- {
- $datetime = $this->getDateTimeXsolla('YmdHis', $request->query->get('datetime'));
- $idShop = $this->paymentStorage->pay(
- $request->query->get('id'),
- $request->query->get('amount'),
- $request->query->get('v1'),
- $this->emptyStringToNull($request->query->get('v2')),
- $this->emptyStringToNull($request->query->get('v3')),
- $request->query->get('currency'),
- $datetime,
- (bool) $request->query->get('dry_run'),
- $request->query->get('userAmount'),
- $request->query->get('userCurrency'),
- $request->query->get('transferAmount'),
- $request->query->get('transferCurrency'),
- $request->query->get('pid'),
- $request->query->get('geotype')
- );
-
- return array('result' => self::CODE_SUCCESS, self::COMMENT_FIELD_NAME => '', 'id_shop' => $idShop);
- }
-
- public function checkSign(Request $request)
- {
- $actualSign = $this->generateSign($request, array('v1', 'amount', 'currency', 'id'));
-
- return $actualSign === $request->query->get('sign');
- }
-
- public function getCommentFieldName()
- {
- return self::COMMENT_FIELD_NAME;
- }
-
- public function getInvalidSignResponseCode()
- {
- return self::CODE_FATAL_ERROR;
- }
-
- public function getInvalidRequestResponseCode()
- {
- return self::CODE_INVALID_REQUEST;
- }
-
- public function getUnprocessableRequestResponseCode()
- {
- return self::CODE_FATAL_ERROR;
- }
-
- public function getTemporaryServerErrorResponseCode()
- {
- return self::CODE_TEMPORARY_ERROR;
- }
-}
diff --git a/src/Protocol/Command/PayShoppingCart3.php b/src/Protocol/Command/PayShoppingCart3.php
deleted file mode 100644
index 720cfe5..0000000
--- a/src/Protocol/Command/PayShoppingCart3.php
+++ /dev/null
@@ -1,62 +0,0 @@
-userStorage = $protocol->getUserStorage();
- $this->project = $protocol->getProject();
- $this->paymentStorage = $protocol->getPaymentShoppingCart3Storage();
- }
-
- public function checkSign(Request $request)
- {
- return $this->generateSign($request, array('command', 'v1', 'foreignInvoice', 'id')) === $request->query->get('md5');
- }
-
- public function process(Request $request)
- {
- $user = $this->createUser($request);
- if (!$this->userStorage->isUserExists($user)) {
- return array(
- 'result' => self::CODE_INVALID_ORDER_DETAILS,
- self::COMMENT_FIELD_NAME => 'User not found'
- );
- }
- $datetime = $this->getDateTimeXsolla('Y-m-d H:i:s', $request->query->get('date'));
- $id = $this->paymentStorage->pay(
- $request->query->get('id'),
- $request->query->get('payment_amount'),
- $request->query->get('payment_currency'),
- $user,
- $datetime,
- (bool) $request->query->get('dry_run')
- );
- return array(
- 'result' => self::CODE_SUCCESS,
- self::COMMENT_FIELD_NAME => '',
- 'id_shop' => $id
- );
- }
-
- public function getRequiredParams()
- {
- return array('command', 'md5', 'id', 'v1', 'date', 'payment_amount', 'payment_currency');
- }
-}
\ No newline at end of file
diff --git a/src/Protocol/Command/PayStandard.php b/src/Protocol/Command/PayStandard.php
deleted file mode 100644
index 59f4f25..0000000
--- a/src/Protocol/Command/PayStandard.php
+++ /dev/null
@@ -1,63 +0,0 @@
-userStorage = $protocol->getUserStorage();
- $this->project = $protocol->getProject();
- $this->paymentStorage = $protocol->getPaymentStandardStorage();
- }
-
- public function getRequiredParams()
- {
- return array('command', 'md5', 'id', 'sum', 'v1', 'date');
- }
-
- public function process(Request $request)
- {
- $user = $this->createUser($request);
- if (!$this->userStorage->isUserExists($user)) {
- return array(
- 'result' => self::CODE_INVALID_ORDER_DETAILS,
- self::COMMENT_FIELD_NAME => 'User not found'
- );
- }
- $datetime = $this->getDateTimeXsolla('Y-m-d H:i:s', $request->query->get('date'));
- $id = $this->paymentStorage->pay(
- $request->query->get('id'),
- $request->query->get('sum'),
- $user,
- $datetime,
- (bool) $request->query->get('dry_run')
- );
-
- return array(
- 'result' => self::CODE_SUCCESS,
- self::COMMENT_FIELD_NAME => '',
- 'id_shop' => $id
- );
- }
-
- public function checkSign(Request $request)
- {
- return $this->generateSign($request, array('command', 'v1', 'id')) === $request->query->get('md5');
- }
-}
diff --git a/src/Protocol/Command/StandardCommand.php b/src/Protocol/Command/StandardCommand.php
deleted file mode 100644
index bdb5cf1..0000000
--- a/src/Protocol/Command/StandardCommand.php
+++ /dev/null
@@ -1,50 +0,0 @@
-emptyStringToNull($request->query->get('v1')),
- $this->emptyStringToNull($request->query->get('v2')),
- $this->emptyStringToNull($request->query->get('v3'))
- );
- }
-
- public function getCommentFieldName()
- {
- return self::COMMENT_FIELD_NAME;
- }
-
- public function getInvalidSignResponseCode()
- {
- return self::CODE_INVALID_SIGN;
- }
-
- public function getInvalidRequestResponseCode()
- {
- return self::CODE_INVALID_REQUEST;
- }
-
- public function getUnprocessableRequestResponseCode()
- {
- return self::CODE_FATAL_ERROR;
- }
-
- public function getTemporaryServerErrorResponseCode()
- {
- return self::CODE_TEMPORARY_ERROR;
- }
-}
diff --git a/src/Protocol/CommandFactory/ShoppingCart3Factory.php b/src/Protocol/CommandFactory/ShoppingCart3Factory.php
deleted file mode 100644
index 6f5da0d..0000000
--- a/src/Protocol/CommandFactory/ShoppingCart3Factory.php
+++ /dev/null
@@ -1,36 +0,0 @@
-getPaymentShoppingCart3Storage());
- default:
- throw new WrongCommandException(sprintf(
- 'Wrong command: "%s". Available commands for Standard protocol are: "%s".',
- $commandName,
- join('", "', $protocol->getProtocolCommands())
- ));
- }
- }
-}
\ No newline at end of file
diff --git a/src/Protocol/CommandFactory/ShoppingCartFactory.php b/src/Protocol/CommandFactory/ShoppingCartFactory.php
deleted file mode 100644
index c8b861d..0000000
--- a/src/Protocol/CommandFactory/ShoppingCartFactory.php
+++ /dev/null
@@ -1,35 +0,0 @@
-getPaymentShoppingCartStorage());
- default:
- throw new WrongCommandException(sprintf(
- 'Wrong command: "%s". Available commands for protocol ShoppingCart are: "%s".',
- $commandName,
- join('", "', $protocol->getProtocolCommands())
- ));
- }
- }
-
-}
diff --git a/src/Protocol/CommandFactory/StandardFactory.php b/src/Protocol/CommandFactory/StandardFactory.php
deleted file mode 100644
index 2f90bd4..0000000
--- a/src/Protocol/CommandFactory/StandardFactory.php
+++ /dev/null
@@ -1,38 +0,0 @@
-getPaymentStandardStorage());
- default:
- throw new WrongCommandException(sprintf(
- 'Wrong command: "%s". Available commands for Standard protocol are: "%s".',
- $commandName,
- join('", "', $protocol->getProtocolCommands())
- ));
- }
- }
-}
diff --git a/src/Protocol/Protocol.php b/src/Protocol/Protocol.php
deleted file mode 100644
index 8c6688d..0000000
--- a/src/Protocol/Protocol.php
+++ /dev/null
@@ -1,112 +0,0 @@
-project = $project;
- $this->xmlResponseBuilder = $xmlResponseBuilder;
- $this->ipChecker = $ipChecker;
- }
-
- /**
- * @return \Xsolla\SDK\Project
- */
- public function getProject()
- {
- return $this->project;
- }
-
- public function run(Request $request)
- {
- try {
- $commandResponse = $this->doRun($request);
- } catch (UnprocessableRequestException $e) {
- $commandResponse = $this->getUnprocessableRequestResponse($e);
- } catch (WrongCommandException $e) {
- $commandResponse = $this->getResponseForWrongCommand($e->getMessage());
- } catch (InvalidSignException $e) {
- $commandResponse = array(
- 'result' => $this->currentCommand->getInvalidSignResponseCode(),
- $this->currentCommand->getCommentFieldName() => $e->getMessage()
- );
- } catch (InvalidRequestException $e) {
- $commandResponse = array(
- 'result' => $this->currentCommand->getInvalidRequestResponseCode(),
- $this->currentCommand->getCommentFieldName() => $e->getMessage()
- );
- } catch (\Exception $e) {
- $commandResponse = array(
- 'result' => $this->currentCommand->getTemporaryServerErrorResponseCode(),
- $this->currentCommand->getCommentFieldName() => $e->getMessage()
- );
- }
-
- return $this->xmlResponseBuilder->get($commandResponse);
- }
-
- protected function doRun(Request $request)
- {
- if ($this->ipChecker) {
- $this->ipChecker->checkIp($request->getClientIp());
- }
- if (!$request->query->get('command')) {
- throw new WrongCommandException(sprintf(
- 'No command in request. Available commands are: "%s".',
- join('", "', $this->getProtocolCommands())
- ));
- }
- $this->currentCommand = $this->commandFactory->getCommand($this, $request->query->get('command'));
-
- return $this->currentCommand->getResponse($request);
- }
-
- protected function getUnprocessableRequestResponse(\Exception $e)
- {
- if ($this->currentCommand) {
- $code = $this->currentCommand->getUnprocessableRequestResponseCode();
- $commentFieldName = $this->currentCommand->getCommentFieldName();
- } else {
- $code = $this->unprocessableRequestResponseCode;
- $commentFieldName = $this->commentFieldName;
-
- }
- $commandResponse = array(
- 'result' => $code,
- $commentFieldName => $e->getMessage()
- );
- return $commandResponse;
- }
-
- // @codeCoverageIgnoreStart
- abstract public function getProtocolCommands();
-
- abstract public function getResponseForWrongCommand($message);
- // @codeCoverageIgnoreEnd
-}
diff --git a/src/Protocol/ProtocolFactory.php b/src/Protocol/ProtocolFactory.php
deleted file mode 100644
index 65a824b..0000000
--- a/src/Protocol/ProtocolFactory.php
+++ /dev/null
@@ -1,76 +0,0 @@
-project = $project;
- $this->ipChecker = $ipChecker;
- }
-
- /**
- * @param PaymentShoppingCartStorageInterface $paymentStorage
- * @return ShoppingCart
- * @see http://xsolla.github.io/en/cash.html
- */
- public function getShoppingCartProtocol(PaymentShoppingCartStorageInterface $paymentStorage)
- {
- return new ShoppingCart(
- $this->project,
- new XmlResponseBuilder($this->enableVersionHeader),
- new ShoppingCartFactory(),
- $paymentStorage,
- $this->ipChecker
- );
- }
-
- /**
- * @param UserStorageInterface $userStorage
- * @param PaymentStandardStorageInterface $paymentStorage
- * @return Standard
- * @see http://xsolla.github.io/en/currency.html
- */
- public function getStandardProtocol(UserStorageInterface $userStorage, PaymentStandardStorageInterface $paymentStorage)
- {
- return new Standard(
- $this->project,
- new XmlResponseBuilder($this->enableVersionHeader),
- new StandardFactory(),
- $userStorage,
- $paymentStorage,
- $this->ipChecker
- );
- }
-
- /**
- * @param UserStorageInterface $userStorage
- * @param PaymentShoppingCart3StorageInterface $paymentStorage
- * @return ShoppingCart3
- * @see http://xsolla.github.io/en/shopingcart3.html
- */
- public function getShoppingCart3Protocol(UserStorageInterface $userStorage, PaymentShoppingCart3StorageInterface $paymentStorage)
- {
- return new ShoppingCart3(
- $this->project,
- new XmlResponseBuilder($this->enableVersionHeader),
- new ShoppingCart3Factory(),
- $userStorage,
- $paymentStorage,
- $this->ipChecker
- );
- }
-}
diff --git a/src/Protocol/ShoppingCart.php b/src/Protocol/ShoppingCart.php
deleted file mode 100644
index 853e7a4..0000000
--- a/src/Protocol/ShoppingCart.php
+++ /dev/null
@@ -1,61 +0,0 @@
-commandFactory = $commandFactory;
- $this->paymentShoppingCartStorage = $paymentShoppingCartStorage;
- }
-
- /**
- * @return array
- */
- public function getProtocolCommands()
- {
- return array('pay', 'cancel');
- }
-
- /**
- * @return PaymentShoppingCartStorageInterface
- */
- public function getPaymentShoppingCartStorage()
- {
- return $this->paymentShoppingCartStorage;
- }
-
- /**
- * @param $message
- * @return array
- */
- public function getResponseForWrongCommand($message)
- {
- return array(
- 'result' => PayShoppingCart::CODE_INVALID_REQUEST,
- PayShoppingCart::COMMENT_FIELD_NAME => $message
- );
- }
-}
diff --git a/src/Protocol/ShoppingCart3.php b/src/Protocol/ShoppingCart3.php
deleted file mode 100644
index abe8283..0000000
--- a/src/Protocol/ShoppingCart3.php
+++ /dev/null
@@ -1,83 +0,0 @@
-commandFactory = $commandFactory;
- $this->userStorage = $userStorage;
- $this->paymentShoppingCart3Storage = $paymentShoppingCart3Storage;
- }
-
- /**
- * @return array
- */
- public function getProtocolCommands()
- {
- return array('check', 'pay', 'cancel');
- }
-
- /**
- * @return \Xsolla\SDK\Protocol\Storage\PaymentShoppingCart3StorageInterface
- */
- public function getPaymentShoppingCart3Storage()
- {
- return $this->paymentShoppingCart3Storage;
- }
-
- /**
- * @return \Xsolla\SDK\Protocol\Storage\UserStorageInterface
- */
- public function getUserStorage()
- {
- return $this->userStorage;
- }
-
- /**
- * @param $message
- * @return array
- */
- public function getResponseForWrongCommand($message)
- {
- return array(
- 'result' => StandardCommand::CODE_INVALID_REQUEST,
- StandardCommand::COMMENT_FIELD_NAME => $message
- );
- }
-}
\ No newline at end of file
diff --git a/src/Protocol/Standard.php b/src/Protocol/Standard.php
deleted file mode 100644
index 0cc801c..0000000
--- a/src/Protocol/Standard.php
+++ /dev/null
@@ -1,84 +0,0 @@
-commandFactory = $commandFactory;
- $this->userStorage = $userStorage;
- $this->paymentStandardStorage = $paymentStandardStorage;
- }
-
- /**
- * @return array
- */
- public function getProtocolCommands()
- {
- return array('check', 'pay', 'cancel');
- }
-
- /**
- * @return \Xsolla\SDK\Protocol\Storage\PaymentStandardStorageInterface
- */
- public function getPaymentStandardStorage()
- {
- return $this->paymentStandardStorage;
- }
-
- /**
- * @return \Xsolla\SDK\Protocol\Storage\UserStorageInterface
- */
- public function getUserStorage()
- {
- return $this->userStorage;
- }
-
- /**
- * @param $message
- * @return array
- */
- public function getResponseForWrongCommand($message)
- {
- return array(
- 'result' => StandardCommand::CODE_INVALID_REQUEST,
- StandardCommand::COMMENT_FIELD_NAME => $message
- );
- }
-}
diff --git a/src/Protocol/Storage/PaymentShoppingCart3StorageInterface.php b/src/Protocol/Storage/PaymentShoppingCart3StorageInterface.php
deleted file mode 100644
index a909ecf..0000000
--- a/src/Protocol/Storage/PaymentShoppingCart3StorageInterface.php
+++ /dev/null
@@ -1,19 +0,0 @@
-insertPay($xsollaPaymentId, $paymentAmount, $paymentCurrency, $user, $date, $dryRun);
- if ($id > 0) {
- return $id;
- }
- return $this->selectPayId($xsollaPaymentId, $paymentAmount, $paymentCurrency, $user);
- }
-
- protected function insertPay($xsollaPaymentId, $paymentAmount, $paymentCurrency, User $user, \DateTime $date, $dryRun)
- {
- $insert = $this->pdo->prepare(
- "INSERT INTO `xsolla_shoppingcart3_invoice`
- (`v1`, `id_xsolla`, `payment_amount`, `payment_currency`, `timestamp_xsolla_ipn`, `is_dry_run`)
- VALUES (:v1, :id_xsolla, :payment_amount, :payment_currency, :timestamp_xsolla_ipn, :is_dry_run)"
- );
- $insert->bindValue(':v1', $user->getV1());
- $insert->bindValue(':id_xsolla', $xsollaPaymentId, \PDO::PARAM_INT);
- $insert->bindValue(':payment_amount', $paymentAmount);
- $insert->bindValue(':payment_currency', $paymentCurrency, \PDO::PARAM_STR);
- $insert->bindValue(':timestamp_xsolla_ipn', $date->format('Y-m-d H:i:s'), \PDO::PARAM_STR);
- $insert->bindValue(':is_dry_run', $dryRun, \PDO::PARAM_BOOL);
- $insert->execute();
-
- return $this->pdo->lastInsertId();
- }
-
- protected function selectPayId($xsollaPaymentId, $paymentAmount, $paymentCurrency, User $user)
- {
- $select = $this->pdo->prepare(
- "SELECT id, v1, `payment_amount`, `payment_currency`, timestamp_xsolla_ipn, is_dry_run
- FROM `xsolla_standard_invoice`
- WHERE id_xsolla = :id_xsolla
- ");
- $select->bindValue(':id_xsolla', $xsollaPaymentId, \PDO::PARAM_INT);
- $select->execute();
- $result = $select->fetch(\PDO::FETCH_ASSOC);
- if ($result === false) {
- throw new \Exception('Temporary error.');
- }
- $diffMessage = '';
- if ($result['v1'] != $user->getV1()) {
- $diffMessage .= sprintf(' and v1=%s (must be "%s")', $result['v1'], $user->getV1());
- }
- if ($result['payment_amount'] != $paymentAmount) {
- $diffMessage .= sprintf(' and payment_amount=%0.2f (must be %0.2f)', $result['payment_amount'], $paymentAmount);
- }
- if ($result['payment_currency'] != $paymentCurrency) {
- $diffMessage .= sprintf(' and payment_currency=%s (must be %s)', $result['payment_currency'], $paymentCurrency);
- }
- if ($diffMessage !== '') {
- throw new UnprocessableRequestException(sprintf(
- 'Found payment with xsollaPaymentId=%s%s.',
- $xsollaPaymentId,
- $diffMessage
- ));
- }
-
- return $result['id'];
- }
-
- protected function getTable()
- {
- return self::TABLE;
- }
-}
\ No newline at end of file
diff --git a/src/Protocol/Storage/Pdo/PaymentShoppingCartStorage.php b/src/Protocol/Storage/Pdo/PaymentShoppingCartStorage.php
deleted file mode 100644
index eb576ec..0000000
--- a/src/Protocol/Storage/Pdo/PaymentShoppingCartStorage.php
+++ /dev/null
@@ -1,147 +0,0 @@
-updatePayment($notificationParams)) {
- return $v1;
- }
- $existentPayment = $this->selectPayment($v1);
- if (false === $existentPayment) {
- throw new UnprocessableRequestException("Invoice with v1='$v1' not found.");
- }
-
- $paramsDiff = $this->getRepeatedNotificationParametersDiff($notificationParams, $existentPayment);
- if (!$paramsDiff) {
- return $v1;
- }
-
- $exceptionMessage = sprintf('Repeated payment notification is received for invoice v1=%s. But new payment notification parameters are not equal with previous: %s.', $v1, join(", ", $paramsDiff));
- throw new UnprocessableRequestException($exceptionMessage);
- }
-
- protected function getRepeatedNotificationParametersDiff(array $new, array $existent)
- {
- unset($new['datetime']);
- $existent['dryRun'] = (bool) $existent['dryRun'];
-
- $descriptions = array();
- $diffKeys = array_keys(array_diff_assoc($new, $existent));
- foreach($diffKeys as $key) {
- $format = $this->getSprintfFormat($new[$key]);
- $desc = sprintf(
- $format,
- $key,
- $this->convertScalarValueToString($existent[$key]),
- $this->convertScalarValueToString($new[$key])
- );
- $descriptions[] = $desc;
- }
-
- return $descriptions;
- }
-
- protected function getSprintfFormat($value)
- {
- if ('double' === gettype($value)) {
- return '%s(previous=%0.2f,repeated=%0.2f)';
- } else {
- return '%s(previous=%s,repeated=%s)';
- }
- }
-
- protected function convertScalarValueToString($value)
- {
- return is_null($value) ? '[null]' : $value;
- }
-
- protected function updatePayment(array $notificationParams)
- {
- $update = $this->pdo->prepare("
- UPDATE xsolla_shopping_cart_invoice SET
- id_xsolla = :xsollaPaymentId,
- timestamp_ipn = NOW(),
- timestamp_xsolla_ipn = FROM_UNIXTIME(:timestamp_xsolla_ipn),
- user_amount = :userAmount,
- user_currency = :userCurrency,
- transfer_amount = :transferAmount,
- transfer_currency = :transferCurrency,
- pid = :pid,
- geotype = :geotype
- WHERE v1 = :v1
- AND v2 <=> :v2
- AND v3 <=> :v3
- AND invoice_amount = :amount
- AND invoice_currency = :currency
- AND is_dry_run = :dryRun
- AND id_xsolla IS NULL
- ;");
- $update->bindValue(':xsollaPaymentId', $notificationParams['xsollaPaymentId'], \PDO::PARAM_INT);
- $datetime = $notificationParams['datetime'];
- $update->bindValue(':timestamp_xsolla_ipn', $datetime->format('Y-m-d H:i:s'), \PDO::PARAM_STR);
- $update->bindValue(':userAmount', $notificationParams['userAmount']);
- $update->bindValue(':userCurrency', $notificationParams['userCurrency']);
- $update->bindValue(':transferAmount', $notificationParams['transferAmount']);
- $update->bindValue(':transferCurrency', $notificationParams['transferCurrency']);
- $update->bindValue(':pid', $notificationParams['pid'], \PDO::PARAM_INT);
- $update->bindValue(':geotype', $notificationParams['geotype'], \PDO::PARAM_INT);
- $update->bindValue(':v1', $notificationParams['v1'], \PDO::PARAM_INT);
- $update->bindValue(':v2', $notificationParams['v2']);
- $update->bindValue(':v3', $notificationParams['v3']);
- $update->bindValue(':amount', $notificationParams['amount']);
- $update->bindValue(':currency', $notificationParams['currency']);
- $update->bindValue(':dryRun', $notificationParams['dryRun'], \PDO::PARAM_BOOL);
- $update->execute();
- return (bool) $update->rowCount();
- }
-
- protected function selectPayment($v1)
- {
- $select = $this->pdo->prepare("
- SELECT v1, v2, v3,
- id_xsolla AS xsollaPaymentId,
- invoice_amount AS amount,
- invoice_currency AS currency,
- user_amount AS userAmount,
- user_currency AS userCurrency,
- transfer_amount AS transferAmount,
- transfer_currency AS transferCurrency,
- pid, geotype,
- is_dry_run AS dryRun
- FROM xsolla_shopping_cart_invoice
- WHERE v1 = :v1
- ;");
- $select->bindValue(':v1', $v1);
- $select->execute();
- return $select->fetch(\PDO::FETCH_ASSOC);
- }
-
- protected function getTable()
- {
- return self::TABLE;
- }
-
-}
diff --git a/src/Protocol/Storage/Pdo/PaymentStandardStorage.php b/src/Protocol/Storage/Pdo/PaymentStandardStorage.php
deleted file mode 100644
index 65ad0c3..0000000
--- a/src/Protocol/Storage/Pdo/PaymentStandardStorage.php
+++ /dev/null
@@ -1,77 +0,0 @@
-insertPay($xsollaPaymentId, $virtualCurrencyAmount, $user, $date, $dryRun);
- if ($id > 0) {
- return $id;
- }
-
- return $this->selectPayId($xsollaPaymentId, $virtualCurrencyAmount, $user);
-
- }
-
- protected function insertPay($xsollaPaymentId, $virtualCurrencyAmount, User $user, \DateTime $date, $dryRun)
- {
- $insert = $this->pdo->prepare(
- "INSERT INTO `xsolla_standard_invoice`
- (`v1`, `id_xsolla`, `amount_virtual_currency`, `timestamp_xsolla_ipn`, `is_dry_run`)
- VALUES (:v1, :id_xsolla, :amount_virtual_currency, :timestamp_xsolla_ipn, :is_dry_run)"
- );
- $insert->bindValue(':v1', $user->getV1());
- $insert->bindValue(':id_xsolla', $xsollaPaymentId, \PDO::PARAM_INT);
- $insert->bindValue(':amount_virtual_currency', $virtualCurrencyAmount, \PDO::PARAM_INT);
- $insert->bindValue(':timestamp_xsolla_ipn', $date->format('Y-m-d H:i:s'), \PDO::PARAM_STR);
- $insert->bindValue(':is_dry_run', $dryRun, \PDO::PARAM_BOOL);
- $insert->execute();
-
- return $this->pdo->lastInsertId();
- }
-
- protected function selectPayId($xsollaPaymentId, $virtualCurrencyAmount, User $user)
- {
- $select = $this->pdo->prepare(
- "SELECT id, v1, amount_virtual_currency, timestamp_xsolla_ipn, is_dry_run
- FROM `xsolla_standard_invoice`
- WHERE id_xsolla = :id_xsolla
- ");
- $select->bindValue(':id_xsolla', $xsollaPaymentId, \PDO::PARAM_INT);
- $select->execute();
- $result = $select->fetch(\PDO::FETCH_ASSOC);
- if ($result === false) {
- throw new \Exception('Temporary error.');
- }
- $diffMessage = '';
- if ($result['v1'] != $user->getV1()) {
- $diffMessage .= sprintf(' and v1=%s (must be "%s")', $result['v1'], $user->getV1());
- }
- if ($result['amount_virtual_currency'] != $virtualCurrencyAmount) {
- $diffMessage .= sprintf(' and amount_virtual_currency=%0.2f (must be %0.2f)', $result['amount_virtual_currency'], $virtualCurrencyAmount);
- }
- if ($diffMessage !== '') {
- throw new UnprocessableRequestException(sprintf(
- 'Found payment with xsollaPaymentId=%s%s.',
- $xsollaPaymentId,
- $diffMessage
- ));
- }
-
- return $result['id'];
- }
-
- protected function getTable()
- {
- return self::TABLE;
- }
-
-}
diff --git a/src/Protocol/Storage/Pdo/PaymentStorage.php b/src/Protocol/Storage/Pdo/PaymentStorage.php
deleted file mode 100644
index 1a37d02..0000000
--- a/src/Protocol/Storage/Pdo/PaymentStorage.php
+++ /dev/null
@@ -1,52 +0,0 @@
-pdo = $pdo;
- }
-
- public function cancel($xsollaPaymentId, $reasonCode = null, $reasonDescription = null)
- {
- // TODO: work with reasonCode and reasonData will be added in new major version
- $table = $this->getTable();
- $update = $this->pdo->prepare("
- UPDATE $table SET
- is_canceled = 1,
- timestamp_canceled = NOW()
- WHERE id_xsolla = :id_xsolla
- AND is_canceled = 0
- ");
- $update->bindValue(':id_xsolla', $xsollaPaymentId, \PDO::PARAM_INT);
- $update->execute();
- if ($update->rowCount() == 1) {
- return;
- }
- $select = $this->pdo->prepare("
- SELECT is_canceled, timestamp_canceled
- FROM $table
- WHERE id_xsolla = :id_xsolla
- ");
- $select->bindValue(':id_xsolla', $xsollaPaymentId, \PDO::PARAM_INT);
- $select->execute();
- $result = $select->fetch(\PDO::FETCH_ASSOC);
- if ($result === false) {
- throw new InvoiceNotFoundException();
- }
- if ($result['is_canceled'] != 1) {
- throw new \Exception('Temporary error');
- }
- }
-
- // @codeCoverageIgnoreStart
- abstract protected function getTable();
- // @codeCoverageIgnoreEnd
-}
diff --git a/src/Protocol/Storage/Pdo/UserStorage.php b/src/Protocol/Storage/Pdo/UserStorage.php
deleted file mode 100644
index 3e77b10..0000000
--- a/src/Protocol/Storage/Pdo/UserStorage.php
+++ /dev/null
@@ -1,37 +0,0 @@
-pdo = $pdo;
- }
-
- public function isUserExists(User $user)
- {
- $statement = $this->pdo->prepare(
- "SELECT 1 FROM xsolla_standard_user WHERE v1 = :v1 AND v2 <=> :v2 AND v3 <=> :v3;"
- );
- $statement->bindValue(':v1', $user->getV1());
- $statement->bindValue(':v2', $user->getV2());
- $statement->bindValue(':v3', $user->getV3());
- $statement->execute();
-
- return (bool) $statement->fetch(\PDO::FETCH_NUM);
- }
-
- public function getAdditionalUserFields(User $user)
- {
- return array();
- }
-}
diff --git a/src/Protocol/Storage/UserStorageInterface.php b/src/Protocol/Storage/UserStorageInterface.php
deleted file mode 100644
index 2bb47e9..0000000
--- a/src/Protocol/Storage/UserStorageInterface.php
+++ /dev/null
@@ -1,20 +0,0 @@
-enableVersionHeader = $enableVersionHeader;
- }
-
- public function get(array $response)
- {
- $xml = new \SimpleXMLElement('');
- $simpleXml = $this->addChildren($xml, $response);
-
- $response = new Response($simpleXml->asXML());
- $response->headers->set('Content-Type', 'text/xml; charset=UTF-8');
- if ($this->enableVersionHeader) {
- $response->headers->set(self::VERSION_HEADER, Version::getVersion());
- }
-
- return $response;
- }
-
- protected function addChildren(\SimpleXMLElement $element, $children)
- {
- foreach ($children as $key => $value) {
- if (is_array($value)) {
- $child = $element->addChild($key);
- $this->addChildren($child, $value);
- } else {
- $element->addChild($key, $value);
- }
- }
-
- return $element;
- }
-}
diff --git a/src/Subscription.php b/src/Subscription.php
deleted file mode 100644
index e21727a..0000000
--- a/src/Subscription.php
+++ /dev/null
@@ -1,39 +0,0 @@
-currency = $currency;
- $this->id = $id;
- $this->name = $name;
- $this->type = $type;
- }
-
- public function getCurrency()
- {
- return $this->currency;
- }
-
- public function getId()
- {
- return $this->id;
- }
-
- public function getName()
- {
- return $this->name;
- }
-
- public function getType()
- {
- return $this->type;
- }
-}
diff --git a/src/User.php b/src/User.php
deleted file mode 100644
index 23e96bc..0000000
--- a/src/User.php
+++ /dev/null
@@ -1,96 +0,0 @@
-email = $email;
- $this->phone = $phone;
- $this->v1 = $v1;
- $this->v2 = $v2;
- $this->v3 = $v3;
- $this->userIP = $userIp;
- }
-
- public function getEmail()
- {
- return $this->email;
- }
-
- public function getPhone()
- {
- return $this->phone;
- }
-
- public function getV1()
- {
- return $this->v1;
- }
-
- public function getV2()
- {
- return $this->v2;
- }
-
- public function getV3()
- {
- return $this->v3;
- }
-
- public function getUserIP()
- {
- return $this->userIP;
- }
-
- public function setEmail($email)
- {
- $this->email = $email;
-
- return $this;
- }
-
- public function setPhone($phone)
- {
- $this->phone = $phone;
-
- return $this;
- }
-
- public function setV1($v1)
- {
- $this->v1 = $v1;
-
- return $this;
- }
-
- public function setV2($v2)
- {
- $this->v2 = $v2;
-
- return $this;
- }
-
- public function setV3($v3)
- {
- $this->v3 = $v3;
-
- return $this;
- }
-
- public function setUserIp($userIP)
- {
- $this->userIP = $userIP;
-
- return $this;
- }
-
-}
diff --git a/src/Validator/IpChecker.php b/src/Validator/IpChecker.php
deleted file mode 100644
index b2ab098..0000000
--- a/src/Validator/IpChecker.php
+++ /dev/null
@@ -1,27 +0,0 @@
-ipWhitelist)) {
- throw new UnprocessableRequestException(sprintf(
- 'IP whitelist(%s) doesn\'t contain client IP address(%s). If you use reverse proxy, you should set a list of trusted proxies via Request::setTrustedProxies(). If you are in development environment, you can skip "IpChecker" parameter in ProtocolFactory.',
- implode(', ', $this->ipWhitelist),
- $clientIp
- ));
- }
- }
-}
diff --git a/src/Validator/Xsd.php b/src/Validator/Xsd.php
deleted file mode 100644
index f308c66..0000000
--- a/src/Validator/Xsd.php
+++ /dev/null
@@ -1,30 +0,0 @@
-loadXML($response)) {
- throw new InvalidResponseException("Wrong format xml");
- }
-
- if (false === @$dom->schemaValidate($schemaFilename)) {
- throw new InvalidResponseException("Wrong schema xml");
- }
-
- libxml_use_internal_errors($internalErrors);
- }
-
- return true;
- }
-}
diff --git a/src/Version.php b/src/Version.php
index 4d64fc2..d03ea9c 100644
--- a/src/Version.php
+++ b/src/Version.php
@@ -1,12 +1,23 @@
request['subscription'];
+ }
+}
diff --git a/src/Webhook/Message/CreateSubscriptionMessage.php b/src/Webhook/Message/CreateSubscriptionMessage.php
new file mode 100644
index 0000000..6df1400
--- /dev/null
+++ b/src/Webhook/Message/CreateSubscriptionMessage.php
@@ -0,0 +1,26 @@
+request['subscription'];
+ }
+
+ /**
+ * @return array
+ */
+ public function getCoupon()
+ {
+ if (!array_key_exists('coupon', $this->request)) {
+ return array();
+ }
+
+ return $this->request['coupon'];
+ }
+}
diff --git a/src/Webhook/Message/Message.php b/src/Webhook/Message/Message.php
new file mode 100644
index 0000000..dc96fd8
--- /dev/null
+++ b/src/Webhook/Message/Message.php
@@ -0,0 +1,115 @@
+ '\Xsolla\SDK\Webhook\Message\UserValidationMessage',
+ self::PAYMENT => '\Xsolla\SDK\Webhook\Message\PaymentMessage',
+ self::REFUND => '\Xsolla\SDK\Webhook\Message\RefundMessage',
+ self::CREATE_SUBSCRIPTION => '\Xsolla\SDK\Webhook\Message\CreateSubscriptionMessage',
+ self::CANCEL_SUBSCRIPTION => '\Xsolla\SDK\Webhook\Message\CancelSubscriptionMessage',
+ self::USER_BALANCE => '\Xsolla\SDK\Webhook\Message\UserBalanceMessage',
+ );
+
+ /**
+ * @var array
+ */
+ protected $request;
+
+ /**
+ * @param array $request
+ *
+ * @return Message
+ *
+ * @throws InvalidParameterException
+ */
+ public static function fromArray(array $request)
+ {
+ if (!array_key_exists('notification_type', $request)) {
+ throw new InvalidParameterException('notification_type key not found in Xsolla webhook request');
+ }
+ $notificationType = $request['notification_type'];
+ if (!array_key_exists($notificationType, self::$classMap)) {
+ throw new InvalidParameterException('Unknown notification_type in Xsolla webhook request: '.$notificationType);
+ }
+ $className = self::$classMap[$notificationType];
+
+ return new $className($request);
+ }
+
+ /**
+ * @param array $request
+ */
+ public function __construct(array $request)
+ {
+ $this->request = $request;
+ }
+
+ /**
+ * @return ParameterBag
+ */
+ public function toArray()
+ {
+ return $this->request;
+ }
+
+ /**
+ * @return string
+ */
+ public function getNotificationType()
+ {
+ return $this->request['notification_type'];
+ }
+
+ /**
+ * @return bool
+ */
+ public function isUserValidation()
+ {
+ return self::USER_VALIDATION === $this->getNotificationType();
+ }
+
+ /**
+ * @return bool
+ */
+ public function isPayment()
+ {
+ return self::PAYMENT === $this->getNotificationType();
+ }
+
+ /**
+ * @return bool
+ */
+ public function isRefund()
+ {
+ return self::REFUND === $this->getNotificationType();
+ }
+
+ /**
+ * @return array
+ */
+ public function getUser()
+ {
+ return $this->request['user'];
+ }
+
+ /**
+ * @return string
+ */
+ public function getUserId()
+ {
+ return $this->request['user']['id'];
+ }
+}
diff --git a/src/Webhook/Message/PaymentMessage.php b/src/Webhook/Message/PaymentMessage.php
new file mode 100644
index 0000000..93bdc5b
--- /dev/null
+++ b/src/Webhook/Message/PaymentMessage.php
@@ -0,0 +1,69 @@
+request['purchase'];
+ }
+
+ /**
+ * @return array
+ */
+ public function getTransaction()
+ {
+ return $this->request['transaction'];
+ }
+
+ public function getPaymentId()
+ {
+ return $this->request['transaction']['id'];
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getExternalPaymentId()
+ {
+ if (array_key_exists('external_id', $this->request['transaction'])) {
+ return $this->request['transaction']['external_id'];
+ }
+ }
+
+ /**
+ * @return array
+ */
+ public function getPaymentDetails()
+ {
+ return $this->request['payment_details'];
+ }
+
+ /**
+ * @return array
+ */
+ public function getCustomParameters()
+ {
+ if (!array_key_exists('custom_parameters', $this->request)) {
+ return array();
+ }
+
+ return $this->request['custom_parameters'];
+ }
+
+ /**
+ * @return bool
+ */
+ public function isDryRun()
+ {
+ if (!array_key_exists('dry_run', $this->request['transaction'])) {
+ return false;
+ }
+
+ return (bool) $this->request['transaction']['dry_run'];
+ }
+}
diff --git a/src/Webhook/Message/RefundMessage.php b/src/Webhook/Message/RefundMessage.php
new file mode 100644
index 0000000..e606251
--- /dev/null
+++ b/src/Webhook/Message/RefundMessage.php
@@ -0,0 +1,14 @@
+request['refund_details'];
+ }
+}
diff --git a/src/Webhook/Message/UserBalanceMessage.php b/src/Webhook/Message/UserBalanceMessage.php
new file mode 100644
index 0000000..cd66551
--- /dev/null
+++ b/src/Webhook/Message/UserBalanceMessage.php
@@ -0,0 +1,62 @@
+request)) {
+ return array();
+ }
+
+ return $this->request['virtual_currency_balance'];
+ }
+
+ /**
+ * @return string
+ */
+ public function getOperationType()
+ {
+ return $this->request['operation_type'];
+ }
+
+ /**
+ * @return int
+ */
+ public function getOperationId()
+ {
+ return $this->request['id_operation'];
+ }
+
+ /**
+ * @return array
+ */
+ public function getCoupon()
+ {
+ if (!array_key_exists('coupon', $this->request)) {
+ return array();
+ }
+
+ return $this->request['coupon'];
+ }
+
+ /**
+ * @return string|null
+ */
+ public function getItemsOperationType()
+ {
+ if (array_key_exists('items_operation_type', $this->request)) {
+ return $this->request['items_operation_type'];
+ }
+ }
+}
diff --git a/src/Webhook/Message/UserValidationMessage.php b/src/Webhook/Message/UserValidationMessage.php
new file mode 100644
index 0000000..8d73464
--- /dev/null
+++ b/src/Webhook/Message/UserValidationMessage.php
@@ -0,0 +1,7 @@
+projectSecretKey = $projectSecretKey;
+ }
+
+ /**
+ * @param WebhookRequest $webhookRequest
+ * @param bool $checkClientIp
+ *
+ * @throws InvalidClientIpException
+ * @throws InvalidSignatureException
+ */
+ public function authenticate(WebhookRequest $webhookRequest, $checkClientIp = true)
+ {
+ if (true === $checkClientIp) {
+ $this->authenticateClientIp($webhookRequest->getClientIp());
+ }
+ $this->authenticateSignature($webhookRequest);
+ }
+
+ /**
+ * @param string $clientIp
+ *
+ * @throws InvalidClientIpException
+ */
+ public function authenticateClientIp($clientIp)
+ {
+ if (false === IpUtils::checkIp($clientIp, self::$xsollaSubnets)) {
+ throw new InvalidClientIpException(sprintf(
+ 'Xsolla trusted subnets (%s) doesn\'t contain client IP address (%s). If you use reverse proxy, you should set correct client IPv4 to WebhookRequest. If you are in development environment, you can set $authenticateClientIp = false in $webhookServer->start();',
+ implode(', ', self::$xsollaSubnets),
+ $clientIp
+ ));
+ }
+ }
+
+ /**
+ * @param WebhookRequest $webhookRequest
+ *
+ * @throws InvalidSignatureException
+ */
+ public function authenticateSignature(WebhookRequest $webhookRequest)
+ {
+ $headers = $webhookRequest->getHeaders();
+ if (!array_key_exists('authorization', $headers)) {
+ throw new InvalidSignatureException('"Authorization" header not found in Xsolla webhook request');
+ }
+ $matches = array();
+ preg_match('~^Signature ([0-9a-f]{40})$~', $headers['authorization'], $matches);
+ if (array_key_exists(1, $matches)) {
+ $clientSignature = $matches[1];
+ } else {
+ throw new InvalidSignatureException('Signature not found in "Authorization" header from Xsolla webhook request: '.$headers['authorization']);
+ }
+ $serverSignature = sha1($webhookRequest->getBody().$this->projectSecretKey);
+ if ($clientSignature !== $serverSignature) {
+ throw new InvalidSignatureException("Invalid Signature. Signature provided in \"Authorization\" header ($clientSignature) does not match with expected");
+ }
+ }
+}
diff --git a/src/Webhook/WebhookRequest.php b/src/Webhook/WebhookRequest.php
new file mode 100644
index 0000000..e199e7b
--- /dev/null
+++ b/src/Webhook/WebhookRequest.php
@@ -0,0 +1,106 @@
+ 'Control character error, possibly incorrectly encoded.',
+ JSON_ERROR_DEPTH => 'The maximum stack depth has been exceeded.',
+ JSON_ERROR_NONE => 'No error has occurred.',
+ JSON_ERROR_STATE_MISMATCH => 'Invalid or malformed JSON.',
+ JSON_ERROR_SYNTAX => 'Syntax error.',
+ JSON_ERROR_UTF8 => 'Malformed UTF-8 characters, possibly incorrectly encoded.',
+ );
+
+ /**
+ * @var string
+ */
+ protected $body;
+
+ /**
+ * @var array
+ */
+ protected $headers;
+
+ /**
+ * @var string
+ */
+ protected $clientIp;
+
+ /**
+ * @return WebhookRequest
+ *
+ * @throws XsollaWebhookException
+ */
+ public static function fromGlobals()
+ {
+ $request = Request::createFromGlobals();
+ $headers = array();
+ foreach ($request->headers->all() as $header => $arrayValue) {
+ $headers[$header] = $arrayValue[0];
+ }
+
+ return new static($headers, $request->getContent(), $request->getClientIp());
+ }
+
+ /**
+ * @param array $headers
+ * @param string $body
+ * @param string $clientIp
+ */
+ public function __construct(array $headers, $body, $clientIp = null)
+ {
+ $this->headers = $headers;
+ $this->body = $body;
+ $this->clientIp = $clientIp;
+ }
+
+ /**
+ * @return string
+ */
+ public function getBody()
+ {
+ return $this->body;
+ }
+
+ /**
+ * @return array
+ *
+ * @throws XsollaWebhookException
+ */
+ public function toArray()
+ {
+ $data = json_decode($this->body, true);
+ $jsonLastError = json_last_error();
+ if (JSON_ERROR_NONE !== $jsonLastError) {
+ $message = 'Unknown error.';
+ if (array_key_exists($jsonLastError, self::$codes)) {
+ $message = self::$codes[$jsonLastError];
+ }
+ throw new InvalidParameterException('Unable to parse Xsolla webhook request into JSON: '.$message);
+ }
+
+ return $data === null ? array() : $data;
+ }
+
+ /**
+ * @return array
+ */
+ public function getHeaders()
+ {
+ return $this->headers;
+ }
+
+ /**
+ * @return string
+ */
+ public function getClientIp()
+ {
+ return $this->clientIp;
+ }
+}
diff --git a/src/Webhook/WebhookResponse.php b/src/Webhook/WebhookResponse.php
new file mode 100644
index 0000000..e25841f
--- /dev/null
+++ b/src/Webhook/WebhookResponse.php
@@ -0,0 +1,84 @@
+getXsollaErrorCode(), $e->getMessage(), $e->getHttpStatusCode());
+ } else {
+ return static::fromErrorCode('FATAL_ERROR', $e->getMessage());
+ }
+ }
+
+ /**
+ * @param string $xsollaErrorCode
+ * @param string $message
+ * @param int $httpStatus
+ *
+ * @return WebhookResponse
+ */
+ public static function fromErrorCode($xsollaErrorCode, $message = '', $httpStatus = 500)
+ {
+ $body = array(
+ 'error' => array(
+ 'code' => $xsollaErrorCode,
+ 'message' => $message,
+ ),
+ );
+ $encodedBody = XsollaClient::jsonEncode($body);
+
+ return new static($httpStatus, $encodedBody);
+ }
+
+ /**
+ * @param int $httpStatusCode
+ * @param string $body
+ */
+ public function __construct($httpStatusCode = 204, $body = null)
+ {
+ $this->symfonyResponse = new Response($body, $httpStatusCode);
+ $this->symfonyResponse->headers->set('x-xsolla-sdk', Version::getVersion());
+ if ($body) {
+ $contentType = 'application/json';
+ } else {
+ $contentType = 'text/plain';
+ }
+ $this->symfonyResponse->headers->set('content-type', $contentType);
+ }
+
+ /**
+ * @return Response
+ */
+ public function getSymfonyResponse()
+ {
+ return $this->symfonyResponse;
+ }
+}
diff --git a/src/Webhook/WebhookServer.php b/src/Webhook/WebhookServer.php
new file mode 100644
index 0000000..7d40a74
--- /dev/null
+++ b/src/Webhook/WebhookServer.php
@@ -0,0 +1,79 @@
+webhookCallback = $webhookCallback;
+ $this->webhookAuthenticator = $webhookAuthenticator;
+ }
+
+ /**
+ * @param WebhookRequest $webhookRequest
+ * @param bool $authenticateClientIp
+ */
+ public function start(WebhookRequest $webhookRequest = null, $authenticateClientIp = true)
+ {
+ $response = $this->getSymfonyResponse($webhookRequest, $authenticateClientIp);
+ $response->send();
+ }
+
+ /**
+ * @param WebhookRequest $webhookRequest
+ * @param bool $authenticateClientIp
+ *
+ * @return Response
+ */
+ public function getSymfonyResponse(WebhookRequest $webhookRequest = null, $authenticateClientIp = true)
+ {
+ try {
+ if (!$webhookRequest) {
+ $webhookRequest = WebhookRequest::fromGlobals();
+ }
+ $this->webhookAuthenticator->authenticate($webhookRequest, $authenticateClientIp);
+ $message = Message::fromArray($webhookRequest->toArray());
+ call_user_func($this->webhookCallback, $message);
+ $webhookResponse = new WebhookResponse();
+
+ return $webhookResponse->getSymfonyResponse();
+ } catch (\Exception $e) {
+ return WebhookResponse::fromException($e)->getSymfonyResponse();
+ }
+ }
+}
diff --git a/tests/API/PaymentUI/TokenRequestTest.php b/tests/API/PaymentUI/TokenRequestTest.php
new file mode 100644
index 0000000..cd80b8f
--- /dev/null
+++ b/tests/API/PaymentUI/TokenRequestTest.php
@@ -0,0 +1,42 @@
+setUserEmail('email@example.com')
+ ->setCustomParameters(array('a' => 1, 'b' => 2))
+ ->setCurrency('USD')
+ ->setExternalPaymentId(12345)
+ ->setSandboxMode(true)
+ ->setUserName('USER_NAME')
+ ->toArray();
+
+ $expectedRequest = array(
+ 'user' => array(
+ 'id' => array('value' => 'USER_ID'),
+ 'email' => array('value' => 'email@example.com'),
+ 'name' => array('value' => 'USER_NAME'),
+ ),
+ 'settings' => array(
+ 'project_id' => 'PROJECT_ID',
+ 'currency' => 'USD',
+ 'external_id' => 12345,
+ 'mode' => 'sandbox',
+ ),
+ 'custom_parameters' => array(
+ 'a' => 1,
+ 'b' => 2,
+ ),
+ );
+ static::assertSame($expectedRequest, $actualRequest);
+ }
+}
diff --git a/tests/Api/ApiFactoryTest.php b/tests/Api/ApiFactoryTest.php
deleted file mode 100644
index a4688aa..0000000
--- a/tests/Api/ApiFactoryTest.php
+++ /dev/null
@@ -1,54 +0,0 @@
-projectMock = $this->getMock('\Xsolla\SDK\Project', array(), array(), '', false);
- $this->apiFactory = new ApiFactory($this->projectMock);
- }
-
- public function testGetCalculatorApi()
- {
- $this->assertInstanceOf('Xsolla\SDK\Api\CalculatorApi', $this->apiFactory->getCalculatorApi());
- }
-
- public function testGetMobilePaymentApi()
- {
- $this->assertInstanceOf('Xsolla\SDK\Api\MobilePaymentApi', $this->apiFactory->getMobilePaymentApi());
- }
-
- public function testGetNumberApi()
- {
- $this->assertInstanceOf('Xsolla\SDK\Api\NumberApi', $this->apiFactory->getNumberApi());
- }
-
- public function testGetQiwiWalletApi()
- {
- $this->assertInstanceOf('Xsolla\SDK\Api\QiwiWalletApi', $this->apiFactory->getQiwiWalletApi());
- }
-
- public function testGetSubscriptionsApi()
- {
- $this->assertInstanceOf('Xsolla\SDK\Api\SubscriptionsApi', $this->apiFactory->getSubscriptionsApi());
- }
-
- public function testGetSubscriptionsApiIsTest()
- {
- $this->assertInstanceOf('Xsolla\SDK\Api\SubscriptionsApi', $this->apiFactory->getSubscriptionsApi(true));
- }
-}
diff --git a/tests/Api/CalculatorApiTest.php b/tests/Api/CalculatorApiTest.php
deleted file mode 100644
index 162a6f0..0000000
--- a/tests/Api/CalculatorApiTest.php
+++ /dev/null
@@ -1,88 +0,0 @@
-responseMock = $this->getMock('\Guzzle\Http\Message\Response', array(), array(), '', false);
-
- $this->requestMock = $this->getMock('\Guzzle\Http\Message\RequestInterface', array(), array(), '', false);
- $this->requestMock->expects($this->once())
- ->method('send')
- ->will($this->returnValue($this->responseMock));
-
- $this->clientMock = $this->getMock('\Guzzle\Http\Client', array(), array(), '', false);
-
- $this->projectMock = $this->getMock('\Xsolla\SDK\Project', array(), array(), '', false);
- $this->projectMock->expects($this->once())
- ->method('getProjectId')
- ->will($this->returnValue(self::PROJECT_ID));
-
- $this->calculatorApi = new CalculatorApi($this->clientMock, $this->projectMock);
- }
-
- public function testCalculateOut()
- {
- $this->generateAsserts(self::SUM_AMOUNT, self::SUM_VIRTUAL_AMOUNT, '/calc/inn.php');
- $this->assertEquals(self::SUM_VIRTUAL_AMOUNT, $this->calculatorApi->calculateAmount(self::GEOTYPE_ID, self::SUM_AMOUNT));
- }
-
- public function testCalculateIn()
- {
- $this->generateAsserts(self::SUM_VIRTUAL_AMOUNT, self::SUM_AMOUNT, '/calc/out.php');
- $this->assertEquals(self::SUM_AMOUNT, $this->calculatorApi->calculateVirtualCurrencyAmount(self::GEOTYPE_ID, self::SUM_VIRTUAL_AMOUNT));
- }
-
- protected function generateAsserts($sum_input, $sum_return, $url)
- {
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue($sum_return));
- $this->clientMock->expects($this->once())
- ->method('get')
- ->with(
- $url,
- array(),
- array(
- 'query' => array(
- 'project_id' => self::PROJECT_ID,
- 'geotype_id' => self::GEOTYPE_ID,
- 'sum' => $sum_input
- )
- ))->will($this->returnValue($this->requestMock));
- }
-}
diff --git a/tests/Api/MobilePaymentApiTest.php b/tests/Api/MobilePaymentApiTest.php
deleted file mode 100644
index f7ace39..0000000
--- a/tests/Api/MobilePaymentApiTest.php
+++ /dev/null
@@ -1,412 +0,0 @@
- 'calculate',
- 'project' => 'projectId',
- 'phone' => 'phone',
- 'sum' => '10',
- );
- protected $queryParamsCalculateWithOut = array(
- 'command' => 'calculate',
- 'project' => 'projectId',
- 'phone' => 'phone',
- 'out' => '100',
- );
-
- protected $queryParamsForCreateInvoice = array(
- 'command' => 'invoice',
- 'project' => 'projectId',
- 'v1' => 'v1',
- 'v2' => 'v2',
- 'v3' => 'v3',
- 'sum' => '10',
- 'out' => '100',
- 'phone' => 'phone',
- 'userip' => 'userIP',
- );
-
- protected $responseWithInvalidRequest =
- '
- 4
- OK
- ';
- protected $responseCalculateWithWrongMd5 =
- '
- 3
- OK
- ';
-
- protected $responseCreateInvoice =
- '
- 0
- OK
- 1
- ';
-
- protected $responseWithWrongMd5 =
- '
- 3
- OK
- ';
-
- protected $responseWithWrongNumber =
- '
- 2
- OK
- ';
-
- protected $responseCalculateWithInvalidRequest =
- '
- 4
- OK
- ';
-
- protected $responseWithTechnicalError =
- '
- 1
- OK
- ';
-
- protected $responseCalculate =
- '
- 10
- 100
- 0
- OK
- ';
-
- protected $responseCreateInvoiceWithTechnicalError =
- '
- 1
- OK
- ';
-
- public function setUp()
- {
- $this->setUpMocks();
- $this->queryParamsForCreateInvoice['email'] = 'email';
- $this->userMock->expects($this->any())
- ->method('getEmail')
- ->will($this->returnValue('email'));
- $this->mobilePaymentApi = new MobilePaymentApi($this->clientMock, $this->projectMock);
- }
-
- protected function setUpMocks()
- {
- $this->requestMock = $this->getMock('\Guzzle\Http\Message\RequestInterface', array(), array(), '', false);
- $this->responseMock = $this->getMock('\Guzzle\Http\Message\Response', array(), array(), '', false);
- $this->clientMock = $this->getMock('\Guzzle\Http\Client', array(), array(), '', false);
- $this->requestMock->expects($this->any())
- ->method('send')
- ->will($this->returnValue($this->responseMock));
-
- $this->projectMock = $this->getMock(
- '\Xsolla\SDK\Project',
- array(),
- array(),
- '',
- false
- );
- $this->projectMock->expects($this->any())
- ->method('getProjectId')
- ->will($this->returnValue('projectId'));
- $this->projectMock->expects($this->any())
- ->method('getSecretKey')
- ->will($this->returnValue(self::PROJECT_SECRET_KEY));
-
- $this->userMock = $this->getMock('\Xsolla\SDK\User', array(), array(), '', false);
- $this->userMock->expects($this->any())
- ->method('getUserIP')
- ->will($this->returnValue('userIP'));
- $this->userMock->expects($this->any())
- ->method('getV1')
- ->will($this->returnValue('v1'));
- $this->userMock->expects($this->any())
- ->method('getV2')
- ->will($this->returnValue('v2'));
- $this->userMock->expects($this->any())
- ->method('getV3')
- ->will($this->returnValue('v3'));
- $this->userMock->expects($this->any())
- ->method('getPhone')
- ->will($this->returnValue('phone'));
-
- $this->invoiceMock = $this->getMock('\Xsolla\SDK\Invoice', array(), array(), '', false);
- }
-
- public function testCalculateWithAmount()
- {
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue($this->responseCalculate));
-
- $signString = $this->createSignString($this->queryParamsCalculateWithSum);
- $this->queryParamsCalculateWithSum['md5'] = md5($signString . self::PROJECT_SECRET_KEY);
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->with(
- $this->url,
- array(),
- array('query' => $this->queryParamsCalculateWithSum)
- )
- ->will($this->returnValue($this->requestMock));
-
- $this->assertInstanceOf(
- '\Xsolla\SDK\Invoice',
- $this->mobilePaymentApi->calculateVirtualCurrencyAmount($this->userMock, 10)
- );
- }
-
- public function testCalculateWithVirtualCurrencyAmount()
- {
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue($this->responseCalculate));
-
- $signString = $this->createSignString($this->queryParamsCalculateWithOut);
- $this->queryParamsCalculateWithOut['md5'] = md5($signString . self::PROJECT_SECRET_KEY);
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->with(
- $this->url,
- array(),
- array('query' => $this->queryParamsCalculateWithOut)
- )
- ->will($this->returnValue($this->requestMock));
-
- $this->assertInstanceOf(
- '\Xsolla\SDK\Invoice',
- $this->mobilePaymentApi->calculateAmount($this->userMock, 100)
- );
- }
-
- public function testCalculateWithWrongMd5()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\SecurityException');
- $this->responseMock->expects($this->once())->
- method('getBody')
- ->will($this->returnValue($this->responseCalculateWithWrongMd5));
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->will($this->returnValue($this->requestMock));
-
- $this->mobilePaymentApi->calculateAmount($this->userMock, 100);
- }
-
- public function testCalculateWithTemporaryError()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\InternalServerException');
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue($this->responseWithTechnicalError));
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->will($this->returnValue($this->requestMock));
-
- $this->mobilePaymentApi->calculateAmount($this->userMock, 100);
- }
-
- public function testCalculateWithWrongNumber()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\InvalidArgumentException');
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue($this->responseWithWrongNumber));
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->will($this->returnValue($this->requestMock));
-
- $this->mobilePaymentApi->calculateAmount($this->userMock, 100);
- }
-
- public function testCalculateWithInvalidRequest()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\InvalidArgumentException');
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue($this->responseCalculateWithInvalidRequest));
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->will($this->returnValue($this->requestMock));
-
- $this->mobilePaymentApi->calculateAmount($this->userMock, 100);
- }
-
- public function testCalculateWithExceeded()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\InvalidArgumentException');
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue(
- '
- 7
- OK
- '
- )
- );
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->will($this->returnValue($this->requestMock));
-
- $this->mobilePaymentApi->calculateAmount($this->userMock, 100);
- }
-
- public function testCreateInvoice()
- {
- $this->invoiceMock->expects($this->any())
- ->method('getAmount')
- ->will($this->returnValue('10'));
- $this->invoiceMock->expects($this->any())
- ->method('getVirtualCurrencyAmount')
- ->will($this->returnValue('100'));
-
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue($this->responseCreateInvoice));
-
- $signString = $this->createSignString($this->queryParamsForCreateInvoice);
- $this->queryParamsForCreateInvoice['md5'] = md5($signString . self::PROJECT_SECRET_KEY);
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->with(
- $this->url,
- array(),
- array('query' => $this->queryParamsForCreateInvoice)
- )
- ->will($this->returnValue($this->requestMock));
-
- $this->assertInstanceOf(
- '\Xsolla\SDK\Invoice',
- $this->mobilePaymentApi->createInvoice($this->userMock, $this->invoiceMock)
- );
- }
-
- protected function createSignString(array $params)
- {
- $signString = '';
- foreach ($params as $value) {
- $signString .= $value;
- }
-
- return $signString;
- }
-
- public function testCreateInvoiceWithWrongMd5()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\SecurityException');
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue($this->responseWithWrongMd5));
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->will($this->returnValue($this->requestMock));
-
- $this->mobilePaymentApi->createInvoice($this->userMock, $this->invoiceMock);
- }
-
- public function testCreateInvoiceWithInvalidRequest()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\InvalidArgumentException');
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue($this->responseWithInvalidRequest));
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->will($this->returnValue($this->requestMock));
-
- $this->mobilePaymentApi->createInvoice($this->userMock, $this->invoiceMock);
- }
-
- public function testCreateInvoiceWithTechnicalError()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\InternalServerException');
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue($this->responseCreateInvoiceWithTechnicalError));
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->will($this->returnValue($this->requestMock));
-
- $this->mobilePaymentApi->createInvoice($this->userMock, $this->invoiceMock);
- }
-
- public function testCheckXSDWithWrongFile()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\InvalidResponseException');
- $xsd = new Xsd();
- $xsd->check('',__DIR__ . $this->xsd_path_invoice.'1');
- }
-
- public function testCheckXSDWithWrongXML()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\InvalidResponseException');
- $xsd = new Xsd();
- $xsd->check('1',__DIR__ . $this->xsd_path_invoice);
- }
-
- public function testCheckXSDWithWrongXMLSchemaValidate()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\InvalidResponseException');
- $xsd = new Xsd();
- $xsd->check('test',__DIR__ . $this->xsd_path_invoice);
- }
-
-}
diff --git a/tests/Api/NumberApiTest.php b/tests/Api/NumberApiTest.php
deleted file mode 100644
index 3c2d7b8..0000000
--- a/tests/Api/NumberApiTest.php
+++ /dev/null
@@ -1,113 +0,0 @@
-projectMock = $this->getMock('\Xsolla\SDK\Project', array(), array(), '', false);
- $this->projectMock->expects($this->once())->method('getProjectId')->will($this->returnValue('projectId'));
-
- $this->userMock = $this->getMock('\Xsolla\SDK\User', array(), array(), '', false);
- $this->userMock->expects($this->once())
- ->method('getV1')
- ->will($this->returnValue('v1'));
- $this->userMock->expects($this->once())
- ->method('getV2')
- ->will($this->returnValue('v2'));
- $this->userMock->expects($this->once())
- ->method('getV3')
- ->will($this->returnValue('v3'));
- $this->userMock->expects($this->once())
- ->method('getEmail')
- ->will($this->returnValue('email'));
-
- $this->clientMock = $this->getMock('\Guzzle\Http\Client', array(), array(), '', false);
- $this->requestMock = $this->getMock('\Guzzle\Http\Message\RequestInterface', array(), array(), '', false);
- $this->responseMock = $this->getMock('\Guzzle\Http\Message\Response', array(), array(), '', false);
-
- $this->requestMock->expects($this->once())
- ->method('send')
- ->will($this->returnValue($this->responseMock));
- $this->clientMock->expects($this->once())->method('get')->with(
- '/xsolla_number.php',
- array(),
- array(
- 'query' => array(
- 'project' => 'projectId',
- 'v1' => 'v1',
- 'v2' => 'v2',
- 'v3' => 'v3',
- 'email' => 'email',
- 'format' => 'json'
- )
- )
- )->will($this->returnValue($this->requestMock));
-
- $this->number = new NumberApi($this->clientMock, $this->projectMock);
- }
-
- public function testGetNumber()
- {
- $this->responseMock->expects($this->once())
- ->method('json')
- ->will($this->returnValue(array('result' => 0, 'number' => 'number')));
-
- $this->assertEquals('number', $this->number->getNumber($this->userMock));
- }
-
- public function testGetNumberInternalException()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\InternalServerException', 'description', 10);
-
- $this->responseMock->expects($this->once())
- ->method('json')
- ->will($this->returnValue(array('result' => 10, 'description' => 'description')));
-
- $this->assertEquals('number', $this->number->getNumber($this->userMock));
- }
-
- public function testGetNumberInvalidArgumentException()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\InvalidArgumentException', 'description', 1);
-
- $this->responseMock->expects($this->once())
- ->method('json')
- ->will($this->returnValue(array('result' => 1, 'description' => 'description')));
-
- $this->assertEquals('number', $this->number->getNumber($this->userMock));
- }
-}
diff --git a/tests/Api/QiwiWalletApiTest.php b/tests/Api/QiwiWalletApiTest.php
deleted file mode 100644
index 24b7e4c..0000000
--- a/tests/Api/QiwiWalletApiTest.php
+++ /dev/null
@@ -1,211 +0,0 @@
- 'calculate',
- 'project' => 'projectId',
- 'phone' => 'phone',
- 'sum' => '10',
- 'ps' => 'qiwi',
- );
-
- protected $queryParamsCalculateWithOut = array(
- 'command' => 'calculate',
- 'project' => 'projectId',
- 'phone' => 'phone',
- 'out' => '100',
- 'ps' => 'qiwi',
- );
-
- protected $responseWithWrongMd5 =
- '
- 3
- OK
- 1
- 1
- ';
-
- protected $responseCalculateWithWrongMd5 =
- '
- 3
- OK
- ';
-
- protected $responseCreateInvoice =
- '
- 0
- OK
- 1
- 1
- 1
- ';
-
- protected $responseWithInvalidRequest =
- '
- 4
- OK
- 1
- 1
- ';
-
- protected $responseCalculateWithInvalidRequest =
- '
- 4
- OK
- ';
-
- protected $responseWithTechnicalError =
- '
- 1
- OK
- ';
- protected $responseCreateInvoiceWithTechnicalError =
- '
- 1
- OK
- 1
- 1
- ';
-
- protected $queryParamsWithoutEmail = array(
- 'command' => 'invoice',
- 'project' => 'projectId',
- 'v1' => 'v1',
- 'v2' => 'v2',
- 'v3' => 'v3',
- 'sum' => '10',
- 'out' => '100',
- 'phone' => 'phone',
- 'userip' => 'userIP',
- 'ps' => 'qiwi'
- );
- protected $queryParamsWithoutPs = array(
- 'command' => 'invoice',
- 'project' => 'projectId',
- 'v1' => 'v1',
- 'v2' => 'v2',
- 'v3' => 'v3',
- 'sum' => '10',
- 'out' => '100',
- 'phone' => 'phone',
- 'userip' => 'userIP',
- 'email' => 'email',
-
- );
-
- protected $queryParamsWithPs = array(
- 'command' => 'invoice',
- 'project' => 'projectId',
- 'v1' => 'v1',
- 'v2' => 'v2',
- 'v3' => 'v3',
- 'sum' => '10',
- 'out' => '100',
- 'phone' => 'phone',
- 'userip' => 'userIP',
- 'email' => 'email',
- 'ps' => 'qiwi',
- );
- protected $responseCreateInvoiceWithoutEmail =
- '
- 0
- OK
- 1
- successUrl
- failUrl
- ';
- protected $responseCreateInvoiceWithoutPS =
- '
- 4
- OK
- successUrl
- failUrl
- ';
- protected $responseCreateInvoiceWithPS =
- '
- 0
- OK
- 1
- successUrl
- failUrl
- ';
-
- public function setUp()
- {
- $this->SetUpMocks();
- $this->queryParamsForCreateInvoice['ps'] = 'qiwi';
- $this->mobilePaymentApi = new QiwiWalletApi($this->clientMock, $this->projectMock);
- }
-
- public function testCreateInvoiceWithoutEmail()
- {
- $this->invoiceMock->expects($this->any())
- ->method('getAmount')
- ->will($this->returnValue('10'));
- $this->invoiceMock->expects($this->any())
- ->method('getVirtualCurrencyAmount')
- ->will($this->returnValue('100'));
- $this->userMock->expects($this->any())
- ->method('getEmail')
- ->will($this->returnValue(''));
-
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue($this->responseCreateInvoiceWithoutEmail));
-
- $signString = $this->createSignString($this->queryParamsWithoutEmail);
- $this->queryParamsWithoutEmail['md5'] = md5($signString . self::PROJECT_SECRET_KEY);
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->with(
- $this->url,
- array(),
- array('query' => $this->queryParamsWithoutEmail)
- )
- ->will($this->returnValue($this->requestMock));
-
- $this->assertInstanceOf(
- '\Xsolla\SDK\Invoice',
- $this->mobilePaymentApi->createInvoice($this->userMock, $this->invoiceMock)
- );
- }
-
- public function testCreateInvoiceWithPS()
- {
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue($this->responseCreateInvoiceWithPS)
- );
- $this->clientMock->expects($this->once())
- ->method('get')
- ->will($this->returnValue($this->requestMock));
-
- $this->mobilePaymentApi->createInvoice($this->userMock, $this->invoiceMock);
- }
-
- public function testCreateInvoiceWithoutPS()
- {
- $this->setExpectedException('\Xsolla\SDK\Exception\InvalidArgumentException');
- $this->responseMock->expects($this->once())
- ->method('getBody')
- ->will($this->returnValue($this->responseCreateInvoiceWithoutPS)
- );
- $signString = $this->createSignString($this->queryParamsWithoutPs);
- $this->queryParamsWithoutPs['md5'] = md5($signString . self::PROJECT_SECRET_KEY);
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->will($this->returnValue($this->requestMock));
-
- $this->mobilePaymentApi->createInvoice($this->userMock, $this->invoiceMock);
- }
-
-}
diff --git a/tests/Api/SubscriptionsApiTest.php b/tests/Api/SubscriptionsApiTest.php
deleted file mode 100644
index 350216e..0000000
--- a/tests/Api/SubscriptionsApiTest.php
+++ /dev/null
@@ -1,275 +0,0 @@
-projectMock = $this->getMock('\Xsolla\SDK\Project', array(), array(), '', false);
- $this->projectMock->expects($this->once())
- ->method('getProjectId')
- ->will($this->returnValue('projectId'));
-
- $this->userMock = $this->getMock('\Xsolla\SDK\User', array(), array(), '', false);
- $this->userMock->expects($this->any())
- ->method('getV1')
- ->will($this->returnValue('v1'));
- $this->userMock->expects($this->any())
- ->method('getV2')
- ->will($this->returnValue('v2'));
- $this->userMock->expects($this->any())
- ->method('getV3')
- ->will($this->returnValue('v3'));
-
- $this->clientMock = $this->getMock('\Guzzle\Http\Client', array(), array(), '', false);
- $this->requestMock = $this->getMock('\Guzzle\Http\Message\RequestInterface', array(), array(), '', false);
- $this->responseMock = $this->getMock('\Guzzle\Http\Message\Response', array(), array(), '', false);
-
- $this->requestMock->expects($this->once())
- ->method('send')
- ->will($this->returnValue($this->responseMock));
-
- $this->subscriptionMock = $this->getMock('\Xsolla\SDK\Subscription', array(), array(), '', false);
- $this->subscriptionMock->expects($this->any())
- ->method('getId')
- ->will($this->returnValue('id'));
- $this->subscriptionMock->expects($this->any())
- ->method('getProjectId')
- ->will($this->returnValue('projectId'));
- $this->subscriptionMock->expects($this->any())
- ->method('getType')
- ->will($this->returnValue('type'));
-
- $this->invoiceMock = $this->getMock('\Xsolla\SDK\Invoice', array(), array(), '', false);
- $this->invoiceMock->expects($this->any())
- ->method('getOut')
- ->will($this->returnValue('out'));
- $this->invoiceMock->expects($this->any())
- ->method('getVirtualCurrencyAmount')
- ->will($this->returnValue(self::AMOUNT_VIRTUAL_CURRENCY));
-
- $this->subscriptionsApi = new SubscriptionsApi($this->clientMock, $this->projectMock, false);
- }
-
- public function testSearch()
- {
- $this->clientMock->expects($this->once())->method('get')->with(
- '/v1/subscriptions'
- )->will($this->returnValue($this->requestMock));
-
- $this->responseMock->expects($this->once())
- ->method('json')
- ->will($this->returnValue(
- array('subscriptions' => array(
- array(
- 'id' => 'id',
- 'name' => 'name',
- 'type' => 'type',
- 'currency' => 'currency',
- )
- ))
- ));
-
- $subscriptions = $this->subscriptionsApi->search($this->userMock, SubscriptionsApi::TYPE_CARD);
- $this->assertInstanceOf(
- '\Xsolla\SDK\Subscription',
- $subscriptions[0]
- );
- }
-
- public function testSearchSecurityException()
- {
- $this->setExpectedException('Xsolla\SDK\Exception\SecurityException');
- $exceptionMock = new ClientErrorResponseException();
- $exceptionMock->setResponse($this->responseMock);
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->with()
- ->will($this->returnValue($this->requestMock));
- $this->requestMock->expects($this->once())
- ->method('send')
- ->will($this->throwException($exceptionMock));
- $this->responseMock->expects($this->once())
- ->method('json')
- ->will($this->returnValue(array(
- 'error' => array(
- 'code' => '23',
- 'message' => 'message'
- )
- )
- ));
-
- $this->subscriptionsApi->search($this->userMock, SubscriptionsApi::TYPE_CARD);
- }
-
- public function testSearchInvalidArgumentException()
- {
- $this->setExpectedException('Xsolla\SDK\Exception\InvalidArgumentException');
- $exceptionMock = new ClientErrorResponseException();
- $exceptionMock->setResponse($this->responseMock);
-
- $this->clientMock->expects($this->once())
- ->method('get')
- ->will($this->returnValue($this->requestMock));
- $this->requestMock->expects($this->once())
- ->method('send')
- ->will($this->throwException($exceptionMock));
- $this->responseMock->expects($this->once())
- ->method('json')
- ->will($this->returnValue(array(
- 'error' => array(
- 'code' => '1234',
- 'message' => 'message'
- )
- )
- ));
-
- $this->subscriptionsApi->search($this->userMock, SubscriptionsApi::TYPE_CARD);
- }
-
- public function testPay()
- {
- $this->clientMock->expects($this->once())
- ->method('post')
- ->with(
- '/v1/subscriptions/type',
- array('X-Xsolla-Sign' => '8ad385f8cb22b4a82d302361e29df198'),
- null,
- array('query' => array(
- 'subscription_id' => 'id',
- 'merchant_id' => 'projectId',
- 'amount_virtual' => self::AMOUNT_VIRTUAL_CURRENCY,
- 'card_cvv' => '',
- ))
- )
- ->will($this->returnValue($this->requestMock));
-
- $this->responseMock->expects($this->once())
- ->method('json')
- ->will($this->returnValue(array('id' => 'invoiceId')));
-
- $this->assertEquals('invoiceId', $this->subscriptionsApi->pay($this->subscriptionMock, $this->invoiceMock));
- }
-
- public function testPayException()
- {
- $this->setExpectedException('Xsolla\SDK\Exception\InvalidArgumentException');
- $exceptionMock = new ClientErrorResponseException();
- $exceptionMock->setResponse($this->responseMock);
-
- $this->clientMock->expects($this->once())
- ->method('post')
- ->with()
- ->will($this->returnValue($this->requestMock));
- $this->requestMock->expects($this->once())
- ->method('send')
- ->will($this->throwException($exceptionMock));
-
- $this->responseMock->expects($this->once())
- ->method('json')
- ->will($this->returnValue(array(
- 'error' => array(
- 'code' => '1234',
- 'message' => 'message'
- )
- )
- ));
-
- $this->subscriptionsApi->pay($this->subscriptionMock, $this->invoiceMock);
- }
-
- public function testDelete()
- {
- $this->clientMock->expects($this->once())
- ->method('delete')
- ->with('/v1/subscriptions/type')
- ->will($this->returnValue($this->requestMock));
-
- $this->responseMock->expects($this->once())
- ->method('getStatusCode')
- ->will($this->returnValue(200));
- $this->subscriptionsApi->delete($this->subscriptionMock);
- }
-
- public function testDeleteException()
- {
- $this->setExpectedException('Xsolla\SDK\Exception\InvalidArgumentException');
- $exceptionMock = new ClientErrorResponseException();
- $exceptionMock->setResponse($this->responseMock);
-
- $this->clientMock->expects($this->once())
- ->method('delete')
- ->with()
- ->will($this->returnValue($this->requestMock));
- $this->requestMock->expects($this->once())
- ->method('send')
- ->will($this->throwException($exceptionMock));
-
- $this->responseMock->expects($this->once())
- ->method('json')
- ->will($this->returnValue(array(
- 'error' => array(
- 'code' => '1234',
- 'message' => 'message'
- )
- )
- ));
-
- $this->subscriptionsApi->delete($this->subscriptionMock);
- }
-
- /**
- * @return \Xsolla\SDK\Api\SubscriptionsApi
- */
- public function getSubscriptionsApi()
- {
- return $this->subscriptionsApi;
- }
-}
diff --git a/tests/Integration/API/AbstractAPITest.php b/tests/Integration/API/AbstractAPITest.php
new file mode 100644
index 0000000..43ded9b
--- /dev/null
+++ b/tests/Integration/API/AbstractAPITest.php
@@ -0,0 +1,33 @@
+projectId = (int) $_SERVER['PROJECT_ID'];
+ $this->xsollaClient = XsollaClient::factory(array(
+ 'merchant_id' => $_SERVER['MERCHANT_ID'],
+ 'api_key' => $_SERVER['API_KEY'],
+ ));
+ global $argv;
+ if (in_array('--dump-http', $argv, true)) {
+ $echoCb = function (Event $event) {
+ echo (string) $event['request'].PHP_EOL;
+ echo (string) $event['response'].PHP_EOL;
+ };
+ $this->xsollaClient->getEventDispatcher()->addListener('request.complete', $echoCb);
+ }
+ }
+}
diff --git a/tests/Integration/API/CouponsTest.php b/tests/Integration/API/CouponsTest.php
new file mode 100644
index 0000000..1543497
--- /dev/null
+++ b/tests/Integration/API/CouponsTest.php
@@ -0,0 +1,42 @@
+xsollaClient->GetCoupon(array(
+ 'project_id' => $this->projectId,
+ 'code' => $this->code,
+ ));
+ static::assertInternalType('array', $actualCouponData);
+ }
+
+ public function testRedeemCoupon()
+ {
+ try {
+ $actualCouponData = $this->xsollaClient->RedeemCoupon(array(
+ 'project_id' => $this->projectId,
+ 'code' => $this->code,
+ 'request' => array(
+ 'user_id' => 1,
+ ),
+ ));
+ static::assertInternalType('array', $actualCouponData);
+ } catch (UnprocessableEntityException $e) {
+ if (false === strpos($e->getMessage(), 'You have used too much of coupons. Try again later')) {
+ throw $e;
+ } else {
+ static::markTestSkipped('You have used too much of coupons. Try again later');
+ }
+ }
+ }
+}
diff --git a/tests/Integration/API/CreatePaymentUITokenTest.php b/tests/Integration/API/CreatePaymentUITokenTest.php
new file mode 100644
index 0000000..c072a1c
--- /dev/null
+++ b/tests/Integration/API/CreatePaymentUITokenTest.php
@@ -0,0 +1,43 @@
+xsollaClient->createCommonPaymentUIToken($_SERVER['PROJECT_ID'], 'USER_ID');
+ static::assertInternalType('string', $token);
+ }
+
+ public function testCreatePaymentUITokenFromRequest()
+ {
+ $tokenRequest = new TokenRequest($_SERVER['PROJECT_ID'], 'USER_ID');
+ $tokenRequest->setUserEmail('email@example.com')
+ ->setCustomParameters(array('a' => 1, 'b' => 2))
+ ->setCurrency('USD')
+ ->setExternalPaymentId(12345)
+ ->setSandboxMode(true)
+ ->setUserName('USER_NAME');
+ $token = $this->xsollaClient->createPaymentUITokenFromRequest($tokenRequest);
+ static::assertInternalType('string', $token);
+ }
+
+ public function testCreatePaymentUIToken()
+ {
+ $requestJsonFileName = __DIR__.'/../../resources/token.json';
+ $tokenPayload = file_get_contents($requestJsonFileName);
+ if (false === $tokenPayload) {
+ static::fail('Could not read token request from tests/resources/token.json');
+ }
+ $request = json_decode($tokenPayload, true);
+ $tokenResponse = $this->xsollaClient->CreatePaymentUIToken(array('request' => $request));
+ static::assertArrayHasKey('token', $tokenResponse);
+ static::assertInternalType('string', $tokenResponse['token']);
+ }
+}
diff --git a/tests/Integration/API/EventsTest.php b/tests/Integration/API/EventsTest.php
new file mode 100644
index 0000000..ed3bb48
--- /dev/null
+++ b/tests/Integration/API/EventsTest.php
@@ -0,0 +1,15 @@
+xsollaClient->ListEvents();
+ static::assertInternalType('array', $events);
+ }
+}
diff --git a/tests/Integration/API/PromotionsTest.php b/tests/Integration/API/PromotionsTest.php
new file mode 100644
index 0000000..256c418
--- /dev/null
+++ b/tests/Integration/API/PromotionsTest.php
@@ -0,0 +1,216 @@
+promotion = array(
+ 'technical_name' => uniqid('promotion_'),
+ 'name' => array(
+ 'en' => 'name',
+ ),
+ 'description' => array(
+ 'en' => 'description',
+ ),
+ 'project_id' => $this->projectId,
+ );
+ }
+
+ public function testListPromotions()
+ {
+ $response = $this->xsollaClient->ListPromotions();
+ static::assertInternalType('array', $response);
+ }
+
+ public function testCreatePromotion()
+ {
+ $response = $this->xsollaClient->CreatePromotion(array(
+ 'request' => $this->promotion,
+ ));
+ static::assertArrayHasKey('id', $response);
+ static::$promotionId = $response['id'];
+ }
+
+ /**
+ * @depends testCreatePromotion
+ */
+ public function testGetPromotion()
+ {
+ $response = $this->xsollaClient->GetPromotion(array(
+ 'promotion_id' => static::$promotionId,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testGetPromotion
+ */
+ public function testUpdatePromotion()
+ {
+ $this->xsollaClient->UpdatePromotion(array(
+ 'promotion_id' => static::$promotionId,
+ 'request' => $this->promotion,
+ ));
+ }
+
+ /**
+ * @depends testUpdatePromotion
+ */
+ public function testSetPromotionSubject()
+ {
+ $this->xsollaClient->SetPromotionSubject(array(
+ 'promotion_id' => static::$promotionId,
+ 'request' => array(
+ 'purchase' => false,
+ 'items' => null,
+ 'packages' => array(1),
+ ),
+ ));
+ }
+
+ /**
+ * @depends testSetPromotionSubject
+ */
+ public function testGetPromotionSubject()
+ {
+ $response = $this->xsollaClient->GetPromotionSubject(array(
+ 'promotion_id' => static::$promotionId,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testGetPromotionSubject
+ */
+ public function testSetPromotionPaymentSystems()
+ {
+ $this->xsollaClient->SetPromotionPaymentSystems(array(
+ 'promotion_id' => static::$promotionId,
+ 'request' => array(
+ 'payment_systems' => array(
+ array('id' => 2682),
+ ),
+ ),
+ ));
+ }
+
+ /**
+ * @depends testSetPromotionPaymentSystems
+ */
+ public function testGetPromotionPaymentSystems()
+ {
+ $response = $this->xsollaClient->GetPromotionPaymentSystems(array(
+ 'promotion_id' => static::$promotionId,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testGetPromotionPaymentSystems
+ */
+ public function testSetPromotionPeriods()
+ {
+ $dateTime = new \DateTime('next month');
+ $this->xsollaClient->SetPromotionPeriods(array(
+ 'promotion_id' => static::$promotionId,
+ 'request' => array(
+ 'periods' => array(
+ array(
+ 'from' => $dateTime->format(\DateTime::ISO8601),
+ 'to' => $dateTime->modify('+ 1 month')->format(\DateTime::ISO8601),
+ ),
+ ),
+ ),
+ ));
+ }
+
+ /**
+ * @depends testSetPromotionPeriods
+ */
+ public function testGetPromotionPeriods()
+ {
+ $response = $this->xsollaClient->GetPromotionPeriods(array(
+ 'promotion_id' => static::$promotionId,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testGetPromotionPeriods
+ */
+ public function testSetPromotionRewards()
+ {
+ $this->xsollaClient->SetPromotionRewards(array(
+ 'promotion_id' => static::$promotionId,
+ 'request' => array(
+ 'purchase' => array(
+ 'discount_percent' => 10,
+ ),
+ ),
+ ));
+ }
+
+ /**
+ * @depends testSetPromotionRewards
+ */
+ public function testGetPromotionRewards()
+ {
+ $response = $this->xsollaClient->GetPromotionRewards(array(
+ 'promotion_id' => static::$promotionId,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testGetPromotionRewards
+ */
+ public function testReviewPromotion()
+ {
+ $response = $this->xsollaClient->ReviewPromotion(array(
+ 'promotion_id' => static::$promotionId,
+ ));
+ static::assertInternalType('array', $response);
+ echo PHP_EOL.'ReviewPromotion'.PHP_EOL.'==================='.PHP_EOL.XsollaClient::jsonEncode($response).PHP_EOL;
+ }
+
+ /**
+ * @depends testReviewPromotion
+ */
+ public function testTogglePromotion()
+ {
+ try {
+ $this->xsollaClient->TogglePromotion(array(
+ 'promotion_id' => static::$promotionId,
+ ));
+ } catch (UnprocessableEntityException $e) {
+ if (false === strpos($e->getMessage(), 'The promotion is not ready for launch')) {
+ throw $e;
+ } else {
+ static::markTestSkipped('The promotion is not ready for launch');
+ }
+ }
+ }
+
+ /**
+ * @depends testTogglePromotion
+ */
+ public function testDeletePromotion()
+ {
+ $this->xsollaClient->DeletePromotion(array(
+ 'promotion_id' => static::$promotionId,
+ ));
+ }
+}
diff --git a/tests/Integration/API/ReportsTest.php b/tests/Integration/API/ReportsTest.php
new file mode 100644
index 0000000..1c130c2
--- /dev/null
+++ b/tests/Integration/API/ReportsTest.php
@@ -0,0 +1,31 @@
+xsollaClient->ListTransfersRegistry();
+ static::assertInternalType('array', $response);
+ }
+
+ public function testListReportsRegistry()
+ {
+ $response = $this->xsollaClient->ListReportsRegistry();
+ static::assertInternalType('array', $response);
+ }
+
+ public function testCreateRefundRequest()
+ {
+ static::markTestSkipped('TODO: 404');
+ }
+}
diff --git a/tests/Integration/API/SubscriptionsTest.php b/tests/Integration/API/SubscriptionsTest.php
new file mode 100644
index 0000000..aff434d
--- /dev/null
+++ b/tests/Integration/API/SubscriptionsTest.php
@@ -0,0 +1,198 @@
+plan = array(
+ 'name' => array(
+ 'en' => 'Subscription Plan Name',
+ ),
+ 'group_id' => 'group_id',
+ 'charge' => array(
+ 'amount' => 1,
+ 'currency' => 'USD',
+ 'period' => array(
+ 'value' => 1,
+ 'type' => 'month',
+ ),
+ ),
+ 'expiration' => array(
+ 'value' => 3,
+ 'type' => 'month',
+ ),
+ );
+ $this->product = array(
+ 'name' => 'Product Name',
+ 'group_id' => 'group_id',
+ );
+ }
+
+ public function testCreateSubscriptionPlan()
+ {
+ try {
+ $response = $this->xsollaClient->CreateSubscriptionPlan(array(
+ 'project_id' => $this->projectId,
+ 'request' => $this->plan,
+ ));
+ static::assertArrayHasKey('plan_id', $response);
+ static::$planId = $response['plan_id'];
+ } catch (UnprocessableEntityException $e) {
+ if (false === strpos($e->getMessage(), 'External id is already exist')) {
+ throw $e;
+ } else {
+ static::markTestSkipped('External id is already exist');
+ }
+ }
+ }
+
+ /**
+ * @depends testCreateSubscriptionPlan
+ */
+ public function testListSubscriptionPlans()
+ {
+ $response = $this->xsollaClient->ListSubscriptionPlans(array(
+ 'project_id' => $this->projectId,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testListSubscriptionPlans
+ */
+ public function testUpdateSubscriptionPlan()
+ {
+ $response = $this->xsollaClient->UpdateSubscriptionPlan(array(
+ 'project_id' => $this->projectId,
+ 'plan_id' => static::$planId,
+ 'request' => $this->plan,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testUpdateSubscriptionPlan
+ */
+ public function testDisableSubscriptionPlan()
+ {
+ $this->xsollaClient->DisableSubscriptionPlan(array(
+ 'project_id' => $this->projectId,
+ 'plan_id' => static::$planId,
+ ));
+ }
+
+ /**
+ * @depends testDisableSubscriptionPlan
+ */
+ public function testEnableSubscriptionPlan()
+ {
+ $this->xsollaClient->EnableSubscriptionPlan(array(
+ 'project_id' => $this->projectId,
+ 'plan_id' => static::$planId,
+ ));
+ }
+
+ /**
+ * @depends testEnableSubscriptionPlan
+ */
+ public function testDeleteSubscriptionPlan()
+ {
+ $this->xsollaClient->DeleteSubscriptionPlan(array(
+ 'project_id' => $this->projectId,
+ 'plan_id' => static::$planId,
+ ));
+ }
+
+ /**
+ * @depends testDeleteSubscriptionPlan
+ */
+ public function testCreateSubscriptionProduct()
+ {
+ $response = $this->xsollaClient->CreateSubscriptionProduct(array(
+ 'project_id' => $this->projectId,
+ 'request' => $this->product,
+ ));
+ static::assertArrayHasKey('product_id', $response);
+ static::$productId = $response['product_id'];
+ }
+
+ /**
+ * @depends testCreateSubscriptionProduct
+ */
+ public function testUpdateSubscriptionProduct()
+ {
+ $response = $this->xsollaClient->UpdateSubscriptionProduct(array(
+ 'project_id' => $this->projectId,
+ 'product_id' => static::$productId,
+ 'request' => $this->product,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testUpdateSubscriptionProduct
+ */
+ public function testDeleteSubscriptionProduct()
+ {
+ $this->xsollaClient->DeleteSubscriptionProduct(array(
+ 'project_id' => $this->projectId,
+ 'product_id' => static::$productId,
+ ));
+ }
+
+ public function testListSubscriptionProducts()
+ {
+ $response = $this->xsollaClient->ListSubscriptionProducts(array(
+ 'project_id' => $this->projectId,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ public function testUpdateSubscription()
+ {
+ static::markTestSkipped('TODO: unit test');
+ }
+
+ public function testListSubscriptions()
+ {
+ $response = $this->xsollaClient->ListSubscriptions(array(
+ 'project_id' => $this->projectId,
+ 'user_id' => 1,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ public function testListSubscriptionPayments()
+ {
+ $response = $this->xsollaClient->ListSubscriptionPayments(array(
+ 'project_id' => $this->projectId,
+ 'user_id' => 1,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ public function testListSubscriptionCurrencies()
+ {
+ $response = $this->xsollaClient->ListSubscriptionCurrencies(array(
+ 'project_id' => $this->projectId,
+ 'user_id' => 1,
+ ));
+ static::assertInternalType('array', $response);
+ }
+}
diff --git a/tests/Integration/API/SupportTest.php b/tests/Integration/API/SupportTest.php
new file mode 100644
index 0000000..821fb9a
--- /dev/null
+++ b/tests/Integration/API/SupportTest.php
@@ -0,0 +1,20 @@
+xsollaClient->ListSupportTickets();
+ static::assertInternalType('array', $response);
+ }
+
+ public function testListSupportTicketComments()
+ {
+ static::markTestSkipped('TODO: add support ticket to test project');
+ }
+}
diff --git a/tests/Integration/API/UserAttributesTest.php b/tests/Integration/API/UserAttributesTest.php
new file mode 100644
index 0000000..920df31
--- /dev/null
+++ b/tests/Integration/API/UserAttributesTest.php
@@ -0,0 +1,81 @@
+userAttribute = array(
+ 'key' => uniqid('user_attribute_'),
+ 'localized_name' => array(
+ 'en' => 'name',
+ ),
+ 'type' => 'string',
+ );
+ }
+
+ public function testCreateUserAttribute()
+ {
+ $response = $this->xsollaClient->CreateUserAttribute(array(
+ 'project_id' => $this->projectId,
+ 'request' => $this->userAttribute,
+ ));
+ static::assertArrayHasKey('id', $response);
+ static::$attributeId = (int) $response['id'];
+ }
+
+ /**
+ * @depends testCreateUserAttribute
+ */
+ public function testGetUserAttribute()
+ {
+ $response = $this->xsollaClient->GetUserAttribute(array(
+ 'project_id' => $this->projectId,
+ 'user_attribute_id' => static::$attributeId,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testGetUserAttribute
+ */
+ public function testUpdateUserAttribute()
+ {
+ $this->xsollaClient->UpdateUserAttribute(array(
+ 'project_id' => $this->projectId,
+ 'user_attribute_id' => static::$attributeId,
+ 'request' => $this->userAttribute,
+ ));
+ }
+
+ /**
+ * @depends testUpdateUserAttribute
+ */
+ public function testListUserAttributes()
+ {
+ $response = $this->xsollaClient->ListUserAttributes(array(
+ 'project_id' => $this->projectId,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testListUserAttributes
+ */
+ public function testDeleteUserAttribute()
+ {
+ $this->xsollaClient->DeleteUserAttribute(array(
+ 'project_id' => $this->projectId,
+ 'user_attribute_id' => static::$attributeId,
+ ));
+ }
+}
diff --git a/tests/Integration/API/VirtualCurrencyTest.php b/tests/Integration/API/VirtualCurrencyTest.php
new file mode 100644
index 0000000..7d9ac14
--- /dev/null
+++ b/tests/Integration/API/VirtualCurrencyTest.php
@@ -0,0 +1,32 @@
+xsollaClient->UpdateProjectVirtualCurrencySettings(array(
+ 'request' => array(
+ 'vc_name' => array(
+ 'en' => 'name',
+ ),
+ 'base' => array(
+ 'USD' => 0.9,
+ ),
+ 'min' => 0.01,
+ 'max' => 100.2,
+ 'default_currency' => 'USD',
+ ),
+ 'project_id' => $this->projectId,
+ ));
+ }
+
+ public function testGetProjectVirtualCurrencySettings()
+ {
+ $this->xsollaClient->GetProjectVirtualCurrencySettings(array('project_id' => $this->projectId));
+ }
+}
diff --git a/tests/Integration/API/VirtualItemsTest.php b/tests/Integration/API/VirtualItemsTest.php
new file mode 100644
index 0000000..3b1d900
--- /dev/null
+++ b/tests/Integration/API/VirtualItemsTest.php
@@ -0,0 +1,212 @@
+ static::$virtualItemSku,
+ 'name' => array(
+ 'en' => 'Virtual Item',
+ ),
+ 'description' => array(
+ 'en' => 'Virtual Item Description',
+ ),
+ 'prices' => array(
+ 'USD' => 1,
+ ),
+ 'default_currency' => 'USD',
+ 'enabled' => true,
+ 'disposable' => false,
+ 'item_type' => 'Consumable',
+ );
+ }
+ $this->virtualItemsGroup = array(
+ 'name' => array(
+ 'en' => 'Virtual Item Group',
+ ),
+ 'description' => array(
+ 'en' => 'Virtual Item Group Description',
+ ),
+ 'enabled' => true,
+ );
+ }
+
+ public function testListVirtualItemsGroups()
+ {
+ $response = $this->xsollaClient->ListVirtualItemsGroups(array(
+ 'project_id' => $this->projectId,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ public function testListVirtualItems()
+ {
+ try {
+ $response = $this->xsollaClient->ListVirtualItems(array(
+ 'project_id' => $this->projectId,
+ ));
+ static::assertInternalType('array', $response);
+ } catch (XsollaAPIException $e) {
+ if (500 == $e->getPrevious()->getResponse()->getStatusCode()) {
+ static::markTestSkipped('TODO: random 500 responses in test merchant account');
+ } else {
+ throw $e;
+ }
+ }
+ }
+
+ public function testCreateVirtualItemsGroup()
+ {
+ $response = $this->xsollaClient->CreateVirtualItemsGroup(array(
+ 'project_id' => $this->projectId,
+ 'request' => $this->virtualItemsGroup,
+ ));
+ static::assertArrayHasKey('group_id', $response);
+ static::$virtualItemsGroupId = $response['group_id'];
+ static::$virtualItem['groups'] = array(static::$virtualItemsGroupId);
+ }
+
+ /**
+ * @depends testCreateVirtualItemsGroup
+ */
+ public function testGetVirtualItemsGroup()
+ {
+ $response = $this->xsollaClient->GetVirtualItemsGroup(array(
+ 'project_id' => $this->projectId,
+ 'group_id' => static::$virtualItemsGroupId,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testGetVirtualItemsGroup
+ */
+ public function testUpdateVirtualItemsGroup()
+ {
+ $this->xsollaClient->UpdateVirtualItemsGroup(array(
+ 'project_id' => $this->projectId,
+ 'group_id' => static::$virtualItemsGroupId,
+ 'request' => $this->virtualItemsGroup,
+ ));
+ }
+
+ /**
+ * @depends testUpdateVirtualItemsGroup
+ */
+ public function testCreateVirtualItem()
+ {
+ $response = $this->xsollaClient->CreateVirtualItem(array(
+ 'project_id' => $this->projectId,
+ 'request' => static::$virtualItem,
+ ));
+ static::assertArrayHasKey('item_id', $response);
+ static::$virtualItemId = $response['item_id'];
+ }
+
+ /**
+ * @depends testCreateVirtualItem
+ */
+ public function testGetVirtualItem()
+ {
+ $response = $this->xsollaClient->GetVirtualItem(array(
+ 'project_id' => $this->projectId,
+ 'item_id' => static::$virtualItemId,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testGetVirtualItem
+ */
+ public function testUpdateVirtualItem()
+ {
+ $this->xsollaClient->UpdateVirtualItem(array(
+ 'project_id' => $this->projectId,
+ 'item_id' => static::$virtualItemId,
+ 'request' => static::$virtualItem,
+ ));
+ }
+
+ /**
+ * @depends testUpdateVirtualItem
+ */
+ public function testUpdateVirtualItemImage()
+ {
+ $url = $this->xsollaClient->UpdateVirtualItemImage(array(
+ 'project_id' => $this->projectId,
+ 'item_id' => static::$virtualItemId,
+ 'request' => array(
+ 'data' => 'iVBORw0KGgoAAAANSUhEUgAAACoAAAAoCAQAAAAiAqDbAAABl0lEQVR4Ae3VsUtVYRjA4VeUa4pRbVENBUoQlEFF\/0CiSEVbwYVoKLBwaYmChiiQmlqagqChOxeCQ0gX27K2xmpKscEhcrlxb54niAOHkvvdzh2c7vlNh+\/wDC+c94tteQwZEHkjQrphi6ri77Z+VDevIoRRK65Lk3VkJtLoPfjDHraKzJG25Ig6qOlPoxXzYNE6Nl1NkMvgRU4m0IJlU1W0rV8NLNvVGQ0nZOCjYZFknxZsGj1qHUBdmu3zLGeHUuh4PsvLajqzB3wGD0UKvYaWqnxmVh1MkF\/Anc4znXFePjOPjYq2nfQDt0UaLdtpN0V5tHQ9tIcW7bGza2jQGVdMGPwXfeJRl+SUb4A1kwrUMb80jXX1XzUB0HSqOFoCC8qjb\/DdpB2mbOB1fuAigOmSZJ8W7udvc\/iZ34q+4q33+KRSCh2QKdbfXbRCCA\/AWZfALVGqD1gxJvIb+F0IhzQAwIa9pdBzILMmA9MhvAQA8FyU6oYGoGFGhHB8S+OiZPvNmjNrX2+h\/Ce6G1zwCks9tIduO\/obgMsmlpJdCMsAAAAASUVORK5CYII="',
+ ),
+ ));
+ static::assertInternalType('string', filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_PATH_REQUIRED));
+ }
+
+ /**
+ * @depends testUpdateVirtualItemImage
+ */
+ public function testDeleteVirtualItemImage()
+ {
+ $this->xsollaClient->DeleteVirtualItemImage(array(
+ 'project_id' => $this->projectId,
+ 'item_id' => static::$virtualItemId,
+ ));
+ }
+
+ /**
+ * @depends testUpdateVirtualItemsGroup
+ */
+ public function testUpdateVirtualItemOrderInGroup()
+ {
+ $this->xsollaClient->UpdateVirtualItemOrderInGroup(array(
+ 'project_id' => $this->projectId,
+ 'request' => array(
+ 'group_id' => static::$virtualItemsGroupId,
+ 'virtual_items' => array(static::$virtualItemSku),
+ ),
+ ));
+ }
+
+ /**
+ * @depends testUpdateVirtualItemOrderInGroup
+ */
+ public function testDeleteVirtualItem()
+ {
+ $this->xsollaClient->DeleteVirtualItem(array(
+ 'project_id' => $this->projectId,
+ 'item_id' => static::$virtualItemId,
+ ));
+ }
+
+ /**
+ * @depends testDeleteVirtualItem
+ */
+ public function testDeleteVirtualItemsGroup()
+ {
+ $this->xsollaClient->DeleteVirtualItemsGroup(array(
+ 'project_id' => $this->projectId,
+ 'group_id' => static::$virtualItemsGroupId,
+ ));
+ }
+}
diff --git a/tests/Integration/API/WalletTest.php b/tests/Integration/API/WalletTest.php
new file mode 100644
index 0000000..9f510de
--- /dev/null
+++ b/tests/Integration/API/WalletTest.php
@@ -0,0 +1,150 @@
+xsollaClient->CreateWalletUser(array(
+ 'project_id' => $this->projectId,
+ 'request' => array('user_id' => static::$userId),
+ ));
+ }
+
+ /**
+ * @depends testCreateWalletUser
+ */
+ public function testGetWalletUser()
+ {
+ $response = $this->xsollaClient->GetWalletUser(array(
+ 'project_id' => $this->projectId,
+ 'user_id' => static::$userId,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testGetWalletUser
+ */
+ public function testUpdateWalletUser()
+ {
+ $this->xsollaClient->UpdateWalletUser(array(
+ 'project_id' => $this->projectId,
+ 'user_id' => static::$userId,
+ 'request' => array(
+ 'user_id' => static::$userId, //TODO
+ 'enabled' => true,
+ ),
+ ));
+ }
+
+ public function testListWalletUsers()
+ {
+ $response = $this->xsollaClient->ListWalletUsers(array(
+ 'project_id' => $this->projectId,
+ 'limit' => 1,
+ 'offset' => 0,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testUpdateWalletUser
+ */
+ public function testListWalletUserOperations()
+ {
+ $response = $this->xsollaClient->ListWalletUserOperations(array(
+ 'project_id' => $this->projectId,
+ 'user_id' => static::$userId,
+ 'datetime_from' => '2015-01-01T00:00:00 UTC',
+ 'datetime_to' => '2016-01-01T00:00:00 UTC',
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testListWalletUserOperations
+ */
+ public function testRechargeWalletUserBalance()
+ {
+ $response = $this->xsollaClient->RechargeWalletUserBalance(array(
+ 'project_id' => $this->projectId,
+ 'user_id' => static::$userId,
+ 'request' => array(
+ 'amount' => 10,
+ 'comment' => 'Comment',
+ ),
+ ));
+ static::assertArrayHasKey('amount', $response);
+ }
+
+ /**
+ * @depends testCreateWalletUser
+ */
+ public function testAddVirtualItemToWalletUser()
+ {
+ $this->xsollaClient->AddVirtualItemToWalletUser(array(
+ 'project_id' => $this->projectId,
+ 'user_id' => static::$userId,
+ 'request' => array(
+ 'virtual_items' => array(
+ array(
+ 'virtual_item' => array(
+ 'sku' => '1468', // https://merchant.xsolla.com/22174/projects/15861/items/15435
+ ),
+ 'amount' => 2,
+ ),
+ ),
+ ),
+ ));
+ }
+
+ /**
+ * @depends testAddVirtualItemToWalletUser
+ */
+ public function testListWalletUserVirtualItems()
+ {
+ $response = $this->xsollaClient->ListWalletUserVirtualItems(array(
+ 'project_id' => $this->projectId,
+ 'user_id' => static::$userId,
+ 'limit' => 1,
+ 'offset' => 0,
+ ));
+ static::assertInternalType('array', $response);
+ }
+
+ /**
+ * @depends testListWalletUserVirtualItems
+ */
+ public function testDeleteVirtualItemFromWalletUser()
+ {
+ $this->xsollaClient->DeleteVirtualItemFromWalletUser(array(
+ 'project_id' => $this->projectId,
+ 'user_id' => static::$userId,
+ 'request' => array(
+ 'virtual_items' => array(
+ array(
+ 'virtual_item' => array(
+ 'sku' => '1468',
+ ),
+ 'amount' => 2,
+ ),
+ ),
+ ),
+ ));
+ }
+}
diff --git a/tests/Integration/Webhook/ServerMock.php b/tests/Integration/Webhook/ServerMock.php
new file mode 100644
index 0000000..a2e5869
--- /dev/null
+++ b/tests/Integration/Webhook/ServerMock.php
@@ -0,0 +1,35 @@
+start(null, 'invalid_ip' === $testCase);
+ }
+}
diff --git a/tests/Integration/Webhook/ServerTest.php b/tests/Integration/Webhook/ServerTest.php
new file mode 100644
index 0000000..08a537f
--- /dev/null
+++ b/tests/Integration/Webhook/ServerTest.php
@@ -0,0 +1,203 @@
+guzzleClient = new Client('http://localhost:8000');
+ }
+
+ /**
+ * @dataProvider cbProvider
+ */
+ public function testResponse(
+ $expectedStatusCode,
+ $expectedResponseContent,
+ $request,
+ $testCase,
+ $testHeaders
+ ) {
+ $process = new Process('php -S localhost:8000', __DIR__.'/../../resources');
+ $process->start();
+ sleep(1);
+ $signature = sha1($request.ServerMock::PROJECT_SECRET_KEY);
+ $headers = null;
+ if ($testHeaders) {
+ $headers = $testHeaders;
+ } else {
+ $headers = array('Authorization' => 'Signature '.$signature);
+ }
+ $request = $this->guzzleClient->post('/webhook_server.php?test_case='.$testCase, $headers, $request);
+ try {
+ $response = $request->send();
+ } catch (BadResponseException $e) {
+ $process->stop();
+ $response = $e->getResponse();
+ }
+ static::assertSame($expectedResponseContent, $response->getBody(true));
+ static::assertSame($expectedStatusCode, $response->getStatusCode());
+ static::assertArrayHasKey('x-xsolla-sdk', $response->getHeaders());
+ static::assertSame(Version::getVersion(), (string) $response->getHeader('x-xsolla-sdk'));
+ static::assertArrayHasKey('content-type', $response->getHeaders());
+ if (204 === $response->getStatusCode()) {
+ static::assertSame('text/plain;charset=UTF-8', (string) $response->getHeader('content-type'));
+ } else {
+ static::assertSame('application/json', (string) $response->getHeader('content-type'));
+ }
+ }
+
+ public function cbProvider()
+ {
+ return array(
+ array(
+ 'expectedStatusCode' => 204,
+ 'expectedResponseContent' => '',
+ 'request' => '{"notification_type": "payment"}',
+ 'testCase' => 'success',
+ 'testHeaders' => null,
+ ),
+ array(
+ 'expectedStatusCode' => 422,
+ 'expectedResponseContent' => XsollaClient::jsonEncode(
+ array(
+ 'error' => array(
+ 'code' => 'INVALID_PARAMETER',
+ 'message' => 'notification_type key not found in Xsolla webhook request',
+ ),
+ )
+ ),
+ 'request' => '{"foo": "bar"}',
+ 'testCase' => 'empty_request',
+ 'testHeaders' => null,
+ ),
+ array(
+ 'expectedStatusCode' => 422,
+ 'expectedResponseContent' => XsollaClient::jsonEncode(
+ array(
+ 'error' => array(
+ 'code' => 'INVALID_PARAMETER',
+ 'message' => 'Unknown notification_type in Xsolla webhook request: unknown',
+ ),
+ )
+ ),
+ 'request' => '{"notification_type": "unknown"}',
+ 'testCase' => 'unknown_notification_type',
+ 'testHeaders' => null,
+ ),
+ array(
+ 'expectedStatusCode' => 401,
+ 'expectedResponseContent' => XsollaClient::jsonEncode(
+ array(
+ 'error' => array(
+ 'code' => 'INVALID_SIGNATURE',
+ 'message' => 'Invalid Signature. Signature provided in "Authorization" header (78143a5ac4b892a68ce8b0b8b49e26667db0fa00) does not match with expected',
+ ),
+ )
+ ),
+ 'request' => null,
+ 'testCase' => 'invalid_signature',
+ 'testHeaders' => array('Authorization' => 'Signature 78143a5ac4b892a68ce8b0b8b49e26667db0fa00'),
+ ),
+ array(
+ 'expectedStatusCode' => 401,
+ 'expectedResponseContent' => XsollaClient::jsonEncode(
+ array(
+ 'error' => array(
+ 'code' => 'INVALID_SIGNATURE',
+ 'message' => '"Authorization" header not found in Xsolla webhook request',
+ ),
+ )
+ ),
+ 'request' => null,
+ 'testCase' => 'authorization_header_not_found',
+ 'testHeaders' => array('foo' => 'bar'),
+ ),
+ array(
+ 'expectedStatusCode' => 401,
+ 'expectedResponseContent' => XsollaClient::jsonEncode(
+ array(
+ 'error' => array(
+ 'code' => 'INVALID_SIGNATURE',
+ 'message' => 'Signature not found in "Authorization" header from Xsolla webhook request: INVALID_FORMAT',
+ ),
+ )
+ ),
+ 'request' => null,
+ 'testCase' => 'invalid_signature_format',
+ 'testHeaders' => array('Authorization' => 'INVALID_FORMAT'),
+ ),
+ array(
+ 'expectedStatusCode' => 422,
+ 'expectedResponseContent' => XsollaClient::jsonEncode(
+ array(
+ 'error' => array(
+ 'code' => 'INVALID_PARAMETER',
+ 'message' => 'Unable to parse Xsolla webhook request into JSON: Syntax error.',
+ ),
+ )
+ ),
+ 'request' => 'INVALID_REQUEST_CONTENT',
+ 'testCase' => 'invalid_request_content',
+ 'testHeaders' => null,
+ ),
+ array(
+ 'expectedStatusCode' => 401,
+ 'expectedResponseContent' => XsollaClient::jsonEncode(
+ array(
+ 'error' => array(
+ 'code' => 'INVALID_CLIENT_IP',
+ 'message' => 'Xsolla trusted subnets (159.255.220.240/28, 185.30.20.16/29, 185.30.21.0/24, 185.30.21.16/29) doesn\'t contain client IP address (127.0.0.1). If you use reverse proxy, you should set correct client IPv4 to WebhookRequest. If you are in development environment, you can set $authenticateClientIp = false in $webhookServer->start();',
+ ),
+ )
+ ),
+ 'request' => null,
+ 'testCase' => 'invalid_ip',
+ 'testHeaders' => null,
+ ),
+ array(
+ 'expectedStatusCode' => 500,
+ 'expectedResponseContent' => XsollaClient::jsonEncode(
+ array(
+ 'error' => array(
+ 'code' => 'SERVER_ERROR',
+ 'message' => 'callback_server_error',
+ ),
+ )
+ ),
+ 'request' => '{"notification_type": "payment"}',
+ 'testCase' => 'callback_server_error',
+ 'testHeaders' => null,
+ ),
+ array(
+ 'expectedStatusCode' => 400,
+ 'expectedResponseContent' => XsollaClient::jsonEncode(
+ array(
+ 'error' => array(
+ 'code' => 'CLIENT_ERROR',
+ 'message' => 'callback_client_error',
+ ),
+ )
+ ),
+ 'request' => '{"notification_type": "payment"}',
+ 'testCase' => 'callback_client_error',
+ 'testHeaders' => null,
+ ),
+ );
+ }
+}
diff --git a/tests/InvoiceTest.php b/tests/InvoiceTest.php
deleted file mode 100644
index f0e056a..0000000
--- a/tests/InvoiceTest.php
+++ /dev/null
@@ -1,68 +0,0 @@
-invoice = new Invoice;
- }
-
- public function testConstructor()
- {
- $invoice = new Invoice(self::OUT, self::SUM, self::CURRENCY, self::ID);
- $this->assertSame(self::OUT, $invoice->getVirtualCurrencyAmount());
- $this->assertSame(self::SUM, $invoice->getAmount());
- $this->assertSame(self::CURRENCY, $invoice->getCurrency());
- $this->assertSame(self::ID, $invoice->getId());
- }
-
- public function testSum()
- {
- $this->assertNull($this->invoice->getAmount());
- $this->invoice->setAmount(self::SUM);
- $this->assertSame(self::SUM, $this->invoice->getAmount());
- }
-
- public function testOut()
- {
- $this->assertNull($this->invoice->getVirtualCurrencyAmount());
- $this->invoice->setVirtualCurrencyAmount(self::OUT);
- $this->assertSame(self::OUT, $this->invoice->getVirtualCurrencyAmount());
- }
-
- public function testCurrency()
- {
- $this->assertNull($this->invoice->getCurrency());
- $this->invoice->setCurrency(self::CURRENCY);
- $this->assertSame(self::CURRENCY, $this->invoice->getCurrency());
- }
-
- public function testId()
- {
- $this->assertNull($this->invoice->getId());
- $this->invoice->setId(self::ID);
- $this->assertSame(self::ID, $this->invoice->getId());
- }
-
- public function testFluentInterface()
- {
- $this->invoice->setAmount(2.22)
- ->setCurrency('RUB')
- ->setId(543)
- ->setVirtualCurrencyAmount(1.11)
- ->getId();
- }
-}
diff --git a/tests/PaymentPage/UrlBuilderFactoryTest.php b/tests/PaymentPage/UrlBuilderFactoryTest.php
deleted file mode 100644
index c060d45..0000000
--- a/tests/PaymentPage/UrlBuilderFactoryTest.php
+++ /dev/null
@@ -1,78 +0,0 @@
-project = new Project(7096, 'KEY');
- $this->urlBuilderFactory = new UrlBuilderFactory($this->project);
- }
-
- public function testGetPayStation()
- {
- $url = $this->urlBuilderFactory->getPayStation()->getUrl();
- $this->assertSame(
- 'https://secure.xsolla.com/paystation2/?marketplace=paystation&project=7096&sign=094eb3c634f2612dead38608dc20eaec',
- $url
- );
- }
-
- public function testGetCreditCards()
- {
- $url = $this->urlBuilderFactory->getCreditCards()->getUrl();
- $this->assertSame(
- 'https://secure.xsolla.com/paystation2/?marketplace=landing&pid=1380&theme=201&project=7096&sign=457a3f06ea55593b6204b992963cf762',
- $url
- );
- }
-
- public function testGetPayDesk()
- {
- $url = $this->urlBuilderFactory->getPayDesk()->getUrl();
- $this->assertSame(
- 'https://secure.xsolla.com/paystation2/?marketplace=paydesk&project=7096&sign=094eb3c634f2612dead38608dc20eaec',
- $url
- );
- }
-
- public function testGetMobilePayment()
- {
- $url = $this->urlBuilderFactory->getMobilePayment()->getUrl();
- $this->assertSame(
- 'https://secure.xsolla.com/paystation2/?marketplace=landing&theme=201&pid=1738&project=7096&sign=457a3f06ea55593b6204b992963cf762',
- $url
- );
- }
-
- public function testGetDirectPayment()
- {
- $url = $this->urlBuilderFactory->getDirectPayment(6)->getUrl();
- $this->assertSame(
- 'https://secure.xsolla.com/paystation2/?marketplace=landing&pid=6&project=7096&sign=094eb3c634f2612dead38608dc20eaec',
- $url
- );
- }
-
- public function testGetMobileVersion()
- {
- $url = $this->urlBuilderFactory->getMobileVersion()->getUrl();
- $this->assertSame(
- 'https://secure.xsolla.com/paystation2/?marketplace=mobile&project=7096&sign=094eb3c634f2612dead38608dc20eaec',
- $url
- );
- }
-}
diff --git a/tests/PaymentPage/UrlBuilderTest.php b/tests/PaymentPage/UrlBuilderTest.php
deleted file mode 100644
index a38cac0..0000000
--- a/tests/PaymentPage/UrlBuilderTest.php
+++ /dev/null
@@ -1,140 +0,0 @@
-user = new User('user_v1');
- $this->user->setV2('user_v2');
- $this->user->setV3('user_v3');
- $this->user->setEmail('email@example.com');
- $this->user->setPhone('user_phone');
- $this->user->setUserIp('user_userIp');
-
- $this->invoice = new Invoice;
- $this->invoice->setCurrency('EUR');
- $this->invoice->setVirtualCurrencyAmount(1.11);
-
- $this->project = new Project(7096, 'KEY');
-
- $this->urlBuilder = new UrlBuilder($this->project);
- }
-
- public function testGetLink()
- {
- $this->assertSame($this->defaultUrl, $this->urlBuilder->getUrl());
- }
-
- public function testGetLinkSandbox()
- {
- $this->assertSame($this->sandboxUrl, $this->urlBuilder->getUrl(UrlBuilder::SANDBOX_URL));
- }
-
- public function testIgnoreBlankParameters()
- {
- $this->urlBuilder->setParameter('description', '');
- $this->testGetLink();
- }
-
- public function testClear()
- {
- $this->urlBuilder->setCountry('US')
- ->clear();
- $this->testGetLink();
- }
-
- public function testHiddenParameters()
- {
- $this->urlBuilder->setInvoice($this->invoice);
- $this->assertSame($this->urlWithHiddenParameters, $this->urlBuilder->getUrl());
- }
-
- public function testClearSignedParameters()
- {
- $this->urlBuilder->setUser($this->user, false);
- $this->assertSame($this->urlWithUserDetailsAndClearedSignedParameters, $this->urlBuilder->getUrl());
- }
-
- public function testDefaultSignedParameters()
- {
- $this->urlBuilder->setInvoice($this->invoice)
- ->unlockParameterForUser('currency')
- ->unlockParameterForUser('currency')
- ->lockParameterForUser('currency');
- $this->assertSame($this->urlWithInvoiceAndWithoutSignparams, $this->urlBuilder->getUrl());
- }
-
- public function testFluentInterface()
- {
- $this->invoice->setAmount(0.1);
-
- $url = $this->urlBuilder->clear()
- ->setLocale('EN')
- ->setCountry('US')
- ->setParameter('limit', 14, true, true)
- ->setUser($this->user, true, false)
- ->setInvoice($this->invoice, true, false)
- ->unlockParameterForUser('v1')
- ->lockParameterForUser('limit')
- ->getUrl();
- $this->assertSame($this->fullUrl, $url);
- }
-
- public function testShoppingCart3()
- {
- $this->invoice->setAmountShoppingCart3(0.1);
- $this->invoice->setCurrencyShoppingCart3('EUR');
- $this->invoice->setVirtualCurrencyAmount(null);
- $this->invoice->setCurrency(null);
- $url = $this->urlBuilder->clear()
- ->setLocale('EN')
- ->setCountry('US')
- ->setParameter('limit', 14, true, true)
- ->setUser($this->user, true, false)
- ->setInvoice($this->invoice, true, false)
- ->unlockParameterForUser('v1')
- ->lockParameterForUser('limit')
- ->getUrl();
- $this->assertSame($this->fullUrlShoppingCart3, $url);
- }
-}
diff --git a/tests/ProjectTest.php b/tests/ProjectTest.php
deleted file mode 100644
index 9f8267b..0000000
--- a/tests/ProjectTest.php
+++ /dev/null
@@ -1,17 +0,0 @@
-assertSame(self::PROJECT_ID, $project->getProjectId());
- $this->assertSame(self::SECRET_KEY, $project->getSecretKey());
- }
-}
diff --git a/tests/Protocol/ProtocolFullTest.php b/tests/Protocol/ProtocolFullTest.php
deleted file mode 100644
index 62286e1..0000000
--- a/tests/Protocol/ProtocolFullTest.php
+++ /dev/null
@@ -1,263 +0,0 @@
-projectMock = $this->getMock('\Xsolla\SDK\Project', array(), array(), '', false);
- $this->projectMock->expects($this->any())
- ->method('getProjectId')
- ->will($this->returnValue(self::PROJECT_ID));
- $this->projectMock->expects($this->any())
- ->method('getSecretKey')
- ->will($this->returnValue(self::PROJECT_KEY));
-
- $this->requestMock = $this->getMock('Symfony\Component\HttpFoundation\Request', array(), array(), '', false);
- $this->ipCheckerMock = $this->getMock('Xsolla\SDK\Validator\IpChecker', array(), array(), '', false);
- $this->requestMock->expects($this->once())
- ->method('getClientIp')
- ->will($this->returnValue(self::CLIENT_IP));
- $this->ipCheckerMock->expects($this->once())
- ->method('checkIp')
- ->with(self::CLIENT_IP);
-
- $this->protocolBuilder = new \Xsolla\SDK\Protocol\ProtocolFactory($this->projectMock, $this->ipCheckerMock);
-
- date_default_timezone_set('Europe/Moscow');
- }
-
- public function protocolTest(array $params, $expectedXml)
- {
- $requestMock = $this->buildRequestMock($params);
- $response = $this->protocol->run($requestMock);
- $actualXml = $response->getContent();
- $message = 'Expected:'.PHP_EOL.$expectedXml.PHP_EOL.'Actual:'.PHP_EOL.$actualXml;
- $this->assertXmlStringEqualsXmlString($expectedXml, $actualXml, $message);
- }
-
- /**
- * @dataProvider ipCheckerProvider
- */
- public function testIpCheckerException(array $params, $expectedXml)
- {
- $this->ipCheckerMock->expects($this->once())
- ->method('checkIp')
- ->with(self::CLIENT_IP)
- ->will($this->throwException(new UnprocessableRequestException('IP whitelist doesn\'t contain client IP address')));
- $this->protocolTest($params, $expectedXml);
- }
-
- /**
- * @dataProvider wrongCommandProvider
- */
- public function testWrongCommand(array $params, $expectedXml)
- {
- $this->protocolTest($params, $expectedXml);
- }
-
- /**
- * @dataProvider noCommandProvider
- */
- public function testNoCommand(array $params, $expectedXml)
- {
- $this->protocolTest($params, $expectedXml);
- }
-
- /**
- * @dataProvider cancelProvider
- */
- public function testCancel(array $params, $expectedXml)
- {
- $this->protocolTest($params, $expectedXml);
- }
-
- /**
- * @dataProvider payProvider
- */
- public function testPay(array $params, $expectedXml)
- {
- $this->protocolTest($params, $expectedXml);
- }
-
- public function cancelProvider()
- {
- return array(
- array(
- array(
- 'command' => 'cancel'
- ),
- '' . PHP_EOL .
- '4' .
- 'Invalid request format. Missed parameters: md5, id' .
- '' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'cancel',
- 'id' => '500'
- ),
- '' . PHP_EOL .
- '4' .
- 'Invalid request format. Missed parameters: md5' .
- '' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'cancel',
- 'id' => '500',
- 'md5' => '11111109bbf31111211175a111c3f11'
- ),
- '' . PHP_EOL .
- '3Invalid md5 signature' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'cancel',
- 'id' => self::CANCEL_ID_VALID,
- 'md5' => 'bc763ff5a8665c7c4c5fa0d8eba75ac8'
- ),
- '' . PHP_EOL .
- '0' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'cancel',
- 'id' => self::CANCEL_ID_NOT_FOUND,
- 'md5' => '19715f09bc5b2e9c2e47ce00cb40fc54'
- ),
- '' . PHP_EOL .
- '2Invoice not found.' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'cancel',
- 'id' => self::CANCEL_ID_UNPROCESSABLE,
- 'md5' => '9e652f044a63f2248633eb9a8afecf8e'
- ),
- '' . PHP_EOL .
- '7' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'cancel',
- 'id' => self::CANCEL_ID_ANY_EXCEPTION,
- 'md5' => 'a4bbcb6f3e1da6366661181f888ef8be'
- ),
- '' . PHP_EOL .
- '1Any exception' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'cancel',
- 'id' => self::ZERO,
- 'md5' => 'ee46550702331221596b8d4dbb68112e'
- ),
- '' . PHP_EOL .
- '0' . PHP_EOL
- ),
- );
- }
-
- public function buildCancelRequestMock()
- {
- return $this->buildRequestMock(array(
- 'command' => 'cancel',
- 'id' => '500',
- 'md5' => '680f9109bbf3d008120e275a4ebc3f45'
- ));
- }
-
- public function addCancelHandler(PaymentStorageInterface $paymentsStorageMock)
- {
- $paymentsStorageMock->expects($this->any())
- ->method('cancel')
- ->will($this->returnCallback(array($this, 'cancelCallback')));
- }
-
- public function cancelCallback($id)
- {
- switch ($id) {
- case self::CANCEL_ID_NOT_FOUND:
- throw new InvoiceNotFoundException();
- case self::CANCEL_ID_UNPROCESSABLE:
- throw new UnprocessableRequestException();
- case self::CANCEL_ID_ANY_EXCEPTION;
- throw new \Exception('Any exception');
- }
- }
-
- public function buildRequestMock(Array $params)
- {
- $queryMock = $this->getMock('Symfony\Component\HttpFoundation\ParameterBag');
- $queryMock->expects($this->any())
- ->method('get')
- ->will($this->returnCallback(
- function ($key) use (&$params) {
- if (array_key_exists($key, $params)) {
- return $params[$key];
- } else {
- return null;
- }
- }
- ));
- $queryMock->expects($this->any())
- ->method('keys')
- ->will($this->returnValue(array_keys($params)));
- $this->requestMock->query = $queryMock;
-
- return $this->requestMock;
- }
-}
diff --git a/tests/Protocol/ShoppingCart3ProtocolFullTest.php b/tests/Protocol/ShoppingCart3ProtocolFullTest.php
deleted file mode 100644
index 6b63df2..0000000
--- a/tests/Protocol/ShoppingCart3ProtocolFullTest.php
+++ /dev/null
@@ -1,257 +0,0 @@
-userStorageMock = $this->getMock('Xsolla\SDK\Protocol\Storage\UserStorageInterface', array(), array(), '', false);
- $this->paymentStorageMock = $this->getMock('Xsolla\SDK\Protocol\Storage\PaymentShoppingCart3StorageInterface', array(), array(), '', false);
- $this->addCancelHandler($this->paymentStorageMock);
- $this->addPayHandler($this->paymentStorageMock);
- $this->addCheckHandler($this->userStorageMock);
- $this->protocol = $this->protocolBuilder->getShoppingCart3Protocol($this->userStorageMock, $this->paymentStorageMock);
- }
-
- /**
- * @dataProvider checkProvider
- */
- public function testCheck(array $params, $expectedXml)
- {
- $this->protocolTest($params, $expectedXml);
- }
-
- public function checkProvider()
- {
- return array(
- array(
- array(
- 'command' => 'check',
- 'v1' => self::CHECK_V1_ANY_EXCEPTION,
- 'md5' => '22a0964fb976608f25f2d55ee44c01d3'
- ),
- '' . PHP_EOL .
- '1Any exception' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'check',
- 'v1' => self::CHECK_V1_NOT_EXISTS,
- 'md5' => '7c7fce6806ae451419dede822033dd9e'
- ),
- '' . PHP_EOL .
- '7' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'check',
- 'v1' => self::CHECK_V1_SUCCESS,
- 'md5' => 'a3561b90df78828133eb285e36965419'
- ),
- '' . PHP_EOL .
- '0value1value2' . PHP_EOL
- ),
- );
- }
-
- public function noCommandProvider()
- {
- return array(
- array(
- array(
- 'id' => '100',
- 'sign' => 'bc763ff5a8665c7c4c5fa0d8eba75ac8'
- ),
- '' . PHP_EOL .
- '4' .
- 'No command in request. Available commands are: "check", "pay", "cancel".' .
- '' . PHP_EOL
- )
- );
- }
-
- public function wrongCommandProvider()
- {
- return array(
- array(
- array(
- 'command' => 'not_exist',
- ),
- '' . PHP_EOL .
- '4' .
- 'Wrong command: "not_exist". Available commands for Standard protocol are: "check", "pay", "cancel".' .
- '' . PHP_EOL
- )
- );
- }
-
- public function ipCheckerProvider()
- {
- return array(
- array(
- array(
- 'command' => 'pay',
- ),
- '' . PHP_EOL .
- '7' .
- 'IP whitelist doesn\'t contain client IP address' .
- '' . PHP_EOL
- )
- );
- }
-
- public function payProvider()
- {
- return array(
- array(
- array(
- 'command' => 'pay'
- ),
- '' . PHP_EOL .
- '4' .
- 'Invalid request format. Missed parameters: md5, id, v1, date, payment_amount, payment_currency' .
- '' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'md5' => '11111ff5a8661171111111d8e1171111',
- 'id' => self::PAY_ID_SUCCESS,
- 'v1' => 'demo',
- 'payment_amount' => '100.20',
- 'payment_currency' => 'EUR',
- 'date' => '2014-02-19 20:07:08'
- ),
- '' . PHP_EOL .
- '3Invalid md5 signature' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'md5' => '151783427f854e7c61e54fae5361cacb',
- 'id' => self::PAY_ID_SUCCESS,
- 'v1' => 'demo',
- 'payment_amount' => '100.20',
- 'payment_currency' => 'EUR',
- 'date' => 'DATE'
- ),
- '' . PHP_EOL .
- '4' .
- 'Datetime string DATE could not be converted to DateTime object from format \'Y-m-d H:i:s\'' .
- '' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'md5' => 'b03894e48c0dfa6a9adda90739ca986c',
- 'id' => self::PAY_ID_ANY_EXCEPTION,
- 'v1' => 'demo',
- 'payment_amount' => '100.20',
- 'payment_currency' => 'EUR',
- 'date' => '2014-02-19 20:07:08'
- ),
- '' . PHP_EOL .
- '1Any exception' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'md5' => '151783427f854e7c61e54fae5361cacb',
- 'id' => self::PAY_ID_SUCCESS,
- 'v1' => 'demo',
- 'payment_amount' => '100.20',
- 'payment_currency' => 'EUR',
- 'date' => '2014-02-19 20:07:08'
- ),
- '' . PHP_EOL .
- '0' . self::PAY_SHOP_ID . '' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'md5' => '6d2228aaf135ea197aaaecf2d1260f13',
- 'id' => self::ZERO,
- 'v1' => 'demo',
- 'payment_amount' => '100.20',
- 'payment_currency' => 'EUR',
- 'date' => '2014-02-19 20:07:08'
- ),
- '' . PHP_EOL .
- '0' . self::PAY_SHOP_ID . '' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'v1' => self::CHECK_V1_NOT_EXISTS,
- 'md5' => '19d8988edfae51f90a1c78180d099a17',
- 'id' => self::PAY_ID_SUCCESS,
- 'payment_amount' => '100.20',
- 'payment_currency' => 'EUR',
- 'date' => '2014-02-19 20:07:08'
- ),
- '' . PHP_EOL .
- '2User not found' . PHP_EOL
- ),
- );
- }
-
- public function addCheckHandler(UserStorageInterface $userStorageMock)
- {
- $userStorageMock->expects($this->any())
- ->method('isUserExists')
- ->with($this->isInstanceOf('Xsolla\SDK\User'))
- ->will($this->returnCallback(array($this, 'isUserExistsCallback')));
- $userStorageMock->expects($this->any())
- ->method('getAdditionalUserFields')
- ->with($this->isInstanceOf('Xsolla\SDK\User'))
- ->will($this->returnValue(array(
- 'parameter1' => 'value1',
- 'parameter2' => 'value2',
- )));
- }
-
- public function isUserExistsCallback(User $user)
- {
- switch ($user->getV1()) {
- case self::CHECK_V1_ANY_EXCEPTION:
- throw new \Exception('Any exception');
- case self::CHECK_V1_NOT_EXISTS:
- return false;
- default:
- return true;
- }
- }
-
- public function addPayHandler(PaymentShoppingCart3StorageInterface $paymentStorageMock)
- {
- $paymentStorageMock->expects($this->any())
- ->method('pay')
- ->will($this->returnCallback(array($this, 'payCallback')));
- }
-
- public function payCallback($invoiceId)
- {
- if ($invoiceId == self::PAY_ID_ANY_EXCEPTION) {
- throw new \Exception('Any exception');
- } else {
- return self::PAY_SHOP_ID;
- }
- }
-}
diff --git a/tests/Protocol/ShoppingCartProtocolFullTest.php b/tests/Protocol/ShoppingCartProtocolFullTest.php
deleted file mode 100644
index eca5990..0000000
--- a/tests/Protocol/ShoppingCartProtocolFullTest.php
+++ /dev/null
@@ -1,171 +0,0 @@
-paymentStorageMock = $this->getMock('Xsolla\SDK\Protocol\Storage\PaymentShoppingCartStorageInterface', array(), array(), '', false);
- $this->addCancelHandler($this->paymentStorageMock);
- $this->addPayHandler($this->paymentStorageMock);
- $this->protocol = $this->protocolBuilder->getShoppingCartProtocol($this->paymentStorageMock);
- }
-
- public function payProvider()
- {
- return array(
- array(
- array(
- 'command' => 'pay',
- 'id' => '100',
- 'sign' => 'bc763ff5a8665c7c4c5fa0d8eba75ac8'
- ),
- '' . PHP_EOL .
- '20' .
- 'Invalid request format. Missed parameters: v1, amount, currency, datetime' .
- '' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'id' => '100',
- 'v1' => self::PAY_V1_SUCCESS,
- 'amount' => '100.20',
- 'currency' => 'RUR',
- 'datetime' => '20130325184822',
- 'sign' => '11111ff5a8661171111111d8e1171111'
- ),
- '' . PHP_EOL .
- '40Invalid md5 signature' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'v1' => self::PAY_V1_SUCCESS,
- 'amount' => '100.20',
- 'currency' => 'RUR',
- 'id' => '555',
- 'datetime' => 'DATETIME',
- 'sign' => 'e15b464029164a011ed8b0eaf14e2fe8'
- ),
- '' . PHP_EOL .
- '20' .
- 'Datetime string DATETIME could not be converted to DateTime object from format \'YmdHis\'' .
- '' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'v1' => self::PAY_V1_ANY_EXCEPTION,
- 'amount' => '100.20',
- 'currency' => 'RUR',
- 'id' => '555',
- 'datetime' => '20130325184822',
- 'sign' => '413ee43a19ff875db28660f501d337f3'
- ),
- '' . PHP_EOL .
- '30Any exception' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'v1' => self::PAY_ID_UNPROCESSABLE,
- 'amount' => '100.20',
- 'currency' => 'RUR',
- 'id' => '555',
- 'datetime' => '20130325184822',
- 'sign' => '42f0ecd5a69e967fff56ae9f5a9ff021'
- ),
- '' . PHP_EOL .
- '40unprocessable request' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'v1' => self::PAY_V1_SUCCESS,
- 'amount' => '100.20',
- 'currency' => 'RUR',
- 'id' => '555',
- 'datetime' => '20130325184822',
- 'sign' => 'e15b464029164a011ed8b0eaf14e2fe8'
- ),
- '' . PHP_EOL .
- '0' . self::PAY_SHOP_ID . '' . PHP_EOL
- ),
- );
- }
-
- public function noCommandProvider()
- {
- return array(
- array(
- array(
- 'id' => '100',
- 'sign' => 'bc763ff5a8665c7c4c5fa0d8eba75ac8'
- ),
- '' . PHP_EOL .
- '20' .
- 'No command in request. Available commands are: "pay", "cancel".' .
- '' . PHP_EOL
- )
- );
- }
-
- public function wrongCommandProvider()
- {
- return array(
- array(
- array(
- 'command' => 'not_exist',
- ),
- '' . PHP_EOL .
- '20' .
- 'Wrong command: "not_exist". Available commands for protocol ShoppingCart are: "pay", "cancel".' .
- '' . PHP_EOL
- )
- );
- }
-
- public function ipCheckerProvider()
- {
- return array(
- array(
- array(
- 'command' => 'pay',
- ),
- '' . PHP_EOL .
- '40' .
- 'IP whitelist doesn\'t contain client IP address' .
- '' . PHP_EOL
- )
- );
- }
-
- public function addPayHandler(PaymentShoppingCartStorageInterface $paymentStorageMock)
- {
- $paymentStorageMock->expects($this->any())
- ->method('pay')
- ->will($this->returnCallback(array($this, 'payCallback')));
- }
-
- public function payCallback($invoiceId, $amount, $v1)
- {
- if ($v1 == self::PAY_V1_ANY_EXCEPTION) {
- throw new \Exception('Any exception');
- } elseif ($v1 == self::PAY_ID_UNPROCESSABLE) {
- throw new UnprocessableRequestException('unprocessable request');
- } else {
- return self::PAY_SHOP_ID;
- }
- }
-}
diff --git a/tests/Protocol/StandardProtocolFullTest.php b/tests/Protocol/StandardProtocolFullTest.php
deleted file mode 100644
index ddaef7c..0000000
--- a/tests/Protocol/StandardProtocolFullTest.php
+++ /dev/null
@@ -1,251 +0,0 @@
-userStorageMock = $this->getMock('Xsolla\SDK\Protocol\Storage\UserStorageInterface', array(), array(), '', false);
- $this->paymentStorageMock = $this->getMock('Xsolla\SDK\Protocol\Storage\PaymentStandardStorageInterface', array(), array(), '', false);
- $this->addCancelHandler($this->paymentStorageMock);
- $this->addPayHandler($this->paymentStorageMock);
- $this->addCheckHandler($this->userStorageMock);
- $this->protocol = $this->protocolBuilder->getStandardProtocol($this->userStorageMock, $this->paymentStorageMock);
- }
-
- /**
- * @dataProvider checkProvider
- */
- public function testCheck(array $params, $expectedXml)
- {
- $this->protocolTest($params, $expectedXml);
- }
-
- public function checkProvider()
- {
- return array(
- array(
- array(
- 'command' => 'check',
- 'v1' => self::CHECK_V1_ANY_EXCEPTION,
- 'md5' => '22a0964fb976608f25f2d55ee44c01d3'
- ),
- '' . PHP_EOL .
- '1Any exception' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'check',
- 'v1' => self::CHECK_V1_NOT_EXISTS,
- 'md5' => '7c7fce6806ae451419dede822033dd9e'
- ),
- '' . PHP_EOL .
- '7' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'check',
- 'v1' => self::CHECK_V1_SUCCESS,
- 'md5' => 'a3561b90df78828133eb285e36965419'
- ),
- '' . PHP_EOL .
- '0value1value2' . PHP_EOL
- ),
- );
- }
-
- public function noCommandProvider()
- {
- return array(
- array(
- array(
- 'id' => '100',
- 'sign' => 'bc763ff5a8665c7c4c5fa0d8eba75ac8'
- ),
- '' . PHP_EOL .
- '4' .
- 'No command in request. Available commands are: "check", "pay", "cancel".' .
- '' . PHP_EOL
- )
- );
- }
-
- public function wrongCommandProvider()
- {
- return array(
- array(
- array(
- 'command' => 'not_exist',
- ),
- '' . PHP_EOL .
- '4' .
- 'Wrong command: "not_exist". Available commands for Standard protocol are: "check", "pay", "cancel".' .
- '' . PHP_EOL
- )
- );
- }
-
- public function ipCheckerProvider()
- {
- return array(
- array(
- array(
- 'command' => 'pay',
- ),
- '' . PHP_EOL .
- '7' .
- 'IP whitelist doesn\'t contain client IP address' .
- '' . PHP_EOL
- )
- );
- }
-
- public function payProvider()
- {
- return array(
- array(
- array(
- 'command' => 'pay'
- ),
- '' . PHP_EOL .
- '4' .
- 'Invalid request format. Missed parameters: md5, id, sum, v1, date' .
- '' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'md5' => '11111ff5a8661171111111d8e1171111',
- 'id' => self::PAY_ID_SUCCESS,
- 'v1' => 'demo',
- 'sum' => '100.20',
- 'date' => '2014-02-19 20:07:08'
- ),
- '' . PHP_EOL .
- '3Invalid md5 signature' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'md5' => '151783427f854e7c61e54fae5361cacb',
- 'id' => self::PAY_ID_SUCCESS,
- 'v1' => 'demo',
- 'sum' => '100.20',
- 'date' => 'DATE'
- ),
- '' . PHP_EOL .
- '4' .
- 'Datetime string DATE could not be converted to DateTime object from format \'Y-m-d H:i:s\'' .
- '' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'md5' => 'b03894e48c0dfa6a9adda90739ca986c',
- 'id' => self::PAY_ID_ANY_EXCEPTION,
- 'v1' => 'demo',
- 'sum' => '100.20',
- 'date' => '2014-02-19 20:07:08'
- ),
- '' . PHP_EOL .
- '1Any exception' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'md5' => '151783427f854e7c61e54fae5361cacb',
- 'id' => self::PAY_ID_SUCCESS,
- 'v1' => 'demo',
- 'sum' => '100.20',
- 'date' => '2014-02-19 20:07:08'
- ),
- '' . PHP_EOL .
- '0' . self::PAY_SHOP_ID . '' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'md5' => '6d2228aaf135ea197aaaecf2d1260f13',
- 'id' => self::ZERO,
- 'v1' => 'demo',
- 'sum' => '100.20',
- 'date' => '2014-02-19 20:07:08'
- ),
- '' . PHP_EOL .
- '0' . self::PAY_SHOP_ID . '' . PHP_EOL
- ),
- array(
- array(
- 'command' => 'pay',
- 'v1' => self::CHECK_V1_NOT_EXISTS,
- 'md5' => '19d8988edfae51f90a1c78180d099a17',
- 'id' => self::PAY_ID_SUCCESS,
- 'sum' => '100.20',
- 'date' => '2014-02-19 20:07:08'
- ),
- '' . PHP_EOL .
- '2User not found' . PHP_EOL
- ),
- );
- }
-
- public function addCheckHandler(UserStorageInterface $userStorageMock)
- {
- $userStorageMock->expects($this->any())
- ->method('isUserExists')
- ->with($this->isInstanceOf('Xsolla\SDK\User'))
- ->will($this->returnCallback(array($this, 'isUserExistsCallback')));
- $userStorageMock->expects($this->any())
- ->method('getAdditionalUserFields')
- ->with($this->isInstanceOf('Xsolla\SDK\User'))
- ->will($this->returnValue(array(
- 'parameter1' => 'value1',
- 'parameter2' => 'value2',
- )));
- }
-
- public function isUserExistsCallback(User $user)
- {
- switch ($user->getV1()) {
- case self::CHECK_V1_ANY_EXCEPTION:
- throw new \Exception('Any exception');
- case self::CHECK_V1_NOT_EXISTS:
- return false;
- default:
- return true;
- }
- }
-
- public function addPayHandler(PaymentStandardStorageInterface $paymentStorageMock)
- {
- $paymentStorageMock->expects($this->any())
- ->method('pay')
- ->will($this->returnCallback(array($this, 'payCallback')));
- }
-
- public function payCallback($invoiceId)
- {
- if ($invoiceId == self::PAY_ID_ANY_EXCEPTION) {
- throw new \Exception('Any exception');
- } else {
- return self::PAY_SHOP_ID;
- }
- }
-}
diff --git a/tests/Protocol/Storage/Pdo/PDOMock.php b/tests/Protocol/Storage/Pdo/PDOMock.php
deleted file mode 100644
index 208f759..0000000
--- a/tests/Protocol/Storage/Pdo/PDOMock.php
+++ /dev/null
@@ -1,8 +0,0 @@
-paymentStorage = new PaymentShoppingCart3Storage($this->pdoMock);
- $this->datetimeObj = \DateTime::createFromFormat('Y-m-d H:i:s', '2013-03-25 18:48:22', $this->xsollaTimeZone);
- }
-
- protected function setUpPayPdoMock()
- {
- $this->pdoMock->expects($this->at(0))
- ->method('prepare')
- ->with($this->anything())
- ->will($this->returnValue($this->insertMock));
- }
-
- protected function setUpPayInsertMock()
- {
- $this->insertMock->expects($this->exactly(6))
- ->method('bindValue')
- ->with($this->anything(), $this->anything());
- $this->insertMock->expects($this->at(6))
- ->method('execute');
- }
-
- public function testPaySuccess()
- {
- $this->setUpPayInsertMock();
-
- $this->pdoMock->expects($this->at(0))
- ->method('prepare')
- ->with($this->anything())
- ->will($this->returnValue($this->insertMock));
- $this->pdoMock->expects($this->at(1))
- ->method('lastInsertId')
- ->will($this->returnValue(555));
-
- $this->assertEquals(555, $this->paymentStorage->pay(10, 10, 'EUR', $this->userMock, $this->datetimeObj, false));
- }
-
- public function testPayExists()
- {
- $this->setUpSelectMock();
- $this->selectMock->expects($this->once())
- ->method('fetch')
- ->with($this->equalTo(\PDO::FETCH_ASSOC))
- ->will($this->returnValue(array('id' => self::INVOICE_ID, 'v1' => $this->userMock->getV1(), 'payment_amount' => self::INVOICE_AMOUNT, 'payment_currency' => self::INVOICE_CURRENCY)));
-
- $this->setUpPayInsertMock();
- $this->pdoMock->expects($this->at(1))
- ->method('lastInsertId')
- ->will($this->returnValue(0));
-
- $this->setUpPayPdoMock();
- $this->pdoMock->expects($this->at(2))
- ->method('prepare')
- ->with($this->anything())
- ->will($this->returnValue($this->selectMock));
-
- $this->assertEquals(self::INVOICE_ID, $this->paymentStorage->pay(self::INVOICE_ID, self::INVOICE_AMOUNT, self::INVOICE_CURRENCY, $this->userMock, $this->datetimeObj, false));
- }
-
- /**
- * @dataProvider payErrorProvider
- */
- public function testPayError($result, $exceptionDesc)
- {
- $this->setUpSelectMock();
- $this->selectMock->expects($this->once())
- ->method('fetch')
- ->with($this->equalTo(\PDO::FETCH_ASSOC))
- ->will($this->returnValue($result));
-
- $this->setUpPayInsertMock();
-
- $this->setUpPayPdoMock();
- $this->pdoMock->expects($this->at(1))
- ->method('lastInsertId')
- ->will($this->returnValue(0));
- $this->pdoMock->expects($this->at(2))
- ->method('prepare')
- ->with($this->anything())
- ->will($this->returnValue($this->selectMock));
-
- $this->setExpectedException($exceptionDesc[0], $exceptionDesc[1]);
- $this->paymentStorage->pay($result['id'], self::INVOICE_AMOUNT, self::INVOICE_CURRENCY, $this->userMock, $this->datetimeObj, false);
- }
-
- public function payErrorProvider()
- {
- return array(
- array(
- array('id' => self::INVOICE_ID, 'v1' => 'demo', 'payment_amount' => 0, 'payment_currency' => 'USD'),
- array('Xsolla\SDK\Exception\UnprocessableRequestException', 'Found payment with xsollaPaymentId=101 and payment_amount=0.00 (must be 100.20) and payment_currency=USD (must be EUR).')
- ),
- array(
- array('id' => self::INVOICE_ID, 'v1' => 'demo1', 'payment_amount' => 100.20, 'payment_currency' => 'EUR'),
- array('Xsolla\SDK\Exception\UnprocessableRequestException', 'Found payment with xsollaPaymentId=101 and v1=demo1 (must be "demo").')
- ),
- array(
- array('id' => self::INVOICE_ID, 'v1' => 'demo1', 'payment_amount' => 0, 'payment_currency' => 'EUR'),
- array('Xsolla\SDK\Exception\UnprocessableRequestException', 'Found payment with xsollaPaymentId=101 and v1=demo1 (must be "demo") and payment_amount=0.00 (must be 100.20).')
- ),
- array(
- false,
- array('Exception', 'Temporary error.')
- )
- );
- }
-}
diff --git a/tests/Protocol/Storage/Pdo/PaymentShoppingCartStorageTest.php b/tests/Protocol/Storage/Pdo/PaymentShoppingCartStorageTest.php
deleted file mode 100644
index aed9f97..0000000
--- a/tests/Protocol/Storage/Pdo/PaymentShoppingCartStorageTest.php
+++ /dev/null
@@ -1,111 +0,0 @@
-paymentStorage = new \Xsolla\SDK\Protocol\Storage\Pdo\PaymentShoppingCartStorage($this->pdoMock);
- $this->datetimeObj = \DateTime::createFromFormat('YmdHis', '20130325184822', $this->xsollaTimeZone);
- }
-
- protected function setUpPayPdoMock()
- {
- $this->pdoMock->expects($this->at(0))
- ->method('prepare')
- ->with($this->anything())
- ->will($this->returnValue($this->updateMock));
- }
-
- protected function setUpPayUpdateMock()
- {
- $this->updateMock->expects($this->exactly(14))
- ->method('bindValue')
- ->with($this->anything(), $this->anything(), $this->anything());
- $this->updateMock->expects($this->at(14))
- ->method('execute');
- }
-
- public function testPaySuccess()
- {
- $expectedV1 = 500;
-
- $this->setUpPayUpdateMock();
- $this->updateMock->expects($this->at(15))
- ->method('rowCount')
- ->will($this->returnValue(1));
-
- $this->setUpPayPdoMock();
-
- $v1 = $this->paymentStorage->pay(100, 100.20, $expectedV1, null, null, 'RUR', $this->datetimeObj, false);
- $this->assertEquals($expectedV1, $v1);
- }
-
- /**
- * @dataProvider payUnprocessableProvider
- */
- public function testPayUnprocessable($result, $exceptionMessage)
- {
- $this->setUpSelectMock();
- $this->setUpPayUpdateMock();
- $this->updateMock->expects($this->at(15))
- ->method('rowCount')
- ->will($this->returnValue(0));
-
- $this->selectMock->expects($this->at(2))
- ->method('fetch')
- ->with($this->equalTo(\PDO::FETCH_ASSOC))
- ->will($this->returnValue($result));
-
- $this->setUpPayPdoMock();
- $this->pdoMock->expects($this->at(1))
- ->method('prepare')
- ->with($this->anything())
- ->will($this->returnValue($this->selectMock));
-
- $this->setExpectedException('Xsolla\SDK\Exception\UnprocessableRequestException', $exceptionMessage);
- $this->paymentStorage->pay(
- 101,
- 100.50,
- 500,
- null,
- null,
- 'RUR',
- $this->datetimeObj,
- false
- );
- }
-
- public function payUnprocessableProvider()
- {
- return array(
- array(false, 'Invoice with v1=\'500\' not found.'),
- array(
- array(
- 'v1' => 500,
- 'v2' => null,
- 'v3' => null,
- 'xsollaPaymentId' => 100,
- 'amount' => 100.20,
- 'currency' => 'RUR',
- 'userAmount' => null,
- 'userCurrency' => null,
- 'transferAmount' => null,
- 'transferCurrency' => null,
- 'pid' => null,
- 'geotype' => null,
- 'dryRun' => 0,
- ),
- 'Repeated payment notification is received for invoice v1=500. But new payment notification parameters are not equal with previous: xsollaPaymentId(previous=100,repeated=101), amount(previous=100.20,repeated=100.50).'
- ),
- );
- }
-
-}
diff --git a/tests/Protocol/Storage/Pdo/PaymentStandardStorageTest.php b/tests/Protocol/Storage/Pdo/PaymentStandardStorageTest.php
deleted file mode 100644
index 2ccffdf..0000000
--- a/tests/Protocol/Storage/Pdo/PaymentStandardStorageTest.php
+++ /dev/null
@@ -1,125 +0,0 @@
-paymentStorage = new PaymentStandardStorage($this->pdoMock);
- $this->datetimeObj = \DateTime::createFromFormat('Y-m-d H:i:s', '2013-03-25 18:48:22', $this->xsollaTimeZone);
- }
-
- protected function setUpPayPdoMock()
- {
- $this->pdoMock->expects($this->at(0))
- ->method('prepare')
- ->with($this->anything())
- ->will($this->returnValue($this->insertMock));
- }
-
- protected function setUpPayInsertMock()
- {
- $this->insertMock->expects($this->exactly(5))
- ->method('bindValue')
- ->with($this->anything(), $this->anything());
- $this->insertMock->expects($this->at(5))
- ->method('execute');
- }
-
- public function testPaySuccess()
- {
- $this->setUpPayInsertMock();
-
- $this->pdoMock->expects($this->at(0))
- ->method('prepare')
- ->with($this->anything())
- ->will($this->returnValue($this->insertMock));
- $this->pdoMock->expects($this->at(1))
- ->method('lastInsertId')
- ->will($this->returnValue(555));
-
- $this->assertEquals(555, $this->paymentStorage->pay(10, 10, $this->userMock, $this->datetimeObj, false));
- }
-
- public function testPayExists()
- {
- $this->setUpSelectMock();
- $this->selectMock->expects($this->once())
- ->method('fetch')
- ->with($this->equalTo(\PDO::FETCH_ASSOC))
- ->will($this->returnValue(array('id' => self::INVOICE_ID, 'v1' => $this->userMock->getV1(), 'amount_virtual_currency' => self::INVOICE_AMOUNT)));
-
- $this->setUpPayInsertMock();
- $this->pdoMock->expects($this->at(1))
- ->method('lastInsertId')
- ->will($this->returnValue(0));
-
- $this->setUpPayPdoMock();
- $this->pdoMock->expects($this->at(2))
- ->method('prepare')
- ->with($this->anything())
- ->will($this->returnValue($this->selectMock));
-
- $this->assertEquals(self::INVOICE_ID, $this->paymentStorage->pay(self::INVOICE_ID, self::INVOICE_AMOUNT, $this->userMock, $this->datetimeObj, false));
- }
-
- /**
- * @dataProvider payErrorProvider
- */
- public function testPayError($result, $exceptionDesc)
- {
- $this->setUpSelectMock();
- $this->selectMock->expects($this->once())
- ->method('fetch')
- ->with($this->equalTo(\PDO::FETCH_ASSOC))
- ->will($this->returnValue($result));
-
- $this->setUpPayInsertMock();
-
- $this->setUpPayPdoMock();
- $this->pdoMock->expects($this->at(1))
- ->method('lastInsertId')
- ->will($this->returnValue(0));
- $this->pdoMock->expects($this->at(2))
- ->method('prepare')
- ->with($this->anything())
- ->will($this->returnValue($this->selectMock));
-
- $this->setExpectedException($exceptionDesc[0], $exceptionDesc[1]);
- $this->paymentStorage->pay($result['id'], self::INVOICE_AMOUNT, $this->userMock, $this->datetimeObj, false);
- }
-
- public function payErrorProvider()
- {
- return array(
- array(
- array('id' => self::INVOICE_ID, 'v1' => 'demo', 'amount_virtual_currency' => 0),
- array('Xsolla\SDK\Exception\UnprocessableRequestException', 'Found payment with xsollaPaymentId=101 and amount_virtual_currency=0.00 (must be 100.20).')
- ),
- array(
- array('id' => self::INVOICE_ID, 'v1' => 'demo1', 'amount_virtual_currency' => 100.20),
- array('Xsolla\SDK\Exception\UnprocessableRequestException', 'Found payment with xsollaPaymentId=101 and v1=demo1 (must be "demo").')
- ),
- array(
- array('id' => self::INVOICE_ID, 'v1' => 'demo1', 'amount_virtual_currency' => 0),
- array('Xsolla\SDK\Exception\UnprocessableRequestException', 'Found payment with xsollaPaymentId=101 and v1=demo1 (must be "demo") and amount_virtual_currency=0.00 (must be 100.20).')
- ),
- array(
- false,
- array('Exception', 'Temporary error.')
- )
- );
- }
-}
diff --git a/tests/Protocol/Storage/Pdo/PaymentStorageTest.php b/tests/Protocol/Storage/Pdo/PaymentStorageTest.php
deleted file mode 100644
index e3e9d36..0000000
--- a/tests/Protocol/Storage/Pdo/PaymentStorageTest.php
+++ /dev/null
@@ -1,139 +0,0 @@
-pdoMock = $this->getMock('Xsolla\SDK\Tests\Protocol\Storage\Pdo\PDOMock');
- $this->userMock = $this->getMock('Xsolla\SDK\User', array(), array(), '', false);
- $this->userMock->expects($this->any())
- ->method('getV1')
- ->will($this->returnValue('demo'));
- $this->insertMock = $this->getMock('PDOStatement');
- $this->updateMock = $this->getMock('PDOStatement');
- $this->selectMock = $this->getMock('PDOStatement');
- $this->xsollaTimeZone = new \DateTimeZone('Europe/Moscow');
- }
-
- protected function setUpSelectMock()
- {
- $this->selectMock->expects($this->at(0))
- ->method('bindValue')
- ->with($this->anything(), $this->anything(), $this->anything());
- $this->selectMock->expects($this->at(1))
- ->method('execute');
- }
-
- protected function setUpCancelDbMock()
- {
- $this->pdoMock->expects($this->at(0))
- ->method('prepare')
- ->with($this->anything())
- ->will($this->returnValue($this->updateMock));
-
- }
-
- public function setUpCancelUpdateMock()
- {
- $this->updateMock->expects($this->at(0))
- ->method('bindValue')
- ->with($this->anything(), $this->anything(), $this->anything());
- $this->updateMock->expects($this->at(1))
- ->method('execute');
- }
-
- public function testCancelSuccess()
- {
- $this->setUpCancelDbMock();
-
- $this->setUpCancelUpdateMock();
- $this->updateMock->expects($this->at(2))
- ->method('rowCount')
- ->will($this->returnValue(1));
-
- $this->paymentStorage->cancel(100, 1, 'Refund');
- }
-
- /**
- * @dataProvider cancelErrorProvider
- */
- public function testCancelError($result, $exceptionDesc)
- {
- $this->setUpSelectMock();
- $this->selectMock->expects($this->at(2))
- ->method('fetch')
- ->with($this->equalTo(\PDO::FETCH_ASSOC))
- ->will($this->returnValue($result));
-
- $this->setUpCancelUpdateMock();
- $this->updateMock->expects($this->at(2))
- ->method('rowCount')
- ->will($this->returnValue(0));
-
- $this->setUpCancelDbMock();
- $this->pdoMock->expects($this->at(1))
- ->method('prepare')
- ->with($this->anything())
- ->will($this->returnValue($this->selectMock));
-
- $this->setExpectedException($exceptionDesc[0], $exceptionDesc[1]);
-
- $this->paymentStorage->cancel(100, 1, 'Refund');
- }
-
- public function cancelErrorProvider()
- {
- return array(
- array(
- false,
- array('Xsolla\SDK\Exception\InvoiceNotFoundException', '')
- ),
- array(
- array('is_canceled' => 0),
- array('Exception', '')
- )
- );
- }
-}
diff --git a/tests/Protocol/Storage/Pdo/UserStorageTest.php b/tests/Protocol/Storage/Pdo/UserStorageTest.php
deleted file mode 100644
index 986db00..0000000
--- a/tests/Protocol/Storage/Pdo/UserStorageTest.php
+++ /dev/null
@@ -1,65 +0,0 @@
-pdoMock = $this->getMock('Xsolla\SDK\Tests\Protocol\Storage\Pdo\PDOMock');
- $this->userMock = $this->getMock('Xsolla\SDK\User', array(), array(), '', false);
- $this->userStorage = new \Xsolla\SDK\Protocol\Storage\Pdo\UserStorage($this->pdoMock);
- }
-
- /**
- * @dataProvider checkProvider
- */
- public function testCheck($expectedValue)
- {
- $selectMock = $this->getMock('PDOStatement');
- $selectMock->expects($this->exactly(3))
- ->method('bindValue')
- ->with($this->anything(), $this->anything());
- $selectMock->expects($this->at(3))
- ->method('execute');
- $selectMock->expects($this->at(4))
- ->method('fetch')
- ->with($this->equalTo(\PDO::FETCH_NUM))
- ->will($this->returnValue($expectedValue));
- $this->pdoMock->expects($this->once())
- ->method('prepare')
- ->with($this->equalTo(
- 'SELECT 1 FROM xsolla_standard_user WHERE v1 = :v1 AND v2 <=> :v2 AND v3 <=> :v3;'
- ))->will($this->returnValue($selectMock));
- $this->assertEquals($expectedValue, $this->userStorage->isUserExists($this->userMock));
- }
-
- public function checkProvider()
- {
- return array(
- array(true),
- array(false)
- );
- }
-
- public function testGetSpec()
- {
- $spec = $this->userStorage->getAdditionalUserFields($this->userMock);
- $this->assertEquals(array(), $spec);
- }
-}
diff --git a/tests/Protocol/XmlResponseBuilderTest.php b/tests/Protocol/XmlResponseBuilderTest.php
deleted file mode 100644
index 0a855db..0000000
--- a/tests/Protocol/XmlResponseBuilderTest.php
+++ /dev/null
@@ -1,53 +0,0 @@
-xml = new XmlResponseBuilder();
- }
-
- public function testDisabledVersionHeader()
- {
- $xml = new XmlResponseBuilder(false);
- $response = $xml->get(array());
- $this->assertFalse($response->headers->has(XmlResponseBuilder::VERSION_HEADER));
- }
-
- public function testGet()
- {
- $response = $this->xml->get(array('key1' => 'value1', 'key2' => array('key3' => 'value3', 'key4' => 'value4')));
- $expectedXml = <<
-value1value3value4
-
-XML;
- $actualXml = $response->getContent();
-
- $this->validateRawXml($actualXml);
- $this->assertEquals($expectedXml, $actualXml);
-
- $this->assertEquals('text/xml; charset=UTF-8', $response->headers->get('Content-Type'));
- $this->assertEquals(
- 'xsolla-sdk-php/'.Version::VERSION.' PHP/'.PHP_VERSION,
- $response->headers->get(XmlResponseBuilder::VERSION_HEADER)
- );
- }
-
- protected function validateRawXml($rawXml)
- {
- $previous = libxml_use_internal_errors(false);
- simplexml_load_string($rawXml);
- libxml_use_internal_errors($previous);
- }
-}
diff --git a/tests/SubscriptionTest.php b/tests/SubscriptionTest.php
deleted file mode 100644
index f5ed8d6..0000000
--- a/tests/SubscriptionTest.php
+++ /dev/null
@@ -1,21 +0,0 @@
-assertSame(self::ID, $subscription->getId());
- $this->assertSame(self::NAME, $subscription->getName());
- $this->assertSame(self::TYPE, $subscription->getType());
- $this->assertSame(self::CURRENCY, $subscription->getCurrency());
- }
-}
diff --git a/tests/UserTest.php b/tests/UserTest.php
deleted file mode 100644
index dafab43..0000000
--- a/tests/UserTest.php
+++ /dev/null
@@ -1,34 +0,0 @@
-assertEquals('1_v1', $user->getV1());
- $this->assertEquals('1_v2', $user->getV2());
- $this->assertEquals('1_v3', $user->getV3());
- $this->assertEquals('1_email', $user->getEmail());
- $this->assertEquals('1_phone', $user->getPhone());
- $this->assertEquals('1_ip', $user->getUserIP());
-
- $user = $user->setV1('2_v1')
- ->setV2('2_v2')
- ->setV3('2_v3')
- ->setEmail('2_email')
- ->setPhone('2_phone')
- ->setUserIp('2_ip');
-
- $this->assertEquals('2_v1', $user->getV1());
- $this->assertEquals('2_v2', $user->getV2());
- $this->assertEquals('2_v3', $user->getV3());
- $this->assertEquals('2_email', $user->getEmail());
- $this->assertEquals('2_phone', $user->getPhone());
- $this->assertEquals('2_ip', $user->getUserIP());
- }
-}
diff --git a/tests/Validator/IpCheckerTest.php b/tests/Validator/IpCheckerTest.php
deleted file mode 100644
index 873c767..0000000
--- a/tests/Validator/IpCheckerTest.php
+++ /dev/null
@@ -1,34 +0,0 @@
-ipChecker = new IpChecker;
- }
-
- public function testCheckIp()
- {
- $this->assertNull($this->ipChecker->checkIp('185.30.20.16'));
- }
-
- public function testCheckIpException()
- {
- $this->setExpectedException(
- 'Xsolla\SDK\Exception\UnprocessableRequestException',
- $this->logicalAnd(
- $this->stringContains('94.103.26.176/29, 159.255.220.240/28, 185.30.20.16/29, 185.30.21.16/29'),
- $this->stringContains('185.30.20.45')
- )
- );
- $this->ipChecker->checkIp('185.30.20.45');
- }
-}
diff --git a/tests/Webhook/Message/CancelSubscriptionMessageTest.php b/tests/Webhook/Message/CancelSubscriptionMessageTest.php
new file mode 100644
index 0000000..eb36507
--- /dev/null
+++ b/tests/Webhook/Message/CancelSubscriptionMessageTest.php
@@ -0,0 +1,32 @@
+ 'cancel_subscription',
+ 'user' => array(
+ 'id' => '1234567',
+ 'name' => 'Xsolla User',
+ ),
+ 'subscription' => array(
+ 'plan_id' => 'b5dac9c8',
+ 'subscription_id' => '10',
+ 'product_id' => 'Demo Product',
+ 'date_create' => '2014-09-22T19:25:25+04:00',
+ 'date_end' => '2015-01-22T19:25:25+04:00',
+ ),
+ );
+
+ public function test()
+ {
+ $message = new CancelSubscriptionMessage($this->request);
+ static::assertSame($this->request['subscription'], $message->getSubscription());
+ }
+}
diff --git a/tests/Webhook/Message/CreateSubscriptionMessageTest.php b/tests/Webhook/Message/CreateSubscriptionMessageTest.php
new file mode 100644
index 0000000..8d71cf0
--- /dev/null
+++ b/tests/Webhook/Message/CreateSubscriptionMessageTest.php
@@ -0,0 +1,41 @@
+ 'create_subscription',
+ 'user' => array(
+ 'id' => '1234567',
+ 'name' => 'Xsolla User',
+ ),
+ 'subscription' => array(
+ 'plan_id' => 'b5dac9c8',
+ 'subscription_id' => '10',
+ 'product_id' => 'Demo Product',
+ 'date_create' => '2014-09-22T19:25:25+04:00',
+ 'date_next_charge' => '2015-01-22T19:25:25+04:00',
+ 'trial' => array(
+ 'value' => 90,
+ 'type' => 'day',
+ ),
+ ),
+ 'coupon' => array(
+ 'coupon_code' => 'ICvj45S4FUOyy',
+ 'campaign_code' => '1507',
+ ),
+ );
+
+ public function test()
+ {
+ $message = new CreateSubscriptionMessage($this->request);
+ static::assertSame($this->request['subscription'], $message->getSubscription());
+ static::assertSame($this->request['coupon'], $message->getCoupon());
+ }
+}
diff --git a/tests/Webhook/Message/MessageTest.php b/tests/Webhook/Message/MessageTest.php
new file mode 100644
index 0000000..ddc80bf
--- /dev/null
+++ b/tests/Webhook/Message/MessageTest.php
@@ -0,0 +1,78 @@
+ 'USER_ID');
+ $request = array('notification_type' => $notificationType, 'user' => $user);
+ $message = Message\Message::fromArray($request);
+ static::assertInstanceOf($expectedClass, $message);
+ static::assertSame($userId, $message->getUserId());
+ static::assertSame($user, $message->getUser());
+ static::assertSame($request, $message->toArray());
+ static::assertSame($notificationType, $message->getNotificationType());
+ static::assertSame($isUserValidation, $message->isUserValidation());
+ static::assertSame($isPayment, $message->isPayment());
+ static::assertSame($isRefund, $message->isRefund());
+ }
+
+ public function factoryProvider()
+ {
+ return array(
+ array(
+ 'notificationType' => 'user_validation',
+ 'expectedClass' => '\Xsolla\SDK\Webhook\Message\UserValidationMessage',
+ 'isUserValidation' => true,
+ 'isPayment' => false,
+ 'isRefund' => false,
+ ),
+ array(
+ 'notificationType' => 'payment',
+ 'expectedClass' => '\Xsolla\SDK\Webhook\Message\PaymentMessage',
+ 'isUserValidation' => false,
+ 'isPayment' => true,
+ 'isRefund' => false,
+ ),
+ array(
+ 'notificationType' => 'refund',
+ 'expectedClass' => '\Xsolla\SDK\Webhook\Message\RefundMessage',
+ 'isUserValidation' => false,
+ 'isPayment' => false,
+ 'isRefund' => true,
+ ),
+ array(
+ 'notificationType' => 'create_subscription',
+ 'expectedClass' => '\Xsolla\SDK\Webhook\Message\CreateSubscriptionMessage',
+ 'isUserValidation' => false,
+ 'isPayment' => false,
+ 'isRefund' => false,
+ ),
+ array(
+ 'notificationType' => 'cancel_subscription',
+ 'expectedClass' => '\Xsolla\SDK\Webhook\Message\CancelSubscriptionMessage',
+ 'isUserValidation' => false,
+ 'isPayment' => false,
+ 'isRefund' => false,
+ ),
+ array(
+ 'notificationType' => 'user_balance_operation',
+ 'expectedClass' => '\Xsolla\SDK\Webhook\Message\UserBalanceMessage',
+ 'isUserValidation' => false,
+ 'isPayment' => false,
+ 'isRefund' => false,
+ ),
+ );
+ }
+}
diff --git a/tests/Webhook/Message/PaymentMessageTest.php b/tests/Webhook/Message/PaymentMessageTest.php
new file mode 100644
index 0000000..a5d3162
--- /dev/null
+++ b/tests/Webhook/Message/PaymentMessageTest.php
@@ -0,0 +1,127 @@
+ 'payment',
+ 'purchase' => array(
+ 'virtual_currency' => array(
+ 'name' => 'Coins',
+ 'quantity' => 10,
+ 'currency' => 'USD',
+ 'amount' => 100,
+ ),
+ 'subscription' => array(
+ 'plan_id' => 'b5dac9c8',
+ 'subscription_id' => '10',
+ 'product_id' => 'Demo Product',
+ 'date_create' => '2014-09-22T19:25:25+04:00',
+ 'currency' => 'USD',
+ 'amount' => 9.99,
+ ),
+ 'checkout' => array(
+ 'currency' => 'USD',
+ 'amount' => 50,
+ ),
+ 'virtual_items' => array(
+ 'items' => array(
+ 0 => array(
+ 'sku' => 'test_item1',
+ 'amount' => 1,
+ ),
+ ),
+ 'currency' => 'USD',
+ 'amount' => 50,
+ ),
+ 'total' => array(
+ 'currency' => 'USD',
+ 'amount' => 200,
+ ),
+ 'promotions[0]' => array(
+ 'technical_name' => 'Demo Promotion',
+ 'id' => '853',
+ ),
+ 'coupon' => array(
+ 'coupon_code' => 'ICvj45S4FUOyy',
+ 'campaign_code' => '1507',
+ ),
+ ),
+ 'user' => array(
+ 'ip' => '127.0.0.1',
+ 'phone' => '18777976552',
+ 'email' => 'support@xsolla.com',
+ 'id' => '1234567',
+ 'name' => 'Xsolla User',
+ 'country' => 'US',
+ ),
+ 'transaction' => array(
+ 'id' => 1,
+ 'external_id' => 1,
+ 'payment_date' => '2014-09-24T20:38:16+04:00',
+ 'payment_method' => 1,
+ 'dry_run' => 1,
+ 'agreement' => 1,
+ ),
+ 'payment_details' => array(
+ 'payment' => array(
+ 'currency' => 'USD',
+ 'amount' => 230,
+ ),
+ 'vat' => array(
+ 'currency' => 'USD',
+ 'amount' => 0,
+ ),
+ 'payout_currency_rate' => 1,
+ 'payout' => array(
+ 'currency' => 'USD',
+ 'amount' => 200,
+ ),
+ 'xsolla_fee' => array(
+ 'currency' => 'USD',
+ 'amount' => 10,
+ ),
+ 'payment_method_fee' => array(
+ 'currency' => 'USD',
+ 'amount' => 20,
+ ),
+ ),
+ 'custom_parameters' => array(
+ 'parameter1' => 'value1',
+ 'parameter2' => 'value2',
+ ),
+ );
+
+ public function test()
+ {
+ $message = new PaymentMessage($this->request);
+ static::assertSame($this->request['purchase'], $message->getPurchase());
+ static::assertSame($this->request['transaction'], $message->getTransaction());
+ static::assertSame($this->request['transaction']['id'], $message->getPaymentId());
+ static::assertSame($this->request['transaction']['external_id'], $message->getExternalPaymentId());
+ static::assertSame($this->request['payment_details'], $message->getPaymentDetails());
+ static::assertSame($this->request['custom_parameters'], $message->getCustomParameters());
+ static::assertTrue($message->isDryRun());
+ }
+
+ public function testEmptyFields()
+ {
+ $requestCopy = $this->request;
+ unset(
+ $requestCopy['custom_parameters'],
+ $requestCopy['transaction']['dry_run'],
+ $requestCopy['transaction']['external_id']
+ );
+ $message = new PaymentMessage($requestCopy);
+
+ static::assertNull($message->getExternalPaymentId());
+ static::assertSame(array(), $message->getCustomParameters());
+ static::assertFalse($message->isDryRun());
+ }
+}
diff --git a/tests/Webhook/Message/RefundMessageTest.php b/tests/Webhook/Message/RefundMessageTest.php
new file mode 100644
index 0000000..514650d
--- /dev/null
+++ b/tests/Webhook/Message/RefundMessageTest.php
@@ -0,0 +1,86 @@
+ 'refund',
+ 'purchase' => array(
+ 'virtual_currency' => array(
+ 'name' => 'Coins',
+ 'quantity' => 10,
+ 'currency' => 'USD',
+ 'amount' => 100,
+ ),
+ 'subscription' => array(
+ 'plan_id' => 'b5dac9c8',
+ 'subscription_id' => '10',
+ 'date_create' => '2014-09-22T19:25:25+04:00',
+ 'currency' => 'USD',
+ 'amount' => 9.99,
+ ),
+ 'checkout' => array(
+ 'currency' => 'USD',
+ 'amount' => 50,
+ ),
+ 'virtual_items' => array(
+ 'items' => array(
+ 0 => array(
+ 'sku' => 'test_item1',
+ 'amount' => 1,
+ ),
+ ),
+ 'currency' => 'USD',
+ 'amount' => 50,
+ ),
+ 'total' => array(
+ 'currency' => 'USD',
+ 'amount' => 200,
+ ),
+ ),
+ 'user' => array(
+ 'ip' => '127.0.0.1',
+ 'phone' => '18777976552',
+ 'email' => 'support@xsolla.com',
+ 'id' => '1234567',
+ 'name' => 'Xsolla User',
+ 'country' => 'US',
+ ),
+ 'transaction' => array(
+ 'id' => 1,
+ 'external_id' => 1,
+ 'dry_run' => 1,
+ 'agreement' => 1,
+ ),
+ 'refund_details' => array(
+ 'code' => 1,
+ 'reason' => 'Fraud',
+ ),
+ 'payment_details' => array(
+ 'xsolla_fee' => array(
+ 'currency' => 'USD',
+ 'amount' => '10',
+ ),
+ 'payout' => array(
+ 'currency' => 'USD',
+ 'amount' => '200',
+ ),
+ 'payment_method_fee' => array(
+ 'currency' => 'USD',
+ 'amount' => '20',
+ ),
+ 'payment' => array(
+ 'currency' => 'USD',
+ 'amount' => '230',
+ ),
+ ),
+ 'custom_parameters' => array(
+ 'parameter1' => 'value1',
+ 'parameter2' => 'value2',
+ ),
+ );
+}
diff --git a/tests/Webhook/Message/UserBalanceMessageTest.php b/tests/Webhook/Message/UserBalanceMessageTest.php
new file mode 100644
index 0000000..ca33051
--- /dev/null
+++ b/tests/Webhook/Message/UserBalanceMessageTest.php
@@ -0,0 +1,60 @@
+ array(
+ 'old_value' => '0',
+ 'new_value' => '200',
+ 'diff' => '200',
+ ),
+ 'user' => array(
+ 'name' => 'Xsolla User',
+ 'id' => '1234567',
+ 'email' => 'support@xsolla.com',
+ ),
+ 'transaction' => array(
+ 'id' => '123456789',
+ 'date' => '2015-05-19T15:54:40+03:00',
+ ),
+ 'operation_type' => 'payment',
+ 'notification_type' => 'user_balance_operation',
+ 'id_operation' => '66989',
+ 'coupon' => array(
+ 'coupon_code' => 'test123',
+ 'campaign_code' => 'Xsolla Campaign',
+ ),
+ 'items_operation_type' => 'add',
+ );
+
+ public function test()
+ {
+ $message = new UserBalanceMessage($this->request);
+ static::assertSame($this->request['operation_type'], $message->getOperationType());
+ static::assertSame($this->request['id_operation'], $message->getOperationId());
+ static::assertSame($this->request['coupon'], $message->getCoupon());
+ static::assertSame($this->request['virtual_currency_balance'], $message->getVirtualCurrencyBalance());
+ static::assertSame($this->request['items_operation_type'], $message->getItemsOperationType());
+ }
+
+ public function testEmptyFields()
+ {
+ $requestCopy = $this->request;
+ unset(
+ $requestCopy['virtual_currency_balance'],
+ $requestCopy['coupon'],
+ $requestCopy['items_operation_type']
+ );
+ $message = new UserBalanceMessage($requestCopy);
+ static::assertSame(array(), $message->getCoupon());
+ static::assertSame(array(), $message->getVirtualCurrencyBalance());
+ static::assertNull($message->getItemsOperationType());
+ }
+}
diff --git a/tests/resources/token.json b/tests/resources/token.json
new file mode 100644
index 0000000..dcb94f2
--- /dev/null
+++ b/tests/resources/token.json
@@ -0,0 +1,48 @@
+{
+ "user": {
+ "id": {
+ "value": "USER_ID",
+ "hidden": false,
+ "allow_modify": true
+ },
+ "name": {
+ "value": "USER_NAME",
+ "hidden": false,
+ "allow_modify": true
+ },
+ "email": {
+ "value": "email@example.com",
+ "hidden": false,
+ "allow_modify": true
+ },
+ "country": {
+ "value": "US",
+ "allow_modify": true
+ }
+ },
+ "settings": {
+ "project_id": 15861,
+ "language": "en",
+ "currency": "USD",
+ "return_url": "http://example.com",
+ "mode": "sandbox",
+ "payment_method": 1,
+ "ui": {
+ "size": "medium",
+ "theme": "dark"
+ }
+ },
+ "purchase": {
+ "virtual_currency": {
+ "quantity": 100,
+ "allow_modify": true,
+ "hidden": false
+ },
+ "description": {
+ "value": "Test Purchase"
+ }
+ },
+ "custom_parameters": {
+ "parameter1": "value1"
+ }
+}
\ No newline at end of file
diff --git a/tests/resources/webhook_server.php b/tests/resources/webhook_server.php
new file mode 100644
index 0000000..4378733
--- /dev/null
+++ b/tests/resources/webhook_server.php
@@ -0,0 +1,8 @@
+run($_GET['test_case']);