From 4faaefcd90628f2ec85d8404a5d98422bb472328 Mon Sep 17 00:00:00 2001 From: Krystian Bajno Date: Mon, 8 Apr 2019 15:51:20 +0200 Subject: [PATCH 1/4] Refunds support --- src/DotpayApi/Client.php | 26 ++++++++ src/DotpayApi/Contracts/IRequest.php | 15 +++++ src/DotpayApi/DotpayApi.php | 43 +++++++++++++- src/DotpayApi/Requests/AbstractRequest.php | 9 +-- src/DotpayApi/Requests/CreatePaymentLink.php | 62 +++++++++++++++++++- src/DotpayApi/Requests/CreateRefund.php | 61 +++++++++++++++++++ src/DotpayApi/Response.php | 34 ++++++++++- src/DotpayApi/UrlCreator.php | 17 +++++- src/DotpayApi/Validator.php | 20 ++++++- src/DotpayManager.php | 36 +++++++++++- src/Facades/Dotpay.php | 9 ++- 11 files changed, 317 insertions(+), 15 deletions(-) create mode 100644 src/DotpayApi/Requests/CreateRefund.php diff --git a/src/DotpayApi/Client.php b/src/DotpayApi/Client.php index 4c69992..b6466d7 100644 --- a/src/DotpayApi/Client.php +++ b/src/DotpayApi/Client.php @@ -4,13 +4,35 @@ use Evilnet\Dotpay\DotpayApi\Contracts\IRequest; +/** + * Class Client + * @package Evilnet\Dotpay\DotpayApi + */ class Client { + /** + * @var + */ private $username; + /** + * @var + */ private $password; + /** + * @var + */ private $base_url; + /** + * @var \GuzzleHttp\Client + */ private $client; + /** + * Client constructor. + * @param $username + * @param $password + * @param $base_url + */ public function __construct($username, $password, $base_url) { $this->username = $username; @@ -19,6 +41,10 @@ public function __construct($username, $password, $base_url) $this->client = new \GuzzleHttp\Client(); } + /** + * @param IRequest $request + * @return mixed + */ public function makeRequest(IRequest $request) { $options = [ diff --git a/src/DotpayApi/Contracts/IRequest.php b/src/DotpayApi/Contracts/IRequest.php index af45759..4614a8c 100644 --- a/src/DotpayApi/Contracts/IRequest.php +++ b/src/DotpayApi/Contracts/IRequest.php @@ -2,9 +2,24 @@ namespace Evilnet\Dotpay\DotpayApi\Contracts; +/** + * Interface IRequest + * @package Evilnet\Dotpay\DotpayApi\Contracts + */ interface IRequest { + /** + * @return mixed + */ public function toArray(); + + /** + * @return mixed + */ public function method(); + + /** + * @return mixed + */ public function path(); } diff --git a/src/DotpayApi/DotpayApi.php b/src/DotpayApi/DotpayApi.php index 8575ca5..a0519d1 100644 --- a/src/DotpayApi/DotpayApi.php +++ b/src/DotpayApi/DotpayApi.php @@ -3,14 +3,35 @@ namespace Evilnet\Dotpay\DotpayApi; use Evilnet\Dotpay\DotpayApi\Requests\CreatePaymentLink; +use Evilnet\Dotpay\DotpayApi\Requests\CreateRefund; +/** + * Class DotpayApi + * @package Evilnet\Dotpay\DotpayApi + */ class DotpayApi { + /** + * @var + */ private $config; + /** + * @var Client + */ private $client; + /** + * @var Validator + */ private $validator; + /** + * @var UrlCreator + */ private $url_creator; + /** + * DotpayApi constructor. + * @param $config + */ public function __construct($config) { $this->config = $config; @@ -19,11 +40,27 @@ public function __construct($config) $this->url_creator = new UrlCreator($this->config['pin']); } + /** + * @param $payment + * @return mixed|string + */ public function createPayment($payment) { return $this->getPaymentUrl($this->client->makeRequest(new CreatePaymentLink($this->config['shop_id'], $payment))); } + /** + * @param $payment + * @return mixed + */ + public function refundPayment($payment){ + return $this->client->makeRequest(new CreateRefund($this->config['shop_id'], $payment)); + } + + /** + * @param $payment + * @return mixed|string + */ public function getPaymentUrl($payment) { switch ($this->config['api_version']) { @@ -37,9 +74,13 @@ public function getPaymentUrl($payment) } } + /** + * @param $data + * @return bool + */ public function verifyCallback($data) { return $this->validator->verify($data); } -} \ No newline at end of file +} diff --git a/src/DotpayApi/Requests/AbstractRequest.php b/src/DotpayApi/Requests/AbstractRequest.php index bbd815e..d786d93 100644 --- a/src/DotpayApi/Requests/AbstractRequest.php +++ b/src/DotpayApi/Requests/AbstractRequest.php @@ -4,15 +4,8 @@ class AbstractRequest { - protected $shop_id; - - public function __construct($shop_id) - { - $this->shop_id = $shop_id; - } - public function toArray() { return get_object_vars($this); } -} \ No newline at end of file +} diff --git a/src/DotpayApi/Requests/CreatePaymentLink.php b/src/DotpayApi/Requests/CreatePaymentLink.php index da98476..017cee8 100644 --- a/src/DotpayApi/Requests/CreatePaymentLink.php +++ b/src/DotpayApi/Requests/CreatePaymentLink.php @@ -4,36 +4,96 @@ use Evilnet\Dotpay\DotpayApi\Contracts\IRequest; +/** + * Class CreatePaymentLink + * @package Evilnet\Dotpay\DotpayApi\Requests + */ class CreatePaymentLink extends AbstractRequest implements IRequest { + /** + * @var + */ protected $amount; + /** + * @var + */ protected $currency; + /** + * @var + */ protected $description; + /** + * @var + */ protected $control; // protected $language; + /** + * @var int + */ protected $onlinetransfer = 1; + /** + * @var int + */ protected $ch_lock = 1; + /** + * @var int + */ protected $redirection_type = 0; + /** + * @var string + */ protected $buttontext = 'Return'; + /** + * @var + */ protected $url; + /** + * @var + */ protected $urlc; + /** + * @var + */ protected $expiration_datetime; + /** + * @var array + */ protected $payer = []; + /** + * @var array + */ protected $recipient = []; + /** + * @var + */ + protected $shop_id; + + /** + * CreatePaymentLink constructor. + * @param $shop_id + * @param $data + */ public function __construct($shop_id, $data) { - parent::__construct($shop_id); + $this->shop_id = $shop_id; + foreach ($data as $key => $value) { $this->$key = $value; } } + /** + * @return string + */ public function method() { return 'POST'; } + /** + * @return string + */ public function path() { return 'api/v1/accounts/'.$this->shop_id.'/payment_links/'; diff --git a/src/DotpayApi/Requests/CreateRefund.php b/src/DotpayApi/Requests/CreateRefund.php new file mode 100644 index 0000000..8092b62 --- /dev/null +++ b/src/DotpayApi/Requests/CreateRefund.php @@ -0,0 +1,61 @@ +operation_number = $operation_number; + foreach ($data as $key => $value) { + $this->$key = $value; + } + } + + /** + * @return string + */ + public function method() + { + return 'POST'; + } + + /** + * @return string + */ + public function path() + { + return 'api/v3/payments/'.$this->operation_number.'/refund/'; + } +} diff --git a/src/DotpayApi/Response.php b/src/DotpayApi/Response.php index d7c615d..0dcb7b6 100644 --- a/src/DotpayApi/Response.php +++ b/src/DotpayApi/Response.php @@ -2,45 +2,77 @@ namespace Evilnet\Dotpay\DotpayApi; +/** + * Class Response + * @package Evilnet\Dotpay\DotpayApi + */ class Response { + /** + * @var + */ private $data; + /** + * Response constructor. + * @param $data + */ public function __construct($data) { $this->data = $data; } + /** + * @return mixed + */ public function getControl() { return $this->data['control']; } + /** + * @return mixed + */ public function getOperationNumber() { return $this->data['operation_number']; } + /** + * @return mixed + */ public function getEmail() { return $this->data['email']; } + /** + * @return mixed + */ public function getOperationAmount() { return $this->data['operation_amount']; } + /** + * @return mixed + */ public function getOperationCurrency() { return $this->data['operation_currency']; } - + + /** + * @return mixed + */ public function getOperationDateTime() { return $this->data['operation_datetime']; } + /** + * @return mixed + */ public function getOperationStatus() { return $this->data['operation_status']; diff --git a/src/DotpayApi/UrlCreator.php b/src/DotpayApi/UrlCreator.php index ceebaa6..0524be4 100644 --- a/src/DotpayApi/UrlCreator.php +++ b/src/DotpayApi/UrlCreator.php @@ -8,21 +8,36 @@ */ class UrlCreator { + /** + * @var + */ private $pin; + /** + * UrlCreator constructor. + * @param $pin + */ public function __construct($pin) { $this->pin = $pin; } + /** + * @param $payment + * @return mixed + */ public function getPaymentUrl($payment) { return $payment->payment_url; } + /** + * @param $payment + * @return string + */ public function getPaymentUrlWithCHK($payment) { return $payment->payment_url.'&chk='.hash('sha256', ($this->pin.$payment->token)); } -} \ No newline at end of file +} diff --git a/src/DotpayApi/Validator.php b/src/DotpayApi/Validator.php index 7679142..0b7e13e 100644 --- a/src/DotpayApi/Validator.php +++ b/src/DotpayApi/Validator.php @@ -2,8 +2,15 @@ namespace Evilnet\Dotpay\DotpayApi; +/** + * Class Validator + * @package Evilnet\Dotpay\DotpayApi + */ class Validator { + /** + * @var array + */ private $keys = [ 'id', 'operation_number', @@ -32,13 +39,24 @@ class Validator 'geoip_country', ]; + /** + * @var + */ private $pin; + /** + * Validator constructor. + * @param $pin + */ public function __construct($pin) { $this->pin = $pin; } + /** + * @param $data + * @return bool + */ public function verify($data) { $concatData = ''; @@ -52,4 +70,4 @@ public function verify($data) return $data['signature'] === $hash; } -} \ No newline at end of file +} diff --git a/src/DotpayManager.php b/src/DotpayManager.php index 2331ae3..9614fae 100644 --- a/src/DotpayManager.php +++ b/src/DotpayManager.php @@ -6,11 +6,25 @@ use Dotenv\Exception\InvalidCallbackException; use Evilnet\Dotpay\DotpayApi\Response; +/** + * Class DotpayManager + * @package Evilnet\Dotpay + */ class DotpayManager { + /** + * @var DotpayApi + */ private $dotpayApi; + /** + * @var + */ private $response; + /** + * DotpayManager constructor. + * @param DotpayApi $dotpayApi + */ public function __construct(DotpayApi $dotpayApi) { $this->dotpayApi = $dotpayApi; @@ -18,18 +32,38 @@ public function __construct(DotpayApi $dotpayApi) //It will return url for dotpay transaction + /** + * @param $data + * @return mixed|string + */ public function createPayment($data) { return $this->dotpayApi->createPayment($data); } + /** + * @param $data + * @return mixed + */ + public function refundPayment($data){ + return $this->dotpayApi->refundPayment($data); + } + + /** + * @return mixed + */ public function response() { return $this->response; } //It will listen for dotpay POST with status. We need to calculate hash and check status + + /** + * @param array $data + * @return Response + */ public function callback(array $data) { if ($this->dotpayApi->verifyCallback($data)) { @@ -37,4 +71,4 @@ public function callback(array $data) } throw new InvalidCallbackException('invalid_hash'); } -} \ No newline at end of file +} diff --git a/src/Facades/Dotpay.php b/src/Facades/Dotpay.php index 70f1ce6..d5c1e1e 100644 --- a/src/Facades/Dotpay.php +++ b/src/Facades/Dotpay.php @@ -4,10 +4,17 @@ use Illuminate\Support\Facades\Facade; +/** + * Class Dotpay + * @package Evilnet\Dotpay\Facades + */ class Dotpay extends Facade { + /** + * @return string + */ protected static function getFacadeAccessor() { return 'dotpay'; } -} \ No newline at end of file +} From 13e7666805e1909b7927e6404d52ff022c8e8a50 Mon Sep 17 00:00:00 2001 From: Krystian Bajno Date: Mon, 8 Apr 2019 18:20:49 +0200 Subject: [PATCH 2/4] Refunds support --- src/DotpayApi/Requests/AbstractRequest.php | 7 +++ src/DotpayApi/Requests/CreateRefund.php | 10 ++++ src/Exceptions/RequestIntegrityException.php | 12 ++++ tests/DotpayRefundTest.php | 60 ++++++++++++++++++++ 4 files changed, 89 insertions(+) create mode 100644 src/Exceptions/RequestIntegrityException.php create mode 100644 tests/DotpayRefundTest.php diff --git a/src/DotpayApi/Requests/AbstractRequest.php b/src/DotpayApi/Requests/AbstractRequest.php index d786d93..ba380bd 100644 --- a/src/DotpayApi/Requests/AbstractRequest.php +++ b/src/DotpayApi/Requests/AbstractRequest.php @@ -2,8 +2,15 @@ namespace Evilnet\Dotpay\DotpayApi\Requests; +/** + * Class AbstractRequest + * @package Evilnet\Dotpay\DotpayApi\Requests + */ class AbstractRequest { + /** + * @return array + */ public function toArray() { return get_object_vars($this); diff --git a/src/DotpayApi/Requests/CreateRefund.php b/src/DotpayApi/Requests/CreateRefund.php index 8092b62..23f60b9 100644 --- a/src/DotpayApi/Requests/CreateRefund.php +++ b/src/DotpayApi/Requests/CreateRefund.php @@ -3,6 +3,7 @@ namespace Evilnet\Dotpay\DotpayApi\Requests; use Evilnet\Dotpay\DotpayApi\Contracts\IRequest; +use Evilnet\Dotpay\Exceptions\RequestIntegrityException; /** * Class CreateRefund @@ -34,11 +35,20 @@ class CreateRefund extends AbstractRequest implements IRequest * CreateRefund constructor. * @param $operation_number * @param $data + * @throws RequestIntegrityException */ public function __construct($operation_number, $data) { + if(!$operation_number){ + throw new RequestIntegrityException("Operation number is not set"); + } + $this->operation_number = $operation_number; + foreach ($data as $key => $value) { + if(!$value || is_numeric($value) && $value <= 0){ + throw new RequestIntegrityException(); + } $this->$key = $value; } } diff --git a/src/Exceptions/RequestIntegrityException.php b/src/Exceptions/RequestIntegrityException.php new file mode 100644 index 0000000..2018120 --- /dev/null +++ b/src/Exceptions/RequestIntegrityException.php @@ -0,0 +1,12 @@ + 120, + "description" => "Refund for payment", + "control" => 123 + ] + ); + $this->assertTrue(isset($request)); + } + + /** + * @throws + */ + public function test_behavior_when_amount_is_invalid(){ + $this->expectException(RequestIntegrityException::class); + $request = new CreateRefund('M1006-4674', + [ + "amount" => -1, + "description" => "Refund for payment", + "control" => 123 + ] + ); + $this->assertTrue(isset($request)); + } + + /** + * @throws + */ + public function test_behavior_when_operation_number_is_null(){ + $this->expectException(RequestIntegrityException::class); + $request = new CreateRefund(null, + [ + "amount" => 120, + "description" => "Refund for payment", + "control" => 123 + ] + ); + $this->assertTrue(isset($request)); + } +} From f90f155b12780268cd463dbb2f4f5504268dcc38 Mon Sep 17 00:00:00 2001 From: Krystian Bajno Date: Tue, 9 Apr 2019 12:10:28 +0200 Subject: [PATCH 3/4] Refunds support --- src/DotpayApi/Requests/CreateRefund.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DotpayApi/Requests/CreateRefund.php b/src/DotpayApi/Requests/CreateRefund.php index 23f60b9..1675785 100644 --- a/src/DotpayApi/Requests/CreateRefund.php +++ b/src/DotpayApi/Requests/CreateRefund.php @@ -66,6 +66,6 @@ public function method() */ public function path() { - return 'api/v3/payments/'.$this->operation_number.'/refund/'; + return 'api/v1/payments/'.$this->operation_number.'/refund/'; } } From 02cff2a386cf5460f41b28e960de0577b44cd874 Mon Sep 17 00:00:00 2001 From: Krystian Bajno Date: Tue, 9 Apr 2019 16:02:02 +0200 Subject: [PATCH 4/4] Refunds support --- src/DotpayApi/Client.php | 1 + src/DotpayApi/DotpayApi.php | 9 ++++++--- src/DotpayApi/Response.php | 1 - src/DotpayApi/UrlCreator.php | 1 - src/DotpayApi/Validator.php | 1 - src/DotpayManager.php | 8 ++++++-- 6 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/DotpayApi/Client.php b/src/DotpayApi/Client.php index b6466d7..c57751f 100644 --- a/src/DotpayApi/Client.php +++ b/src/DotpayApi/Client.php @@ -44,6 +44,7 @@ public function __construct($username, $password, $base_url) /** * @param IRequest $request * @return mixed + * @throws \GuzzleHttp\Exception\GuzzleException */ public function makeRequest(IRequest $request) { diff --git a/src/DotpayApi/DotpayApi.php b/src/DotpayApi/DotpayApi.php index a0519d1..68deebd 100644 --- a/src/DotpayApi/DotpayApi.php +++ b/src/DotpayApi/DotpayApi.php @@ -43,6 +43,7 @@ public function __construct($config) /** * @param $payment * @return mixed|string + * @throws \GuzzleHttp\Exception\GuzzleException */ public function createPayment($payment) { @@ -51,10 +52,13 @@ public function createPayment($payment) /** * @param $payment + * @param $operation_number * @return mixed + * @throws \Evilnet\Dotpay\Exceptions\RequestIntegrityException + * @throws \GuzzleHttp\Exception\GuzzleException */ - public function refundPayment($payment){ - return $this->client->makeRequest(new CreateRefund($this->config['shop_id'], $payment)); + public function refundPayment($operation_number, $payment){ + return $this->client->makeRequest(new CreateRefund($operation_number, $payment)); } /** @@ -82,5 +86,4 @@ public function verifyCallback($data) { return $this->validator->verify($data); } - } diff --git a/src/DotpayApi/Response.php b/src/DotpayApi/Response.php index 0dcb7b6..1a599e8 100644 --- a/src/DotpayApi/Response.php +++ b/src/DotpayApi/Response.php @@ -77,5 +77,4 @@ public function getOperationStatus() { return $this->data['operation_status']; } - } diff --git a/src/DotpayApi/UrlCreator.php b/src/DotpayApi/UrlCreator.php index 0524be4..67e3c44 100644 --- a/src/DotpayApi/UrlCreator.php +++ b/src/DotpayApi/UrlCreator.php @@ -39,5 +39,4 @@ public function getPaymentUrlWithCHK($payment) { return $payment->payment_url.'&chk='.hash('sha256', ($this->pin.$payment->token)); } - } diff --git a/src/DotpayApi/Validator.php b/src/DotpayApi/Validator.php index 0b7e13e..d3422a7 100644 --- a/src/DotpayApi/Validator.php +++ b/src/DotpayApi/Validator.php @@ -69,5 +69,4 @@ public function verify($data) return $data['signature'] === $hash; } - } diff --git a/src/DotpayManager.php b/src/DotpayManager.php index 9614fae..7b7cdc2 100644 --- a/src/DotpayManager.php +++ b/src/DotpayManager.php @@ -35,6 +35,7 @@ public function __construct(DotpayApi $dotpayApi) /** * @param $data * @return mixed|string + * @throws \GuzzleHttp\Exception\GuzzleException */ public function createPayment($data) { @@ -42,11 +43,14 @@ public function createPayment($data) } /** + * @param $operation_number * @param $data * @return mixed + * @throws Exceptions\RequestIntegrityException + * @throws \GuzzleHttp\Exception\GuzzleException */ - public function refundPayment($data){ - return $this->dotpayApi->refundPayment($data); + public function refundPayment($operation_number, $data){ + return $this->dotpayApi->refundPayment($operation_number, $data); }