1
0
Fork 0

Initial commit

Initial structure with tests, pre-commit checks and .env config.
This commit is contained in:
Alexander Yakovlev 2022-06-13 14:22:17 +07:00
parent 07717698f5
commit 58777b4973
12 changed files with 4181 additions and 124 deletions

13
.editorconfig Normal file
View file

@ -0,0 +1,13 @@
# Editor configuration, see http://editorconfig.org
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
max_line_length = 0
trim_trailing_whitespace = false

2
.env.example Normal file
View file

@ -0,0 +1,2 @@
PAYEER_ID=123456
SECRET=yoursecretkey

3
.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
*.cache
vendor
.env

4
.phpcs.xml Normal file
View file

@ -0,0 +1,4 @@
<?xml version="1.0"?>
<ruleset name="PSR Strict Standard">
<rule ref="PSR12"></rule>
</ruleset>

6
.phpstan.neon Normal file
View file

@ -0,0 +1,6 @@
parameters:
level: 5
paths:
- lib
excludePaths:
- vendor/

24
.phpunit.xml Normal file
View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
bootstrap="vendor/autoload.php"
backupGlobals="false"
backupStaticAttributes="false"
colors="true"
verbose="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
<coverage>
<include>
<directory suffix=".php">lib/</directory>
</include>
</coverage>
<testsuites>
<testsuite name="Library Test Suite">
<directory>test</directory>
</testsuite>
</testsuites>
</phpunit>

22
.pre-commit-config.yaml Normal file
View file

@ -0,0 +1,22 @@
fail_fast: true
repos:
- repo: git@github.com:justin-at-demac/pre-commit-php.git
rev: 3.0.1
hooks:
- id: php-lint
- id: php-cbf
files: \.(php)$
- id: php-no-var_dumps
- id: php-no-exits
- id: php-cs
files: \.(php)$
- id: php-stan
files: \.(php)$
args: ["--configuration=.phpstan.neon"]
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
hooks:
- id: check-json
- id: check-xml
- id: check-yaml
- id: check-merge-conflict

124
class.php
View file

@ -1,124 +0,0 @@
<?php
class Api_Trade_Payeer
{
private $arParams = array();
private $arError = array();
public function __construct($params = array())
{
$this->arParams = $params;
}
private function Request($req = array())
{
$msec = round(microtime(true) * 1000);
$req['post']['ts'] = $msec;
$post = json_encode($req['post']);
$sign = hash_hmac('sha256', $req['method'].$post, $this->arParams['key']);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://payeer.com/api/trade/".$req['method']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"API-ID: ".$this->arParams['id'],
"API-SIGN: ".$sign
));
$response = curl_exec($ch);
curl_close($ch);
$arResponse = json_decode($response, true);
if ($arResponse['success'] !== true)
{
$this->arError = $arResponse['error'];
throw new Exception($arResponse['error']['code']);
}
return $arResponse;
}
public function GetError()
{
return $this->arError;
}
public function Info()
{
$res = $this->Request(array(
'method' => 'info',
));
return $res;
}
public function Orders($pair = 'BTC_USDT')
{
$res = $this->Request(array(
'method' => 'orders',
'post' => array(
'pair' => $pair,
),
));
return $res['pairs'];
}
public function Account()
{
$res = $this->Request(array(
'method' => 'account',
));
return $res['balances'];
}
public function OrderCreate($req = array())
{
$res = $this->Request(array(
'method' => 'order_create',
'post' => $req,
));
return $res;
}
public function OrderStatus($req = array())
{
$res = $this->Request(array(
'method' => 'order_status',
'post' => $req,
));
return $res['order'];
}
public function MyOrders($req = array())
{
$res = $this->Request(array(
'method' => 'my_orders',
'post' => $req,
));
return $res['items'];
}
}

37
composer.json Normal file
View file

