Completed
Push — master ( 3f4b39...daa8e9 )
by Kirill
10:57
created

Client::send()   A

Complexity

Conditions 2
Paths 4

Size

Total Lines 16
Code Lines 10

Duplication

Lines 16
Ratio 100 %

Importance

Changes 0
Metric Value
cc 2
eloc 10
nc 4
nop 1
dl 16
loc 16
rs 9.4285
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Personnage\Tinkoff\SDK\Merchant;
4
5
use GuzzleHttp\Psr7\Request;
6
use Personnage\Tinkoff\SDK\Exception\HttpException;
7
use Personnage\Tinkoff\SDK\HasSender;
8
use function Personnage\Tinkoff\SDK\pack;
9
use Personnage\Tinkoff\SDK\Exception\ResponseException;
10
use Personnage\Tinkoff\SDK\Response\Cancel;
11
use Personnage\Tinkoff\SDK\Response\Charge;
12
use Personnage\Tinkoff\SDK\Response\Confirm;
13
use Personnage\Tinkoff\SDK\Response\Init;
14
use Personnage\Tinkoff\SDK\Sender;
15
use Psr\Http\Message\RequestInterface;
16
17
final class Client
18
{
19
    use HasSignature, HasSender;
20
21
    private $baseUri;
22
    private $terminalKey;
23
    private $secretKey;
24
25
    /**
26
     * @var array
27
     */
28
    private static $requestHeaders = [
29
        'Accept' => 'application/json',
30
        'Content-Type' => 'application/x-www-form-urlencoded',
31
    ];
32
33
    /**
34
     * Init a new instance.
35
     *
36
     * @param string  $uri
37
     * @param string  $terminalKey
38
     * @param string  $secretKey
39
     * @param Sender  $sender
40
     */
41
    public function __construct(string $uri, string $terminalKey, string $secretKey, Sender $sender)
42
    {
43
        $this->baseUri = rtrim($uri, '/');
44
        $this->terminalKey = $terminalKey;
45
        $this->secretKey = $secretKey;
46
        $this->setSender($sender);
47
    }
48
49
    /**
50
     * Init a new payment session.
51
     *
52
     * @param string  $orderId Номер заказа в системе Продавца.
53
     * @param int     $amount  Сумма в копейках.
54
     * @param array   $extra   Массив дополнительных полей, которые могут быть переданы в этом запросе.
55
     *
56
     * @return Init
57
     * @throws HttpException
58
     */
59 View Code Duplication
    public function init(string $orderId, int $amount, array $extra = []): Init
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
60
    {
61
        $extra['Amount'] = $amount;
62
        $extra['OrderId'] = $orderId;
63
64
        return new Init($this->send($this->makeRequest('Init', $extra)));
65
    }
66
67
    /**
68
     * Init a new payment session.
69
     *
70
     * @param string  $customerKey
71
     * @param string  $orderId
72
     * @param int     $amount
73
     * @param array   $extra
74
     *
75
     * @return Init
76
     * @throws HttpException
77
     */
78
    public function rInit(string $customerKey, string $orderId, int $amount, array $extra = []): Init
79
    {
80
        $extra['Recurrent'] = 'Y';
81
        $extra['CustomerKey'] = $customerKey;
82
83
        return $this->init($orderId, $amount, $extra);
84
    }
85
86
    /**
87
     * Call charge.
88
     *
89
     * @param mixed  $paymentId
90
     * @param mixed  $rebillId
91
     *
92
     * @return Charge
93
     *
94
     * @throws HttpException
95
     */
96
    public function charge($paymentId, $rebillId): Charge
97
    {
98
        return new Charge($this->send($this->makeRequest('Charge', [
99
            'PaymentId' => $paymentId,
100
            'RebillId' => $rebillId,
101
        ])));
102
    }
103
104
    /**
105
     * Init a new payment session and call charge.
106
     *
107
     * @param mixed   $rebillId
108
     * @param string  $orderId
109
     * @param int     $amount
110
     * @param array   $extra
111
     *
112
     * @return Charge
113
     * @throws HttpException
114
     * @throws ResponseException
115
     */
116 View Code Duplication
    public function recurrent($rebillId, string $orderId, int $amount, array $extra = []): Charge
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
117
    {
118
        $response = $this->init($orderId, $amount, $extra);
119
        if ($response->hasError()) {
120
            throw new ResponseException($response);
121
        }
122
123
        $response = $this->charge($response->getPaymentId(), $rebillId);
124
        if ($response->hasError()) {
125
            throw new ResponseException($response);
126
        }
127
128
        return $response;
129
    }
130
131
    /**
132
     * Send confirm request.
133
     *
134
     * @param int       $paymentId
135
     * @param int|null  $amount
136
     * @param array     $extra
137
     *
138
     * @return Confirm
139
     * @throws HttpException
140
     */
141 View Code Duplication
    public function confirm(int $paymentId, int $amount = null, array $extra = []): Confirm
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
142
    {
143
        $extra['PaymentId'] = $paymentId;
144
145
        if (null !== $amount) {
146
            $extra['Amount'] = $amount;
147
        }
148
149
        return new Confirm($this->send($this->makeRequest('Confirm', $extra)));
150
    }
151
152
    /**
153
     * Send cancel request.
154
     *
155
     * @param int       $paymentId
156
     * @param int|null  $amount
157
     * @param array     $extra
158
     *
159
     * @return Cancel
160
     * @throws HttpException
161
     */
162 View Code Duplication
    public function cancel(int $paymentId, int $amount = null, array $extra = []): Cancel
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
163
    {
164
        $extra['PaymentId'] = $paymentId;
165
166
        if (null !== $amount) {
167
            $extra['Amount'] = $amount;
168
        }
169
170
        return new Cancel($this->send($this->makeRequest('Cancel', $extra)));
171
    }
172
173
    /**
174
     * Make a new http request.
175
     *
176
     * @param string  $uri
177
     * @param array   $body
178
     *
179
     * @return RequestInterface
180
     */
181
    private function makeRequest(string $uri, array $body = []): RequestInterface
182
    {
183
        if (isset($body['DATA'])) {
184
            $body['DATA'] = pack($body['DATA']);
185
        }
186
187
        $body['TerminalKey'] = $this->terminalKey;
188
        $body['Token'] = $this->sign($body, $this->secretKey);
189
190
        return new Request('post', "$this->baseUri/$uri", self::$requestHeaders, http_build_query($body, '', '&'));
191
    }
192
}
193