@ -0,0 +1,37 @@
{
"name": "oreolek/payeer",
"type": "library",
"description": "Simple wrapper for Payeer API",
"license": "Proprietary",
"authors": [
{
"name": "Alexander Yakovlev",
"email": "keloero@oreolek.me"
}
],
"autoload": {
"psr-4": { "Payeer\\" : "lib" }
},
"require": {
"php": "^8.1",
"php-http/client-implementation": "^1",
"php-http/message": "^1.5",
"php-http/discovery": "^1.14",
"symfony/http-foundation": "^6"
},
"require-dev": {
"php-http/mock-client": "^1",
"php-http/guzzle7-adapter": "^1",
"phpstan/phpstan": "^1.7",
"vlucas/phpdotenv": "^5.4",
"phpunit/phpunit": "^9.5"
},
"scripts": {
"test": "phpunit -c .phpunit.xml",
"check-style": "phpcs",
"fix-style": "phpcbf",
"analyze": "./vendor/phpstan/phpstan/phpstan analyse lib/ -c .phpstan.neon"
},
"minimum-stability": "dev",
"prefer-stable": true
}

3876
composer.lock generated Normal file

File diff suppressed because it is too large Load diff

157
lib/Adapter.php Normal file
View file

@ -0,0 +1,157 @@
<?php
declare(strict_types=1);
namespace Payeer;
class Adapter
{
private array $arParams = array();
private array $arError = array();
public function __construct(array $params = array())
{
$this->arParams = $params;
if (!isset($params['key']) || !is_string($params['key'])) {
throw new \Exception('Payeer API key is required.');
}
}
protected function request(array $req = array())
{
$msec = round(microtime(true) * 1000);
$req['post']['ts'] = $msec;
$post = json_encode($req['post']);
$sign = hash_hmac('sha256', $req['method'] . $post, $this->arParams['key']);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://payeer.com/api/trade/" . $req['method']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, false);
//curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt(
$ch,
CURLOPT_HTTPHEADER,
array(
"Content-Type: application/json",
"API-ID: " . $this->arParams['id'],
"API-SIGN: " . $sign
)
);
$response = curl_exec($ch);
curl_close($ch);
$arResponse = json_decode($response, true);
if ($arResponse['success'] !== true) {
$this->arError = $arResponse['error'];
throw new \Exception($arResponse['error']['code']);
}
return $arResponse;
}
public function getError(): array
{
return $this->arError;
}
/**
* @param string $pair
* @return array Return values
**/
public function orders($pair = 'BTC_USDT')
{
$res = $this->Request(
array(
'method' => 'orders',
'post' => array(
'pair' => $pair,
),
)
);
return $res['pairs'];
}
/**
* @return array Return values
**/
public function account()
{
$res = $this->Request(
array(
'method' => 'account',
)
);
return $res['balances'];
}
public function orderCreate($req = array())
{
return $this->order_create($req);
}
/**
* @param array $req POST parameters.
* @return array Return values
**/
public function orderStatus($req = array())
{
$res = $this->Request(
array(
'method' => 'order_status',
'post' => $req,
)
);
return $res['order'];
}
/**
* @param array $req POST parameters.
* @return array Return values
**/
public function myOrders($req = array()): array
{
$res = $this->Request(
array(
'method' => 'my_orders',
'post' => $req,
)
);
return $res['items'];
}
/**
* Catch-all magic method
*
* @param string $name
* @param array<string, mixed> $arguments
*/
public function __call(string $name, array $arguments): mixed
{
$res = $this->Request(
array(
'method' => strtolower($name),
'post' => $arguments,
)
);
return $res;
}
}

37
test/PayeerTest.php Normal file
View file

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace Payeer;
use PHPUnit\Framework\TestCase;
use Payeer\Adapter;
final class PayeerTest extends TestCase
{
/**
* @var Adapter
*/
protected $adapter;
public function setUp(): void
{
$dotenv = \Dotenv\Dotenv::createImmutable(dirname(__DIR__));
$dotenv->load();
$this->adapter = new Adapter([
'id' => $_ENV['PAYEER_ID'],
'key' => $_ENV['SECRET'],
]);
}
public function testGetTime(): void
{
$response = $this->adapter->time();
$this->assertArrayHasKey('success', $response);
$this->assertArrayHasKey('time', $response);
$this->assertTrue($response['success']);
$this->assertNotEmpty($response['time']);
// php vs js timestamps
$timestamp = (int) round($response['time'] / 1000);
$this->assertSame(date('Y-m-d H:i'), date('Y-m-d H:i', $timestamp));
}
}